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

Generated on Wed Feb 14 15:15:18 2007 for Alchemy by  doxygen 1.5.1