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

Generated on Sun Jun 7 11:55:15 2009 for Alchemy by  doxygen 1.5.1