database.h

00001 /*
00002  * All of the documentation and software included in the
00003  * Alchemy Software is copyrighted by Stanley Kok, Parag
00004  * Singla, Matthew Richardson, Pedro Domingos, Marc
00005  * Sumner and Hoifung Poon.
00006  * 
00007  * Copyright [2004-07] Stanley Kok, Parag Singla, Matthew
00008  * Richardson, Pedro Domingos, Marc Sumner and Hoifung
00009  * Poon. All rights reserved.
00010  * 
00011  * Contact: Pedro Domingos, University of Washington
00012  * (pedrod@cs.washington.edu).
00013  * 
00014  * Redistribution and use in source and binary forms, with
00015  * or without modification, are permitted provided that
00016  * the following conditions are met:
00017  * 
00018  * 1. Redistributions of source code must retain the above
00019  * copyright notice, this list of conditions and the
00020  * following disclaimer.
00021  * 
00022  * 2. Redistributions in binary form must reproduce the
00023  * above copyright notice, this list of conditions and the
00024  * following disclaimer in the documentation and/or other
00025  * materials provided with the distribution.
00026  * 
00027  * 3. All advertising materials mentioning features or use
00028  * of this software must display the following
00029  * acknowledgment: "This product includes software
00030  * developed by Stanley Kok, Parag Singla, Matthew
00031  * Richardson, Pedro Domingos, Marc Sumner and Hoifung
00032  * Poon in the Department of Computer Science and
00033  * Engineering at the University of Washington".
00034  * 
00035  * 4. Your publications acknowledge the use or
00036  * contribution made by the Software to your research
00037  * using the following citation(s): 
00038  * Stanley Kok, Parag Singla, Matthew Richardson and
00039  * Pedro Domingos (2005). "The Alchemy System for
00040  * Statistical Relational AI", Technical Report,
00041  * Department of Computer Science and Engineering,
00042  * University of Washington, Seattle, WA.
00043  * http://www.cs.washington.edu/ai/alchemy.
00044  * 
00045  * 5. Neither the name of the University of Washington nor
00046  * the names of its contributors may be used to endorse or
00047  * promote products derived from this software without
00048  * specific prior written permission.
00049  * 
00050  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF WASHINGTON
00051  * AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
00052  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00053  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00054  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY
00055  * OF WASHINGTON OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
00056  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00057  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00058  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00059  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
00060  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00061  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00062  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
00063  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00064  * 
00065  */
00066 #ifndef DATABASE_H_JUN_28_2005
00067 #define DATABASE_H_JUN_28_2005
00068 
00069 #include "groundpreds.h"
00070 #include "domain.h"
00071 #include "arraysaccessor.h"
00072 #include "groundpredicate.h"
00073 
00074   // Used by Database::paramMultByPred_. 
00075   // First value is the multiplier and the second is the class id.
00076 typedef pair<unsigned int, unsigned int> MultAndType;
00077 
00078 const int dbdebug = 0;
00079 //const int dbdebug = 1;
00080 
00081 // T_INDEX = True, FA_INDEX = False and Active
00082 enum IndexType { T_INDEX = 0, FA_INDEX = 1, INDEX_TYPE_COUNT = 2 };
00083 
00084 struct NumTrueFalse 
00085 { 
00086   NumTrueFalse(): numTrue(0), numFalse(0) {}  
00087   int numTrue; 
00088   int numFalse; 
00089 };
00090 
00091 
00092 class Database
00093 {
00094  public:
00095     //ASSUMPTION: constants of the same type are ordered consecutively
00096     //            should have called d's reorderConstants()
00097   Database(Domain* const & d, const Array<bool>& closedWorld, 
00098            const bool &storeGndPreds) : domain_(d)
00099   {
00100         lazyFlag_ = false;
00101         performingInference_ = false;
00102         assert(closedWorld.size() == domain_->getNumPredicates());
00103     int numFOPreds = domain_->getNumPredicates();
00104 
00105     int numTypes = domain_->getNumTypes();
00106     firstConstIdByType_.growToSize(numTypes);
00107     for (int i = 0; i < numTypes; i++)
00108     {
00109       assert(domain_->isType(i));
00110       const Array<int>* constIds = domain_->getConstantsByType(i);
00111       if (constIds->empty()) firstConstIdByType_[i] = (unsigned int)0;
00112       else                   firstConstIdByType_[i] = (*constIds)[0];
00113     }
00114 
00115     closedWorld_.growToSize(numFOPreds);
00116     memcpy((void*)closedWorld_.getItems(), closedWorld.getItems(),
00117            closedWorld.size()*sizeof(bool));
00118         
00119     termMultByPred_.growToSize(numFOPreds, NULL);
00120 
00121     truePredIdxSet_ = new Array<hash_set<int> >(numFOPreds);
00122     falsePredIdxSet_ = new Array<hash_set<int> >(numFOPreds);
00123     numberOfGroundings_.growToSize(numFOPreds);
00124     truePredIdxSet_->growToSize(numFOPreds);
00125     falsePredIdxSet_->growToSize(numFOPreds);
00126 
00127     paramPredsArray_ = new Array<Array<Array<Array<Array<int>*>*>*>*>;
00128     paramPredsArray_->growToSize(INDEX_TYPE_COUNT);
00129       
00130           //Initialize inverse index
00131     for(int idxType = 0; idxType < INDEX_TYPE_COUNT; idxType++)
00132     {
00133       (*paramPredsArray_)[idxType] = new Array<Array<Array<Array<int>*>*>*>;
00134       (*paramPredsArray_)[idxType]->growToSize(numFOPreds, NULL);
00135     }
00136 
00137     for (int i = 0; i < numFOPreds; i++)
00138     {
00139         // if this is a '=' pred, leave termMultByPred_[i]
00140         // as NULL
00141       const PredicateTemplate* t = domain_->getPredicateTemplate(i);
00142           if (t->isEqualPredWithType()) continue;
00143                 // Internal predicates are included!
00144                 
00145           const Array<int>* termTypes = domain_->getPredicateTermTypesAsInt(i);
00146       Array<MultAndType>* matArr = new Array<MultAndType>;
00147       int numTermTypes = termTypes->size(); 
00148       matArr->growToSize(numTermTypes);
00149       int curMult = 1;
00150       for (int j = numTermTypes-1; j >= 0; j--)
00151       {
00152         int typeId = (*termTypes)[j];
00153         (*matArr)[j] = MultAndType(curMult,typeId);
00154         curMult *= domain_->getNumConstantsByType(typeId);
00155       }
00156       termMultByPred_[i] = matArr;
00157 
00158         //Initialize inverse index for this predicate
00159       for(int idxType = 0; idxType < INDEX_TYPE_COUNT; idxType++)
00160       {
00161         (*((*paramPredsArray_)[idxType]))[i] = new Array<Array<Array<int>*>*>;
00162         (*((*paramPredsArray_)[idxType]))[i]->growToSize(t->getNumTerms());
00163       }
00164         
00165       int numGnd = 1;
00166       for (int j = 0; j < t->getNumTerms(); j++)
00167       {
00168         int numConstByType =
00169           domain_->getNumConstantsByType(t->getTermTypeAsInt(j));
00170         for(int idxType = 0; idxType < INDEX_TYPE_COUNT; idxType++)
00171         {
00172           (*((*((*paramPredsArray_)[idxType]))[i]))[j] = new Array<Array<int>*>;
00173           (*((*((*paramPredsArray_)[idxType]))[i]))[j]->
00174             growToSize(numConstByType);
00175           for (int k = 0; k < numConstByType; k++)
00176           {
00177             (*((*((*((*paramPredsArray_)[idxType]))[i]))[j]))[k] =
00178               new Array<int>;
00179           }
00180         }
00181         numGnd *= numConstByType;
00182       }
00183       numberOfGroundings_[i] = numGnd;
00184     }
00185   
00186     predIdToNumTF_ = new Array<NumTrueFalse>(numFOPreds);
00187     predIdToNumTF_->growToSize(numFOPreds);
00188 
00189     activePredIdxSet_ = NULL;
00190     evidencePredIdxSet_ = NULL;
00191     deactivatedPredIdxSet_ = NULL;
00192   }
00193 
00194     //Copy constructor
00195   Database(const Database& db)
00196   {
00197     domain_ = db.domain_;
00198         closedWorld_.growToSize(db.closedWorld_.size());
00199     memcpy((void*)closedWorld_.getItems(), db.closedWorld_.getItems(),
00200            db.closedWorld_.size()*sizeof(bool));
00201     //closedWorld_ = db.closedWorld_;
00202     lazyFlag_ = db.lazyFlag_;
00203     performingInference_ = db.performingInference_;
00204     firstConstIdByType_ = db.firstConstIdByType_;
00205     numberOfGroundings_ = db.numberOfGroundings_;
00206     
00207     oppEqGndPreds_ = db.oppEqGndPreds_;
00208 
00209         termMultByPred_.growToSize(db.termMultByPred_.size(), NULL);
00210         for (int i = 0; i < db.termMultByPred_.size(); i++)
00211         {
00212           if (db.termMultByPred_[i])
00213           {
00214             Array<MultAndType>* matArr = new Array<MultAndType>;
00215         matArr->growToSize(db.termMultByPred_[i]->size());
00216         for (int j = 0; j < db.termMultByPred_[i]->size(); j++)
00217         {
00218                   MultAndType mat;
00219                   mat.first = (*db.termMultByPred_[i])[j].first;
00220                   mat.second = (*db.termMultByPred_[i])[j].second;
00221           (*matArr)[j] = mat;
00222         }
00223         termMultByPred_[i] = matArr;            
00224           }
00225         }
00226 
00227     if (db.paramPredsArray_)
00228     {
00229       paramPredsArray_ = new Array<Array<Array<Array<Array<int>*>*>*>*>;
00230       int size0 = db.paramPredsArray_->size();
00231       paramPredsArray_->growToSize(size0);
00232       
00233       for(int idxType = 0; idxType < size0; idxType++)
00234       {
00235         Array<Array<Array<Array<int>*>*>*>* arr1 =
00236           ((*db.paramPredsArray_)[idxType]);
00237         int size1 = arr1->size();
00238         (*paramPredsArray_)[idxType] = new Array<Array<Array<Array<int>*>*>*>;
00239         (*paramPredsArray_)[idxType]->growToSize(size1);
00240         
00241         for (int i = 0; i < size1; i++)
00242         {
00243           Array<Array<Array<int>*>*>* arr2 = ((*arr1)[i]);
00244           if (arr2 == NULL) 
00245           {
00246             (*(*paramPredsArray_)[idxType])[i] = NULL;
00247             continue;
00248           }
00249           int size2 = arr2->size();
00250           (*(*paramPredsArray_)[idxType])[i] = new Array<Array<Array<int>*>*>;
00251           (*(*paramPredsArray_)[idxType])[i]->growToSize(size2);
00252           
00253           for (int j = 0; j < size2; j++)
00254           {
00255             Array<Array<int>*>* arr3 = ((*arr2)[j]);
00256             int size3 = arr3->size();
00257             (*(*(*paramPredsArray_)[idxType])[i])[j] = new Array<Array<int>*>;
00258             (*(*(*paramPredsArray_)[idxType])[i])[j]->growToSize(size3);
00259             
00260             for (int k = 0; k < size3; k++)
00261             {
00262               Array<int>* arr4 = ((*arr3)[k]);
00263               int size4 = arr4->size();
00264               (*(*(*(*paramPredsArray_)[idxType])[i])[j])[k] = new Array<int>;
00265               (*(*(*(*paramPredsArray_)[idxType])[i])[j])[k]->growToSize(size4);
00266               
00267               for (int l = 0; l < size4; l++)
00268               {
00269                 (*(*(*(*(*paramPredsArray_)[idxType])[i])[j])[k])[l] = 
00270                   ((*arr4)[l]);
00271               }
00272             }
00273           }
00274         }
00275       }
00276     }
00277 
00278         if (db.predIdToNumTF_)
00279         {
00280           predIdToNumTF_ = new Array<NumTrueFalse>(db.predIdToNumTF_->size());
00281           predIdToNumTF_->growToSize(db.predIdToNumTF_->size());
00282           for (int i = 0; i < db.predIdToNumTF_->size(); i++)
00283           {
00284                 (*predIdToNumTF_)[i] = (*db.predIdToNumTF_)[i];
00285           }
00286         }
00287         
00288         if (db.truePredIdxSet_)
00289         {
00290           truePredIdxSet_ = new Array<hash_set<int> >(db.truePredIdxSet_->size());
00291           truePredIdxSet_->growToSize(db.truePredIdxSet_->size());
00292           for (int i = 0; i < db.truePredIdxSet_->size(); i++)
00293           {
00294                 (*truePredIdxSet_)[i] = (*db.truePredIdxSet_)[i];
00295           }
00296         }
00297         
00298         if (db.falsePredIdxSet_)
00299         {       
00300           falsePredIdxSet_ = new Array<hash_set<int> >();
00301           falsePredIdxSet_->growToSize(db.falsePredIdxSet_->size());
00302           for (int i = 0; i < db.falsePredIdxSet_->size(); i++)
00303                 (*falsePredIdxSet_)[i] = (*db.falsePredIdxSet_)[i];
00304         }
00305         
00306         if (db.activePredIdxSet_)
00307         {
00308           activePredIdxSet_ = new Array<hash_set<int> >();
00309           activePredIdxSet_->growToSize(db.activePredIdxSet_->size());
00310           for (int i = 0; i < db.activePredIdxSet_->size(); i++)
00311                 (*activePredIdxSet_)[i] = (*db.activePredIdxSet_)[i];
00312         }
00313         
00314         if (db.evidencePredIdxSet_)
00315         {
00316           evidencePredIdxSet_ = new Array<hash_set<int> >();
00317           evidencePredIdxSet_->growToSize(db.evidencePredIdxSet_->size());
00318           for (int i = 0; i < db.evidencePredIdxSet_->size(); i++)
00319                 (*evidencePredIdxSet_)[i] = (*db.evidencePredIdxSet_)[i];
00320         }
00321 
00322         if (db.deactivatedPredIdxSet_)
00323         {
00324           deactivatedPredIdxSet_ = new Array<hash_set<int> >();
00325           deactivatedPredIdxSet_->growToSize(db.deactivatedPredIdxSet_->size());
00326           for (int i = 0; i < db.deactivatedPredIdxSet_->size(); i++)
00327                 (*deactivatedPredIdxSet_)[i] = (*db.deactivatedPredIdxSet_)[i];
00328         }
00329   }
00330   
00331   ~Database()
00332   {
00333     for (int i = 0; i < termMultByPred_.size(); i++) 
00334       if (termMultByPred_[i]) delete termMultByPred_[i];
00335     termMultByPred_.clearAndCompress();
00336 
00337     for (int i = 0; i < truePredIdxSet_->size(); i++)
00338       (*truePredIdxSet_)[i].clear();
00339     delete truePredIdxSet_;
00340                 
00341     for (int i = 0; i < falsePredIdxSet_->size(); i++)
00342       (*falsePredIdxSet_)[i].clear();
00343     delete falsePredIdxSet_;
00344 
00345     if (lazyFlag_)
00346     {
00347       for (int i = 0; i < activePredIdxSet_->size(); i++)
00348         (*activePredIdxSet_)[i].clear();
00349       delete activePredIdxSet_;
00350 
00351       for (int i = 0; i < evidencePredIdxSet_->size(); i++)
00352         (*evidencePredIdxSet_)[i].clear();
00353       delete evidencePredIdxSet_;
00354                 
00355       for (int i = 0; i < deactivatedPredIdxSet_->size(); i++)
00356         (*deactivatedPredIdxSet_)[i].clear();
00357       delete deactivatedPredIdxSet_;
00358     }
00359 
00360     if (predIdToNumTF_)  { delete predIdToNumTF_; predIdToNumTF_ = NULL; }
00361 
00362     if (paramPredsArray_)
00363     {
00364       int size0 = paramPredsArray_->size();
00365       for(int idxType = 0; idxType < size0; idxType++)
00366       {
00367         Array<Array<Array<Array<int>*>*>*>* arr1 =
00368           ((*paramPredsArray_)[idxType]);
00369         int size1 = arr1->size();
00370         
00371         for (int i = 0; i < size1; i++)
00372         {
00373           Array<Array<Array<int>*>*>* arr2 = ((*arr1)[i]);
00374           if (arr2 == NULL) 
00375           {
00376             continue;
00377           }
00378           int size2 = arr2->size();
00379           
00380           for (int j = 0; j < size2; j++)
00381           {
00382             Array<Array<int>*>* arr3 = ((*arr2)[j]);
00383             arr3->deleteItemsAndClear();
00384           }
00385           arr2->deleteItemsAndClear();
00386         }
00387         arr1->deleteItemsAndClear();
00388       }
00389       paramPredsArray_->deleteItemsAndClear();
00390       delete paramPredsArray_;
00391     }
00392   }
00393   
00394   void compress()
00395   {
00396     for (int i = 0; i < termMultByPred_.size(); i++) 
00397       if (termMultByPred_[i]) termMultByPred_[i]->compress();
00398     termMultByPred_.compress();
00399 
00400     firstConstIdByType_.compress();
00401   }
00402 
00403   void printInfo()
00404   {
00405     cout << "GNDINGS " << endl;
00406     for (int i = 0; i < numberOfGroundings_.size(); i++)
00407       cout << i << ": " << numberOfGroundings_[i] << endl;
00408       
00409     cout << "TRUE " << truePredIdxSet_->size() << endl;
00410     for (int i = 0; i < truePredIdxSet_->size(); i++)
00411     {
00412       hash_set<int> hs = (*truePredIdxSet_)[i];
00413       cout << i << ": " << hs.size() << endl;
00414     }
00415     cout << "FALSE " << falsePredIdxSet_->size() << endl;
00416     for (int i = 0; i < falsePredIdxSet_->size(); i++)
00417     {
00418       hash_set<int> hs = (*falsePredIdxSet_)[i];
00419       cout << i << ": " << hs.size() << endl;
00420     }
00421     cout << "ACTIVE " << activePredIdxSet_->size() << endl;
00422     cout << "EVIDENCE " << evidencePredIdxSet_->size() << endl;
00423     cout << "DEACTIVE " << deactivatedPredIdxSet_->size() << endl;
00424   }
00425   
00426   // Set the lazy flag, update the structures accordingly
00427   void setLazyFlag()
00428   {
00429     setLazyFlag(true);
00430   }
00431 
00432   void setLazyFlag(const bool& lf)
00433   {
00434       // If lazyFlag_ is already set this way, do nothing
00435     if ((lf && lazyFlag_) || (!lf && !lazyFlag_)) return;
00436 
00437       // If changing lazy flag, our lazy index sets become invalid
00438       if (activePredIdxSet_)
00439       {
00440         for (int i = 0; i < activePredIdxSet_->size(); i++)
00441           (*activePredIdxSet_)[i].clear();
00442         delete activePredIdxSet_;
00443       activePredIdxSet_ = NULL;
00444       }
00445       if (evidencePredIdxSet_)
00446       {
00447         for (int i = 0; i < evidencePredIdxSet_->size(); i++)
00448           (*evidencePredIdxSet_)[i].clear();
00449         delete evidencePredIdxSet_;
00450       evidencePredIdxSet_ = NULL;
00451       }
00452       if (deactivatedPredIdxSet_)
00453       {
00454         for (int i = 0; i < deactivatedPredIdxSet_->size(); i++)
00455           (*deactivatedPredIdxSet_)[i].clear();
00456         delete deactivatedPredIdxSet_;
00457       deactivatedPredIdxSet_ = NULL;
00458       }
00459 
00460     if (lf)
00461     {
00462       lazyFlag_ = true;
00463       int numFOPreds = domain_->getNumPredicates();
00464 
00465       activePredIdxSet_ = new Array<hash_set<int> >(numFOPreds);
00466       evidencePredIdxSet_ = new Array<hash_set<int> >(numFOPreds);
00467       deactivatedPredIdxSet_ = new Array<hash_set<int> >(numFOPreds);
00468       activePredIdxSet_->growToSize(numFOPreds);
00469       evidencePredIdxSet_->growToSize(numFOPreds);
00470       deactivatedPredIdxSet_->growToSize(numFOPreds);
00471     }
00472     if (!lf)
00473     {
00474       lazyFlag_ = false;    
00475     }
00476   }
00477        
00478   // Set the performing inference flag. Returns the previous setting
00479   bool setPerformingInference(bool pi)
00480   {
00481     bool previous = performingInference_;
00482     performingInference_ = pi;
00483     return previous;
00484   }
00485 
00486   const Domain* getDomain() const { return domain_; }
00487 
00488   static bool sameTruthValueAndSense(const TruthValue& tv, const bool& sense)
00489   { return (tv==TRUE && sense) || (tv==FALSE && !sense); }
00490 
00494   TruthValue getValue(const Predicate* const& pred) const
00495   {
00496         if (dbdebug >= 1) cout << "Calling database::getValue" << endl;         
00497     assert(((Predicate*)pred)->isGrounded());
00498     Predicate* ppred = (Predicate*) pred;
00499     int predId = pred->getId();
00500 
00501       //if this is a '=' predicate
00502     if (pred->isEqualPredWithType())
00503     {
00504       // If the two const ids are the same, actual truth value is TRUE,
00505       // else FALSE
00506       TruthValue actual 
00507         = (pred->getTerm(0)->getId()==pred->getTerm(1)->getId()) ? TRUE : FALSE;
00508 
00509         //if pred is in oppEqGndPreds_, return opposite of actual value
00510       for (int i = 0; i < oppEqGndPreds_.size(); i++)
00511         if (ppred->same(oppEqGndPreds_[i]))
00512         {
00513           if (actual == TRUE)
00514           {
00515                 if (dbdebug >= 1) cout << "Returning FALSE" << endl;
00516                 return FALSE;
00517           }
00518           if (dbdebug >= 1) cout << "Returning TRUE" << endl;
00519           return TRUE;
00520         }
00521 
00522       if (dbdebug >= 1) cout << "Returning " << actual << endl;
00523       return actual;
00524     }
00525     
00526     int idx = getIdxOfGndPredValues(pred);
00527     return getValue(idx, predId);
00528   }
00529   
00534   TruthValue getValue(const GroundPredicate* const& pred) const
00535   {
00536     if (dbdebug >= 1) cout << "Calling database::getValue" << endl;     
00537     int predId = pred->getId();
00538     
00539     int idx = getIdxOfGndPredValues(pred);
00540     return getValue(idx, predId);
00541   }
00542  
00546   bool getActiveStatus(const Predicate* const& pred) const
00547   {
00548         if (dbdebug >= 1) cout << "Calling database::getActiveStatus" << endl;
00549         if (pred->isEqualPredWithType()) return false;
00550         assert(lazyFlag_);
00551         assert(((Predicate*)pred)->isGrounded());
00552     
00553     int idx = getIdxOfGndPredValues(pred);
00554     return getActiveStatus(idx, pred->getId());
00555   }
00556   
00561   bool getActiveStatus(const GroundPredicate* const& pred) const
00562   {
00563     if (dbdebug >= 1) cout << "Calling database::getActiveStatus" << endl;
00564     assert(lazyFlag_);
00565 
00566     int idx = getIdxOfGndPredValues(pred);
00567     return getActiveStatus(idx, pred->getId());
00568   }
00569   
00570 
00574   bool getDeactivatedStatus(const Predicate* const& pred) const
00575   {
00576         if (dbdebug >= 1) cout << "Calling database::getDeactivatedStatus" << endl;
00577         if (pred->isEqualPredWithType()) return false;
00578         assert(lazyFlag_);
00579         assert(((Predicate*)pred)->isGrounded());
00580     
00581     int idx = getIdxOfGndPredValues(pred);
00582     return getDeactivatedStatus(idx, pred->getId());
00583   }
00584   
00589   bool getDeactivatedStatus(const GroundPredicate* const& pred) const
00590   {
00591     if (dbdebug >= 1) cout << "Calling database::getDeactivatedStatus" << endl;
00592     assert(lazyFlag_);
00593     
00594     int idx = getIdxOfGndPredValues(pred);
00595     return getDeactivatedStatus(idx, pred->getId());
00596   }
00597     
00601   bool getEvidenceStatus(const Predicate* const& pred) const
00602   {     
00603         if (dbdebug >= 1) cout << "Calling database::getEvidenceStatus" << endl;
00604         if (pred->isEqualPredWithType()) return true;
00605     assert(lazyFlag_);
00606         assert(((Predicate*)pred)->isGrounded());
00607 
00608     int idx = getIdxOfGndPredValues(pred);
00609     return getEvidenceStatus(idx, pred->getId());
00610   }
00611   
00616   bool getEvidenceStatus(const GroundPredicate* const& pred) const
00617   { 
00618     if (dbdebug >= 1) cout << "Calling database::getEvidenceStatus" << endl;
00619     assert(lazyFlag_);
00620 
00621     int idx = getIdxOfGndPredValues(pred);
00622     return getEvidenceStatus(idx, pred->getId());
00623   }
00624   
00625   string getValueAsString(const Predicate* const& pred) const
00626   {
00627     TruthValue tv = getValue(pred);
00628     if (tv == TRUE)    return "TRUE";
00629     if (tv == FALSE)   return "FALSE";
00630     if (tv == UNKNOWN) return "UNKNOWN";
00631     assert(false); 
00632     return "UNKNOWN";
00633   }
00634 
00635 
00646   TruthValue setValue(const Predicate* const & pred, const TruthValue& tv)
00647   { return setValueHelper(pred, false, tv); }
00648 
00659   TruthValue setValue(const GroundPredicate* const & pred, const TruthValue& tv)
00660   { 
00661     return setValueHelper(pred, false, tv);
00662   }
00663 
00670   TruthValue flipValue(const Predicate* const & pred)
00671   { return setValueHelper(pred, true, UNKNOWN); }
00672     
00679   TruthValue flipValue(const GroundPredicate* const & pred)
00680   { return setValueHelper(pred, true, UNKNOWN); }
00681     
00688   bool setActiveStatus(const Predicate* const & pred, const bool& as)
00689   { 
00690         if (dbdebug >= 1) cout << "Calling database::setActiveStatus" << endl;
00691         if (pred->isEqualPredWithType())
00692         {
00693           if (dbdebug >= 1) cout << "Returning false" << endl;
00694           return false;
00695         }
00696           // Active preds can not be evidence
00697         if (as) assert(!getEvidenceStatus(pred));
00698         
00699         assert(lazyFlag_);
00700     assert(((Predicate*)pred)->isGrounded());
00701         
00702     int predId = pred->getId();
00703     int idx = getIdxOfGndPredValues(pred);
00704     return setActiveStatus(idx, predId, as, pred, NULL);
00705   }
00706   
00713   bool setActiveStatus(const GroundPredicate* const & pred, const bool& as)
00714   { 
00715     if (dbdebug >= 1) cout << "Calling database::setActiveStatus" << endl;
00716       // Active preds can not be evidence
00717     if (as) assert(!getEvidenceStatus(pred));
00718     assert(lazyFlag_);
00719     
00720     int predId = pred->getId();
00721     int idx = getIdxOfGndPredValues(pred);
00722     return setActiveStatus(idx, predId, as, NULL, pred);
00723   }
00724   
00725   void resetActiveStatus()
00726   {
00727         assert(lazyFlag_);
00728     for (int i = 0; i < activePredIdxSet_->size(); i++)
00729       (*activePredIdxSet_)[i].clear();
00730   }
00731 
00738   bool setDeactivatedStatus(const Predicate* const & pred, const bool& das)
00739   { 
00740         if (dbdebug >= 1) cout << "Calling database::setDeactivatedStatus" << endl;
00741         if (pred->isEqualPredWithType())
00742         {
00743           if (dbdebug >= 1) cout << "Returning false" << endl;
00744           return false;
00745         }
00746         //deactivated preds can not be evidence
00747         if (das) assert(!getEvidenceStatus(pred));
00748         
00749         assert(lazyFlag_);
00750     assert(((Predicate*)pred)->isGrounded());
00751         
00752     int predId = pred->getId();
00753     int idx = getIdxOfGndPredValues(pred);
00754     return setDeactivatedStatus(idx, predId, das);
00755   }
00756   
00763   bool setDeactivatedStatus(const GroundPredicate* const & pred,
00764                             const bool& das)
00765   { 
00766     if (dbdebug >= 1) cout << "Calling database::setDeactivatedStatus" << endl;
00767       // Deactivated preds can not be evidence
00768     if (das) assert(!getEvidenceStatus(pred));
00769     assert(lazyFlag_);
00770     
00771     int predId = pred->getId();
00772     int idx = getIdxOfGndPredValues(pred);
00773     return setDeactivatedStatus(idx, predId, das);
00774   }
00775   
00776   void resetDeactivatedStatus()
00777   {
00778         assert(lazyFlag_);
00779     for (int i = 0; i < deactivatedPredIdxSet_->size(); i++)
00780       (*deactivatedPredIdxSet_)[i].clear();
00781   }
00782 
00789   bool setEvidenceStatus(const Predicate* const & pred, const bool& es)
00790   {
00791         if (dbdebug >= 1) cout << "Calling database::setEvidenceStatus" << endl;
00792         if (pred->isEqualPredWithType())
00793         {
00794           if (dbdebug >= 1) cout << "Returning true" << endl;
00795           return true;
00796         }
00797         //active preds can not be evidence
00798         if (es) assert(!getActiveStatus(pred));
00799                                   
00800         assert(lazyFlag_);
00801     assert(((Predicate*)pred)->isGrounded());
00802 
00803     int predId = pred->getId();
00804     int idx = getIdxOfGndPredValues(pred);
00805     return setEvidenceStatus(idx, predId, es);
00806   }
00807   
00814   bool setEvidenceStatus(const GroundPredicate* const & pred, const bool& es)
00815   {
00816     if (dbdebug >= 1) cout << "Calling database::setEvidenceStatus" << endl;
00817       // Active preds can not be evidence
00818     if (es) assert(!getActiveStatus(pred));
00819     assert(lazyFlag_);
00820 
00821     int predId = pred->getId();
00822     int idx = getIdxOfGndPredValues(pred);
00823     return setEvidenceStatus(idx, predId, es);
00824   }
00825   
00826   void setValuesToUnknown(const Array<Predicate*>* const & gndPreds,
00827                           Array<TruthValue>* const & prevValues)
00828   {
00829     if (prevValues) prevValues->clear();
00830     for (int i = 0; i < gndPreds->size(); i++)
00831     {
00832       TruthValue prev = setValue((*gndPreds)[i], UNKNOWN);
00833       if (prevValues) prevValues->append(prev);
00834     }
00835   }
00836 
00837   void setValuesToUnknown(const GroundPredicateHashArray* const & gndPreds,
00838                           Array<TruthValue>* const & prevValues)
00839   {
00840     if (prevValues) prevValues->clear();
00841     for (int i = 0; i < gndPreds->size(); i++)
00842     {
00843       TruthValue prev = setValue((*gndPreds)[i], UNKNOWN);
00844       if (prevValues) prevValues->append(prev);
00845     }
00846   }
00847 
00848 
00849   void setValuesToGivenValues(const Array<Predicate*>* const & gndPreds,
00850                               const Array<TruthValue>* const & values)
00851   {
00852     assert(values);
00853     assert(values->size() == gndPreds->size());
00854     for (int i = 0; i < gndPreds->size(); i++)
00855       setValue((*gndPreds)[i], (*values)[i]);
00856   }
00857 
00858   void setValuesToGivenValues(const GroundPredicateHashArray* const & gndPreds,
00859                               const Array<TruthValue>* const & values)
00860   {
00861     assert(values);
00862     assert(values->size() == gndPreds->size());
00863     for (int i = 0; i < gndPreds->size(); i++)
00864       setValue((*gndPreds)[i], (*values)[i]);
00865   }
00866 
00867     //Change all ground predicates with toBeAlteredVal to newVal. 
00868     //gndPredValues contains the previous values of gndPreds.
00869   void alterTruthValue(const Array<Predicate*>* const & gndPreds, 
00870                        const TruthValue& tobeAlteredVal,
00871                        const TruthValue& newVal, 
00872                        Array<TruthValue>* const & gndPredValues) 
00873   {
00874     for (int i = 0; i < gndPreds->size(); i++) 
00875     {
00876           TruthValue val = getValue((*gndPreds)[i]);
00877           gndPredValues->append(val);
00878           if (val == tobeAlteredVal) 
00879       {
00880         setValue((*gndPreds)[i], newVal);
00881           }
00882     }
00883   }
00884 
00885 
00886         // Called only for evidence atoms
00887     // Caller should delete pred if required
00888   void addEvidenceGroundPredicate(Predicate* const & pred)
00889   {
00890         if (dbdebug >= 1)
00891       cout << "Calling database::addEvidenceGroundPredicate" << endl;
00892         setValue(pred, pred->getTruthValue());
00893           //Evidence status only needs to be set for open-world preds
00894         if (lazyFlag_ && !closedWorld_[pred->getId()])
00895         {
00896           setEvidenceStatus(pred, true);
00897         }
00898         if (dbdebug >= 1) cout << "Returning" << endl;
00899   }
00900 
00901   int getNumGroundings(const int& predId) const
00902   {
00903       //if it is a '=' predicate
00904     const PredicateTemplate* t = domain_->getPredicateTemplate(predId);    
00905     if (t->isEqualPredWithType())
00906     {
00907       int nc = domain_->getNumConstantsByType(t->getTermTypeAsInt(0));
00908       return nc*nc;
00909     }
00910     
00911     return numberOfGroundings_[predId];
00912   }
00913 
00914   int getNumEvidenceGndPreds(const int& predId) const
00915   {
00916       // All '=' predicates are evidence
00917     const PredicateTemplate* t = domain_->getPredicateTemplate(predId);    
00918     if (t->isEqualPredWithType())
00919     {
00920       int nc = domain_->getNumConstantsByType(t->getTermTypeAsInt(0));
00921       return nc*nc;
00922     }
00923 
00924       // All closed-world preds are evidence
00925     if (closedWorld_[predId])
00926     {
00927       return numberOfGroundings_[predId];
00928     }
00929     return (*evidencePredIdxSet_)[predId].size();
00930   }
00931 
00932   int getNumTrueGndPreds(const int& predId) const
00933   {
00934       //if it is a '=' predicate
00935     const PredicateTemplate* t = domain_->getPredicateTemplate(predId);    
00936     if (t->isEqualPredWithType())
00937     {
00938       int nc = domain_->getNumConstantsByType(t->getTermTypeAsInt(0));
00939       int minus = 0;
00940       for (int i = 0; i < oppEqGndPreds_.size(); i++)
00941       {
00942         Predicate* pred = oppEqGndPreds_[i];
00943         if (pred->getId() == predId &&
00944             pred->getTerm(0)->getId() == pred->getTerm(1)->getId())
00945           minus++;
00946       }
00947 
00948       return nc-minus;
00949     }
00950 
00951     return (*predIdToNumTF_)[predId].numTrue;
00952   }
00953 
00954 
00955   int getNumFalseGndPreds(const int& predId) const
00956   {
00957       //if it is a '=' predicate
00958     const PredicateTemplate* t = domain_->getPredicateTemplate(predId);    
00959     if (t->isEqualPredWithType())
00960     {
00961       int nc = domain_->getNumConstantsByType(t->getTermTypeAsInt(0));
00962       int minus = 0;
00963       for (int i = 0; i < oppEqGndPreds_.size(); i++)
00964       {
00965         Predicate* pred = oppEqGndPreds_[i];
00966         if (pred->getId() == predId &&
00967             pred->getTerm(0)->getId() != pred->getTerm(1)->getId())
00968           minus++;
00969       }
00970 
00971       return nc*(nc-1)-minus;
00972     }
00973 
00974     if (closedWorld_[predId])
00975       return numberOfGroundings_[predId]-(*predIdToNumTF_)[predId].numTrue;
00976     else
00977       return (*predIdToNumTF_)[predId].numFalse;
00978   }
00979 
00980 
00981   int getNumUnknownGndPreds(const int& predId) const
00982   {
00983       //if it is a '=' predicate
00984     const PredicateTemplate* t = domain_->getPredicateTemplate(predId);    
00985     if (t->isEqualPredWithType()) return 0;
00986 
00987     //assert(!closedWorld_[predId]);
00988     if (closedWorld_[predId]) return 0;
00989     
00990     return numberOfGroundings_[predId] -(*predIdToNumTF_)[predId].numTrue
00991                                        -(*predIdToNumTF_)[predId].numFalse;
00992   }
00993 
00994 
00995   int getNumPredIds() const 
00996   {
00997     return predIdToNumTF_->size();
00998   }
00999 
01000   bool isClosedWorld(const int& predId) const { return closedWorld_[predId]; }
01001   void setClosedWorld(const int& predId, const bool& b) 
01002   { closedWorld_[predId] = b; }
01003   const Array<bool>& getClosedWorld() const { return closedWorld_; }
01004   
01005     // Caller should delete returned array but not modify its contents.
01006   const PredicateHashArray* getTrueNonEvidenceGndPreds(const int& predId) const
01007   {
01008     PredicateHashArray* preds = new PredicateHashArray();
01009     
01010     hash_set<int>::const_iterator it = (*truePredIdxSet_)[predId].begin();
01011     for (; it != (*truePredIdxSet_)[predId].end(); it++)
01012     {
01013         // Check if in evidence
01014       if ((*evidencePredIdxSet_)[predId].find(*it) ==
01015           (*evidencePredIdxSet_)[predId].end())
01016       {
01017         Predicate* p = getPredFromIdx((*it),
01018                                       domain_->getPredicateTemplate(predId));
01019         preds->append(p);
01020       }
01021     }
01022     return preds;
01023   }
01024   
01037   void getIndexedGndings(Array<Predicate*>* const & indexedGndings,
01038                                                  Predicate* const & pred,
01039                          bool const & ignoreActivePreds)
01040   {
01041     assert(pred->getNumTerms() == 2);
01042     int predId = pred->getId();
01043 
01044     const Term* term0 = pred->getTerm(0);
01045     const Term* term1 = pred->getTerm(1);
01046           
01047           // Both terms are grounded
01048     if (term0->getType() == Term::CONSTANT &&
01049         term1->getType() == Term::CONSTANT)
01050     {
01051         // Check if pred is true or, if getting active preds, active
01052       TruthValue tv = getValue(pred);
01053       if (tv == TRUE || (!ignoreActivePreds && tv == FALSE))
01054       {
01055         Predicate* p = new Predicate(*pred);
01056         indexedGndings->append(p);
01057       }
01058       return;
01059     }
01060 
01061           // Neither term is grounded
01062         if (term0->getType() != Term::CONSTANT && 
01063         term1->getType() != Term::CONSTANT)
01064         {
01065           const Array<int>* constArray =
01066             domain_->getConstantsByType(pred->getTermTypeAsInt(0));
01067         
01068                 //
01069           for (int j = 0; j < constArray->size(); j++)
01070           {
01071                 int constIdx = domain_->getConstantIndexInType((*constArray)[j]);
01072         Array<int>* preds =
01073           (*(*(*(*paramPredsArray_)[T_INDEX])[predId])[0])[constIdx];
01074         for (int i = 0; i < preds->size(); i++)
01075                 {
01076           Predicate* p = getPredFromIdx((*preds)[i], pred->getTemplate());
01077                   indexedGndings->append(p);
01078                 }
01079           }
01080         
01081           if (!ignoreActivePreds)
01082           {
01083                 for (int j = 0; j < constArray->size(); j++)
01084                 {
01085                   int constIdx = domain_->getConstantIndexInType((*constArray)[j]);
01086           Array<int>* preds =
01087             (*(*(*(*paramPredsArray_)[FA_INDEX])[predId])[0])[constIdx];
01088           for (int i = 0; i < preds->size(); i++)
01089               {
01090             Predicate* p = getPredFromIdx((*preds)[i], pred->getTemplate());
01091                         indexedGndings->append(p);
01092               }
01093                 }
01094           }     
01095           return;       
01096         }
01097           // If we've reached here, then one term is grounded, the other isn't
01098         int gndTerm = (term0->getType() == Term::CONSTANT) ? 0 : 1;
01099         int constIdx =
01100       domain_->getConstantIndexInType(pred->getTerm(gndTerm)->getId());
01101     Array<int>* preds =
01102       (*(*(*(*paramPredsArray_)[T_INDEX])[predId])[gndTerm])[constIdx];
01103     for (int i = 0; i < preds->size(); i++)
01104         {
01105       Predicate* p = getPredFromIdx((*preds)[i], pred->getTemplate());
01106           indexedGndings->append(p);
01107          }
01108           
01109         if (!ignoreActivePreds)
01110         {
01111       Array<int>* preds =
01112         (*(*(*(*paramPredsArray_)[FA_INDEX])[predId])[gndTerm])[constIdx];
01113       for (int i = 0; i < preds->size(); i++)
01114           {
01115         Predicate* p = getPredFromIdx((*preds)[i], pred->getTemplate());
01116                 indexedGndings->append(p);
01117           }
01118         }       
01119   }
01120 
01121 
01122 
01123 
01124 
01125  private:
01126 
01140   int getIdxOfGndPredValues(const Predicate* const & pred) const
01141   {
01142     int numTerms = pred->getNumTerms();
01143     Array<MultAndType>* multAndTypes = termMultByPred_[pred->getId()];
01144     int idx = 0;
01145     for (int i = 0; i < numTerms; i++)
01146     {
01147       int constId = pred->getTerm(i)->getId();
01148       assert(constId >= 0);
01149         // idx += mutliplier * num of constants belonging to type d]);
01150       idx += (*multAndTypes)[i].first 
01151         * (constId - firstConstIdByType_[(*multAndTypes)[i].second]);
01152     }
01153     return idx;
01154   }
01155 
01169   int getIdxOfGndPredValues(const GroundPredicate* const & pred) const
01170   {
01171     int numTerms = pred->getNumTerms();
01172     Array<MultAndType>* multAndTypes = termMultByPred_[pred->getId()];
01173     int idx = 0;
01174     for (int i = 0; i < numTerms; i++)
01175     {
01176       int constId = pred->getTermId(i);
01177       assert(constId >= 0);
01178         // idx += mutliplier * num of constants belonging to type d]);
01179       idx += (*multAndTypes)[i].first 
01180         * (constId - firstConstIdByType_[(*multAndTypes)[i].second]);
01181     }
01182     return idx;
01183   }
01184   
01193   Predicate* getPredFromIdx(const int& idx,
01194                             const PredicateTemplate* const & predTemplate) const
01195   {
01196         Predicate* p = new Predicate(predTemplate);
01197         Array<int>* auxIdx = new Array<int>(predTemplate->getNumTerms());
01198         auxIdx->growToSize(predTemplate->getNumTerms());
01199         Array<MultAndType>* multAndTypes = termMultByPred_[p->getId()];
01200         for (int i = 0; i < predTemplate->getNumTerms(); i++)
01201         {
01202           int aux = 0;
01203           for (int j = 0; j < i; j++)
01204           {
01205                 aux += (*auxIdx)[j] * ((*multAndTypes)[j].first);
01206           }
01207           (*auxIdx)[i] = (idx - aux) / (*multAndTypes)[i].first;
01208           int constId = (*auxIdx)[i] +
01209                     firstConstIdByType_[(*multAndTypes)[i].second];
01210           p->setTermToConstant(i, constId);
01211         }
01212         delete auxIdx;
01213         return p;
01214   }
01215 
01222   TruthValue getValue(const int& idx, const int& predId) const
01223   {
01224     hash_set<int>::const_iterator it = (*truePredIdxSet_)[predId].find(idx);
01225     if (it != (*truePredIdxSet_)[predId].end())
01226     {
01227       if (dbdebug >= 1) cout << "returning TRUE" << endl;
01228       return TRUE;
01229     }
01230 
01231     if (!closedWorld_[predId] && !performingInference_)
01232     {
01233       if((*falsePredIdxSet_)[predId].find(idx) !=
01234          (*falsePredIdxSet_)[predId].end())
01235       {
01236         if (dbdebug >= 1) cout << "returning FALSE" << endl;
01237         return FALSE;
01238       }
01239       else
01240       {
01241         if (dbdebug >= 1) cout << "returning UNKNOWN" << endl;
01242         return UNKNOWN;
01243       }
01244     }
01245     if (dbdebug >= 1) cout << "returning FALSE" << endl;
01246     return FALSE;
01247   }
01248   
01255   bool getActiveStatus(const int& idx, const int& predId) const
01256   { 
01257       // Evidence atoms can not be active
01258     if (getEvidenceStatus(idx, predId))
01259     {
01260       if (dbdebug >= 1) cout << "Returning false(1)" << endl;       
01261       return false;
01262     }
01263 
01264     if ((*activePredIdxSet_)[predId].find(idx) !=
01265         (*activePredIdxSet_)[predId].end())
01266     {
01267       if (dbdebug >= 1) cout << "Returning true" << endl;
01268       return true;
01269     }
01270     if (dbdebug >= 1) cout << "Returning false(2)" << endl;     
01271     return false;
01272   }
01273 
01280   bool getDeactivatedStatus(const int& idx, const int& predId) const
01281   {
01282       // Evidence atoms can not be active or deactivated
01283     if (getEvidenceStatus(idx, predId))
01284     {
01285       if (dbdebug >= 1) cout << "Returning false(1)" << endl;       
01286       return false;
01287     }
01288 
01289     if ((*deactivatedPredIdxSet_)[predId].find(idx) !=
01290         (*deactivatedPredIdxSet_)[predId].end())
01291     {
01292       if (dbdebug >= 1) cout << "Returning true" << endl;       
01293       return true;
01294     }
01295     if (dbdebug >= 1) cout << "Returning false(2)" << endl;     
01296     return false;
01297   }
01298   
01305   bool getEvidenceStatus(const int& idx, const int& predId) const
01306   {
01307       // All closed-world preds are evidence
01308     if (closedWorld_[predId])
01309     {
01310       if (dbdebug >= 1) cout << "Returning true(1)" << endl;        
01311       return true;
01312     }
01313     if ((*evidencePredIdxSet_)[predId].find(idx) !=
01314         (*evidencePredIdxSet_)[predId].end())
01315     {
01316       if (dbdebug >= 1) cout << "Returning true(2)" << endl;        
01317       return true;
01318     }
01319     if (dbdebug >= 1) cout << "Returning false" << endl;        
01320     return false;
01321   }
01322 
01332   TruthValue setValueHelper(const Predicate* const & pred, const bool& flip,
01333                             const TruthValue& ttv)
01334   {
01335     if (dbdebug >= 1) cout << "Calling database::setValueHelper" << endl;       
01336     Predicate* ppred = (Predicate *)pred;
01337     assert(ppred->isGrounded());
01338       
01339       // If this is a '=' predicate
01340     if (pred->isEqualPredWithType())
01341     {
01342       // If the two const ids are the same, actual truth value is TRUE,
01343       // otherwise FALSE
01344       TruthValue actual
01345         = (pred->getTerm(0)->getId() == pred->getTerm(1)->getId()) ?
01346           TRUE : FALSE;
01347       TruthValue opposite = (actual==TRUE) ? FALSE : TRUE;
01348 
01349         //if pred is in oppEqGndPreds_, return opposite of actual value
01350       for (int i = 0; i < oppEqGndPreds_.size(); i++)
01351         if (ppred->same(oppEqGndPreds_[i]))
01352         {
01353           if (flip || ttv == actual)
01354           {
01355             Predicate* pr = oppEqGndPreds_[i];
01356             oppEqGndPreds_.removeItemFastDisorder(i);
01357             delete pr;
01358           }
01359           if (dbdebug >= 1) cout << "returning " << opposite << endl;
01360           return opposite;
01361         }
01362 
01363       if (flip || ttv == opposite) oppEqGndPreds_.append(new Predicate(*pred));
01364       if (dbdebug >= 1) cout << "returning " << actual << endl;
01365       return actual;
01366     }
01367 
01368     int idx = getIdxOfGndPredValues(pred);
01369     int predId = pred->getId();
01370     return setValueHelper(idx, predId, flip, ttv, pred, NULL);
01371   }
01372 
01383   TruthValue setValueHelper(const GroundPredicate* const & pred,
01384                             const bool& flip, const TruthValue& ttv)
01385   {
01386     if (dbdebug >= 1) cout << "Calling database::setValueHelper" << endl;      
01387     int idx = getIdxOfGndPredValues(pred);
01388     int predId = pred->getId();
01389     return setValueHelper(idx, predId, flip, ttv, NULL, pred);
01390   }
01391 
01407   TruthValue setValueHelper(const int& idx, const int& predId,
01408                             const bool& flip, const TruthValue& ttv,
01409                             const Predicate* const & pred,
01410                             const GroundPredicate* const & gndPred)
01411   {
01412     assert((pred && !gndPred) || (!pred && gndPred));
01413     TruthValue oldtv = getValue(idx, predId);
01414     //TruthValue oldtv = FALSE;
01415     TruthValue tv = ttv;
01416 
01417     if (flip) 
01418     {
01419       assert(oldtv == TRUE || oldtv == FALSE);
01420       if (oldtv == FALSE) tv = TRUE;
01421       else                tv = FALSE;
01422     }
01423 
01424     if (oldtv != tv)
01425     {
01426       if (closedWorld_[predId])
01427       {
01428         if (oldtv == TRUE)  //TRUE->FALSE
01429         {
01430           assert(tv == FALSE);
01431           (*predIdToNumTF_)[predId].numTrue--;
01432           (*truePredIdxSet_)[predId].erase(idx);
01433           if (lazyFlag_)
01434           {
01435             if (pred) removeFromInverseIndex(pred, idx, T_INDEX);
01436             else if (gndPred) removeFromInverseIndex(gndPred, idx, T_INDEX);
01437 
01438             if (getActiveStatus(idx, predId))
01439             {
01440               if (pred) addToInverseIndex(pred, idx, FA_INDEX);
01441               else if (gndPred) addToInverseIndex(gndPred, idx, FA_INDEX);
01442             }
01443           }
01444         }
01445         else 
01446         { //FALSE->TRUE
01447           assert(oldtv == FALSE && tv == TRUE);
01448           (*predIdToNumTF_)[predId].numTrue++;
01449           (*truePredIdxSet_)[predId].insert(idx);
01450           if (lazyFlag_)
01451           {
01452             if (pred) addToInverseIndex(pred, idx, T_INDEX);
01453             else if (gndPred) addToInverseIndex(gndPred, idx, T_INDEX);
01454  
01455             if (getActiveStatus(idx, predId))
01456             {
01457               if (pred) removeFromInverseIndex(pred, idx, FA_INDEX);
01458               else if (gndPred) removeFromInverseIndex(gndPred, idx, FA_INDEX);
01459             }
01460           }
01461         }
01462       }
01463       else
01464       { //open world
01465         if (oldtv == UNKNOWN)
01466         {
01467           if (tv == TRUE)
01468           { //UNKNOWN->TRUE
01469             (*predIdToNumTF_)[predId].numTrue++;
01470             (*truePredIdxSet_)[predId].insert(idx);
01471             if (lazyFlag_)
01472             {
01473               if (pred) addToInverseIndex(pred, idx, T_INDEX);
01474               else if (gndPred) addToInverseIndex(gndPred, idx, T_INDEX);
01475             }
01476           }
01477           else
01478           { //UKNOWN->FALSE
01479             (*predIdToNumTF_)[predId].numFalse++;
01480             if (!performingInference_) (*falsePredIdxSet_)[predId].insert(idx);
01481             if (lazyFlag_)
01482             {
01483               if (getActiveStatus(idx, predId))
01484               {
01485                 if (pred) addToInverseIndex(pred, idx, FA_INDEX);
01486                 if (gndPred) addToInverseIndex(gndPred, idx, FA_INDEX);
01487               }
01488             }
01489           }
01490         }
01491         else
01492         if (oldtv == TRUE)
01493         {
01494           (*predIdToNumTF_)[predId].numTrue--;
01495           (*truePredIdxSet_)[predId].erase(idx);
01496           if (lazyFlag_)
01497           {
01498             if (pred) removeFromInverseIndex(pred, idx, T_INDEX);
01499             if (gndPred) removeFromInverseIndex(gndPred, idx, T_INDEX);
01500           }
01501           if (tv == FALSE) 
01502           { //TRUE->FALSE
01503             (*predIdToNumTF_)[predId].numFalse++;
01504             if (!performingInference_) (*falsePredIdxSet_)[predId].insert(idx);
01505             if (lazyFlag_)
01506             {
01507               if (getActiveStatus(idx, predId))
01508               {
01509                 if (pred) addToInverseIndex(pred, idx, FA_INDEX);
01510                 if (gndPred) addToInverseIndex(gndPred, idx, FA_INDEX);
01511               }
01512             }
01513           }
01514         }
01515         else
01516         {
01517           assert(oldtv == FALSE);
01518           (*predIdToNumTF_)[predId].numFalse--;
01519           if (!performingInference_) (*falsePredIdxSet_)[predId].erase(idx);
01520           if (lazyFlag_)
01521           {
01522             if (getActiveStatus(idx, predId))
01523             {
01524               if (pred) removeFromInverseIndex(pred, idx, FA_INDEX);
01525               else if (gndPred) removeFromInverseIndex(gndPred, idx, FA_INDEX);
01526             }
01527           }
01528           if (tv == TRUE)
01529           { //FALSE->TRUE
01530             (*predIdToNumTF_)[predId].numTrue++;
01531             (*truePredIdxSet_)[predId].insert(idx);
01532             if (lazyFlag_)
01533             {
01534               if (pred) addToInverseIndex(pred, idx, T_INDEX);
01535               else if (gndPred) addToInverseIndex(gndPred, idx, T_INDEX);
01536             }
01537           }
01538         }          
01539       }
01540     } // if (oldtv != tv)
01541     if (dbdebug >= 1) cout << "returning " << oldtv << endl;
01542     return oldtv;
01543   }
01544 
01555   bool setActiveStatus(const int& idx, const int& predId,
01556                        const bool& as, const Predicate* const & pred,
01557                        const GroundPredicate* const & gndPred)
01558   {
01559     assert((pred && !gndPred) || (!pred && gndPred));
01560     bool oldas = getActiveStatus(idx, predId);
01561     if (oldas != as)
01562     {
01563       if (as)
01564       {
01565         (*activePredIdxSet_)[predId].insert(idx);
01566       }
01567       else
01568       {
01569         (*activePredIdxSet_)[predId].erase(idx);
01570       }
01571       
01572       // If truth value is false then add to/remove from inverse index
01573       if (lazyFlag_)
01574       {
01575         TruthValue tv = getValue(idx, predId);
01576         if (tv == FALSE)
01577         {
01578           if (as)
01579           {
01580             if (pred) addToInverseIndex(pred, idx, FA_INDEX);
01581             else if (gndPred) addToInverseIndex(gndPred, idx, FA_INDEX);
01582           }
01583           else
01584           {
01585             if (pred) removeFromInverseIndex(pred, idx, FA_INDEX);
01586             if (gndPred) removeFromInverseIndex(gndPred, idx, FA_INDEX);
01587           }
01588         }
01589       }
01590     }
01591     if (dbdebug >= 1) cout << "Returning " << oldas << endl;
01592     return oldas;
01593   }
01594 
01601   bool setDeactivatedStatus(const int& idx, const int& predId, const bool& das)
01602   {
01603     bool olddas = getDeactivatedStatus(idx, predId);
01604     if (olddas != das)
01605     {
01606       if (das)
01607       {
01608         (*deactivatedPredIdxSet_)[predId].insert(idx);
01609       }
01610       else
01611       {
01612         (*deactivatedPredIdxSet_)[predId].erase(idx);
01613       }
01614     }
01615     if (dbdebug >= 1) cout << "Returning " << olddas << endl;
01616     return olddas;
01617   }
01618 
01625   bool setEvidenceStatus(const int& idx, const int& predId, const bool& es)
01626   {  
01627     bool oldes = getEvidenceStatus(idx, predId);
01628     if (oldes != es)
01629     {
01630       if (es)
01631       {
01632         (*evidencePredIdxSet_)[predId].insert(idx);
01633       }
01634       else
01635       {
01636         (*evidencePredIdxSet_)[predId].erase(idx);
01637       }
01638     }
01639     if (dbdebug >= 1) cout << "Returning " << oldes << endl;
01640     return oldes;
01641   }
01642 
01646   void addToInverseIndex(const Predicate* const & pred, const int& predIdx,
01647                          IndexType idxType)
01648   {
01649     int numTerms = pred->getNumTerms();
01650     if (numTerms == 2)
01651     {
01652       int predId = pred->getId();
01653       for (int term = 0; term < numTerms; term++)
01654       {
01655         int constantId = pred->getTerm(term)->getId();
01656         assert(constantId >= 0);
01657         int constantIndex = domain_->getConstantIndexInType(constantId);
01658         (*(*(*(*paramPredsArray_)[idxType])[predId])[term])
01659           [constantIndex]->append(predIdx);
01660       }
01661     }
01662   }
01663 
01667   void addToInverseIndex(const GroundPredicate* const & pred,
01668                          const int& predIdx, IndexType idxType)
01669   {
01670     int numTerms = pred->getNumTerms();
01671     if (numTerms == 2)
01672     {
01673       int predId = pred->getId();
01674       for (int term = 0; term < numTerms; term++)
01675       {
01676         int constantId = pred->getTermId(term);
01677         assert(constantId >= 0);
01678         int constantIndex = domain_->getConstantIndexInType(constantId);
01679         (*(*(*(*paramPredsArray_)[idxType])[predId])[term])
01680           [constantIndex]->append(predIdx);
01681       }
01682     }
01683   }
01684 
01688   void removeFromInverseIndex(const Predicate* const & pred,
01689                               const int& predIdx, IndexType idxType)
01690   {
01691     int numTerms = pred->getNumTerms();
01692     if (numTerms == 2)
01693     {
01694       int predId = pred->getId();
01695       for (int term = 0; term < numTerms; term++)
01696       {
01697         int constantId = pred->getTerm(term)->getId();
01698         assert(constantId >= 0);
01699         int constantIndex = domain_->getConstantIndexInType(constantId);
01700         int pos = (*(*(*(*paramPredsArray_)[idxType])[predId])[term])
01701                     [constantIndex]->find(predIdx);
01702         if (pos > -1)
01703         {
01704           (*(*(*(*paramPredsArray_)[idxType])[predId])[term])
01705             [constantIndex]->removeItemFastDisorder(pos);
01706         }
01707       }
01708     }
01709   }
01710 
01714   void removeFromInverseIndex(const GroundPredicate* const & pred,
01715                               const int& predIdx, IndexType idxType)
01716   {
01717     int numTerms = pred->getNumTerms();
01718     if (numTerms == 2)
01719     {
01720       int predId = pred->getId();
01721       for (int term = 0; term < numTerms; term++)
01722       {
01723         int constantId = pred->getTermId(term);
01724         assert(constantId >= 0);
01725         int constantIndex = domain_->getConstantIndexInType(constantId);
01726         int pos = (*(*(*(*paramPredsArray_)[idxType])[predId])[term])
01727                     [constantIndex]->find(predIdx);
01728         if (pos > -1)
01729         {
01730           (*(*(*(*paramPredsArray_)[idxType])[predId])[term])
01731             [constantIndex]->removeItemFastDisorder(pos);
01732         }
01733       }
01734     }
01735   }
01736 
01737  private:
01738   const Domain* domain_; // not owned by Database
01739 
01740     // closedWorld_[p]==true: the closed world assumption is made for pred p
01741   Array<bool> closedWorld_; 
01742 
01743         // Flag is set when performing lazy inference
01744   bool lazyFlag_;
01745   
01746     // Flag set when performing inference. If set, hash table of false ground
01747     // atoms is not used (all atoms are true or false).
01748   bool performingInference_;
01749   
01750     // firstConstId_[c] is the id of the first constant of class c
01751   Array<unsigned int> firstConstIdByType_;
01752 
01753     //Suppose a predicate with id i has three terms, and the number of 
01754     //groundings of the first, second and third terms are 
01755     //4, 3, 2 respectively. Then termMultByPred_[i][0].first = 3x2,
01756     //termMultByPred_[i][1].first = 2, and termMultByPred_[i][2].first = 1.
01757     //termMultByPred_[i][j].first is the product of the number of groundings
01758     //of terms j > i;
01759   Array<Array<MultAndType>*> termMultByPred_;
01760 
01761     // predIdToNumTF_[p] contains the number of TRUE/FALSE groundings of pred
01762     // with id p  
01763   Array<NumTrueFalse>* predIdToNumTF_;
01764 
01765 
01766     //'=' ground preds that are set to opposite of their actual values
01767     //We are using a simple array because we are setting one ground predicate 
01768     //at a time to the opposite of its actual value and then reverting it to 
01769     //its actual value,so there's no efficiency penalty when searching the array
01770   Array<Predicate*> oppEqGndPreds_;
01771   
01772     //The following structure implements the inverse index
01773         //3 levels of indirection. First - the first order predicate
01774     //the true list is for, second - parameter in the predicate it 
01775     //is indexed, and third - value of the parameter it is
01776     //indexed.
01777   Array<Array<Array<Array<Array<int>*>*>*>*>* paramPredsArray_;
01778 
01779         // Hash set of true ground atoms
01780   Array<hash_set<int> >* truePredIdxSet_;
01781   
01782         // Hash set of false ground atoms - only used for open world preds
01783   Array<hash_set<int> >* falsePredIdxSet_;
01784 
01785         // Hash set of active ground atoms
01786   Array<hash_set<int> >* activePredIdxSet_;
01787 
01788         // Hash set of evidence ground atoms
01789   Array<hash_set<int> >* evidencePredIdxSet_;
01790   
01791         // Hash set of deactivated ground atoms
01792   Array<hash_set<int> >* deactivatedPredIdxSet_;
01793 
01794     // Total number of groundings for each predicate
01795   Array<int> numberOfGroundings_;
01796 };
01797 
01798 
01799 #endif

Generated on Tue Jan 16 05:30:04 2007 for Alchemy by  doxygen 1.5.1