# 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  

clause.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/clause.h"
00021 #include "nel/ai/logic/boolval.h"
00022 #include "nel/ai/logic/ai_assert.h"
00023 #include "nel/ai/logic/valueset.h"
00024 #include "nel/ai/logic/fo_assert.h"
00025 
00026 namespace NLAILOGIC
00027 {
00028         using namespace NLAIAGENT;
00029 
00030         CClause::CClause()
00031         {
00032                 _Liaisons.push_back( new CValueSet( _Vars.size() ) );
00033                 _NbValid = 0;
00034         }
00035 
00036         CClause::CClause(std::list<CFactPattern *> &conds) : CVarSet()
00037         {
00038                 _NbValid = 0;
00039                 std::list<CFactPattern *>::iterator it_c = conds.begin();
00040                 while ( it_c != conds.end() )
00041                 {
00042                         addCond( (CFactPattern *) (*it_c)->clone() );
00043                         it_c++;
00044                 }
00045                 _Liaisons.push_back( new CValueSet( _Vars.size() ) );
00046         }
00047 
00048         CClause::CClause(const CClause &cl) : CVarSet(cl)
00049 
00050         {
00051                 _NbValid = cl._NbValid;
00052                 std::vector<IBaseBoolType *>::const_iterator it_c = cl._Conds.begin();
00053                 while ( it_c != cl._Conds.end() )
00054                 {
00055                         addCond( (CFactPattern *) *it_c );
00056                         it_c++;
00057                 }
00058 
00059                 std::vector< std::vector<sint32> >::const_iterator it_li = cl._PosVarsCond.begin();
00060                 while ( it_li != cl._PosVarsCond.end() )
00061                 {
00062                         std::vector<sint32>::const_iterator it_i = (*it_li).begin();
00063                         _PosVarsCond.push_back( std::vector<sint32>() );
00064 
00065                         while ( it_i != (*it_li).end() )
00066                         {
00067                                 _PosVarsCond.back().push_back( *it_i ) ;
00068                                 it_i++;
00069                         }
00070                         it_li++;
00071                 }
00072         }
00073 
00074         CClause::~CClause()
00075         {
00076                 for ( sint32 i = 0; i < (sint32) _Conds.size(); i++ )
00077                         _Conds[i]->release();
00078                 
00079                 while ( ! _Conflits.empty() )
00080                 {
00081                         delete _Conflits.front();
00082                         _Conflits.pop_front();
00083                 }
00084 
00085                 while ( ! _Liaisons.empty() )
00086                 {
00087                         delete _Liaisons.front();
00088                         _Liaisons.pop_front();
00089                 }
00090 
00091                 while ( ! _BufLiaisons.empty() )
00092                 {
00093                         delete _BufLiaisons.front();
00094                         _BufLiaisons.pop_front();
00095                 }
00096         }
00097 
00098         const NLAIC::IBasicType *CClause::clone() const
00099         {
00100                 CClause *clone = new CClause( *this );
00101                 return clone;
00102         }       
00103         
00104         const NLAIC::IBasicType *CClause::newInstance() const
00105         {
00106                 CClause *instance = new CClause();
00107                 return instance;
00108         }
00109 
00110         sint32 CClause::findAssert(IBaseAssert *a)
00111         {
00112                 if ( a )
00113                         for ( sint32 i = 0; i < (sint32)_Asserts.size(); i++ )
00114                         {
00115                                 if ( _Asserts[i]->getName() == a->getName() )
00116                                 {
00117                                         return i;
00118                                 }
00119                         }
00120 
00121                 return -1;
00122         }
00123 
00124         void CClause::addCond(CFactPattern *cond)
00125         {
00126                 _Conds.push_back( (CFactPattern *) cond->clone() );
00127 
00128                 // Recherche l'assertion
00129                 sint32 pos_assert= findAssert( cond->getAssert() );
00130                 if ( pos_assert  < 0 )
00131                 {
00132                         _Asserts.push_back( cond->getAssert() );
00133                         pos_assert = _Asserts.size();
00134                 }
00135 
00136                 // Recherche si variables à ajouter
00137                 std::vector<sint32> pos_vars;
00138                 std::vector<IBaseVar *> *vars_cond = cond->getVars();
00139                 if ( vars_cond )
00140                 {
00141                         std::vector<IBaseVar *>::iterator it_cond = vars_cond->begin();
00142                         while ( it_cond != vars_cond->end() )
00143                         {
00144                                 bool found;
00145                                 if ( _Vars.size() )
00146                                 {
00147                                         found = false;
00148                                         for (sint32 i = 0; i < (sint32)_Vars.size() ; i++ ) 
00149                                         {
00150                                                 if ( ( *it_cond )->getName() == _Vars[ i ]->getName() )
00151                                                 {
00152                                                         found = true;
00153                                                         pos_vars.push_back( i );
00154                                                 }
00155                                         }
00156                                 }
00157                                 else
00158                                         found = false;
00159                                 
00160                                 if ( !found ) 
00161                                 {
00162                                         _Vars.push_back( (IBaseVar *)(*it_cond)->clone() );
00163                                         pos_vars.push_back( _Vars.size() - 1);
00164                                 }
00165                                 it_cond++;
00166                         }
00167                 }
00168 
00169                 // Prévenir l'assertion
00170                 if ( cond->getAssert() )
00171                 {
00172                         ((CFirstOrderAssert *) cond->getAssert())->addClause( this, pos_vars );
00173                         _PosVarsCond.push_back( pos_vars );
00174                 }
00175 
00176                 for ( sint32 i = 0; i < (sint32) vars_cond->size(); i++ )
00177                 {
00178                         (*vars_cond)[i]->release();
00179                 }
00180                 delete vars_cond;
00181         }
00182 
00183         void CClause::getDebugString(std::string &txt) const
00184         {               
00185                 txt += "CClause ";
00186                 for (sint32 i = 0; i < (sint32)_Vars.size(); i++ )
00187                 {
00188                         std::string buf;
00189                         _Vars[ i ]->getDebugString( buf );
00190                         txt += "  - ";
00191                         txt += buf;
00192                 }
00193         }
00194 
00195         void CClause::propagate(CFactPattern *fp)
00196         {
00197                 // Pour chaque liaison...
00198 /*              std::list< CValueSet *>::iterator it_l = _Liaisons.begin();
00199                 
00200                 while ( it_l != _Liaisons.end() )
00201                 {
00202                         CValueSet *result;
00203                         if ( result = fp->unify( *it_l ) )
00204                         {
00205                                 if ( result->undefined() == 0 )
00206                                         _Conflits.push_back( result );
00207                                 else 
00208                                         _BufLiaisons.push_back( result );
00209                         }
00210                         it_l++;
00211                 }*/
00212         }
00213         
00214         void CClause::propagate(std::list<IObjectIA *> *vals, std::vector<sint32> &pos_vals) 
00215         {
00216                 // Pour chaque liaison...
00217                 std::list< CValueSet *>::iterator it_l = _Liaisons.begin();
00218                 
00219                 while ( it_l != _Liaisons.end() )
00220                 {
00221 //                      char buf[512];
00222                         CValueSet *l = *it_l;
00223 /*                      l->getDebugString( buf );
00224                         TRACE( "Pour liaison: %s \n", buf );*/
00225                         CValueSet *result = unifyLiaison( l, vals, pos_vals );
00226                         if ( result )
00227                         {
00228 
00229 /*                              char buf[512];
00230                                 result->getDebugString( buf );
00231                                 TRACE( "Unification: %s \n", buf );*/
00232 
00233                                 if ( result->undefined() == 0 )
00234                                 {
00235                                         _Conflits.push_back( result );
00236                                         _NbValid++;
00237                                 }
00238 
00239                                 else 
00240                                         _BufLiaisons.push_back( result );
00241                         }
00242                         it_l++;
00243                 }
00244 
00245                 addBuffer();
00246                 addConflicts();
00247 
00248         }       
00249 
00250         // Tente d'unifier deux instanciations partielles des variables de la CClause
00251         CValueSet *CClause::unifyLiaison( const CValueSet *fp, std::list<IObjectIA *> *vals, std::vector<sint32> &pos_vals)
00252         {
00253                 CValueSet *result;
00254 
00255                 if ( (result = fp->unify( vals, pos_vals )) )
00256                         return result;
00257                 else
00258                 {
00259                         delete result;
00260                         return NULL;
00261                 }
00262         }
00263 
00264         IObjetOp *CClause::operator ! () const
00265         {
00266 
00267                 return new CBoolType( !isTrue() );
00268         }
00269 
00270         IObjetOp *CClause::operator != (IObjetOp &a) const
00271         {
00272                 return new CBoolType( isTrue() != a.isTrue() );
00273         }
00274 
00275         bool CClause::isTrue() const
00276         {
00277                 return ( _NbValid > 0 );
00278         }
00279 
00280         float CClause::truthValue() const
00281         {
00282                 if ( _NbValid > 0 )
00283                         return 1.0;
00284                 else
00285                         return 0.0;
00286         }
00287 
00288         IObjetOp *CClause::operator == (IObjetOp &a) const
00289         {
00290                 return new CBoolType( isTrue() == a.isTrue() );
00291         }
00292 
00293         void CClause::showConflicts()
00294         {
00295                 std::list<CValueSet *>::iterator it_vs = _Conflits.begin();
00296                 while ( it_vs != _Conflits.end() )
00297                 {
00298                         std::string buf;
00299                         ( *it_vs )->getDebugString( buf );
00300                         it_vs++;
00301                 }
00302         }
00303 
00304         void CClause::showBuffer()
00305         {
00306                 std::list<CValueSet *>::iterator it_vs = _BufLiaisons.begin();
00307                 while ( it_vs != _BufLiaisons.end() )
00308                 {
00309                         std::string buf;
00310                         ( *it_vs )->getDebugString( buf );                      
00311                         it_vs++;
00312                 }
00313         }
00314 
00315         void CClause::showLiaisons()
00316         {
00317                 std::list<CValueSet *>::iterator it_vs = _Liaisons.begin();
00318                 while ( it_vs != _Liaisons.end() )
00319                 {
00320                         std::string buf;
00321                         ( *it_vs )->getDebugString( buf );                      
00322                         it_vs++;
00323                 }
00324         }
00325 
00326 
00327         // Transfert des liaisons du buffer à la liste des liaisons
00328         void CClause::addBuffer()
00329         {
00330                 while ( !_BufLiaisons.empty() )
00331                 {
00332                         _Liaisons.push_back( _BufLiaisons.front() );
00333                         std::string buf;
00334                         _BufLiaisons.front()->getDebugString( buf );
00335                         //TRACE ( "Ajout de la liaison du buffer: %s ", buf );
00336                         _BufLiaisons.pop_front();
00337                 }
00338         }
00339         
00340         // Traitement des conflits
00341         void CClause::addConflicts()
00342         {
00343         }
00344 
00345         // Renvoie les assertions des conditions de la CClause
00346         std::vector<IBaseAssert *> &CClause::getAssert()
00347         {
00348                 return _Asserts;
00349         }
00350 
00351         CVarSet *CClause::unify(CVarSet *)
00352         {
00353                 // TODO:
00354 /*
00355                 std::list<CValueSet *>::iterator it_l = _Liaisons.begin();
00356                 while ( it_cond != _Conds.end() )
00357                 {
00358                         CVarSet *tmp = ( *it_cond )->unify( fact );
00359                         
00360                         if ( !tmp )
00361                                 return;
00362                         it_cond++;
00363                 }
00364                 */
00365                 return NULL;
00366         }
00367 
00368         std::list<CClause *> *CClause::getInputs()
00369         {
00370                 return new std::list<CClause *>;
00371         }
00372 
00373         sint32 CClause::nbVars()
00374         {
00375                 return _Vars.size();
00376         }
00377 
00378         void CClause::init(IObjectIA *params)
00379         {
00380 /*              if ( params->size() != 3 )
00381                 {
00382                         // TODO throw Exc::....
00383                 }*/
00384 
00385                 // Conditions
00386                 CIteratorContener it_fp = ((IBaseGroupType *)params)->getIterator();
00387                 while ( !it_fp.isInEnd())
00388                 {
00389                         addCond( (CFactPattern *) it_fp++ );                    
00390                 }
00391         }
00392 
00393 /*      const std::vector< std::list<sint32> > &CClause::getPosVar()
00394         {
00395                 return _pos_vars;
00396         }
00397         */
00398 }