00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
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
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
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
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
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
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
00287 Predicate* getPredicate(const int& idx) const { return (*predicates_)[idx]; }
00288
00289
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
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
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
00399
00400 void canonicalize(Array<int> * const & oldVarIdToNewVarId=NULL)
00401 {
00402
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
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
00511
00512
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
00536
00537
00538 }
00539 }
00540 }
00541 }
00542 }
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
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
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
00653
00654
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
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
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
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
01036
01037
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
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
01055
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
01064 double numTrueGndActual =
01065 countNumTrueGroundingsForAllComb(gndPredIndexes, gndPred, actual, flipped,
01066 domain, hasUnknownPreds, sampleClauses);
01067
01068
01069
01070 double numTrueGndOpp = 0.0;
01071
01072 int blockIdx = domain->getBlock(gndPred);
01073 if (blockIdx >= 0)
01074 {
01075
01076
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
01085 assert(oldTrueOne > -1);
01086
01087 int newTrueOne = (oldTrueOne <= combo) ? combo + 1 : combo;
01088
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
01110
01111
01112
01113
01114
01115
01116
01117
01118 if (oldTruePred) db->setValue(oldTruePred, TRUE);
01119 db->setValue(newTruePred, FALSE);
01120
01121 delete newTruePred;
01122 }
01123 else
01124 {
01125
01126 flipped = true;
01127
01128
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
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
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
01170 for (int i = 0; i < predicates_->size(); i++)
01171 {
01172 Predicate* p = (*predicates_)[i];
01173
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 }
01187 }
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
01238 for (int i = 0; i < predicates_->size(); i++)
01239 {
01240 Predicate* p = (*predicates_)[i];
01241
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 }
01256 }
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++)
01264 {
01265 Predicate* p = (*predicates_)[i];
01266 for (int j = 0; j < p->getNumTerms(); j++)
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 }
01302 }
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
01327
01328
01329
01330
01331
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
01357
01358
01359
01360
01361
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
01387
01388
01389
01390
01391
01392 void groundPredVars(const int& predIdx, Predicate* const& gndPred)
01393 {
01394 assert(varIdToVarsGroundedType_);
01395 groundPredVars(predIdx, gndPred, varIdToVarsGroundedType_);
01396 }
01397
01398
01399
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
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_);
01490
01491
01492 for (unsigned int i = 0; i < (unsigned int) clauseLits.size(); i++)
01493 {
01494
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
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
01512 int constId = varGndings.getArray(j)->item(0);
01513
01514
01515 Array<Term*>& vars = (*varIdToVarsGroundedType_)[-varIds[j]]->vars;
01516 for (int k = 0; k < vars.size(); k++) vars[k]->setId(constId);
01517 }
01518
01519
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 }
01532
01533 if (clausedebug >= 2)
01534 {
01535 cout << "createAllLitIdxVarsGndings lit after: ";
01536 clauseLits[i]->printWithStrVar(cout, domain);
01537 cout << endl;
01538 }
01539 }
01540 }
01541
01542
01543
01544 static void deleteAllLitIdxVarsGndings(Array<LitIdxVarIdsGndings*>& ivgArr)
01545 {
01546 for (int i = 0; i < ivgArr.size(); i++)
01547 {
01548
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
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
01593 if (lit->isGrounded())
01594 {
01595 arr.append(pair<double,Predicate*>(DBL_MAX, lit));
01596 continue;
01597 }
01598
01599
01600 double numTrue = (lit->getSense())? db->getNumTrueGndPreds(lit->getId())
01601 :db->getNumFalseGndPreds(lit->getId());
01602 double numTotal = lit->getNumGroundingsIfAllVarDiff(domain);
01603
01604
01605 double numGnd = 1;
01606
01607 Array<int> varIds;
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;
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
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
01676
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
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
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);
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);
01762 for (int i = 0; i < inCombSize; i++)
01763 {
01764 if (inComb[i]) multDArrIndexes.append(1);
01765 else multDArrIndexes.append(0);
01766 }
01767
01768
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
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
01853
01854
01855
01856
01857
01858
01859
01860
01861 double countNumTrueGroundings(const Domain* const & domain,
01862 const Database* const & db,
01863 const bool& hasUnknownPreds,
01864 const bool& checkSatOnly,
01865
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
01873 const AddGroundClauseStruct* const & agcs,
01874
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
01884
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
01902 Array<Predicate*> bannedPreds;
01903 if (findUnknownClauses)
01904 getBannedPreds(bannedPreds, gndPredIdx, groundPred, gndPred);
01905
01906 double numTrueGndings = 0;
01907
01908
01909
01910 Array<Predicate*>* origClauseLits = new Array<Predicate*>(*predicates_);
01911
01912
01913
01914 Array<Array<Predicate*>* > partGroundedClauses;
01915
01916 if ((findUnknownClauses || getActiveClauses) && useInverseIndex)
01917 {
01918 bool newIgnoreActivePreds = ignoreActivePreds;
01919
01920 if (wt_ < 0) newIgnoreActivePreds = true;
01921
01922
01923 sortLiteralsByNegationAndArity(*origClauseLits, newIgnoreActivePreds, db);
01924 groundIndexableLiterals(domain, db, *origClauseLits, partGroundedClauses,
01925 ignoreActivePreds);
01926 }
01927 else
01928 {
01929
01930
01931
01932
01933
01934
01935 sortLiteralsByTrueDivTotalGroundings(*origClauseLits, domain, db);
01936
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
01945
01946
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
01964
01965
01966 for (int pgcIdx = 0; pgcIdx < partGroundedClauses.size(); pgcIdx++)
01967 {
01968
01969 Array<Predicate*> clauseLits = *(partGroundedClauses[pgcIdx]);
01970 assert(clauseLits.size() == origClauseLits->size());
01971
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
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
01997 delete clauseLits[i];
01998 clauseLits[i] = (*origClauseLits)[i];
01999 }
02000
02001
02002
02003 Array<LitIdxVarIdsGndings*> ivgArr;
02004 createAllLitIdxVarsGndings(clauseLits, ivgArr, domain, true);
02005 if (findUnknownClauses)
02006 createBannedPreds(clauseLits, ivgArr, bannedPreds);
02007 int ivgArrIdx = 0;
02008 bool lookAtNextLit = false;
02009
02010
02011 while (ivgArrIdx >= 0 && stillActivating)
02012 {
02013
02014 LitIdxVarIdsGndings* ivg = ivgArr[ivgArrIdx];
02015
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
02030 while ((hasComb = varGndings.hasNextCombination()) || litUnseen)
02031 {
02032
02033 if (litUnseen) litUnseen = false;
02034
02035 if (hasComb)
02036 {
02037
02038 int constId;
02039 int v = 0;
02040
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
02057 if (getActiveClauses)
02058 {
02059
02060
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
02071
02072
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
02086 if (ivgArrIdx + 1 < ivgArr.size())
02087 {
02088 lookAtNextLit = true;
02089 ivgArrIdx++;
02090 break;
02091 }
02092
02093
02094
02095
02096 if (wt_ < 0 && !getSatisfied &&
02097 !isSatisfiedGivenActivePreds(db, ignoreActivePreds))
02098 {
02099 if (clausedebug >= 2) cout << "continuing..." << endl;
02100 continue;
02101 }
02102
02103
02104
02105
02106
02107
02108
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
02123 else
02124 {
02125
02126 if (literalOrSubsequentLiteralsAreTrue(lit, ivg->subseqGndLits, db))
02127 {
02128 if (clausedebug >= 2)
02129 cout << "Clause satisfied" << endl;
02130
02131 if (checkSatOnly) return 1;
02132
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
02150 }
02151 else
02152 {
02153
02154 if (ivgArrIdx + 1 < ivgArr.size())
02155 {
02156 if (clausedebug >= 2) cout << "Moving to next literal" << endl;
02157 lookAtNextLit = true;
02158 ivgArrIdx++;
02159 break;
02160 }
02161
02162
02163
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
02181 createAndAddUnknownClause(unknownGndClauses, unknownClauses,
02182 numUnknownClauses, agcs, db);
02183 }
02184 }
02185 }
02186 }
02187
02188
02189 if (!stillActivating) break;
02190
02191
02192
02193 if (lookAtNextLit) { lookAtNextLit = false; }
02194
02195 else { varGndings.reset(); litUnseen = true; ivgArrIdx--; }
02196
02197 }
02198
02199
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
02239
02240
02241
02242
02243 Array<int> dim;
02244 for (int i = 0; i < gndPredIndexes.size(); i++) dim.append(2);
02245
02246
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
02253
02254 PowerSet* ps = PowerSet::getPowerSet();
02255
02256 ps->prepareAccess(gndPredIndexes.size(), false);
02257
02258 const Array<int>* set;
02259 while (ps->getNextSet(set))
02260 {
02261
02262 bool sameTruthValueAndSense;
02263 bool gndPredPosSameSense;
02264 bool valid = groundPredicates(set, gndPredIndexes, gndPred, gndPredTV, db,
02265 sameTruthValueAndSense,gndPredPosSameSense);
02266
02267
02268
02269
02270
02271
02272
02273 if (!valid || !gndPredPosSameSense) { restoreVars(); continue; }
02274
02275
02276 double cnt, numGndings = countNumGroundings();
02277
02278
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
02288
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
02305 double cntDueToThisComb
02306 = addCountToCombination(inComb,inCombSize,set,gndedPredPosArr,cnt);
02307 count += cntDueToThisComb;
02308
02309
02310
02311
02312
02313 Array<int> inCombIndexes;
02314 for (int i = 0; i < set->size(); i++) inCombIndexes.append((*set)[i]);
02315
02316
02317 PowerSetInstanceVars psInstVars;
02318 ps->prepareAccess(inCombIndexes.size(), psInstVars);
02319 const Array<int>* falseSet;
02320 while (ps->getNextSet(falseSet, psInstVars))
02321 {
02322
02323 if (falseSet->size() == set->size()) continue;
02324 minusRepeatedCounts(inComb, inCombSize, inCombIndexes, set, falseSet,
02325 gndedPredPosArr, cntDueToThisComb);
02326 }
02327 restoreVars();
02328 }
02329 delete [] inComb;
02330 return count;
02331 }
02332
02333
02334
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;
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
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
02370 bool isUnsatisfiedGivenActivePreds(Predicate* const & lit,
02371 const Array<Predicate*>& subseqLits,
02372 const Database* const & db,
02373 bool const & ignoreActivePreds)
02374 {
02375
02376
02377
02378
02379 if (db->getDeactivatedStatus(lit)) return false;
02380 bool active = false;
02381 if (!ignoreActivePreds)
02382 active = db->getActiveStatus(lit);
02383
02384 TruthValue tv = db->getValue(lit);
02385 lit->setTruthValue(tv);
02386
02387 if (!active && db->sameTruthValueAndSense(tv, lit->getSense()))
02388 return false;
02389
02390 for (int i = 0; i < subseqLits.size(); i++)
02391 {
02392
02393
02394
02395 if (!ignoreActivePreds)
02396 active = db->getActiveStatus(subseqLits[i]);
02397
02398 tv = db->getValue(subseqLits[i]);
02399 subseqLits[i]->setTruthValue(tv);
02400
02401 if (!active && db->sameTruthValueAndSense(tv,subseqLits[i]->getSense()))
02402 return false;
02403 }
02404 return true;
02405 }
02406
02407
02408
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
02418
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
02428
02429 evidence = db->getEvidenceStatus(lit);
02430
02431
02432
02433
02434
02435 if (evidence && db->sameTruthValueAndSense(tv, lit->getSense()))
02436 return false;
02437
02438
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
02469 if (isIndexable)
02470 {
02471
02472 if (db->isClosedWorld(lit->getId()))
02473 {
02474
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
02483 else if (!ignoreActivePreds)
02484 {
02485
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
02506
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
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
02549 for (int litIdx = 0; litIdx < clauseLits.size(); litIdx++)
02550 {
02551
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
02559
02560 Array<Array<Predicate*>* > tmpClauses;
02561 if (clausedebug >= 1)
02562 {
02563 cout << "Resulting clauses size before: " << resultingClauses.size()
02564 << endl;
02565 }
02566
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
02580 Array<Predicate *>* indexedGndings = new Array<Predicate *>;
02581
02582
02583 bool trueGndings = !(clauseLits[litIdx]->getSense());
02584
02585
02586
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
02605
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
02617
02618
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
02640 for (int j = 0;
02641 j < (*resultingClauses[pgcIdx])[litIdx]->getNumTerms(); j++)
02642 {
02643 const Term* term =
02644 (*resultingClauses[pgcIdx])[litIdx]->getTerm(j);
02645
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
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
02659 if (pred->getTerm(l)->getId() == varId)
02660 pred->setTermToConstant(l, constId);
02661 }
02662 }
02663 }
02664 }
02665
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
02681
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
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
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
02716 else
02717 {
02718 break;
02719 }
02720 }
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
02756
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
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
02786 bool sameTruthValueAndSense;
02787 bool gndPredPosSameSense;
02788 unarySet[0] = i;
02789
02790
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
02843
02844
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
02921
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
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
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
02974 typedef HashArray<Clause*, HashClause, EqualClauseOp> ClauseOpHashArray;
02975
02976 #endif
02977