clause.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 CLAUSE_H_JUN_26_2005
00067 #define CLAUSE_H_JUN_26_2005
00068 
00069 #include <ext/hash_set>
00070 using namespace __gnu_cxx;
00071 #include <ostream>
00072 #include <sstream>
00073 using namespace std;
00074 #include <climits>
00075 #include "domain.h"
00076 #include "hashstring.h"
00077 #include "hashlist.h"
00078 #include "arraysaccessor.h"
00079 #include "powerset.h"
00080 #include "multdarray.h"
00081 #include "hashint.h"
00082 #include "database.h"
00083 #include "predicate.h"
00084 #include "groundpredicate.h"
00085 #include "intclause.h"
00086 #include "clausesampler.h"
00087 #include "clausehelper.h"
00088 
00089 //const bool useInverseIndex = false;
00090 const bool useInverseIndex = true;
00091 
00092 /******************************************************************************/
00094 class HashClause;
00095 class EqualClause;
00096 typedef HashArray<Clause*, HashClause, EqualClause> ClauseHashArray;
00097 /******************************************************************************/
00098 
00099 class AddGroundClauseStruct;
00100 
00101 
00102   //Ensure that the dirty_ bit is consistently updated.
00103 class Clause
00104 {
00105   friend class ClauseSampler;
00106 
00107  public: 
00108   Clause() 
00109     : wt_(0), predicates_(new Array<Predicate*>), intArrRep_(NULL),
00110       hashCode_(0), dirty_(true), isHardClause_(false),
00111       varIdToVarsGroundedType_(NULL), auxClauseData_(NULL) {}
00112 
00113   Clause(const double& wt) 
00114     : wt_(wt), predicates_(new Array<Predicate*>), intArrRep_(NULL),
00115       hashCode_(0), dirty_(true), isHardClause_(false),
00116       varIdToVarsGroundedType_(NULL), auxClauseData_(NULL) {}
00117 
00118 
00119   Clause(const Clause& c)
00120   {
00121     wt_ = c.wt_;
00122     predicates_ = new Array<Predicate*>;
00123     Array<Predicate*>* cpredicates = c.predicates_;
00124     for (int i = 0; i < cpredicates->size(); i++)
00125     {
00126       Predicate* p = (*cpredicates)[i];
00127       predicates_->append(new Predicate(*p, this));      
00128     }
00129     dirty_ = c.dirty_;
00130 
00131     if (!dirty_) { assert(noDirtyPredicates()); }
00132 
00133     if (c.intArrRep_)  intArrRep_ = new Array<int>(*(c.intArrRep_));
00134     else               intArrRep_ = NULL;
00135 
00136     hashCode_ = c.hashCode_;
00137     
00138     isHardClause_ = c.isHardClause_;
00139 
00140     if (c.varIdToVarsGroundedType_)
00141     {
00142       varIdToVarsGroundedType_ = new Array<VarsGroundedType*>;
00143       for (int i = 0; i < c.varIdToVarsGroundedType_->size(); i++)
00144       {
00145         VarsGroundedType* vgt = (*(c.varIdToVarsGroundedType_))[i];
00146         varIdToVarsGroundedType_->append(new VarsGroundedType(*vgt));
00147       }
00148     }
00149     else
00150       varIdToVarsGroundedType_ = NULL;
00151 
00152     if (c.auxClauseData_)
00153     {
00154       auxClauseData_ = new AuxClauseData(c.auxClauseData_->gain,
00155                                          c.auxClauseData_->op,
00156                                          c.auxClauseData_->removedClauseIdx,
00157                                          c.auxClauseData_->hasBeenExpanded,
00158                                          c.auxClauseData_->lastStepExpanded,
00159                                        c.auxClauseData_->lastStepOverMinWeight);
00160       if (c.auxClauseData_->constTermPtrs) trackConstants();
00161       if (c.auxClauseData_->cache)
00162       {
00163         Array<Array<Array<CacheCount*>*>*>* cache, * otherCache;
00164         cache  = new Array<Array<Array<CacheCount*>*>*>;
00165         otherCache = c.auxClauseData_->cache;
00166 
00167         cache->growToSize(otherCache->size(),NULL);
00168 
00169         for (int i = 0; i < otherCache->size(); i++)
00170         {
00171           (*cache)[i] = new Array<Array<CacheCount*>*>;
00172           (*cache)[i]->growToSize((*otherCache)[i]->size(), NULL);
00173           for (int j = 0; j < (*otherCache)[i]->size(); j++)
00174           {
00175             Array<CacheCount*>* ccArr = (*(*otherCache)[i])[j];
00176             if (ccArr == NULL) continue;
00177             (*(*cache)[i])[j] = new Array<CacheCount*>;
00178             (*(*cache)[i])[j]->growToSize(ccArr->size());
00179             for (int k = 0; k < ccArr->size(); k++)
00180             {
00181               (*(*(*cache)[i])[j])[k] = new CacheCount((*ccArr)[k]->g,
00182                                                        (*ccArr)[k]->c,
00183                                                        (*ccArr)[k]->cnt); 
00184             }
00185           }
00186         }
00187         auxClauseData_->cache = cache;
00188       }
00189       
00190       auxClauseData_->prevClauseStr = c.auxClauseData_->prevClauseStr;
00191       auxClauseData_->addedPredStr = c.auxClauseData_->addedPredStr;
00192       auxClauseData_->removedPredIdx = c.auxClauseData_->removedPredIdx;
00193     }
00194     else
00195       auxClauseData_ = NULL;
00196   }
00197 
00198 
00199   ~Clause() 
00200   {
00201     for (int i = 0; i < predicates_->size(); i++)
00202       delete (*predicates_)[i];
00203     delete predicates_;
00204     if (intArrRep_) delete intArrRep_;
00205     if (varIdToVarsGroundedType_) deleteVarIdToVarsGroundedType();
00206     if (auxClauseData_) delete auxClauseData_;
00207   }
00208 
00209   
00210     //returns approximate size in MB, mainly due to cache in auxClauseData_
00211   double sizeMB() const
00212   {
00213     double sizeMB = (fixedSizeB_ + intArrRep_->size()*sizeof(int) + 
00214                      predicates_->size()*sizeof(Predicate*)) /1000000.0;
00215     for (int i = 0; i < predicates_->size(); i++)
00216       sizeMB += (*predicates_)[i]->sizeMB();
00217     if (auxClauseData_ != NULL) sizeMB += auxClauseData_->sizeMB(); 
00218     return sizeMB;
00219   }
00220 
00221 
00222   static void computeFixedSizeB()
00223   {
00224     fixedSizeB_ = sizeof(Clause) + sizeof(Array<Predicate*>) +
00225                   sizeof(Array<int>);
00226     //+ sizeof(Array<VarsGroundedType*>); // this is transient
00227   }
00228 
00229 
00230   void compress()
00231   {
00232     predicates_->compress();
00233     for (int i = 0; i < predicates_->size(); i++) (*predicates_)[i]->compress();
00234     if (intArrRep_) intArrRep_->compress();
00235     if (varIdToVarsGroundedType_) varIdToVarsGroundedType_->compress();
00236     if (auxClauseData_) auxClauseData_->compress();
00237   }
00238 
00239 
00240   bool same(Clause* const & c)
00241   {
00242     if (this == c)  return true;
00243     const Array<int>* cArr  = c->getIntArrRep();
00244     const Array<int>* myArr = getIntArrRep();
00245     if (myArr->size() != cArr->size()) return false;
00246     const int* cItems  = c->getIntArrRep()->getItems();
00247     const int* myItems = getIntArrRep()->getItems();
00248     return (memcmp(myItems, cItems, myArr->size()*sizeof(int))==0);
00249   }
00250 
00251   size_t hashCode() 
00252   {
00253     if (dirty_) computeAndStoreIntArrRep();
00254     return hashCode_;
00255   }
00256 
00257 
00258   int getNumPredicates() const { return predicates_->size(); }
00259 
00260   double getWt() const { return wt_; }
00261 
00262   const double* getWtPtr() const { return &wt_; }
00263 
00264     // not setting dirty bit because it does not affect the clause
00265   void setWt(const double& wt) { wt_ = wt; }  
00266   void addWt(const double& wt) { wt_ += wt;  }
00267  
00268   void setDirty() { dirty_ = true; }
00269   bool isDirty() const { return dirty_; }
00270 
00271     // Caller should not delete returned Predicate*.
00272   Predicate* getPredicate(const int& idx) const { return (*predicates_)[idx]; }
00273   
00274     // Caller should not delete returned array nor modify its contents.
00275   const Array<Predicate*>* getPredicates() const { return predicates_; }
00276 
00277 
00278   bool containsPredicate(const Predicate* const & pred) const
00279   {
00280     for (int i = 0; i < predicates_->size(); i++)
00281       if ((*predicates_)[i]->same((Predicate*)pred)) return true;
00282     return false;
00283   }
00284 
00285   
00286   int getNumVariables() const
00287   {
00288     hash_set<int> intset;
00289     for (int i = 0; i < predicates_->size(); i++)
00290       for (int j = 0; j < (*predicates_)[i]->getNumTerms(); j++)
00291       {
00292         if ((*predicates_)[i]->getTerm(j)->getType() == Term::VARIABLE)
00293           intset.insert((*predicates_)[i]->getTerm(j)->getId());
00294       }
00295     return intset.size();
00296   }
00297 
00298 
00299   int getNumVariablesAssumeCanonicalized() const
00300   {
00301     int minVarId = 0;
00302     for (int i = 0; i < predicates_->size(); i++)
00303       for (int j = 0; j < (*predicates_)[i]->getNumTerms(); j++)
00304       {
00305         if ((*predicates_)[i]->getTerm(j)->getType() == Term::VARIABLE &&
00306             (*predicates_)[i]->getTerm(j)->getId() < minVarId)
00307           minVarId = (*predicates_)[i]->getTerm(j)->getId();
00308 
00309       }
00310     return -minVarId;
00311   }
00312 
00313 
00314   bool isHardClause() const { return isHardClause_; }
00315   void setIsHardClause(const bool& b) { isHardClause_ = b; }
00316 
00317 
00318     // p is stored in MLN and the caller of this function should not delete it.
00319   void appendPredicate(Predicate* const& p) {predicates_->append(p);setDirty();}
00320 
00321     // after removing a predicate, the clause is no longer canonicalized
00322   Predicate* removePredicate(const int& i) 
00323   { 
00324     if (0 <= i && i < predicates_->size()) 
00325     { setDirty(); return predicates_->removeItemFastDisorder(i); }
00326     return NULL;
00327   }
00328 
00329 
00330     //returns true if redundant predicates were removed
00331   bool hasRedundantPredicates()
00332   {
00333     for (int i = 0; i < predicates_->size(); i++)
00334     {
00335       Predicate* ip = (*predicates_)[i];
00336       for (int j = i+1; j < predicates_->size(); j++)
00337       {
00338         Predicate* jp = (*predicates_)[j];
00339         if (jp->same(ip) && jp->getSense() == ip->getSense()) return true;
00340       }
00341     }
00342     return false;
00343   }
00344 
00345 
00346     //returns true if redundant predicates were removed
00347   bool removeRedundantPredicates()
00348   {
00349     bool changed = false;
00350     for (int i = 0; i < predicates_->size(); i++)
00351     {
00352       Predicate* ip = (*predicates_)[i];
00353       for (int j = i+1; j < predicates_->size(); j++)
00354       {
00355         Predicate* jp = (*predicates_)[j];
00356         if (jp->same(ip) && jp->getSense() == ip->getSense())
00357         {
00358           predicates_->removeItemFastDisorder(j);
00359           changed = true;
00360           j--;
00361         }
00362       }
00363     }
00364     return changed;
00365   }
00366 
00367   
00368   void removeRedundantPredicatesAndCanonicalize()
00369   { if (removeRedundantPredicates()) canonicalize(); }
00370 
00371   
00372   void canonicalize()
00373   {
00374       // rename the variables in decreasing order (negative numbers) 
00375     Array<VarsGroundedType*>* vgtArr = new Array<VarsGroundedType*>;
00376     createVarIdToVarsGroundedType(vgtArr);
00377 
00378     sortPredicatesByIdAndSenseAndTerms(0, predicates_->size()-1, vgtArr);
00379 
00380     IntHashArray varAppearOrder;
00381     getVarOrder(varAppearOrder);
00382 
00383     int newVarId = 0;
00384     for (int i = 0; i < varAppearOrder.size(); i++)
00385     {
00386       int varId = varAppearOrder[i];
00387       ++newVarId;
00388       Array<Term*>& vars = (*vgtArr)[varId]->vars;
00389       for (int j = 0; j < vars.size(); j++)  vars[j]->setId(-newVarId);
00390     }
00391     assert(newVarId == varAppearOrder.size());
00392 
00393     int i = 0, j = 0;
00394     while (i < predicates_->size())
00395     {
00396       while (++j < predicates_->size() 
00397              && (*predicates_)[i]->getId() == (*predicates_)[j]->getId() 
00398              && (*predicates_)[i]->getSense() == (*predicates_)[j]->getSense());
00399       if (i < j-1) sortPredicatesByTerms(i, j-1);
00400       i = j;
00401     }
00402     
00403     deleteVarIdToVarsGroundedType(vgtArr);
00404     setDirty();
00405   }
00406 
00407 
00408   static bool moveTermsFromUnseenToSeen(Array<Term*>* const & terms,
00409                                  PredicateHashArray& unseenPreds,
00410                                  Array<Predicate*>& seenPreds)
00411   {
00412     for (int j = 0; j < terms->size(); j++)
00413     {
00414       bool parIsPred;
00415       Predicate* parent = (Predicate*) (*terms)[j]->getParent(parIsPred);      
00416       assert(parIsPred);
00417       int a;
00418       if ((a=unseenPreds.find(parent)) >= 0)
00419       {
00420         Predicate* par = unseenPreds.removeItemFastDisorder(a);
00421         if (unseenPreds.empty()) return true;
00422         assert(par == parent);
00423         seenPreds.append(par);
00424       }
00425     }
00426     return false;
00427   }
00428 
00429 
00430     //Returns true if there is a path of shared variables between any two preds
00431   bool checkPredsAreConnected()
00432   {
00433     if (predicates_->size() <= 1) return true;
00434     Array<Array<Term*>*>* varIdToTerms = new Array<Array<Term*>*>;
00435     hash_map<int,Array<Term*>*>* constIdToTerms=new hash_map<int,Array<Term*>*>;
00436     createVarConstIdToTerms(varIdToTerms, constIdToTerms);
00437     PredicateHashArray unseenPreds;
00438     Array<Predicate*> seenPreds;
00439     hash_set<int> seenIds;
00440 
00441     seenPreds.append((*predicates_)[0]);
00442     for (int i = 1; i < predicates_->size(); i++) 
00443       unseenPreds.append((*predicates_)[i]);
00444 
00445     while (!seenPreds.empty())
00446     {
00447       Predicate* curPred = seenPreds.removeLastItem();
00448       for (int i = 0; i < curPred->getNumTerms(); i++) 
00449       {
00450         const Term* t = curPred->getTerm(i);
00451         int id = t->getId();
00452         if (seenIds.find(id) != seenIds.end()) continue;
00453         seenIds.insert(id);
00454 
00455         if (t->getType() == Term::VARIABLE)
00456         {
00457           Array<Term*>* terms = (*varIdToTerms)[-id];
00458           for (int j = 0; j < terms->size(); j++)
00459           {
00460             bool parIsPred;
00461             Predicate* parent = (Predicate*) (*terms)[j]->getParent(parIsPred);
00462             assert(parIsPred);
00463             int a;
00464             if ((a=unseenPreds.find(parent)) >= 0)
00465             {
00466               Predicate* par = unseenPreds.removeItemFastDisorder(a);
00467               if (unseenPreds.empty()) 
00468               {
00469                 deleteVarConstIdToTerms(varIdToTerms, constIdToTerms);
00470                 return true;
00471               }
00472               seenPreds.append(par);
00473 
00474               //commented out: not true if there a duplicate preds in clause
00475               //               e.g. !isMale(p) v isMale(p)
00476               //assert(par == parent);
00477             }
00478           }
00479         }
00480         else
00481         if (t->getType() == Term::CONSTANT)
00482         {
00483           Array<Term*>* terms = (*constIdToTerms)[id];
00484           for (int j = 0; j < terms->size(); j++)
00485           {
00486             bool parIsPred;
00487             Predicate* parent = (Predicate*) (*terms)[j]->getParent(parIsPred);
00488             assert(parIsPred);
00489             int a;
00490             if ((a=unseenPreds.find(parent)) >= 0)
00491             {
00492               Predicate* par = unseenPreds.removeItemFastDisorder(a);
00493               if (unseenPreds.empty()) 
00494               {
00495                 deleteVarConstIdToTerms(varIdToTerms, constIdToTerms);
00496                 return true;
00497               }
00498               seenPreds.append(par);
00499                 //commented out: not true if there a duplicate preds in clause
00500                 //               e.g. !isMale(p) v isMale(p)
00501               //assert(par == parent);
00502             }
00503           }
00504         }
00505       } // for each term of curPred
00506     } // while (!seenPreds.empty())
00507 
00508     assert(!unseenPreds.empty());
00509     deleteVarConstIdToTerms(varIdToTerms, constIdToTerms);
00510     return false;
00511   }
00512 
00513 
00514   void canonicalizeWithoutVariables()
00515   {
00516     sortPredicatesByIdAndSenseAndTerms(0, predicates_->size()-1, NULL);
00517     int i = 0, j = 0;
00518     while (i < predicates_->size())
00519     {
00520       while (++j < predicates_->size() 
00521              && (*predicates_)[i]->getId() == (*predicates_)[j]->getId() 
00522              && (*predicates_)[i]->getSense() == (*predicates_)[j]->getSense());
00523       if (i < j-1) sortPredicatesByTerms(i, j-1);
00524       i = j;
00525     }
00526     setDirty();
00527   }
00528 
00529   
00530   AuxClauseData* getAuxClauseData() const { return auxClauseData_; }
00531 
00532 
00533   void setAuxClauseData(AuxClauseData* const& acd ) 
00534   { 
00535     if (auxClauseData_ == acd) return;
00536     if (auxClauseData_) delete auxClauseData_;
00537     auxClauseData_ = acd;
00538   }
00539 
00540 
00541   void newAuxClauseData() 
00542   {if (auxClauseData_) delete auxClauseData_; auxClauseData_=new AuxClauseData;}
00543 
00544 
00545   static void setClauseSampler(ClauseSampler* const & cs) 
00546   { if (clauseSampler_) delete clauseSampler_; clauseSampler_ = cs; }
00547 
00548 
00549   static const ClauseSampler* getClauseSampler() { return clauseSampler_; }
00550   
00551 
00552   bool containsConstants() const
00553   {
00554     return (auxClauseData_ && auxClauseData_->constTermPtrs && 
00555             auxClauseData_->constTermPtrs->size() > 0);
00556   }
00557 
00558 
00559     //auxClauseData_ must have been set to a valid AuxClauseData object
00560   void trackConstants()
00561   {
00562     if (auxClauseData_ == NULL) auxClauseData_ = new AuxClauseData; 
00563     Array<Term*>*& constTermPtrs = auxClauseData_->constTermPtrs;
00564     if (constTermPtrs) constTermPtrs->clear();
00565     for (int i = 0; i < predicates_->size(); i++)
00566     {
00567       Predicate* p = (*predicates_)[i];
00568       for (int j = 0; j < p->getNumTerms(); j++)
00569       {
00570         const Term* t = p->getTerm(j);
00571         if (t->getType() == Term::CONSTANT)
00572         {
00573           if (constTermPtrs == NULL) constTermPtrs = new Array<Term*>;
00574           constTermPtrs->append((Term*)t);
00575         }
00576       }
00577     }
00578   }
00579 
00580 
00581     //auxClauseData_ must have been set to a valid AuxClauseData object  
00582   void newCache(const int& numDomains, const int& numPreds)
00583   {
00584     assert(auxClauseData_);
00585     auxClauseData_->deleteCache();
00586     auxClauseData_->cache = new Array<Array<Array<CacheCount*>*>*>;
00587     auxClauseData_->cache->growToSize(numDomains, NULL);
00588     for (int i = 0; i < numDomains; i++)
00589     {
00590       (*auxClauseData_->cache)[i] = new Array<Array<CacheCount*>*>;
00591       (*auxClauseData_->cache)[i]->growToSize(numPreds, NULL);
00592     }
00593   }
00594 
00595   
00596   void translateConstants(const Domain* const & orig, const Domain* const& nnew)
00597   {
00598     if (auxClauseData_ == NULL || auxClauseData_->constTermPtrs == NULL) return;
00599 
00600     Array<Term*>* constTermPtrs = auxClauseData_->constTermPtrs;
00601     for (int i = 0; i < constTermPtrs->size(); i++)
00602     {
00603       Term* t = (*constTermPtrs)[i];
00604       int newId = nnew->getConstantId(orig->getConstantName(t->getId()));
00605       t->setId(newId);
00606       if (newId < 0)
00607       {
00608         cout << "ERROR: in Clause::translateConstants(). Failed to translate "
00609              <<orig->getConstantName(t->getId())<<" from one domain to another."
00610              << "Check that the constant exists in all domains." << endl;
00611         exit(-1);                                      
00612       }
00613     }
00614   }
00615 
00616     //Returns a map from typeId to variable ids. ReturnedArray[typeId] is NULL
00617     //if there are no variables for the corresponding typeId.
00618     //Caller is responsible for deleting the return Array and its contents.
00619   Array<Array<int>*>* getTypeIdToVarIdsMapAndSmallestVarId(int& smallestVarId)
00620   {
00621     smallestVarId = 0;
00622     hash_set<int> intSet;
00623     Array<Array<int>*>* arr = new Array<Array<int>*>;
00624     for (int i = 0; i < predicates_->size(); i++)
00625     {
00626       Predicate* pred = (*predicates_)[i];
00627       for (int j = 0; j < pred->getNumTerms(); j++)
00628       {
00629         const Term* t = pred->getTerm(j);
00630         if (t->getType() == Term::VARIABLE)
00631         {
00632           int varId = t->getId();
00633           if (intSet.find(varId) != intSet.end()) continue;
00634           intSet.insert(varId);
00635 
00636           int typeId = pred->getTermTypeAsInt(j); 
00637           if (typeId >= arr->size()) arr->growToSize(typeId+1, NULL);
00638           if ((*arr)[typeId] == NULL) (*arr)[typeId] = new Array<int>;
00639           (*arr)[typeId]->append(varId); 
00640           
00641           if (varId < smallestVarId) smallestVarId = varId;
00642         }
00643       }
00644     }
00645     return arr;
00646   }
00647 
00648 
00649   static void sortByLen(Array<Clause*>& ca) { sortByLen(ca, 0, ca.size()-1); } 
00650 
00651 
00652   static string getOpAsString(const int& op)
00653   {
00654     if (op == OP_ADD)             return "OP_ADD";
00655     if (op == OP_REPLACE_ADDPRED) return "OP_REPLACE_ADDPRED";
00656     if (op == OP_REPLACE_REMPRED) return "OP_REPLACE_REMPRED";
00657     if (op == OP_REMOVE)          return "OP_REMOVE";
00658     if (op == OP_REPLACE)         return "OP_REPLACE";
00659     if (op == OP_NONE)            return "OP_NONE";
00660     return "";
00661   }
00662 
00663 
00664   ostream& print(ostream& out, const Domain* const& domain, 
00665                  const bool& withWt, const bool& asInt, 
00666                  const bool& withStrVar) const
00667   {
00668     if (withWt) out << wt_ << " ";
00669 
00670     Array<Predicate*> eqPreds;
00671     Array<Predicate*> internalPreds;
00672     for (int i = 0; i < predicates_->size(); i++)
00673     {
00674       if ((*predicates_)[i]->isEqualPred()) 
00675         eqPreds.append((*predicates_)[i]);
00676       else
00677       if ((*predicates_)[i]->isInternalPred()) 
00678         internalPreds.append((*predicates_)[i]);
00679       else
00680       {
00681         if (asInt)           (*predicates_)[i]->printAsInt(out);
00682         else if (withStrVar) (*predicates_)[i]->printWithStrVar(out, domain);
00683         else                 (*predicates_)[i]->print(out,domain);
00684         if (i < predicates_->size()-1 || !eqPreds.empty() ||
00685                 !internalPreds.empty()) out << " v ";
00686       }
00687     }
00688 
00689     for (int i = 0; i < eqPreds.size(); i++)
00690     {
00691       if (asInt)           eqPreds[i]->printAsInt(out);
00692       else if (withStrVar) eqPreds[i]->printWithStrVar(out,domain);
00693       else                 eqPreds[i]->print(out,domain);
00694       out << ((i != eqPreds.size()-1 || !internalPreds.empty())?" v ":"");      
00695     }
00696 
00697     for (int i = 0; i < internalPreds.size(); i++)
00698     {
00699       if (asInt)           internalPreds[i]->printAsInt(out);
00700       else if (withStrVar) internalPreds[i]->printWithStrVar(out,domain);
00701       else                 internalPreds[i]->print(out,domain);
00702       out << ((i!=internalPreds.size()-1)?" v ":"");      
00703     }
00704 
00705     return out;
00706   }
00707 
00708 
00709   ostream& printAsInt(ostream& out) const
00710   { return print(out, NULL, true, true, false); }
00711 
00712   ostream& printWithoutWt(ostream& out, const Domain* const & domain) const
00713   { return print(out, domain, false, false, false); }
00714 
00715   ostream& 
00716   printWithoutWtWithStrVar(ostream& out, const Domain* const & domain) const
00717   { return print(out, domain, false, false, true); }
00718 
00719   ostream& printWithWtAndStrVar(ostream& out, const Domain* const& domain) const
00720   { return print(out, domain, true, false, true); }
00721 
00722   ostream& print(ostream& out, const Domain* const& domain) const
00723   { return print(out, domain, true, false, false); }
00724     
00725   ostream& printWithoutWtWithStrVarAndPeriod(ostream& out, 
00726                                               const Domain* const& domain) const
00727   {
00728     printWithoutWtWithStrVar(out, domain);
00729     if (isHardClause_) out << ".";
00730     return out;
00731   }
00732 
00733 
00734  private:
00735   static int comparePredicatesByIdAndSenseAndTerms(
00736                              const Predicate* const & l, 
00737                                              const Predicate* const & r,
00738                                  const Array<VarsGroundedType*>* const & vgtArr)
00739   {
00740     if (l->getId() < r->getId()) return -1;
00741     if (l->getId() > r->getId()) return 1;
00742     if (l->getSense() && !(r->getSense())) return -1;
00743     if (!(l->getSense()) && r->getSense()) return 1;
00744     assert(l->getNumTerms() == r->getNumTerms());
00745     for (int i = 0; i < l->getNumTerms(); i++)
00746     {
00747       int lid = l->getTerm(i)->getId();
00748       int rid = r->getTerm(i)->getId();
00749       if (vgtArr && lid < 0 && rid < 0)
00750       {
00751         bool lbound = (*vgtArr)[-lid]->vars.size() > 1;
00752         bool rbound = (*vgtArr)[-rid]->vars.size() > 1;
00753         if (lbound && !rbound) return -1;
00754         if (!lbound && rbound) return 1;
00755       }
00756       if (lid > rid) return -1;
00757       if (lid < rid) return 1;
00758     }
00759     return 0;
00760   }
00761 
00762 
00763   void sortPredicatesByIdAndSenseAndTerms(const int& l, const int& r,
00764                                  const Array<VarsGroundedType*>* const & vgtArr)
00765   {
00766     if (l >= r) return;
00767     Predicate* tmp = (*predicates_)[l];
00768     (*predicates_)[l] = (*predicates_)[(l+r)/2];
00769     (*predicates_)[(l+r)/2] = tmp;
00770 
00771     int last = l;
00772     for (int i = l+1; i <= r; i++)
00773     if (comparePredicatesByIdAndSenseAndTerms((*predicates_)[i],
00774                                               (*predicates_)[l], vgtArr) < 0)
00775       {
00776         ++last;
00777         tmp = (*predicates_)[last];
00778         (*predicates_)[last] = (*predicates_)[i];
00779         (*predicates_)[i] = tmp;
00780       }
00781     
00782     tmp = (*predicates_)[l];
00783     (*predicates_)[l] = (*predicates_)[last];
00784     (*predicates_)[last] = tmp;
00785     sortPredicatesByIdAndSenseAndTerms(l, last-1, vgtArr);
00786     sortPredicatesByIdAndSenseAndTerms(last+1, r, vgtArr);  
00787   }
00788 
00789 
00790     //l and r must have the same id and sense
00791   static int comparePredicatesByTerms(const Predicate* const & l,
00792                                const Predicate* const & r)
00793   {
00794     assert(l->getId() == r->getId());
00795     assert(l->getSense() == r->getSense());
00796     for (int i = 0; i < l->getNumTerms(); i++)
00797     {
00798       const Term* lTerm =l->getTerm(i);
00799       const Term* rTerm =r->getTerm(i);
00800       int lTermType = lTerm->getType();
00801       int rTermType = rTerm->getType();
00802       if (lTermType == Term::VARIABLE && rTermType == Term::VARIABLE)
00803       {
00804         if (lTerm->getId() > rTerm->getId()) return -1;
00805         if (lTerm->getId() < rTerm->getId()) return 1;
00806       }
00807       else
00808       if (lTermType == Term::CONSTANT && rTermType == Term::CONSTANT)
00809       {
00810         if (lTerm->getId() < rTerm->getId()) return -1;
00811         if (lTerm->getId() > rTerm->getId()) return 1;
00812       }
00813       else
00814       if (lTermType == Term::VARIABLE && rTermType == Term::CONSTANT)
00815         return -1;
00816       else
00817       if (lTermType == Term::CONSTANT && rTermType == Term::VARIABLE)
00818         return 1;
00819       else
00820       {
00821         assert(false);
00822       }
00823     }
00824     return 0;
00825   }
00826 
00827 
00828     //The lth to rth predicates must have the same id and sense 
00829   void sortPredicatesByTerms(const int& l, const int& r)
00830   {
00831     if (l >= r) return;
00832     Predicate* tmp = (*predicates_)[l];
00833     (*predicates_)[l] = (*predicates_)[(l+r)/2];
00834     (*predicates_)[(l+r)/2] = tmp;
00835     
00836     int last = l;
00837     for (int i = l+1; i <= r; i++)
00838       if (comparePredicatesByTerms((*predicates_)[i],(*predicates_)[l]) < 0)
00839       {
00840         ++last;
00841         tmp = (*predicates_)[last];
00842         (*predicates_)[last] = (*predicates_)[i];
00843         (*predicates_)[i] = tmp;
00844       }
00845     
00846     tmp = (*predicates_)[l];
00847     (*predicates_)[l] = (*predicates_)[last];
00848     (*predicates_)[last] = tmp;
00849     sortPredicatesByTerms(l, last-1);
00850     sortPredicatesByTerms(last+1, r);  
00851   }
00852 
00853 
00854   bool noDirtyPredicates() const
00855   {
00856     for (int i = 0; i < predicates_->size(); i++)
00857       if ((*predicates_)[i]->isDirty()) return false;
00858     return true;
00859   }
00860 
00861   const Array<int>* getIntArrRep() 
00862   { if (dirty_) computeAndStoreIntArrRep(); return intArrRep_; }
00863 
00864 
00865   void computeAndStoreIntArrRep()
00866   {
00867     dirty_ = false;
00868     if (intArrRep_ == NULL) intArrRep_ = new Array<int>;
00869     else                    intArrRep_->clear();
00870 
00871     int numPred = predicates_->size();
00872     for (int i = 0; i < numPred; i++)
00873     {
00874       if ((*predicates_)[i]->getSense()) intArrRep_->append(1);
00875       else                               intArrRep_->append(0);
00876       (*predicates_)[i]->appendIntArrRep(*intArrRep_);      
00877     }
00878     hashCode_ = Hash::hash(*intArrRep_);
00879   }
00880 
00881   
00883  public:
00884   void addUnknownClauses(const Domain* const & domain, 
00885                          const Database* const& db, const int& gndPredIdx, 
00886                          const GroundPredicate* const & groundPred,
00887                          const AddGroundClauseStruct* const & agcs)
00888   {
00889     createVarIdToVarsGroundedType(domain);
00890     if (gndPredIdx >= 0) groundPredVars(gndPredIdx, groundPred);
00891     countNumTrueGroundings(domain, db, true, false, gndPredIdx, groundPred, 
00892                            NULL, NULL, NULL, NULL, agcs);
00893     restoreVars();
00894     deleteVarIdToVarsGroundedType();
00895   }
00896 
00897 
00898   void getUnknownClauses(const Domain* const & domain, 
00899                          const Database* const& db, const int& gndPredIdx, 
00900                          const GroundPredicate* const & groundPred,
00901                          const Predicate* const & gndPred,
00902                          Array<GroundClause*>* const& unknownGndClauses,
00903                          Array<Clause*>* const& unknownClauses)
00904   {
00905     createVarIdToVarsGroundedType(domain);
00906     if (gndPredIdx >= 0) 
00907     {
00908       if (groundPred)          groundPredVars(gndPredIdx, groundPred);
00909       else  { assert(gndPred); groundPredVars(gndPredIdx, (Predicate*)gndPred);}
00910     }
00911     countNumTrueGroundings(domain, db, true, false, gndPredIdx, groundPred, 
00912                            gndPred, unknownGndClauses,unknownClauses,NULL,NULL);
00913     restoreVars();
00914     deleteVarIdToVarsGroundedType();
00915   }
00916 
00917 
00918   bool isSatisfiable(const Domain* const & domain, const Database* const& db,
00919                      const bool& hasUnknownPreds)
00920   {
00921     createVarIdToVarsGroundedType(domain);
00922 
00923     double i = countNumTrueGroundings(domain, db, hasUnknownPreds ,true,
00924                                       -1, NULL, NULL, NULL, NULL, NULL, NULL);
00925     restoreVars();
00926     deleteVarIdToVarsGroundedType();
00927     return (i > 0);
00928   }
00929 
00930 
00931     //count the number of groundings of clause variables
00932   double getNumGroundings(const Domain* const & domain)
00933   {
00934     createVarIdToVarsGroundedType(domain);
00935     double n = countNumGroundings();
00936     deleteVarIdToVarsGroundedType();
00937     return n;
00938   }
00939 
00940 
00941   double getNumTrueGroundings(const Domain* const & domain,
00942                               const Database* const & db,
00943                               const bool& hasUnknownPreds)
00944   {
00945     createVarIdToVarsGroundedType(domain);
00946     double n = countNumTrueGroundings(domain, db, hasUnknownPreds, false, 
00947                                       -1, NULL, NULL, NULL, NULL, NULL,NULL);
00948     restoreVars();
00949     deleteVarIdToVarsGroundedType();
00950     return n;
00951   }
00952 
00953 
00954   void getNumTrueUnknownGroundings(const Domain* const & domain,
00955                                    const Database* const & db,
00956                                    const bool& hasUnknownPreds,
00957                                    double& numTrue, double& numUnknown)
00958   {
00959     createVarIdToVarsGroundedType(domain);
00960     numTrue = countNumTrueGroundings(domain, db, hasUnknownPreds, false, 
00961                                      -1, NULL, NULL, NULL, NULL, &numUnknown,
00962                                      NULL);
00963     restoreVars();
00964     deleteVarIdToVarsGroundedType();
00965   }
00966 
00967 
00968   double getNumUnknownGroundings(const Domain* const & domain,
00969                                  const Database* const & db,
00970                                  const bool& hasUnknownPreds)
00971   {
00972     double numTrue, numUnknown;
00973     getNumTrueUnknownGroundings(domain, db, hasUnknownPreds,numTrue,numUnknown);
00974     return numUnknown;
00975   }
00976   
00977   void getNumTrueFalseUnknownGroundings(const Domain* const & domain,
00978                                         const Database* const & db,
00979                                         const bool& hasUnknownPreds,
00980                                         double& numTrue, double& numFalse,
00981                                         double& numUnknown)
00982   {
00983     getNumTrueUnknownGroundings(domain, db, hasUnknownPreds,numTrue,numUnknown);
00984     numFalse = getNumGroundings(domain) - numTrue - numUnknown;
00985     assert(numTrue >= 0);
00986     assert(numUnknown >= 0);
00987     assert(numFalse >= 0);
00988   }
00989 
00990 
00991     //Count the difference between the number of true groundings of the clause
00992     //when gndPred is held to the opposite of its actual value and when held to
00993     //its actual value. 
00994   double countDiffNumTrueGroundings(Predicate* const & gndPred, 
00995                                     const Domain* const & domain,
00996                                     Database* const & db,
00997                                     const bool& hasUnknownPreds,
00998                                     const bool& sampleClauses,
00999                                     const int& combo)
01000   {
01001     assert(gndPred->isGrounded());
01002 
01003       //store the indexes of the predicates that can be grounded as gndPred
01004     Array<int> gndPredIndexes;
01005 
01006     for (int i = 0; i < predicates_->size(); i++)
01007     {
01008       if ((*predicates_)[i]->canBeGroundedAs(gndPred)) gndPredIndexes.append(i);
01009     }
01010       //create mapping of variable ids (e.g. -1) to variable addresses,
01011       //note whether they have been grounded, and store their types
01012     createVarIdToVarsGroundedType(domain); 
01013 
01014     TruthValue actual = db->getValue(gndPred);
01015     assert(actual == TRUE || actual == FALSE);
01016     TruthValue opp = (actual == TRUE) ? FALSE : TRUE;
01017     bool flipped = false;
01018 
01019       //count # true groundings when gndPred is held to its actual value
01020     double numTrueGndActual = 
01021       countNumTrueGroundingsForAllComb(gndPredIndexes, gndPred, actual, flipped,
01022                                        domain, hasUnknownPreds, sampleClauses);
01023     //cout << "numTrueGndActual = " << numTrueGndActual << endl;
01024     
01025       //count # true groundings when gndPred is held to opposite value
01026     double numTrueGndOpp = 0.0;
01027     flipped = true;
01028     
01029     int blockIdx = domain->getBlock(gndPred);
01030     if (blockIdx >= 0)
01031     {
01032         // Pred in block: We have to look at combination c
01033         // of other preds in block
01034       const Array<Predicate*>* block = domain->getPredBlock(blockIdx);
01035       assert(combo < block->size());
01036 
01037       int oldTrueOne = 0;
01038       for (int i = 0; i < block->size(); i++)
01039       {
01040         if (db->getValue((*block)[i]) == TRUE)
01041         {
01042           oldTrueOne = i;
01043           break;
01044         }
01045       }
01046 
01047       int newTrueOne = (oldTrueOne <= combo) ? combo + 1 : combo;
01048       
01049       assert(db->getValue((*block)[oldTrueOne]) == TRUE);
01050       assert(db->getValue((*block)[newTrueOne]) == FALSE);
01051       
01052       db->setValue((*block)[oldTrueOne], FALSE);
01053       db->setValue((*block)[newTrueOne], TRUE);
01054       
01055    //numTrueGndOpp +=
01056    //  countNumTrueGroundingsForAllComb(gndPredIndexes, gndPred, opp, flipped,
01057    //                                   domain, hasUnknownPreds, sampleClauses);
01058 
01059       numTrueGndOpp +=
01060         countNumTrueGroundingsForAllComb(gndPredIndexes, (*block)[oldTrueOne],
01061                                          opp, flipped, domain, hasUnknownPreds,
01062                                          sampleClauses);
01063       numTrueGndOpp +=
01064         countNumTrueGroundingsForAllComb(gndPredIndexes, (*block)[newTrueOne],
01065                                          opp, flipped, domain, hasUnknownPreds,
01066                                          sampleClauses);
01067       
01068       db->setValue((*block)[oldTrueOne], TRUE);
01069       db->setValue((*block)[newTrueOne], FALSE);
01070     }
01071     else
01072     {
01073         // Pred not in block: Count gndings with pred flipped
01074 
01075         //set gndPred to have the opposite of its actual value
01076       db->setValue(gndPred, opp);
01077 
01078       numTrueGndOpp +=
01079         countNumTrueGroundingsForAllComb(gndPredIndexes, gndPred, opp, flipped,
01080                                         domain, hasUnknownPreds, sampleClauses);
01081 
01082       db->setValue(gndPred, actual);
01083     }
01084     //cout << "numTrueGndOpp    = " << numTrueGndOpp << endl;
01085 
01086     deleteVarIdToVarsGroundedType();
01087     return numTrueGndOpp - numTrueGndActual;
01088   }
01089 
01090 
01091  private:
01092   static void addVarId(Term* const & t, const int& typeId, 
01093                 const Domain* const & domain,                
01094                 Array<VarsGroundedType*>*& vgtArr)
01095   {
01096     int id = -(t->getId());
01097     assert(id > 0);
01098     if (id >= vgtArr->size()) vgtArr->growToSize(id+1,NULL);
01099     VarsGroundedType*& vgt = (*vgtArr)[id];
01100     if (vgt == NULL) 
01101     {
01102       vgt = new VarsGroundedType; 
01103       // vgt->isGrounded init to false
01104       vgt->typeId = typeId;
01105       assert(vgt->typeId >= 0);
01106       vgt->numGndings = domain->getNumConstantsByType(vgt->typeId);
01107       assert(vgt->numGndings > 0);
01108     }
01109     assert(typeId == vgt->typeId);
01110     vgt->vars.append(t);
01111   }
01112   
01113   void createVarIdToVarsGroundedType(const Domain* const & domain,
01114                                      Array<VarsGroundedType*>*& vgtArr) const
01115   {    
01116       //for each predicate 
01117     for (int i = 0; i < predicates_->size(); i++)
01118     {
01119       Predicate* p = (*predicates_)[i];
01120         //for each variable of the predicate
01121       for (int j = 0; j < p->getNumTerms(); j++)
01122       {
01123         Term* t = (Term*) p->getTerm(j);
01124         if (t->getType() == Term::VARIABLE)
01125           addVarId(t, p->getTermTypeAsInt(j), domain, vgtArr);
01126         else
01127         if (t->getType() == Term::FUNCTION)
01128         {
01129           cout << "Clause::createVarIdToVarsGroundedType() not expecting a "
01130                << "FUNCTION term" << endl;
01131           exit(-1);
01132         }
01133       }// for each variable of the predicate
01134     } // for each predicate
01135   }
01136 
01137 
01138   void createVarIdToVarsGroundedType(const Domain* const & domain)
01139   {    
01140     deleteVarIdToVarsGroundedType();
01141     varIdToVarsGroundedType_ = new Array<VarsGroundedType*>;
01142     createVarIdToVarsGroundedType(domain, varIdToVarsGroundedType_);
01143   }
01144 
01145 
01146   static void deleteVarIdToVarsGroundedType(Array<VarsGroundedType*>*& vgtArr)
01147   {
01148     for (int i = 0; i < vgtArr->size(); i++)
01149       if ((*vgtArr)[i]) delete (*vgtArr)[i];
01150     delete vgtArr;
01151     vgtArr = NULL;
01152   }
01153 
01154 
01155   void deleteVarIdToVarsGroundedType()
01156   {
01157     if (varIdToVarsGroundedType_)
01158       deleteVarIdToVarsGroundedType(varIdToVarsGroundedType_);
01159   }
01160 
01161 
01162   void getVarOrder(IntHashArray& varAppearOrder) const
01163   {
01164     varAppearOrder.clear();
01165     for (int i = 0; i < predicates_->size(); i++)
01166     {
01167       const Predicate* p = (*predicates_)[i];
01168       for (int j = 0; j < p->getNumTerms(); j++)
01169       {
01170         const Term* t = p->getTerm(j);
01171         if (t->getType() == Term::VARIABLE)
01172         {
01173           int id = -(t->getId());
01174           assert(id > 0);
01175           varAppearOrder.append(id);
01176         }
01177       }
01178     }
01179   }
01180 
01181 
01182   void createVarIdToVarsGroundedType(Array<VarsGroundedType*>*& vgtArr)
01183   {    
01184       //for each predicate 
01185     for (int i = 0; i < predicates_->size(); i++)
01186     {
01187       Predicate* p = (*predicates_)[i];
01188         //for each variable of the predicate
01189       for (int j = 0; j < p->getNumTerms(); j++)
01190       {
01191         Term* t = (Term*) p->getTerm(j);
01192         if (t->getType() == Term::VARIABLE)
01193         {
01194           assert(t->getId()<0);
01195           int id = -(t->getId());
01196           if (id >= vgtArr->size()) vgtArr->growToSize(id+1,NULL);
01197           VarsGroundedType*& vgt = (*vgtArr)[id];
01198           if (vgt == NULL)  vgt = new VarsGroundedType; 
01199           vgt->vars.append(t);
01200         }
01201         assert(t->getType() != Term::FUNCTION);
01202       }// for each variable of the predicate
01203     } // for each predicate    
01204   }
01205   
01206 
01207   void createVarConstIdToTerms(Array<Array<Term*>*>*& varIdToTerms,
01208                                hash_map<int,Array<Term*>*>*& constIdToTerms)
01209   {    
01210     for (int i = 0; i < predicates_->size(); i++) //for each predicate 
01211     {
01212       Predicate* p = (*predicates_)[i];
01213       for (int j = 0; j < p->getNumTerms(); j++) //for each term of predicate
01214       {
01215         Term* t = (Term*) p->getTerm(j);
01216         if (t->getType() == Term::VARIABLE)
01217         {
01218           if (varIdToTerms == NULL) continue;
01219           int id = -(t->getId());
01220           if (id >= varIdToTerms->size()) varIdToTerms->growToSize(id+1,NULL);
01221           Array<Term*>*& termArr = (*varIdToTerms)[id];
01222           if (termArr == NULL) termArr = new Array<Term*>;             
01223           termArr->append(t);
01224         }
01225         else
01226         if (t->getType() == Term::CONSTANT)
01227         {
01228           if (constIdToTerms == NULL) continue;
01229           int id = t->getId();
01230           Array<Term*>* termArr;
01231           hash_map<int,Array<Term*>*>::iterator it = constIdToTerms->find(id);
01232           if (it == constIdToTerms->end()) 
01233           {
01234             termArr = new Array<Term*>;
01235             (*constIdToTerms)[id] = termArr;
01236           }
01237           else
01238             termArr = (*it).second;
01239           termArr->append(t);
01240         }
01241         else
01242         if (t->getType() == Term::FUNCTION)
01243         {
01244           cout << "Clause::createVarIdToTerms() not expecting a "
01245                << "FUNCTION term" << endl;
01246           exit(-1);
01247         }
01248       }// for each variable of the predicate
01249     } // for each predicate
01250   }
01251 
01252 
01253   void deleteVarConstIdToTerms(Array<Array<Term*>*>*& varIdToTerms,
01254                                hash_map<int,Array<Term*>*>*&  constIdToTerms)
01255   {
01256     if (varIdToTerms)
01257     {
01258       for (int i = 0; i < varIdToTerms->size(); i++)
01259         if ((*varIdToTerms)[i]) delete (*varIdToTerms)[i];
01260       delete varIdToTerms;
01261       varIdToTerms = NULL;
01262     }
01263     if (constIdToTerms)
01264     {
01265       hash_map<int,Array<Term*>*>::iterator it = constIdToTerms->begin();
01266       for (; it != constIdToTerms->end(); it++) delete (*it).second;
01267       delete constIdToTerms;
01268       constIdToTerms = NULL;
01269     }
01270   }
01271 
01272 
01273     //Predicate at position predIdx must be able to be grounded as gndPred.
01274     //Call Predicate::canBeGroundedAs() to check this.
01275     //After one or more invocation of this function restoreVars() should
01276     //be called to restore the variables in the clause to their original 
01277     //values. Since the variables will be restored later, the dirty_ bit is 
01278     //not set.
01279   void groundPredVars(const int& predIdx, Predicate* const& gndPred,
01280                       Array<VarsGroundedType*>*& vgtArr) const
01281   {
01282     assert((*predicates_)[predIdx]->canBeGroundedAs(gndPred));
01283     assert(predIdx < predicates_->size());
01284     assert(gndPred->isGrounded());
01285 
01286     const Predicate* pred = (*predicates_)[predIdx];
01287     for (int i = 0; i < pred->getNumTerms(); i++)
01288     {
01289       const Term* t = pred->getTerm(i);
01290       if (t->getType() == Term::VARIABLE)
01291       {
01292         int constId = gndPred->getTerm(i)->getId();
01293         VarsGroundedType* vgt = (*vgtArr)[-t->getId()];
01294         Array<Term*>& vars = vgt->vars;
01295         for (int j = 0; j < vars.size(); j++)  vars[j]->setId(constId);
01296         vgt->isGrounded = true;
01297       }
01298       assert(t->getType() != Term::FUNCTION);
01299     }
01300   }
01301 
01302 
01303     //Predicate at position predIdx must be able to be grounded as gndPred.
01304     //Call Predicate::canBeGroundedAs() to check this.
01305     //After one or more invocation of this function restoreVars() should
01306     //be called to restore the variables in the clause to their original 
01307     //values. Since the variables will be restored later, the dirty_ bit is 
01308     //not set.
01309   void groundPredVars(const int& predIdx, 
01310                       const GroundPredicate* const& gndPred) const
01311   {
01312     assert(varIdToVarsGroundedType_);
01313     assert((*predicates_)[predIdx]->canBeGroundedAs(gndPred));
01314     assert(predIdx < predicates_->size());
01315 
01316     const Predicate* pred = (*predicates_)[predIdx];
01317     for (int i = 0; i < pred->getNumTerms(); i++)
01318     {
01319       const Term* t = pred->getTerm(i);
01320       if (t->getType() == Term::VARIABLE)
01321       {
01322         int constId = gndPred->getTermId(i);
01323         VarsGroundedType* vgt = (*varIdToVarsGroundedType_)[-t->getId()];
01324         Array<Term*>& vars = vgt->vars;
01325         for (int j = 0; j < vars.size(); j++)  vars[j]->setId(constId);
01326         vgt->isGrounded = true;
01327       }
01328       assert(t->getType() != Term::FUNCTION);
01329     }
01330   }
01331 
01332 
01333     //Predicate at position predIdx must be able to be grounded as gndPred.
01334     //Call Predicate::canBeGroundedAs() to check this.
01335     //After one or more invocation of this function restoreVars() should
01336     //be called to restore the variables in the clause to their original 
01337     //values. Since the variables will be restored later, the dirty_ bit is 
01338     //not set.
01339   void groundPredVars(const int& predIdx, Predicate* const& gndPred)
01340   {
01341     assert(varIdToVarsGroundedType_);
01342     groundPredVars(predIdx, gndPred, varIdToVarsGroundedType_); 
01343   }
01344 
01345 
01346     // restore variables to original values
01347   static void restoreVars(Array<VarsGroundedType*>* const & vgtArr)
01348   {    
01349     for (int i = 1; i < vgtArr->size(); i++)
01350     {
01351       if ((*vgtArr)[i] == NULL) continue;
01352       Array<Term*>& vars = (*vgtArr)[i]->vars;
01353       for (int j = 0; j < vars.size(); j++)  vars[j]->setId(-i);
01354       (*vgtArr)[i]->isGrounded = false;
01355     }
01356   }
01357   
01358 
01359     // restore variables to original values
01360   void restoreVars()
01361   {    
01362     assert(varIdToVarsGroundedType_);
01363     restoreVars(varIdToVarsGroundedType_);
01364   }
01365 
01366 
01367   static void addVarIdAndGndings(const int& varId, const int& varType,
01368                           const Domain* const & domain,
01369                           LitIdxVarIdsGndings* const & ivg)
01370   {
01371     ivg->varIds.append(varId);
01372     const Array<int>* constants = domain->getConstantsByType(varType);
01373     ivg->varGndings.appendArray(constants);
01374   }
01375 
01376     //Caller should delete the returned LitIdxVarsGndings*
01377     //Returns NULL if the literal at litIdx is grounded 
01378   static LitIdxVarIdsGndings* createLitIdxVarIdsGndings(
01379                                              Predicate* const & lit,
01380                                                  const unsigned int& litIdx,
01381                                                  const Domain* const & domain)
01382   {
01383     LitIdxVarIdsGndings* ivg = new LitIdxVarIdsGndings;
01384     ivg->litIdx = litIdx;
01385     for (int i = 0; i < lit->getNumTerms(); i++)
01386     {
01387       const Term* t = lit->getTerm(i);
01388       int termType = t->getType();
01389       if (termType == Term::VARIABLE)
01390       {
01391         int varId = t->getId();
01392         if (!ivg->varIds.contains(varId))
01393           addVarIdAndGndings(varId, lit->getTermTypeAsInt(i), domain, ivg);
01394       }
01395       assert(t->getType() != Term::FUNCTION);
01396       assert(ivg->varIds.size() == ivg->varGndings.getNumArrays());
01397     }
01398     ivg->litUnseen = true;
01399     return ivg;
01400   }
01401 
01402 
01403   void createAllLitIdxVarsGndings(Array<Predicate*>& clauseLits, 
01404                                   Array<LitIdxVarIdsGndings*>& ivgArr,
01405                                   const Domain* const & domain,
01406                                   const bool& setGroundedClausesToNull) const
01407   {
01408     assert(varIdToVarsGroundedType_); // this must already be created
01409     
01410       //for each literal
01411     for (unsigned int i = 0; i < (unsigned int) clauseLits.size(); i++)
01412     {
01413         //the literal was grounded when a previous literal was grounded
01414       if (clauseLits[i] == NULL) continue;
01415       
01416       ivgArr.append(createLitIdxVarIdsGndings(clauseLits[i], i, domain));
01417       
01418         //ground variables of the last literal we looked at throughout clause
01419       ArraysAccessor<int>& varGndings = ivgArr.lastItem()->varGndings;
01420       Array<int>& varIds = ivgArr.lastItem()->varIds;
01421       for (int j = 0; j < varIds.size(); j++)
01422       {
01423           // get the first constant that can be used to ground the var
01424         int constId = varGndings.getArray(j)->item(0);
01425         
01426           // ground all occurrences of var
01427         Array<Term*>& vars = (*varIdToVarsGroundedType_)[-varIds[j]]->vars;
01428         for (int k = 0; k < vars.size(); k++) vars[k]->setId(constId);
01429       }
01430     
01431         //store subsequent literals that are grounded when literal i is grounded
01432       Array<Predicate*>& subseqGndLits = ivgArr.lastItem()->subseqGndLits;
01433 
01434       for (int j = i+1; j < clauseLits.size(); j++)
01435       {
01436         Predicate* subseqLit = clauseLits[j];
01437         if (subseqLit==NULL) continue;
01438         if (subseqLit->isGrounded()) 
01439         {
01440           subseqGndLits.append(subseqLit);
01441           if (setGroundedClausesToNull) clauseLits[j] = NULL;
01442         }
01443       } //for each subsequent literal
01444     } //for each literal
01445   }
01446 
01447 
01448     // Also sets to -1 the ids of the parent terms of functions in ivgArr[i]. 
01449   static void deleteAllLitIdxVarsGndings(Array<LitIdxVarIdsGndings*>& ivgArr)
01450   { 
01451     for (int i = 0; i < ivgArr.size(); i++) delete ivgArr[i]; 
01452   }
01453 
01454 
01455   static void quicksortLiterals(pair<double,Predicate*> items[], 
01456                          const int& l, const int& r)
01457   {
01458     if (l >= r) return;
01459     pair<double,Predicate*> tmp = items[l];
01460     items[l] = items[(l+r)/2];
01461     items[(l+r)/2] = tmp;
01462 
01463     int last = l;
01464     for (int i = l+1; i <= r; i++)
01465       if (items[i].first > items[l].first)
01466       {
01467         ++last;
01468         tmp = items[last];
01469         items[last] = items[i];
01470         items[i] = tmp;
01471       }
01472     
01473     tmp = items[l];
01474     items[l] = items[last];
01475     items[last] = tmp;
01476     quicksortLiterals(items, l, last-1);
01477     quicksortLiterals(items, last+1, r);  
01478   }
01479 
01480 
01481     // sort literals in decreasing order of (# true groundings/# groundings)
01482   void sortLiteralsByTrueDivTotalGroundings(Array<Predicate*>& clauseLits,
01483                                             const Domain* const & domain,
01484                                             const Database* const & db) const
01485   {
01486     assert(predicates_->size() == clauseLits.size());
01487 
01488     Array<pair<double, Predicate*> > arr;
01489     for (int i = 0; i < clauseLits.size(); i++)
01490     {
01491       Predicate* lit = clauseLits[i];
01492     
01493         // put all the grounded literal in the front
01494       if (lit->isGrounded()) 
01495       {
01496         arr.append(pair<double,Predicate*>(DBL_MAX, lit));
01497         continue;
01498       }
01499 
01500         //estimate how likely the literal is true
01501       double numTrue = (lit->getSense())? db->getNumTrueGndPreds(lit->getId())
01502                                          :db->getNumFalseGndPreds(lit->getId());
01503       double numTotal = lit->getNumGroundingsIfAllVarDiff(domain);
01504 
01505         //get number of groundings of the literal
01506       double numGnd = 1;
01507 
01508       Array<int> varIds; //used to check unique var ids. A hash_set is slower.
01509       varIds.growToSize(lit->getNumTerms(),1);
01510       for (int i = 0; i < lit->getNumTerms(); i++)
01511       {
01512         const Term* t = lit->getTerm(i);
01513         if (t->getType() == Term::VARIABLE)
01514         {
01515           int tid = t->getId();
01516           if (!varIds.contains(tid))
01517           {
01518             varIds.append(tid);
01519             numGnd *= domain->getNumConstantsByType(lit->getTermTypeAsInt(i));
01520           }
01521         }
01522         assert(t->getType() != Term::FUNCTION);
01523       }
01524 
01525       arr.append(pair<double,Predicate*>(numTrue/numTotal/numGnd, lit));
01526     }
01527   
01528     quicksortLiterals((pair<double,Predicate*>*) arr.getItems(),0,arr.size()-1);
01529     assert(arr.size() == clauseLits.size());
01530     for (int i = 0; i < arr.size(); i++) clauseLits[i] = arr[i].second;
01531   }
01532 
01533 
01534   static bool literalOrSubsequentLiteralsAreTrue(Predicate* const & lit,
01535                                           const Array<Predicate*>& subseqLits,
01536                                           const Database* const & db)
01537   {
01538     TruthValue tv = db->getValue(lit);
01539     lit->setTruthValue(tv);
01540     if (db->sameTruthValueAndSense(tv,lit->getSense())) return true;
01541     
01542     for (int i = 0; i < subseqLits.size(); i++)
01543     {
01544       tv = db->getValue(subseqLits[i]);
01545       subseqLits[i]->setTruthValue(tv);
01546       if (db->sameTruthValueAndSense(tv,subseqLits[i]->getSense())) return true;
01547     }
01548     return false;
01549   }
01550 
01551 
01552   bool hasTwoLiteralsWithOppSense() const
01553   {    
01554     PredicateSet predSet; // used to detect duplicates
01555     PredicateSet::iterator iter;
01556     
01557     for (int i = 0; i < predicates_->size(); i++)
01558     {
01559       Predicate* predicate = (*predicates_)[i];
01560       assert(predicate->isGrounded());
01561       if (predicate->getTruthValue() == UNKNOWN)
01562       {
01563         if ( (iter=predSet.find(predicate)) != predSet.end() )
01564         {
01565             // the two gnd preds are of opp sense, so clause must be satisfied
01566           if ((*iter)->getSense() !=  predicate->getSense()) return true;
01567         }
01568         else
01569           predSet.insert(predicate);        
01570       }
01571     }
01572       
01573     return false;
01574   }
01575 
01576 
01577     //returns true if the (ground) clause has two literals with opposite sense
01578     //i.e. the clause is satisfied; otherwise returns false
01579   bool createAndAddUnknownClause(Array<GroundClause*>* const& unknownGndClauses,
01580                                  Array<Clause*>* const& unknownClauses,
01581                                  double* const & numUnknownClauses,
01582                                  const AddGroundClauseStruct* const & agcs);
01583 
01584   bool groundPredicates(const Array<int>* const & set,
01585                         const Array<int>& gndPredIndexes,
01586                         Predicate* const & gndPred,
01587                         const TruthValue& gndPredTV,
01588                         const Database* const & db,
01589                         bool& sameTruthValueAndSense,
01590                         bool& gndPredPosHaveSameSense)
01591   {
01592     sameTruthValueAndSense = false;
01593     gndPredPosHaveSameSense = true;
01594     bool prevSense = false;
01595     for (int i = 0; i < set->size(); i++)
01596     {
01597       int gndPredIdx = gndPredIndexes[(*set)[i]];
01598       Predicate* pred = (*predicates_)[gndPredIdx];
01599         // if inconsistent grounding of variables, proceed to next combination
01600       if (!pred->canBeGroundedAs(gndPred)) return false;
01601       groundPredVars(gndPredIdx, gndPred);
01602       if (db->sameTruthValueAndSense(gndPredTV, pred->getSense()))
01603         sameTruthValueAndSense = true;
01604       if (i == 0) 
01605         prevSense = pred->getSense();
01606       else
01607       if (prevSense != pred->getSense())
01608         gndPredPosHaveSameSense = false;
01609     }
01610     return true;
01611   }
01612 
01613 
01614     //count the number of groundings of clause variables
01615   double countNumGroundings()
01616   {
01617     double n = 1;
01618     for (int i = 1; i < varIdToVarsGroundedType_->size(); i++)
01619     {
01620       if (!((*varIdToVarsGroundedType_)[i]->isGrounded))
01621         n *= (*varIdToVarsGroundedType_)[i]->numGndings;
01622     }
01623     return n;
01624   }
01625   
01626 
01627   static double addCountToCombination(bool inComb[], const int& inCombSize,
01628                                const Array<int>* const & set,
01629                                MultDArray<double>& gndedPredPosArr,
01630                                const double& count)
01631   {
01632     memset(inComb, false, inCombSize*sizeof(bool));
01633     for (int i = 0; i < set->size(); i++)  inComb[(*set)[i]] = true;
01634     Array<int> multDArrIndexes(inCombSize); //e.g. [0][1][0][1]
01635     for (int i = 0; i < inCombSize; i++)
01636     {
01637       if (inComb[i]) multDArrIndexes.append(1);
01638       else           multDArrIndexes.append(0);    
01639     }
01640     gndedPredPosArr.addItem(&multDArrIndexes, count);   
01641     return gndedPredPosArr.getItem(&multDArrIndexes);
01642   }
01643 
01644   
01645   static void minusRepeatedCounts(bool inComb[], const int& inCombSize,
01646                            const Array<int>& inCombIndexes,
01647                            const Array<int>* const & set,
01648                            const Array<int>* const & falseSet,
01649                            MultDArray<double>& gndedPredPosArr,
01650                            const double& count)
01651   {
01652     memset(inComb, false, inCombSize*sizeof(bool));
01653     for (int i = 0; i < set->size(); i++)  inComb[(*set)[i]] = true;
01654     
01655     for (int i = 0; i < falseSet->size(); i++)
01656     {
01657       int idx = inCombIndexes[(*falseSet)[i]];
01658       assert(inComb[idx] == true);
01659       inComb[idx] = false;
01660     }
01661     
01662     Array<int> multDArrIndexes(inCombSize); //e.g. [0][1][0][1]
01663     for (int i = 0; i < inCombSize; i++)
01664     {
01665       if (inComb[i]) multDArrIndexes.append(1);
01666       else           multDArrIndexes.append(0);    
01667     }      
01668     
01669       //subtract count from that of a smaller combination that includes it
01670     gndedPredPosArr.addItem(&multDArrIndexes, -count);
01671   }  
01672 
01673 
01675   void getBannedPreds(Array<Predicate*>& bannedPreds,
01676                       const int& gndPredIdx,
01677                       const GroundPredicate* const & groundPred,
01678                       const Predicate* const & gndPred) const
01679   {
01680     assert(gndPredIdx < predicates_->size());
01681     for (int i = 0; i < gndPredIdx; i++)
01682     {
01683       if ( (groundPred && (*predicates_)[i]->canBeGroundedAs(groundPred)) ||
01684            (gndPred && (*predicates_)[i]->canBeGroundedAs((Predicate*)gndPred)))
01685         bannedPreds.append((*predicates_)[i]);
01686     }
01687   }
01688 
01689 
01690 
01691   static void createBannedPreds(Array<Predicate*>& clauseLits,
01692                          Array<LitIdxVarIdsGndings*>& ivgArr,
01693                          Array<Predicate*>& bannedPreds)
01694   {
01695     if (bannedPreds.size() == 0) return;
01696 
01697     int a;
01698     for (int i = 0; i < ivgArr.size(); i++)
01699     {
01700       LitIdxVarIdsGndings* ivg = ivgArr[i];
01701       a = bannedPreds.find(clauseLits[ivg->litIdx]);
01702       if (a >= 0) ivg->bannedPreds.append(bannedPreds[a]);
01703       for (int j = 0; j < ivg->subseqGndLits.size(); j++)
01704       {
01705         a = bannedPreds.find(ivg->subseqGndLits[j]);
01706         if (a >= 0) ivg->bannedPreds.append(bannedPreds[a]);        
01707       }
01708     }   
01709   }
01710 
01711 
01712     //the array parameter should be LitIdxVarIdsGndings.bannedGndPreds
01713   static bool bannedPredsAreGndedAsGndPred(
01714                                 const Array<Predicate*>& bannedPreds,
01715                                     const GroundPredicate* const & groundPred,
01716                                     const Predicate* const & gndPred)
01717   {
01718     for (int i = 0; i < bannedPreds.size(); i++)
01719     {
01720       if ( (groundPred && bannedPreds[i]->same(groundPred)) ||
01721            (gndPred    && bannedPreds[i]->same((Predicate*)gndPred)) ) 
01722         return true;
01723     }
01724     return false;
01725   }
01726 
01727 
01728   bool containsGndPredBeforeIdx(const int& gndPredIdx, 
01729                                 const GroundPredicate* const & groundPred,
01730                                 const Predicate* const & gndPred)
01731   {
01732     assert(gndPredIdx < predicates_->size());
01733  
01734     if (gndPredIdx < 0) return false;
01735 
01736     if (groundPred)
01737     {
01738       for (int i = 0; i < gndPredIdx; i++)
01739         if ((*predicates_)[i]->same(groundPred)) return true;
01740     }
01741     else
01742     {
01743       assert(gndPred);
01744       for (int i = 0; i < gndPredIdx; i++)
01745         if ((*predicates_)[i]->same((Predicate*)gndPred)) return true; 
01746     }
01747     return false;
01748   }
01749 
01750 
01752 
01753     //Even though it is more intuitive to use a recursive function to count
01754     //the number of true groundings, we are not doing so in order to allow the 
01755     //compiler to inline it.
01756     //Returns the number of true groundings, unknown clauses, number of unknown
01757     //clauses, and satisfiability
01758     //If gndPredId >= 0, the returned clauses do not contain groundPred/gndPred 
01759     //before position gndPredIdx
01760     //No more than one of the array parameters can be non-NULL.
01761     //No more than one of the groundPred/gndPred parameters can be non-NULL  
01762   double countNumTrueGroundings(const Domain* const & domain,
01763                                 const Database* const & db,
01764                                 const bool& hasUnknownPreds,
01765                                 const bool& checkSatOnly,
01766                                   //params below: find unknown clauses
01767                                 const int& gndPredIdx,
01768                                 const GroundPredicate* const & groundPred,
01769                                 const Predicate* const & gndPred,
01770                                 Array<GroundClause*>* const & unknownGndClauses,
01771                                 Array<Clause*>* const & unknownClauses,
01772                                 double* const & numUnknownClauses,
01773                                   //params below: add unknown clauses to MRF
01774                                 const AddGroundClauseStruct* const & agcs)
01775   {
01776     assert(unknownGndClauses == NULL || unknownClauses == NULL);
01777     assert(groundPred == NULL || gndPred == NULL);
01778 
01779     if (numUnknownClauses) *numUnknownClauses = 0;
01780 
01781     bool findUnknownClauses = (unknownGndClauses || unknownClauses || 
01782                                numUnknownClauses || agcs);
01783       // these predicates must not be grounded as groundPred/gndPred
01784     Array<Predicate*> bannedPreds;
01785     if (findUnknownClauses)
01786       getBannedPreds(bannedPreds, gndPredIdx, groundPred, gndPred);
01787 
01788     double numTrueGndings = 0;
01789     
01790       //Copy the literals so that their original order in the clause is
01791       //not affected by the subsequent sorting
01792     Array<Predicate*> clauseLits(*predicates_);
01793 
01794       //Sort preds in decreasing order of #TrueGndOfLiteral/#numOfGroundings.
01795       //The larger the number of true groundings of a literal, the more likely
01796       //it is to be true, so put it in front so that we can decide whether the
01797       //clause is true early.The larger the number of groundings of the literal,
01798       //the larger the savings when we decide that preceding literals are true.
01799     sortLiteralsByTrueDivTotalGroundings(clauseLits, domain, db);
01800 
01801       //simulate a stack, back/front corresponds to top/bottom
01802       //ivg stands for index, varIds, groundings
01803     Array<LitIdxVarIdsGndings*> ivgArr;
01804     createAllLitIdxVarsGndings(clauseLits, ivgArr, domain, true);
01805     if (findUnknownClauses) createBannedPreds(clauseLits, ivgArr, bannedPreds);
01806     int ivgArrIdx = 0; //store current position in ivgArr
01807     bool lookAtNextLit = false;
01808     
01809       // while stack is not empty
01810     while (ivgArrIdx >= 0)
01811     {
01812         //get variable groundings at top of stack
01813       LitIdxVarIdsGndings* ivg = ivgArr[ivgArrIdx];
01814       Predicate* lit = clauseLits[ivg->litIdx];
01815       Array<int>& varIds = ivg->varIds;
01816       ArraysAccessor<int>& varGndings = ivg->varGndings;
01817       bool& litUnseen = ivg->litUnseen;
01818       bool hasComb;
01819 
01820         // while there are groundings of literal's variables
01821       while ((hasComb=varGndings.hasNextCombination()) || litUnseen)
01822       {
01823           // there may be no combinations if the literal is fully grounded
01824         if (litUnseen) litUnseen = false;
01825 
01826         if (hasComb)
01827         {
01828             //ground the literal's variables throughout the clause
01829           int constId;
01830           int v = 0; // index of varIds
01831             //for each variable in literal
01832           while(varGndings.nextItemInCombination(constId))
01833           {
01834             Array<Term*>& vars =(*varIdToVarsGroundedType_)[-varIds[v++]]->vars;
01835             for (int i = 0; i < vars.size(); i++) vars[i]->setId(constId);
01836           }
01837           
01838           //return values of grounded functions are assigned to their parent
01839           //terms in literalOrSubsequentLiteralsAreTrue()
01840         }
01841 
01842           //if literal or subsequent grounded literals are true,
01843         if (literalOrSubsequentLiteralsAreTrue(lit, ivg->subseqGndLits, db))
01844         {
01845           if (checkSatOnly) return 1;
01846             //count the number of combinations of remaining variables
01847           double numComb = 1;
01848           for (int i = ivgArrIdx+1; i < ivgArr.size(); i++)
01849           {
01850             int numVar = ivgArr[i]->varGndings.getNumArrays();
01851             for (int j = 0; j < numVar; j++)
01852               numComb *= ivgArr[i]->varGndings.getArray(j)->size();
01853           }
01854           numTrueGndings += numComb;
01855         }
01856         else
01857         if (findUnknownClauses && 
01858             bannedPredsAreGndedAsGndPred(ivg->bannedPreds, groundPred, gndPred))
01859         {
01860           //do nothing, will move down stack later
01861         }
01862         else
01863         {
01864             // if there are more literals
01865           if (ivgArrIdx+1 < ivgArr.size())
01866           {
01867             lookAtNextLit = true;
01868             ivgArrIdx++; // move up stack
01869             break;
01870           }
01871             //At this point all the literals are grounded, and they are either
01872             //unknown or false (have truth values opposite of their senses).
01873 
01874           bool twoLitWithOppSense = false;
01875           if (hasUnknownPreds)
01876           {
01877             if (hasTwoLiteralsWithOppSense()) 
01878             {
01879               twoLitWithOppSense = true;
01880               ++numTrueGndings;
01881               if (checkSatOnly) return 1;
01882             }
01883           }
01884 
01885           if (!twoLitWithOppSense && findUnknownClauses)
01886           {
01887             assert(!containsGndPredBeforeIdx(gndPredIdx, groundPred, gndPred));
01888 
01889               //Create a new clause by appending unknown predicates to it.
01890             createAndAddUnknownClause(unknownGndClauses, unknownClauses, 
01891                                       numUnknownClauses, agcs);
01892           }
01893         }
01894       } //while there are groundings of literal's variables
01895 
01896         //if we exit the while loop in order to look at next literal 
01897         //(i.e. without considering all groundings of current literal)
01898       if (lookAtNextLit) { lookAtNextLit = false; }
01899       else { varGndings.reset(); litUnseen = true; ivgArrIdx--; }//mv down stack
01900 
01901     } // while stack is not empty
01902 
01903     deleteAllLitIdxVarsGndings(ivgArr);
01904 
01905     return numTrueGndings;
01906   }
01907 
01908 
01909   double countNumTrueGroundingsForAllComb(const Array<int>& gndPredIndexes,
01910                                           Predicate* const & gndPred,
01911                                           const TruthValue& gndPredTV,
01912                                           const bool& gndPredFlipped,
01913                                           const Domain* const & domain,
01914                                           const bool& hasUnknownPreds,
01915                                           const bool& sampleClauses)
01916   {
01917     assert(varIdToVarsGroundedType_);
01918     const Database* db = domain->getDB();
01919     double count = 0;
01920     int inCombSize = gndPredIndexes.size();
01921     bool* inComb = new bool[inCombSize];
01922 
01923       //initialize the number of true groundings for each way grounding the
01924       //predicates represented by gndPredIndexes.
01925       //e.g. gndedPredPosArr[0][0][1][1] is the number of true groundings when
01926       //the 1st and 2nd predicates in gndPredIndexes are not grounded and
01927       //the 3rd and 4th are grounded
01928     Array<int> dim;
01929     for (int i = 0; i < gndPredIndexes.size(); i++) dim.append(2);
01930       //WARNING: this may take up a lot of memory when gndPred can be grounded
01931       //at many positions in the clause
01932     MultDArray<double> gndedPredPosArr(&dim);
01933     const Array<double>* oneDArray = gndedPredPosArr.get1DArray();
01934     double* oneDArrayItems = (double*) oneDArray->getItems();
01935     memset(oneDArrayItems, 0, oneDArray->size()*sizeof(double));
01936 
01937       //for each possible combination of grounding the predicates
01938       //(represented by gndPredIndexes) as gndPred
01939     PowerSet* ps = PowerSet::getPowerSet();
01940       //the combinations are accessed in order of decreasing size
01941     ps->prepareAccess(gndPredIndexes.size(), false);
01942 
01943     const Array<int>* set;
01944     while(ps->getNextSet(set))
01945     {
01946         //ground the predicates in current combination
01947       bool sameTruthValueAndSense; //a ground pred has the same tv and sense
01948       bool gndPredPosSameSense;
01949       bool valid = groundPredicates(set, gndPredIndexes, gndPred, gndPredTV, db,
01950                                     sameTruthValueAndSense,gndPredPosSameSense);
01951 
01952         //If it is not possible to ground the predicates according to current
01953         //combination or the grounded predicates are not all of the same sense,
01954         //then skip the combination.
01955         //We can ignore the combination when the grounded predicates are not all
01956         //of the same sense because the counts when gndPred is held to true and
01957         //false cancel one another out exactly
01958       if (!valid || !gndPredPosSameSense) { restoreVars(); continue; }
01959       
01960         //count number of true groundings
01961       double cnt, numGndings = countNumGroundings();
01962 
01963         //if any of the grounded predicates has the same truth value and sense
01964       if (sameTruthValueAndSense)
01965         cnt = numGndings;
01966       else
01967       {
01968         double samp; int np;
01969         bool toSampleClauses = (sampleClauses && (np=predicates_->size()) > 1 &&
01970                                 (samp = clauseSampler_->computeNumSamples(np))
01971                                 < numGndings);
01972         //commented out: for testing sampling only
01973         //toSampleClauses = (sampleClauses && np > 1);
01974 
01975         if (toSampleClauses)
01976         {
01977           Predicate* flippedGndPred = (gndPredFlipped) ? gndPred : NULL;
01978           cnt = clauseSampler_->estimateNumTrueGroundings(this, flippedGndPred,
01979                                                           domain, samp);
01980           if (cnt > numGndings) cnt = numGndings;
01981           else if (cnt < 0)     cnt = 0;
01982         }
01983         else
01984           cnt = countNumTrueGroundings(domain, db, hasUnknownPreds, false,
01985                                        -1, NULL, NULL, NULL, NULL, NULL, NULL);
01986       }
01987 
01988         // add cnt to that of current combination
01989       double cntDueToThisComb
01990         = addCountToCombination(inComb,inCombSize,set,gndedPredPosArr,cnt);
01991       count += cntDueToThisComb;
01992 
01993       //for (int i = 0; i < inCombSize; i++)  cout << ((int) inComb[i]) << " ";
01994       //cout << " = " << cntDueToThisComb << "/" << cnt << endl;
01995     
01996         //find the indexes that are in this combination
01997       Array<int> inCombIndexes;
01998       for (int i = 0; i < set->size(); i++)  inCombIndexes.append((*set)[i]);
01999 
02000         // subtract all the repeated counts of cntDueToThisComb
02001       PowerSetInstanceVars psInstVars;
02002       ps->prepareAccess(inCombIndexes.size(), psInstVars);
02003       const Array<int>* falseSet;
02004       while (ps->getNextSet(falseSet, psInstVars))
02005       {
02006           // at least one of the predicates must be gnded as gndPred
02007         if (falseSet->size() == set->size()) continue;
02008         minusRepeatedCounts(inComb, inCombSize, inCombIndexes, set, falseSet,
02009                             gndedPredPosArr, cntDueToThisComb);
02010       }
02011       restoreVars();
02012     } //for each possible combination of grounding the predicates as gndPred
02013     delete [] inComb;
02014     return count;
02015   }
02016 
02017 
02018     // Returns true if the ground clause was active 
02019   bool createAndAddActiveClause(Array<IntClause *> * const & activeIntClauses,
02020                             Array<GroundClause *> * const & activeGroundClauses,
02021                                 IntClauseHashArray * const & uniqueClauses,
02022                                 PredicateHashArray * const & seenPreds,
02023                                 PredicateHashArray * const & uniquePreds,
02024                                 GroundPredicateHashArray* const& seenGndPreds,
02025                                 const Database* const & db,
02026                                 bool const & getSatisfied);
02027   
02028   bool isActive(const Database* const & db)
02029   {
02030     PredicateSet predSet; // used to detect duplicates
02031     PredicateSet::iterator iter;
02032     bool isEmpty = true;
02033  
02034     for (int i = 0; i < predicates_->size(); i++)
02035     {
02036       Predicate* predicate = (*predicates_)[i];
02037       assert(predicate); 
02038           assert(predicate->isGrounded());
02039       if ( (iter=predSet.find(predicate)) != predSet.end() )
02040       {
02041           // the two gnd preds are of opp sense, so clause must be satisfied
02042             if (wt_ >= 0 && (*iter)->getSense() !=  predicate->getSense())
02043                   return false;
02044         continue;
02045           }
02046       else
02047         predSet.insert(predicate);
02048           
02049       bool isEvidence = db->getEvidenceStatus(predicate);
02050           if (!isEvidence)
02051         isEmpty = false;
02052     }
02053     return !isEmpty;
02054   }
02055 
02056   // Assumption: clause has pos. weight
02057 bool isUnsatisfiedGivenActivePreds(Predicate* const & lit,
02058                                    const Array<Predicate*>& subseqLits,
02059                                    const Database* const & db,
02060                                                                    bool const & ignoreActivePreds)
02061 {
02062         // If atom has been deactivated, then we don't want any clauses that it's in
02063 //cout << "ignoreActivePreds " << ignoreActivePreds << endl;
02064 //cout << "lit "; lit->printWithStrVar(cout, db->getDomain()); cout << endl;
02065   if (db->getDeactivatedStatus(lit)) return false;
02066   bool active = false;
02067   if(!ignoreActivePreds)
02068         active = db->getActiveStatus(lit);
02069 //cout << "active " << active << endl;
02070   TruthValue tv = db->getValue(lit);
02071   lit->setTruthValue(tv);
02072 //cout << "tv  " << tv << endl;
02073   if (!active && db->sameTruthValueAndSense(tv, lit->getSense())) return false;
02074     //cout<<"okies *** came here.."<<endl;
02075   for (int i = 0; i < subseqLits.size(); i++)
02076   {
02077 //cout << "subseqLit " << i << " ";
02078 //subseqLits[i]->printWithStrVar(cout, db->getDomain());
02079 //cout << endl;
02080     if (!ignoreActivePreds)
02081           active = db->getActiveStatus(subseqLits[i]);
02082 //cout << "active " << active << endl;
02083     tv = db->getValue(subseqLits[i]);
02084     subseqLits[i]->setTruthValue(tv);
02085 //cout << "tv  " << tv << endl;
02086     if (!active && db->sameTruthValueAndSense(tv,subseqLits[i]->getSense()))
02087       return false;
02088   }
02089   return true;
02090 }
02091 
02092 
02093   // Assumption: clause has neg. weight
02094 bool isSatisfiedGivenActivePreds(const Database* const & db,
02095                                  bool const & ignoreActivePreds)
02096 {
02097   bool isSatisfied = false;
02098   for (int i = 0; i < predicates_->size(); i++)
02099   {
02100     Predicate* lit = getPredicate(i);
02101     assert(lit->isGrounded());
02102       // If atom has been deactivated, then we don't want any clauses
02103       // that it's in
02104     if (db->getDeactivatedStatus(lit)) return false;
02105     bool active = false;
02106     bool evidence = false;
02107     if(!ignoreActivePreds)
02108       active = db->getActiveStatus(lit);
02109     
02110     TruthValue tv = db->getValue(lit);
02111     lit->setTruthValue(tv);
02112       // If true evidence atom is in clause, then clause is always satisfied
02113       // and we want to ignore it.
02114     evidence = db->getEvidenceStatus(lit);
02115 
02116 //cout << "Lit: ";
02117 //lit->printWithStrVar(cout, db->getDomain());
02118 //cout << " ev. " << evidence << " act. " << active << " stvas "
02119 //       << db->sameTruthValueAndSense(tv, lit->getSense()) << endl;
02120     if (evidence && db->sameTruthValueAndSense(tv, lit->getSense()))
02121       return false;
02122       // Any active atom in clause or any true non-active atom
02123       // means it is candidate for active clause
02124     if (active || db->sameTruthValueAndSense(tv, lit->getSense()))
02125       isSatisfied = true;
02126   }
02127   return isSatisfied;
02128 }
02129 
02130 
02131   // Sort literals for use by the inverted index.
02132   // For pos. clauses: negative literals first, then of increasing arity
02133   // For neg. clauses: positive literals first, then of increasing arity
02134 void sortLiteralsByNegationAndArity(Array<Predicate*>& clauseLits)
02135 {
02136   //cout << "Sorting lits by neg. and arity:" << endl;
02137   assert(predicates_->size() == clauseLits.size());
02138 
02139   Array<pair<double, Predicate*> > arr;
02140   for (int i = 0; i < clauseLits.size(); i++)
02141   {
02142     Predicate* lit = clauseLits[i];
02143     
02144       // Put all the grounded literals in the front
02145     if (lit->isGrounded()) 
02146     {
02147       arr.append(pair<double,Predicate*>(DBL_MAX, lit));
02148       continue;
02149     }
02150 /*
02151           // Pos. clause: negative literals of arity two next
02152         if (!lit->getSense())
02153         {
02154           if (wt_ >= 0 && lit->getNumTerms() == 2)
02155                 arr.append(pair<double,Predicate*>((double)lit->getNumTerms(), lit));
02156           else
02157                 arr.append(pair<double,Predicate*>(-(double)lit->getNumTerms(), lit));          
02158           continue;
02159         }
02160 
02161       // Neg. clause: positive literals of arity two next
02162     if (lit->getSense())
02163     {
02164       if (wt_ < 0 && lit->getNumTerms() == 2)
02165         arr.append(pair<double,Predicate*>((double)lit->getNumTerms(), lit));
02166       else
02167         arr.append(pair<double,Predicate*>(-(double)lit->getNumTerms(), lit));      
02168     }
02169 */
02170     if (lit->isIndexable(wt_ >= 0))
02171       arr.append(pair<double,Predicate*>((double)lit->getNumTerms(), lit));
02172     else
02173       arr.append(pair<double,Predicate*>(-(double)lit->getNumTerms(), lit));      
02174   }
02175   
02176   quicksortLiterals((pair<double,Predicate*>*) arr.getItems(),0,arr.size()-1);
02177   assert(arr.size() == clauseLits.size());
02178   for (int i = 0; i < arr.size(); i++)
02179   {
02180         clauseLits[i] = arr[i].second;
02181         //cout << clauseLits[i]->getSense() << " " << clauseLits[i]->getName()
02182     //     << endl;
02183   }
02184 }
02185 
02186 
02187   //Assumes clauseLits is ordered so that indexable lits are in the front
02188 void groundIndexableLiterals(const Domain* const & domain,
02189                              Array<IntClause *> * const & activeIntClauses,
02190                              Array<GroundClause *> * const & activeGroundClauses,
02191                              int & activeClauseCnt,
02192                              IntClauseHashArray * const & uniqueClauses,
02193                              PredicateHashArray * const & seenPreds,
02194                              PredicateHashArray * const & uniquePreds,
02195                              GroundPredicateHashArray* const& seenGndPreds,
02196                              Array<Predicate*>& clauseLits,
02197                              int litIdx, bool const & ignoreActivePreds,
02198                              bool const & getSatisfied)
02199 {
02200   const Database* db = domain->getDB();
02201 //cout << "litIdx " << litIdx << endl;
02202 //cout << "clauseLits size " << clauseLits.size() << endl;
02203 //cout << "clauseLits start ";
02204 /*
02205 for (int i = 0; i < clauseLits.size(); i++)
02206 {
02207   if (clauseLits[i])
02208   {
02209   cout << i << " ";
02210   clauseLits[i]->printWithStrVar(cout, db->getDomain());
02211   cout << " ";
02212   }
02213 }
02214 */
02215 //cout << endl;
02216 //cout << "LIT ";
02217 //clauseLits[litIdx]->printWithStrVar(cout, db->getDomain());
02218 //cout << endl;
02219   bool posClause = (wt_ >= 0) ? true : false;
02220   if (clauseLits[litIdx]->isIndexable(posClause))
02221   {
02222           // Branch and bound on indexable literals
02223         Array<Predicate *>* indexedGndings = new Array<Predicate *>;
02224           // Bound
02225         ((Database *)db)->getIndexedGndings(indexedGndings, clauseLits[litIdx],
02226                                         ignoreActivePreds);
02227 /*
02228 cout << "indexedGndings: " << endl;
02229 for (int i = 0; i < indexedGndings->size(); i ++)
02230 {
02231   cout << "\t";
02232   (*indexedGndings)[i]->printWithStrVar(cout, domain);
02233   cout << endl;
02234 }
02235 */
02236       // Branch on the indexed groundings
02237     for (int i = 0; i < indexedGndings->size(); i++)
02238     {
02239       Array<int>* origVarIds = new Array<int>;
02240         // Ground variables throughout clause
02241       for (int j = 0; j < clauseLits[litIdx]->getNumTerms(); j++)
02242       {
02243         const Term* term = clauseLits[litIdx]->getTerm(j);
02244         if (term->getType() == Term::VARIABLE)
02245         {
02246           int varId = term->getId();
02247           origVarIds->append(varId);
02248           int constId = (*indexedGndings)[i]->getTerm(j)->getId();
02249           assert(constId >= 0);
02250           Array<Term*>& vars = (*varIdToVarsGroundedType_)[-varId]->vars;
02251           for (int k = 0; k < vars.size(); k++) vars[k]->setId(constId);
02252         }
02253       }
02254 
02255         // Save literal in tmp, then set to null
02256       Predicate* tmpLit = clauseLits[litIdx];
02257       clauseLits[litIdx] = NULL;
02258       delete (*indexedGndings)[i];
02259       
02260         // Move to next literal
02261       if (litIdx + 1 < clauseLits.size())
02262             groundIndexableLiterals(domain, activeIntClauses, activeGroundClauses,
02263                                 activeClauseCnt, uniqueClauses, seenPreds,
02264                                 uniquePreds, seenGndPreds, clauseLits,
02265                                 litIdx + 1,
02266                                 ignoreActivePreds, getSatisfied);
02267 
02268                 // Restore literal and variables
02269           clauseLits[litIdx] = tmpLit;
02270       for (int i = 0; i < origVarIds->size(); i++)
02271       {
02272         int varId = (*origVarIds)[i];
02273         assert(varId < 0);
02274         Array<Term*>& vars = (*varIdToVarsGroundedType_)[-varId]->vars;
02275         for (int j = 0; j < vars.size(); j++) vars[j]->setId(varId);
02276         (*varIdToVarsGroundedType_)[-varId]->isGrounded = false;
02277       }
02278           delete origVarIds;
02279         }
02280         delete indexedGndings;
02281         return;
02282   }
02283   
02284         // All indexable literals are grounded, now deal with the others
02285   Array<LitIdxVarIdsGndings*> ivgArr;
02286     // RIGHT
02287   createAllLitIdxVarsGndings(clauseLits, ivgArr, domain, false);
02288     // WRONG
02289   //createAllLitIdxVarsGndings(clauseLits, ivgArr, domain, true);
02290   int ivgArrIdx = 0; //store current position in ivgArr
02291   bool lookAtNextLit = false;
02292 
02293     // while stack is not empty
02294   while (ivgArrIdx >= 0)
02295   {
02296       //get variable groundings at top of stack
02297     LitIdxVarIdsGndings* ivg = ivgArr[ivgArrIdx];
02298     Predicate* lit = clauseLits[ivg->litIdx];
02299 /*
02300 cout << "LIT1 ";
02301 lit->printWithStrVar(cout, db->getDomain());
02302 cout << endl;
02303 cout << "clauseLits size " << clauseLits.size() << endl;
02304 cout << "Rest of clauseLits ";
02305 for (int i = 0; i < clauseLits.size(); i++)
02306 {
02307   if (clauseLits[i])
02308   {
02309   cout << i << " ";
02310   clauseLits[i]->printWithStrVar(cout, db->getDomain());
02311   cout << " ";
02312   }
02313 }
02314 cout << endl;
02315 cout << "Subseq. size " << ivg->subseqGndLits.size() << endl;
02316 */
02317     Array<int>& varIds = ivg->varIds;
02318     ArraysAccessor<int>& varGndings = ivg->varGndings;
02319     bool& litUnseen = ivg->litUnseen;
02320     bool hasComb;
02321 
02322       // while there are groundings of literal's variables
02323     while ((hasComb=varGndings.hasNextCombination()) || litUnseen)
02324     {
02325         // there may be no combinations if the literal is fully grounded
02326       if (litUnseen) litUnseen = false;
02327 
02328       if (hasComb)
02329       {
02330           //ground the literal's variables throughout the clause
02331         int constId;
02332         int v = 0; // index of varIds
02333           //for each variable in literal
02334         while (varGndings.nextItemInCombination(constId))
02335         {
02336           Array<Term*>& vars = (*varIdToVarsGroundedType_)[-varIds[v++]]->vars;
02337           for (int i = 0; i < vars.size(); i++) vars[i]->setId(constId);
02338         }
02339       }
02340         
02341         //proceed further only if:
02342         // 1. positive weight and partially grounded clause is unsatisfied or
02343         // 2. negative weight and partially grounded clause is satisfied
02344       bool proceed = true;
02345       if (wt_ >= 0)
02346         proceed = isUnsatisfiedGivenActivePreds(lit, ivg->subseqGndLits, db,
02347                                                 ignoreActivePreds);
02348 
02349 //cout << "Clause: ";
02350 //printWithWtAndStrVar(cout, domain);
02351 //cout << endl;
02352 //cout << " proceed " << proceed << endl;
02353 
02354       if (proceed)
02355       {
02356                 // if there are more literals
02357         if (ivgArrIdx + 1 < ivgArr.size())
02358         {
02359           lookAtNextLit = true;
02360           ivgArrIdx++; // move up stack
02361           break;
02362         }
02363           // Now we can check neg. clauses: if not satisfied (no true literals)
02364           // or satisfied with evidence atom, then do not activate
02365         if (wt_ < 0 &&
02366             !isSatisfiedGivenActivePreds(db, ignoreActivePreds))
02367         {
02368           continue;
02369         }
02370                   
02371           // At this point all the literals are grounded
02372                   // and does not have any true literal. To make sure that
02373                   // it is active, need to check the following two conditions:
02374                   // 1. It may have the same literal appearing in opposite senses =>
02375           // satisfied (and hence not active)
02376                   // 2. It may be empty when evidence is pruned away => not active
02377     
02378         bool active;
02379         bool accumulateClauses = (activeIntClauses || activeGroundClauses);
02380         if (!uniqueClauses && !accumulateClauses)
02381         {
02382           active = isActive(db);
02383         }
02384         else
02385         {
02386           active = createAndAddActiveClause(activeIntClauses,
02387                                             activeGroundClauses, uniqueClauses,
02388                                             seenPreds, uniquePreds,
02389                                             seenGndPreds, db, getSatisfied);
02390         }
02391 //cout << "Active " << active << endl;
02392         if (active) activeClauseCnt++;
02393       }
02394     } //while there are groundings of literal's variables
02395 
02396       //if we exit the while loop in order to look at next literal 
02397       //(i.e. without considering all groundings of current literal)
02398     if (lookAtNextLit) { lookAtNextLit = false; }
02399     else { varGndings.reset(); litUnseen = true; ivgArrIdx--; }//mv down stack
02400 
02401   } // while stack is not empty
02402   deleteAllLitIdxVarsGndings(ivgArr);
02403 }
02404 
02405 
02406 
02407 void getActiveClausesAndCnt(const Domain* const & domain,
02408                             Array<IntClause *> * const & activeIntClauses,
02409                             Array<GroundClause *> * const & activeGroundClauses,
02410                             int & activeClauseCnt,
02411                             IntClauseHashArray * const & uniqueClauses,
02412                             PredicateHashArray * const & seenPreds,
02413                             PredicateHashArray * const & uniquePreds,
02414                             GroundPredicateHashArray* const& seenGndPreds,
02415                             bool const & ignoreActivePreds,
02416                             bool const & getSatisfied)
02417 {
02418   activeClauseCnt = 0;
02419   Array<Predicate*> clauseLits(*predicates_);
02420   const Database* db = domain->getDB();
02421 
02422 //cout << "Getting active clauses for FO Clause: ";
02423 //printWithWtAndStrVar(cout, domain);
02424 //cout << endl;
02425 
02426   if (useInverseIndex)
02427   {
02428         sortLiteralsByNegationAndArity(clauseLits);
02429         groundIndexableLiterals(domain, activeIntClauses, activeGroundClauses,
02430                             activeClauseCnt, uniqueClauses, seenPreds,
02431                             uniquePreds, seenGndPreds, clauseLits, 0,
02432                             ignoreActivePreds, getSatisfied);
02433   }
02434   else
02435   {
02436           //Sort preds in increasing order of #TrueGndOfLiteral/#numOfGroundings.
02437       //The larger the number of true groundings of a literal, the more likely
02438       //it is to be true, so put it in front so that we can decide whether the
02439       //clause is true early.The larger the number of groundings of the literal,
02440       //the larger the savings when we decide that preceding literals are true.
02441         sortLiteralsByTrueDivTotalGroundings(clauseLits, domain, db);
02442 
02443       //simulate a stack, back/front corresponds to top/bottom
02444       //ivg stands for index, varIds, groundings
02445         Array<LitIdxVarIdsGndings*> ivgArr;
02446         createAllLitIdxVarsGndings(clauseLits, ivgArr, domain, true);
02447         int ivgArrIdx = 0; //store current position in ivgArr
02448         bool lookAtNextLit = false;
02449 
02450       // while stack is not empty
02451         while (ivgArrIdx >= 0)
02452         {
02453         //get variable groundings at top of stack
02454       LitIdxVarIdsGndings* ivg = ivgArr[ivgArrIdx];
02455       Predicate* lit = clauseLits[ivg->litIdx];
02456       Array<int>& varIds = ivg->varIds;
02457       ArraysAccessor<int>& varGndings = ivg->varGndings;
02458       bool& litUnseen = ivg->litUnseen;
02459       bool hasComb;
02460 
02461         // while there are groundings of literal's variables
02462       while ((hasComb=varGndings.hasNextCombination()) || litUnseen)
02463       {
02464           // there may be no combinations if the literal is fully grounded
02465         if (litUnseen) litUnseen = false;
02466 
02467         if (hasComb)
02468         {
02469                 //ground the literal's variables throughout the clause
02470           int constId;
02471           int v = 0; // index of varIds
02472             //for each variable in literal
02473           while (varGndings.nextItemInCombination(constId))
02474           {
02475                 Array<Term*>& vars =
02476               (*varIdToVarsGroundedType_)[-varIds[v++]]->vars;
02477                 for (int i = 0; i < vars.size(); i++) vars[i]->setId(constId);
02478           }
02479         }
02480        
02481                   //proceed further only if:
02482           // 1. positive weight and partially grounded clause is unsatisfied or
02483           // 2. negative weight and partially grounded clause is satisfied
02484         bool proceed = true;
02485         if (wt_ >= 0 && !getSatisfied)
02486           proceed = isUnsatisfiedGivenActivePreds(lit, ivg->subseqGndLits, db,
02487                                                   ignoreActivePreds);
02488 
02489 //cout << "Clause: ";
02490 //printWithWtAndStrVar(cout, domain);
02491 //cout << endl;
02492 //cout << " proceed " << proceed << endl;
02493 
02494         if (proceed)
02495         {
02496                         // if there are more literals
02497           if (ivgArrIdx + 1 < ivgArr.size())
02498           {
02499                 lookAtNextLit = true;
02500                 ivgArrIdx++; // move up stack
02501                 break;
02502           }
02503                   
02504 //cout << "Clause: ";
02505 //printWithWtAndStrVar(cout, domain);
02506 //cout << endl;
02507             // Now we can check neg. clauses: if not satisfied (no true
02508             // literals) or satisfied with evidence atom, then do not activate
02509           if (wt_ < 0 && !getSatisfied &&
02510               !isSatisfiedGivenActivePreds(db, ignoreActivePreds))
02511           {
02512             //cout << "continuing..." << endl;
02513             continue;
02514           }
02515           
02516                 // At this point all the literals are grounded
02517                         // and does not have any true literal. To make sure that
02518                         // it is active, need to check the following two conditions:
02519                         // 1. It may have the same literal appearing in opposite senses =>
02520             // satisfied (and hence not active)
02521                         // 2. It may be empty when evidence is pruned away => not active
02522                   bool active;
02523           bool accumulateClauses = (activeIntClauses || activeGroundClauses);
02524           if (!uniqueClauses && !accumulateClauses)
02525             active = isActive(db);
02526           else
02527             active = createAndAddActiveClause(activeIntClauses,
02528                                               activeGroundClauses,
02529                                               uniqueClauses, seenPreds,
02530                                               uniquePreds, seenGndPreds, db,
02531                                               getSatisfied);
02532             
02533 //cout << "Active " << active << endl;
02534           if (active) activeClauseCnt++;
02535                    
02536                 }
02537       } //while there are groundings of literal's variables
02538 
02539         //if we exit the while loop in order to look at next literal 
02540         //(i.e. without considering all groundings of current literal)
02541       if (lookAtNextLit) { lookAtNextLit = false; }
02542       else { varGndings.reset(); litUnseen = true; ivgArrIdx--; }//mv down stack
02543 
02544         } // while stack is not empty
02545     deleteAllLitIdxVarsGndings(ivgArr);
02546   }
02547   
02548   assert(!uniqueClauses || !activeIntClauses || 
02549          uniqueClauses->size()==activeIntClauses->size());
02550   assert(!uniqueClauses || !activeGroundClauses ||
02551          uniqueClauses->size()==activeGroundClauses->size());
02552 }
02553 
02554  
02555   //get Active Clauses unifying with the given predicate - if ignoreActivePreds 
02556   //is true, this is equivalent to getting all the unsatisfied clauses
02557 void getActiveClausesAndCnt(Predicate*  const & gndPred,
02558                             const Domain* const & domain,
02559                             Array<IntClause *>* const & activeIntClauses,
02560                             Array<GroundClause *>* const & activeGroundClauses,
02561                             int & activeClauseCnt,
02562                             PredicateHashArray * const & seenPreds,
02563                             GroundPredicateHashArray* const& seenGndPreds,
02564                             bool const & ignoreActivePreds,
02565                             bool const & getSatisfied)
02566 {       
02567         //at most one of them is non-null   
02568   assert(!activeIntClauses || !activeGroundClauses);
02569     
02570     //create mapping of variable ids (e.g. -1) to variable addresses,
02571     //note whether they have been grounded, and store their types   
02572   IntClauseHashArray *uniqueClauses = NULL;
02573   PredicateHashArray *uniquePreds = NULL;
02574 
02575   createVarIdToVarsGroundedType(domain); 
02576   if (gndPred == NULL)
02577   {
02578     getActiveClausesAndCnt(domain, activeIntClauses, activeGroundClauses,
02579                            activeClauseCnt, uniqueClauses, seenPreds,
02580                            uniquePreds, seenGndPreds, ignoreActivePreds,
02581                            getSatisfied);
02582     restoreVars();
02583   }
02584   else
02585   {
02586         assert(gndPred->isGrounded());
02587 
02588         //store the indexes of the predicates that can be grounded as gndPred
02589     Array<int> gndPredIndexes;
02590     for (int i = 0; i < predicates_->size(); i++)
02591           if ((*predicates_)[i]->canBeGroundedAs(gndPred)) gndPredIndexes.append(i);
02592     
02593     const Database* db = domain->getDB();
02594     Array<int> unarySet;
02595         unarySet.append(-1);
02596 
02597           //we need to take care of duplicates only if there the predicate appears
02598           //in one more than one place in the clause
02599         if(gndPredIndexes.size() > 1)
02600         {
02601           uniqueClauses = new IntClauseHashArray();
02602           uniquePreds = new PredicateHashArray();
02603         }
02604     
02605         activeClauseCnt = 0;
02606         for (int i = 0; i < gndPredIndexes.size(); i++)
02607         {
02608       //ground the predicates in current combination
02609       bool sameTruthValueAndSense; //a ground pred has the same tv and sense
02610       bool gndPredPosSameSense;
02611       unarySet[0] = i; //gndPredIndexes[i];
02612                 //cout<<"size of unary predicate set "<<unarySet.size()<<endl;
02613                 //cout<<"Element[0] = "<<unarySet[0]<<endl;
02614           groundPredicates(&unarySet, gndPredIndexes, gndPred,
02615                        gndPred->getTruthValue(), db,sameTruthValueAndSense,
02616                        gndPredPosSameSense);
02617       int cnt;
02618           getActiveClausesAndCnt(domain, activeIntClauses, activeGroundClauses, cnt,
02619                                                      uniqueClauses, seenPreds, uniquePreds,
02620                              seenGndPreds, ignoreActivePreds, getSatisfied);
02621           activeClauseCnt += cnt;
02622           restoreVars();
02623         }
02624   }
02625 
02626   assert(!uniqueClauses || uniqueClauses->size() == activeClauseCnt);
02627   assert(!activeIntClauses || activeIntClauses->size() == activeClauseCnt);
02628   assert(!activeGroundClauses ||
02629          activeGroundClauses->size() == activeClauseCnt);
02630    
02631   if(uniqueClauses)
02632   {
02633         for (int i = 0; i < uniqueClauses->size(); i++)
02634         {
02635           IntClause *intClause = (*uniqueClauses)[i];
02636           intClause->deleteIntPredicates();
02637           delete intClause;
02638         }
02639         delete uniqueClauses;
02640   }
02641     
02642   if(uniquePreds)
02643   {
02644         for (int i = 0; i < uniquePreds->size(); i++) 
02645           delete (*uniquePreds)[i];
02646         delete uniquePreds;
02647   }
02648 } 
02649 
02650 
02651 public:
02652 
02653 //get Active Clauses unifying with the given predicate - if ignoreActivePreds 
02654 //is true, this is equivalent to getting all the unsatisfied clauses
02655 // Returns the intClauses
02656 void getActiveClauses(Predicate*  const & gndPred, 
02657                       const Domain* const & domain,
02658                                           Array<IntClause *>* const & activeIntClauses,
02659                                           PredicateHashArray * const & seenPreds,
02660                                           bool const & ignoreActivePreds)
02661 {
02662   int cnt = 0;
02663   Array<GroundClause *>* const & activeGroundClauses = NULL;
02664   GroundPredicateHashArray* const & seenGndPreds = NULL;
02665   bool getSatisfied = false;
02666   getActiveClausesAndCnt(gndPred, domain, activeIntClauses, activeGroundClauses, cnt,
02667                          seenPreds, seenGndPreds, ignoreActivePreds,
02668                          getSatisfied);
02669 } 
02670 
02671 // Get inactive clauses unifying with the given predicate
02672 // Returns the intClauses
02673 void getInactiveClauses(Predicate*  const & gndPred, 
02674                         const Domain* const & domain,
02675                         Array<IntClause *>* const & activeIntClauses,
02676                         PredicateHashArray * const & seenPreds)
02677 {
02678   int cnt = 0;
02679   Array<GroundClause *>* const & activeGroundClauses = NULL;
02680   GroundPredicateHashArray* const & seenGndPreds = NULL;
02681   bool ignoreActivePreds = true;
02682   bool getSatisfied = true;
02683   getActiveClausesAndCnt(gndPred, domain, activeIntClauses, activeGroundClauses, cnt,
02684                          seenPreds, seenGndPreds, ignoreActivePreds,
02685                          getSatisfied);
02686 }
02687 
02688 //get Active Clauses unifying with the given predicate - if ignoreActivePreds 
02689 //is true, this is equivalent to getting all the unsatisfied clauses
02690 // Returns the groundClauses
02691 void getActiveClauses(Predicate* const & gndPred, 
02692                       const Domain* const & domain,
02693                       Array<GroundClause *>* const & activeGroundClauses,
02694                       GroundPredicateHashArray * const & seenGndPreds,
02695                                           bool const & ignoreActivePreds)
02696 {
02697   int cnt = 0;
02698   Array<IntClause *>* const & activeIntClauses = NULL;
02699   PredicateHashArray* const & seenPreds = NULL;
02700   bool getSatisfied = false;
02701   getActiveClausesAndCnt(gndPred, domain, activeIntClauses, activeGroundClauses, cnt,
02702                          seenPreds, seenGndPreds, ignoreActivePreds,
02703                          getSatisfied);
02704                          
02705 } 
02706 
02707 
02708 //get the count of Active Clauses unifying with the given predicate
02709 //- if ignoreActivePreds is true, this is equivalent to getting the
02710 //count of all the unsatisfied clauses
02711 int getActiveClauseCnt(Predicate*  const & gndPred, 
02712                        const Domain* const & domain,
02713                        PredicateHashArray * const & seenPreds,
02714                        bool const & ignoreActivePreds)
02715 {
02716   int cnt = 0;
02717            
02718   Array<IntClause *> *activeIntClauses = NULL;
02719   Array<GroundClause *> *activeGroundClauses = NULL;
02720   GroundPredicateHashArray* const & seenGndPreds = NULL;
02721   bool getSatisfied = false;
02722   getActiveClausesAndCnt(gndPred, domain, activeIntClauses, activeGroundClauses, cnt,
02723                          seenPreds, seenGndPreds, ignoreActivePreds,
02724                          getSatisfied);
02725 
02726   return cnt;
02727 }
02728 
02729 
02730 private:
02731   
02732   static void sortByLen(Array<Clause*>& clauses, const int& l, const int& r)
02733   {
02734     Clause** items = (Clause**) clauses.getItems();
02735     if (l >= r) return;
02736     Clause* tmp = items[l];
02737     items[l] = items[(l+r)/2];
02738     items[(l+r)/2] = tmp;
02739 
02740     int last = l;
02741     for (int i = l+1; i <= r; i++)
02742       if (items[i]->getNumPredicates() < items[l]->getNumPredicates())
02743       {
02744         ++last;
02745         Clause* tmp = items[last];
02746         items[last] = items[i];
02747         items[i] = tmp;
02748       }
02749     
02750     tmp = items[l];
02751     items[l] = items[last];
02752     items[last] = tmp;
02753     sortByLen(clauses, l, last-1);
02754     sortByLen(clauses, last+1, r); 
02755   }
02756 
02757 
02758  private:
02759   double wt_;
02760   Array<Predicate*>* predicates_;
02761   Array<int>* intArrRep_;
02762   size_t hashCode_;
02763   bool dirty_;
02764   bool isHardClause_;
02765 
02766     // (*varIdToVarsGroundedType_)[v] is the VarsGroundType of variable -v
02767     // start accessing this array from index 1
02768   Array<VarsGroundedType*>* varIdToVarsGroundedType_ ;
02769 
02770   AuxClauseData* auxClauseData_;
02771   static ClauseSampler* clauseSampler_;
02772   static double fixedSizeB_;
02773 };
02774 
02775 
02777 
02778 class HashClause
02779 {
02780  public:
02781   size_t operator()(Clause* const & c) const  { return c->hashCode(); }
02782 };
02783 
02784 
02785 class EqualClause
02786 {
02787  public:
02788   bool operator()(Clause* const & c1, Clause* const & c2) const
02789   { return c1->same(c2); }
02790 };
02791 
02792 
02793 class EqualClauseOp
02794 {
02795  public:
02796     //the auxClauseData_ of c1 and c2 must be NON-NULL
02797   bool operator()(Clause* const & c1, Clause* const & c2) const
02798   { 
02799     AuxClauseData* acd1 = c1->getAuxClauseData();
02800     AuxClauseData* acd2 = c2->getAuxClauseData();
02801     if (acd1->op != acd2->op) return false;
02802     if (acd1->op == OP_ADD) return c1->same(c2);
02803     if (acd1->op == OP_REMOVE) 
02804       return acd1->removedClauseIdx == acd2->removedClauseIdx;
02805       //acd1->op is OP_REPLACE || OP_REPLACE_ADDPRED || OP_REPLACE_REMPRED
02806     return acd1->removedClauseIdx == acd2->removedClauseIdx && c1->same(c2);
02807   }
02808 };
02809 
02810 
02812 
02813 typedef hash_set<Clause*, HashClause, EqualClause> ClauseSet;
02814 typedef hash_set<Clause*, HashClause, EqualClauseOp> ClauseOpSet;
02815 typedef hash_map<Clause*, Array<Clause*>*, HashClause, EqualClause> 
02816   ClauseToClausesMap;
02817 
02818 typedef HashList<Clause*, HashClause, EqualClause> ClauseHashList;
02819 //typedef HashArray<Clause*, HashClause, EqualClause> ClauseHashArray;
02820 typedef HashArray<Clause*, HashClause, EqualClauseOp> ClauseOpHashArray;
02821 
02822 #endif

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