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