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