# 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  

rule.cpp

Go to the documentation of this file.
00001 /* Copyright, 2000 Nevrax Ltd.
00002  *
00003  * This file is part of NEVRAX <MODULE_NAME>.
00004  * NEVRAX <MODULE_NAME> is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2, or (at your option)
00007  * any later version.
00008 
00009  * NEVRAX <MODULE_NAME> is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00012  * General Public License for more details.
00013 
00014  * You should have received a copy of the GNU General Public License
00015  * along with NEVRAX <MODULE_NAME>; see the file COPYING. If not, write to the
00016  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00017  * MA 02111-1307, USA.
00018  */
00019 
00020 #include "nel/ai/logic/rule.h"
00021 #include "nel/ai/logic/ai_assert.h"
00022 #include "nel/ai/logic/valueset.h"
00023 #include "nel/ai/logic/fo_assert.h"
00024 
00025 namespace NLAILOGIC
00026 {
00027         using namespace NLAIAGENT;
00028 
00029         CRule::CRule()
00030         {
00031         }
00032 
00033         CRule::CRule(std::list<CFactPattern *> &conds, std::list<CFactPattern *> &concs) : CClause( conds )
00034         {
00035                 std::list<CFactPattern *>::iterator it_c = concs.begin();
00036                 while ( it_c != concs.end() )
00037                 {
00038                         addConc( *it_c );
00039                         it_c++;
00040                 }
00041         }
00042 
00043         CRule::CRule(const CRule &c) : CClause(c)
00044         {
00045                 std::vector<IBaseAssert *>::const_iterator it_c = c._Concs.begin();
00046                 while ( it_c != c._Concs.end() )
00047                 {
00048                         _Concs.push_back( *it_c );
00049                         it_c++;
00050                 }
00051 
00052                 std::vector< std::vector<sint32> >::const_iterator it_li = c._PosVarsConc.begin();
00053                 while ( it_li != c._PosVarsConc.end() )
00054                 {
00055                         std::vector<sint32>::const_iterator it_i = (*it_li).begin();
00056                         _PosVarsConc.push_back( std::vector<sint32>() );
00057 
00058                         while ( it_i != (*it_li).end() )
00059                         {
00060                                 _PosVarsConc.back().push_back( *it_i ) ;
00061                                 it_i++;
00062                         }
00063                         it_li++;
00064                 }
00065         }
00066 
00067         void CRule::setCond(CClause &c)
00068         {
00069 /*              std::list< std::vector<sint32> >::const_iterator it_li = c._pos_vars.begin();
00070                 while ( it_li != c._pos_vars.end() )
00071                 {
00072                         std::vector<sint32>::const_iterator it_i = (*it_li).begin();
00073                         _pos_vars.push_back( std::vector<sint32>() );
00074 
00075                         while ( it_i != (*it_li).end() )
00076                         {
00077                                 _pos_vars.back().push_back( *it_i ) ;
00078                                 it_i++;
00079                         }
00080                         it_li++;
00081                 }*/
00082         }
00083 
00084         CRule::~CRule()
00085         {
00086         }
00087 
00088         const NLAIC::IBasicType *CRule::clone() const
00089         {
00090                 NLAIC::IBasicInterface *m = new CRule(*this);
00091                 return m;
00092         }
00093 
00094         const NLAIC::IBasicType *CRule::newInstance() const
00095         {
00096                 CRule *instance = new CRule();
00097                 return instance;
00098         }
00099 
00100 
00101         void CRule::addConc(CFactPattern *conc)
00102         {
00103                 _Concs.push_back( conc->getAssert() );
00104 
00105                 // Recherche l'assertion
00106                 sint32 pos_assert= findAssert( conc->getAssert() );
00107                 if ( pos_assert  < 0 )
00108                 {
00109                         _Asserts.push_back( conc->getAssert() );
00110                         pos_assert = _Asserts.size();
00111                 }
00112 
00113                 // Recherche si variables à ajouter
00114                 std::vector<sint32> pos_vars;
00115                 std::vector<IBaseVar *> *vars_conc = conc->getVars();
00116                 if ( vars_conc )
00117                 {
00118                         std::vector<IBaseVar *>::iterator it_conc = vars_conc->begin();
00119                         while ( it_conc != vars_conc->end() )
00120                         {
00121                                 bool found;
00122                                 if ( _Vars.size() )
00123                                 {
00124                                         found = false;
00125                                         for (sint32 i = 0; i < (sint32)_Vars.size() ; i++ ) 
00126                                         {
00127                                                 if ( ( *it_conc )->getName() == _Vars[ i ]->getName() )
00128                                                 {
00129                                                         found = true;
00130                                                         pos_vars.push_back( i );
00131                                                 }
00132                                         }
00133                                 }
00134                                 else
00135                                         found = false;
00136                                 
00137                                 if ( !found ) 
00138                                 {
00139                                         _Vars.push_back( (IBaseVar *)(*it_conc)->clone() );
00140                                         pos_vars.push_back( _Vars.size() - 1);
00141                                 }
00142                                 it_conc++;
00143                         }
00144                 }
00145 
00146                 // Prévenir l'assertion
00147                 if ( conc->getAssert() )
00148                 {
00149                         ((CFirstOrderAssert *)conc->getAssert())->addInput( this, pos_vars );
00150                         _PosVarsConc.push_back( pos_vars );
00151                 }
00152 
00153                 for ( sint32 i = 0; i < (sint32) vars_conc->size(); i++ )
00154                 {
00155                         (*vars_conc)[i]->release();
00156                 }
00157                 delete vars_conc;
00158         }
00159 
00160         void CRule::forward(CVarSet *fp)
00161         {
00162                 
00163         }
00164 
00165         void CRule::addConflicts()
00166         {
00167                 // Execute la conclusion de la règle
00168                 std::list<CValueSet *>::iterator it_conf = _Conflits.begin();
00169                 while ( it_conf != _Conflits.end() )
00170                 {
00171                         sint32 pos = 0;
00172                         std::vector<IBaseAssert *>::iterator it_conc = _Concs.begin();
00173                         std::vector< std::vector<sint32> >::iterator it_pos = _PosVarsConc.begin();
00174                         while ( it_conc != _Concs.end() )
00175                         {
00176                                 // Construire le fait correspondant par rapport à la position des variables
00177                                 CValueSet *conflit = new CValueSet( *it_conf , *it_pos );
00178                                 
00180 #ifdef NL_DEBUG
00181                                 std::string buf;
00182                                 std::string buf2;
00183                                 (*it_conc)->getDebugString( buf );
00184                                 conflit->getDebugString( buf2 );
00185 #endif
00186                                 //TRACE("\nCONCLUSION DE LA REGLE: \n   ASSERTION: %s   VALEURS: %s\n", buf, buf2);
00188                                 it_conc++;
00189                         }
00190                         it_conf++;
00191                         pos++;
00192                 }
00193         }
00194 
00195         void CRule::init(IObjectIA *params)
00196         {
00197 /*              if ( params->size() != 3 )
00198                 {
00199                         // TODO throw Exc::....
00200                 }*/
00201 
00202                 // Conditions
00203                 CClause *cond = (CClause *) ((IBaseGroupType *)params)->popFront();
00204                 std::vector<IBaseVar *> *vars = cond->getVars();
00205 
00206                 int i;
00207 
00208                 for ( i = 0; i < (sint32)vars->size() ; i++ )
00209                 {
00210                         _Vars.push_back( (IBaseVar *) (* vars)[ i ]->clone() );
00211                 }
00212                 
00213                 for ( i = 0; i < (sint32) vars->size() ; i++ )
00214                         (*vars)[i]->release();
00215                 delete vars;
00216                 cond->release();
00217 
00218                 // Conclusions
00219                 IBaseGroupType *concs = (IBaseGroupType *) ((IBaseGroupType *)params)->popFront();
00220                 CIteratorContener it_fp = concs->getIterator();
00221                 sint32 s = concs->size();
00222                 while ( !it_fp.isInEnd() )
00223                 {
00224                         CFactPattern *tmp = (CFactPattern *) ( it_fp ++)->clone();
00225                         addConc( tmp);
00226                         tmp->release();
00227                         //it_fp++;
00228                 }
00229 
00230                 concs->release();
00231         }
00232 
00233         const NLAIC::CIdentType &CRule::getType() const
00234         {
00235                 return IdRule;
00236         }
00237 
00238         void CRule::getDebugString(std::string &txt) const
00239         {               
00240                 txt += "CRule\n - Conditions: ";
00241                 std::vector<IBaseBoolType *>::const_iterator it_c = _Conds.begin();
00242                 while ( it_c != _Conds.end() )
00243                 {
00244                         std::string buf;
00245                         ( *it_c )->getDebugString( buf );
00246                         txt += "    - ";
00247                         txt += buf;
00248                         it_c++;
00249                 }
00250 
00251                 txt += "\n - Conclusions: ";
00252                 
00253                 std::vector<IBaseAssert *>::const_iterator it_cc = _Concs.begin();
00254 
00255                 while ( it_cc != _Concs.end() )
00256                 {
00257                         std::string buf;
00258                         ( *it_cc )->getDebugString( buf );
00259                         txt += "    - ";
00260                         txt += buf;
00261                         it_cc++;
00262                 }
00263 
00264                 txt += "\n - Variables ";
00265                 for (sint32 i = 0; i < (sint32)_Vars.size(); i++ )
00266                 {
00267                         std::string buf;
00268                         _Vars[ i ]->getDebugString( buf );
00269                         txt += "    - ";
00270                         txt += buf;
00271                 }
00272         }
00273 
00276 // Chainage arrière
00277 
00278 
00279         CVarSet *CRule::backWard(CFactPattern *fp)
00280         {
00281                 // Vecteur temporaire des variables
00282                 CVarSet *tmp_vars = new CVarSet;
00283                 for (sint32 i = 0; i < (sint32) _Vars.size() ; i++)
00284                         tmp_vars->addVar( _Vars[i] );
00285 
00286                 // Trouver l'assertion dans la conclusion
00287                 std::vector<IBaseAssert *>::iterator it_a = _Concs.begin();
00288                 std::vector< std::vector<sint32> >::iterator it_p = _PosVarsConc.begin();
00289                 while ( it_a != _Concs.end() && (*it_a) != fp->getAssert() )
00290                 {
00291                         it_a++;
00292                         it_p++;
00293                 }
00294                 if ( it_a == _Concs.end() )
00295                         return NULL;
00296 
00297                 std::vector<sint32> pos_list = *it_p;
00298                 std::vector<sint32>::iterator it_pos = pos_list.begin();
00299         
00300                 // Unification avec la valeur des variables
00301                 sint32 index = 0;
00302                 while ( it_pos != pos_list.end() )
00303                 {
00304                         if ( (*tmp_vars->getVars())[*it_pos]->getValue() == NULL)
00305                                 (*tmp_vars)[*it_pos]->setValue( (*fp)[index]->getValue() );
00306                         else
00307                         {
00308                                 return NULL;
00309                         }
00310                         it_pos++;
00311                         index++;
00312                 }
00313                 return tmp_vars;
00314         }
00315  
00316         // Retourne une liste de faits complets
00317         std::list<CValueSet *> *CRule::unifyBack(CFactPattern *fp)
00318         {
00319                 std::list<CValueSet *> *unified_list = new std::list<CValueSet *>;
00320                 
00321                 // Vecteur temporaire des variables
00322                 CVarSet *tmp_vars = new CVarSet;
00323                 for (sint32 i = 0; i < (sint32) _Vars.size() ; i++)
00324                         tmp_vars->addVar( _Vars[i] );
00325 
00326                 // Trouver l'assertion dans la conclusion
00327                 std::vector<IBaseAssert *>::iterator it_a = _Concs.begin();
00328                 std::vector< std::vector<sint32> >::iterator it_p = _PosVarsConc.begin();
00329                 while ( it_a != _Concs.end() && (*it_a) != fp->getAssert() )
00330                 {
00331                         it_a++;
00332                         it_p++;
00333                 }
00334                 if ( it_a == _Concs.end() )
00335                         return NULL;
00336 
00337                 IBaseAssert *my_assert = *it_a;
00338 
00339                 // Créé la liste des valeurs 
00340                 std::list<IObjetOp *> *vals = fp->getValues();
00341 
00342                 // Pour chaque liaison...
00343                 std::list< CValueSet *>::iterator it_l = _Liaisons.begin();
00344                 
00345                 while ( it_l != _Liaisons.end() )
00346                 {
00347                         CValueSet *l = *it_l;
00348                         bool complete;
00349                         CValueSet *result = unifyLiaisonBack( l, *vals, *it_p, complete );
00350                         if ( result )
00351                         {
00352                                 if ( complete )
00353                                 {
00354                                         // Ceux là on les rajoute direct dans la liste
00355                                         //char test[1024 * 2];
00356                                         //result->getDebugString( test );
00357                                         CValueSet *n = fp->asCValueSet();
00358                                         sint32 pos_r = 0;
00359                                         std::vector<sint32>::iterator it_i = (*it_p).begin();
00360                                         while ( it_i != (*it_p).end() )
00361                                         {
00362                                                 sint32 i = *it_i;
00363 #ifdef NL_DEBUG
00364                                                 std::string buf;
00365                                                 (*result)[ *it_i ]->getDebugString(buf);
00366 #endif
00367 
00368                                                 n->setValue( pos_r, (*result)[ *it_i ] );
00369                                                 it_i++;
00370                                                 pos_r++;
00371                                         }
00372                                         unified_list->push_back( n );
00373                                 }
00374 #ifdef NL_DEBUG
00375                                 else 
00376                                 {
00377                                         // Ceux là on continue à les propager en arrière!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00378 
00379                                         std::string test;
00380                                         result->getDebugString( test );
00381                                 }
00382 #endif
00383                         }
00384                         it_l++;
00385                 }
00386                 return unified_list;
00387         }
00388 
00389         void CRule::backward( std::list<CValueSet *> *vs )
00390         {
00391                 std::vector<IBaseBoolType *>::iterator it_cond = _Conds.begin();
00392                 while ( it_cond != _Conds.end() )
00393                 {
00394                         std::list<CValueSet *>::iterator it_vs = vs->begin();
00395                         while ( it_vs != vs->end() )
00396                         {
00397 //                              ( (CFirstOrderAssert *) *it_cond )->backward( *it_vs );
00398                                 it_vs++;
00399                         }
00400                         it_cond++;
00401                 }
00402         }
00403 
00404         CValueSet *CRule::unifyLiaisonBack(CValueSet *liaison, std::list<IObjetOp *> &vals, std::vector<sint32> &pos, bool &defined)
00405         {
00406                 sint32 nb_undefined = pos.size();
00407                 CValueSet *unified = new CValueSet( *liaison );
00408                 std::vector<sint32>::iterator it_pos = pos.begin();
00409                 std::list<IObjetOp *>::iterator it_v = vals.begin();
00410                 while ( it_pos != pos.end() )
00411                 {
00412                         IObjectIA *l_val = (*unified)[*it_pos];
00413                         IObjectIA *r_val = *it_v;
00414                         sint32 p = *it_pos;
00415                         if ( !l_val )
00416                         {
00417 /*                              if ( r_val )
00418                                 {
00419                                         unified->setValue( p , r_val );
00420                                         nb_undefined--;
00421                                 }*/
00422                         }
00423                         else
00424                         {
00425                                 if ( r_val && ( l_val != r_val ) )
00426                                 {
00427                                         unified->release();
00428                                         return NULL;
00429                                 }
00430                                 else 
00431                                         if ( r_val ) 
00432                                                 nb_undefined--;
00433                         }
00434                         it_pos++;
00435                         it_v++;
00436                 }
00437                 defined = ( nb_undefined == 0 );
00438 
00439 #ifdef NL_DEBUG
00440                 std::string buf;
00441                 unified->getDebugString(buf);
00442 #endif
00443 
00444 
00445                 return unified;
00446         }
00447 
00448         // Retourne les assertions avec les positions des variables d'une conclusion dans les conditions
00449         void CRule::getPosListBackward(sint32 no_conc, sint32 no_cond, std::vector<sint32> &cond_pos)
00450         {
00451                 std::vector<sint32>::iterator it_conc = _PosVarsConc[ no_conc ].begin();
00452                 while ( it_conc != _PosVarsConc[ no_conc ].end() )
00453                 {
00454                         std::vector<sint32>::iterator it_cond = _PosVarsCond[ no_cond ].begin();
00455                         while ( it_cond != _PosVarsCond[ no_cond ].end() )
00456                         {
00457                                 if ( (*it_conc) == (*it_cond) )
00458                                 {
00459                                         cond_pos.push_back( *it_cond );
00460                                 }
00461                                 it_cond++;
00462                         }
00463                         it_conc++;
00464                 }
00465         }
00466 
00467         // Retourne les assertions avec les positions des variables d'une conclusion dans les conditions
00468         void CRule::getPosListForward(sint32 no_cond, sint32 no_conc, std::vector<sint32> &conc_pos)
00469         {
00470                 std::vector<sint32>::iterator it_cond = _PosVarsCond[ no_cond ].begin();
00471                 while ( it_cond != _PosVarsCond[ no_cond ].end() )
00472                 {
00473                         std::vector<sint32>::iterator it_conc = _PosVarsConc[ no_conc ].begin();
00474                         while ( it_conc != _PosVarsConc[ no_conc ].end() )
00475                         {
00476                                 if ( (*it_cond) == (*it_conc) )
00477                                 {
00478                                         conc_pos.push_back( *it_conc );
00479                                 }
00480                                 it_conc++;
00481                         }
00482                         it_cond++;
00483                 }
00484         } 
00485 }