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 MLN_H_JUN_26_2005
00067 #define MLN_H_JUN_26_2005
00068
00069 #include <cfloat>
00070 #include <ext/hash_map>
00071 #include <ext/hash_set>
00072 using namespace __gnu_cxx;
00073 #include "clause.h"
00074 #include "equalstr.h"
00075 #include "mlnhelper.h"
00076
00077
00078 class MLN
00079 {
00080 public:
00081 MLN() : clauses_(new ClauseHashArray),clauseInfos_(new Array<MLNClauseInfo*>),
00082 formAndClausesArray_(new FormulaAndClausesArray),
00083 predIdToClausesMap_(new Array<Array<IndexClause*>*>) {}
00084
00085 ~MLN()
00086 {
00087 clauses_->deleteItemsAndClear(); delete clauses_;
00088 clauseInfos_->deleteItemsAndClear(); delete clauseInfos_;
00089 formAndClausesArray_->deleteItemsAndClear(); delete formAndClausesArray_;
00090 for (int i = 0; i < predIdToClausesMap_->size(); i++)
00091 if ((*predIdToClausesMap_)[i])
00092 {
00093 (*predIdToClausesMap_)[i]->deleteItemsAndClear();
00094 delete (*predIdToClausesMap_)[i];
00095 }
00096 delete predIdToClausesMap_;
00097 }
00098
00099
00100 int getNumClauses() const { return clauses_->size(); }
00101
00102 int getNumHardClauses() const
00103 {
00104 int numHardClauses = 0;
00105 for (int i = 0; i < clauses_->size(); i++)
00106 {
00107 if ((*clauses_)[i]->isHardClause()) numHardClauses++;
00108 }
00109 return numHardClauses;
00110 }
00111
00112
00113 bool containsClause(const Clause* const & c) const
00114 { return clauses_->contains((Clause*)c); }
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 bool appendClause(const string& formulaString, const bool& hasExist,
00125 Clause* const& c, const double& wt,
00126 const bool& isHardClause, int& retClauseIdx)
00127 {
00128 assert(c);
00129 c->canonicalize();
00130 bool isAppended;
00131 Clause* clause;
00132 if ((retClauseIdx = clauses_->find(c)) >= 0)
00133 {
00134 clause = (*clauses_)[retClauseIdx];
00135 delete c;
00136 isAppended = false;
00137 }
00138 else
00139 {
00140
00141 retClauseIdx = clauses_->append(c);
00142 clause = c;
00143 isAppended = true;
00144 clause->setWt(0);
00145 }
00146 clause->addWt(wt);
00147 if (isHardClause) clause->setIsHardClause(isHardClause);
00148
00149
00150 FormulaAndClauses* fac = new FormulaAndClauses(formulaString,
00151 formAndClausesArray_->size(),
00152 hasExist);
00153 int fidx;
00154
00155 if ( (fidx = formAndClausesArray_->find(fac)) < 0 )
00156 {
00157 fidx = formAndClausesArray_->append(fac);
00158 assert(fac->index == fidx);
00159 }
00160 else
00161 {
00162 delete fac;
00163 fac = (*formAndClausesArray_)[fidx];
00164 assert(fac->index == fidx);
00165 }
00166 IndexClause* ic = new IndexClause(fac->indexClauses->size(), clause);
00167 int cidx = fac->indexClauses->append(ic);
00168 if (cidx < 0) { delete ic; ic = NULL; }
00169 else assert(ic->index == cidx);
00170
00171 if (isAppended)
00172 {
00173
00174 appendClauseInfo(clause, retClauseIdx, &(fac->index), &(ic->index));
00175 }
00176 else
00177 if (cidx >= 0)
00178 {
00179
00180
00181 updateClauseInfo(retClauseIdx, &(fac->index), &(ic->index));
00182 }
00183
00184 assert(clauses_->size() == clauseInfos_->size());
00185 return isAppended;
00186 }
00187
00188
00189
00190 Clause* removeClause(const int& remIdx)
00191 {
00192
00193 Clause* r = clauses_->removeItemFastDisorder(remIdx);
00194 MLNClauseInfo* ci = clauseInfos_->removeItemFastDisorder(remIdx);
00195 assert(ci->index == remIdx);
00196
00197 if (clauseInfos_->size() != remIdx)
00198 {
00199
00200
00201 (*clauseInfos_)[remIdx]->index = remIdx;
00202 }
00203
00204
00205 Array<PredIdClauseIndex*>& piciArr = ci->predIdsClauseIndexes;
00206 for (int i = 0; i < piciArr.size(); i++)
00207 {
00208 int predId = piciArr[i]->predId;
00209 int remIdx = *(piciArr[i]->clauseIndex);
00210
00211 Array<IndexClause*>* indexesClauses = (*predIdToClausesMap_)[predId];
00212 IndexClause* ic = indexesClauses->removeItemFastDisorder(remIdx);
00213 assert(ic->index == remIdx && ic->clause == r);
00214 delete ic;
00215
00216
00217 if (indexesClauses->size() != remIdx)
00218 {
00219
00220
00221 (*indexesClauses)[remIdx]->index = remIdx;
00222 }
00223
00224 if (indexesClauses->empty())
00225 {
00226 delete indexesClauses;
00227 (*predIdToClausesMap_)[predId] = NULL;
00228 }
00229 }
00230
00231
00232 Array<FormulaClauseIndexes*>& fciArr = ci->formulaClauseIndexes;
00233 for (int i = 0; i < fciArr.size(); i++)
00234 {
00235 int fidx = *(fciArr[i]->formulaIndex);
00236 int remIdx = *(fciArr[i]->clauseIndex);
00237 FormulaAndClauses* fac = (*formAndClausesArray_)[fidx];
00238 IndexClauseHashArray* indexClauses = fac->indexClauses;
00239 IndexClause* ic = indexClauses->removeItemFastDisorder(remIdx);
00240 assert(ic->index == remIdx);
00241 delete ic;
00242 if (indexClauses->size() != remIdx)
00243 (*indexClauses)[remIdx]->index = remIdx;
00244
00245 if (indexClauses->empty())
00246 {
00247 fac = formAndClausesArray_->removeItemFastDisorder(fidx);
00248 assert(fac->index == fidx);
00249 delete fac;
00250 if (formAndClausesArray_->size() != fidx)
00251 (*formAndClausesArray_)[fidx]->index = fidx;
00252 }
00253 }
00254
00255 delete ci;
00256 assert(clauses_->size() == clauseInfos_->size());
00257 return r;
00258 }
00259
00260
00261
00262 Clause* removeClause(const Clause* const & c)
00263 {
00264 int idx = findClauseIdx(c);
00265 if (idx < 0) return NULL;
00266 return removeClause(idx);
00267 }
00268
00269
00270 void removeAllClauses(Array<Clause*>* const & clauses)
00271 {
00272 while (!clauses_->empty())
00273 {
00274 Clause* c = removeClause(0);
00275 if (clauses) clauses->append(c);
00276 else delete c;
00277 }
00278 }
00279
00280
00281
00282
00283
00284
00285
00286 void rehashClauses()
00287 {
00288 ClauseHashArray* newha = new ClauseHashArray;
00289 for (int i = 0; i < clauses_->size(); i++)
00290 {
00291 int a = newha->append((*clauses_)[i]);
00292 assert(a >= 0); a = 0;
00293 }
00294 delete clauses_;
00295 clauses_ = newha;
00296
00297
00298 for (int i = 0; i < formAndClausesArray_->size(); i++)
00299 {
00300 FormulaAndClauses* fac = (*formAndClausesArray_)[i];
00301 IndexClauseHashArray* newArr = new IndexClauseHashArray;
00302 IndexClauseHashArray* curArr = fac->indexClauses;
00303 for (int j = 0; j < curArr->size(); j++)
00304 {
00305 int a = newArr->append((*curArr)[j]);
00306 assert((*curArr)[j]->index == a); a = 0;
00307 }
00308 curArr->clear();
00309 delete curArr;
00310 fac->indexClauses = newArr;
00311 }
00312 }
00313
00314
00315
00316
00317
00318 double getMaxAbsSoftWt()
00319 {
00320
00321 double maxSoftWt = 0;
00322 for (int i = 0; i < clauses_->size(); i++)
00323 {
00324 Clause* c = (*clauses_)[i];
00325 if (!c->isHardClause() && !isExistUniqueClause(c))
00326 {
00327 double abWt = fabs(c->getWt());
00328 if (abWt > maxSoftWt) maxSoftWt = abWt;
00329 }
00330 }
00331 return maxSoftWt;
00332 }
00333
00334
00335
00336 int findClauseIdx(const Clause* const & c) const
00337 { return clauses_->find((Clause*)c); }
00338
00339
00340 const Clause* findClause(const Clause* const & c) const
00341 {
00342 int i = findClauseIdx(c);
00343 if (i < 0) return NULL;
00344 return (*clauses_)[i];
00345 }
00346
00347
00348
00349
00350 const Clause* getClause(const int& i) const
00351 {
00352 if (i < 0 || i >= clauses_->size()) return NULL;
00353 return (*clauses_)[i];
00354 }
00355
00356
00357
00358
00359 bool isExistClause(const int& i) const
00360 {
00361 assert(0 <= i && i < clauses_->size());
00362 Array<FormulaClauseIndexes*>& fciArr
00363 = (*clauseInfos_)[i]->formulaClauseIndexes;
00364 for (int i = 0; i < fciArr.size(); i++)
00365 if ((*formAndClausesArray_)[*(fciArr[i]->formulaIndex)]->hasExist)
00366 return true;
00367 return false;
00368 }
00369
00370
00371
00372
00373 bool isExistClause(const Clause* const & c) const
00374 {
00375 int i = findClauseIdx(c);
00376 assert(i >= 0);
00377 return isExistClause(i);
00378 }
00379
00380
00381
00382
00383 bool isExistUniqueClause(const int& i) const
00384 {
00385 assert(0 <= i && i < clauses_->size());
00386 Array<FormulaClauseIndexes*>& fciArr
00387 = (*clauseInfos_)[i]->formulaClauseIndexes;
00388 for (int i = 0; i < fciArr.size(); i++)
00389 if ((*formAndClausesArray_)[*(fciArr[i]->formulaIndex)]->isExistUnique)
00390 return true;
00391 return false;
00392 }
00393
00394
00395
00396
00397 bool isExistUniqueClause(const Clause* const & c) const
00398 {
00399 int i = findClauseIdx(c);
00400 assert(i >= 0);
00401 return isExistUniqueClause(i);
00402 }
00403
00404
00405
00406
00407 bool clauseInNonExistAndNonExistUniqueFormulaCNF(const int& i) const
00408 {
00409 assert(0 <= i && i < clauses_->size());
00410 Array<FormulaClauseIndexes*>& fciArr
00411 = (*clauseInfos_)[i]->formulaClauseIndexes;
00412 for (int i = 0; i < fciArr.size(); i++)
00413 {
00414 FormulaAndClauses*fnc=(*formAndClausesArray_)[*(fciArr[i]->formulaIndex)];
00415 if (!fnc->hasExist && !fnc->isExistUnique) return true;
00416 }
00417 return false;
00418 }
00419
00420
00421
00422
00423 bool clauseInNonExistAndNonExistUniqueFormulaCNF(const Clause* const & c)
00424 const
00425 {
00426 int i = findClauseIdx(c);
00427 assert(i >= 0);
00428 return clauseInNonExistAndNonExistUniqueFormulaCNF(i);
00429 }
00430
00431
00432
00433 const ClauseHashArray* getClauses() const { return clauses_; }
00434
00435
00436 void getClauses(Array<Clause*>* const & clauses) const
00437 { for (int i = 0; i < clauses_->size();i++) clauses->append((*clauses_)[i]); }
00438
00439
00440 const MLNClauseInfo* getMLNClauseInfo(const int& i) const
00441 {
00442 if (i < 0 || i >= clauseInfos_->size()) return NULL;
00443 return (*clauseInfos_)[i];
00444 }
00445
00446
00447 int* getMLNClauseInfoIndexPtr(const int& i) const
00448 {
00449 assert(0 <= i && i < clauseInfos_->size());
00450 return &((*clauseInfos_)[i]->index);
00451 }
00452
00453 const Array<MLNClauseInfo*>* getMLNClauseInfos() const
00454 { return clauseInfos_; }
00455
00456
00457 void setClauseInfoPriorMeansToClauseWts()
00458 {
00459 assert(clauses_->size() == clauseInfos_->size());
00460 for (int i = 0; i < clauseInfos_->size(); i++)
00461 (*clauseInfos_)[i]->priorMean = (*clauses_)[i]->getWt();
00462 }
00463
00464
00465 void getClauseWts(Array<double>& wts) const
00466 {
00467 wts.clear();
00468 for (int i = 0; i < clauses_->size(); i++)
00469 wts.append((*clauses_)[i]->getWt());
00470 }
00471
00472
00473 void setClauseWts(Array<double>& wts)
00474 {
00475 assert (wts.size() == clauses_->size());
00476 for (int i = 0; i < clauses_->size(); i++)
00477 (*clauses_)[i]->setWt(wts[i]);
00478 }
00479
00480
00481 const IndexClauseHashArray*
00482 getClausesOfFormula(const string& formulaStr) const
00483 {
00484 FormulaAndClauses tmp(formulaStr, 0, false);
00485 int i = formAndClausesArray_->find(&tmp);
00486 if (i < 0) return NULL;
00487 FormulaAndClauses* fnc = (*formAndClausesArray_)[i];
00488 return fnc->indexClauses;
00489 }
00490
00491
00492
00493
00494 bool setFormulaNumPreds(const string& formulaStr, const int& numPreds)
00495 {
00496 FormulaAndClauses tmp(formulaStr, 0, false);
00497 int i = formAndClausesArray_->find(&tmp);
00498 if (i < 0) return false;
00499 FormulaAndClauses* fnc = (*formAndClausesArray_)[i];
00500 fnc->numPreds = numPreds;
00501 return true;
00502 }
00503
00504
00505
00506
00507 bool setFormulaIsHard(const string& formulaStr, const bool& isHard)
00508 {
00509 FormulaAndClauses tmp(formulaStr, 0, false);
00510 int i = formAndClausesArray_->find(&tmp);
00511 if (i < 0) return false;
00512 FormulaAndClauses* fnc = (*formAndClausesArray_)[i];
00513 fnc->isHard = isHard;
00514 return true;
00515 }
00516
00517
00518
00519
00520 bool setFormulaPriorMean(const string& formulaStr, const double& priorMean)
00521 {
00522 FormulaAndClauses tmp(formulaStr, 0, false);
00523 int i = formAndClausesArray_->find(&tmp);
00524 if (i < 0) return false;
00525 FormulaAndClauses* fnc = (*formAndClausesArray_)[i];
00526 fnc->priorMean = priorMean;
00527 return true;
00528 }
00529
00530
00531
00532 bool setFormulaWt(const string& formulaStr, const double& wt)
00533 {
00534 FormulaAndClauses tmp(formulaStr, 0, false);
00535 int i = formAndClausesArray_->find(&tmp);
00536 if (i < 0) return false;
00537 FormulaAndClauses* fnc = (*formAndClausesArray_)[i];
00538 fnc->wt = wt;
00539 return true;
00540 }
00541
00542
00543
00544
00545 bool setFormulaIsExistUnique(const string& formulaStr,
00546 const bool& isExistUnique)
00547 {
00548 FormulaAndClauses tmp(formulaStr, 0, false);
00549 int i = formAndClausesArray_->find(&tmp);
00550 if (i < 0) return false;
00551 FormulaAndClauses* fnc = (*formAndClausesArray_)[i];
00552 fnc->isExistUnique = isExistUnique;
00553 return true;
00554 }
00555
00556
00557
00558 double getFormulaWt(const string& formulaStr)
00559 {
00560 FormulaAndClauses tmp(formulaStr, 0, false);
00561 int i = formAndClausesArray_->find(&tmp);
00562 FormulaAndClauses* fnc = (*formAndClausesArray_)[i];
00563 return fnc->wt;
00564 }
00565
00566
00567 const FormulaAndClausesArray* getFormulaAndClausesArray() const
00568 { return formAndClausesArray_; }
00569
00570
00571
00572 const Array<Array<IndexClause*>*>* getPredIdToClausesMap() const
00573 { return predIdToClausesMap_; }
00574
00575
00576 const Array<IndexClause*>* getClausesContainingPred(const int& predId) const
00577 {
00578 if (predId < predIdToClausesMap_->size())
00579 return (*predIdToClausesMap_)[predId];
00580 return NULL;
00581 }
00582
00583
00584 void compress()
00585 {
00586 clauses_->compress();
00587 for (int i = 0; i < clauseInfos_->size(); i++)
00588 (*clauseInfos_)[i]->compress();
00589 clauseInfos_->compress();
00590 for (int i = 0; i < formAndClausesArray_->size(); i++)
00591 (*formAndClausesArray_)[i]->indexClauses->compress();
00592 formAndClausesArray_->compress();
00593 for (int i = 0; i < predIdToClausesMap_->size(); i++)
00594 if ((*predIdToClausesMap_)[i]) (*predIdToClausesMap_)[i]->compress();
00595 predIdToClausesMap_->compress();
00596 }
00597
00598
00599
00600 void printMLN(ostream& out, const Domain* const & domain)
00601 {
00602 int outprec = 6;
00603 out.precision(outprec);
00604 out.setf(ios_base::left, ios_base::adjustfield);
00605
00606 const FormulaAndClausesArray* fncArr = formAndClausesArray_;
00607
00608 Array<int> fncArrIdxs;
00609 for (int i = 0; i < fncArr->size(); i++)
00610 if (!(*fncArr)[i]->hasExist && !(*fncArr)[i]->isExistUnique)
00611 fncArrIdxs.append(i);
00612
00613 for (int i = 0; i < fncArr->size(); i++)
00614 if ((*fncArr)[i]->isExistUnique)
00615 fncArrIdxs.append(i);
00616
00617 for (int i = 0; i < fncArr->size(); i++)
00618 if ((*fncArr)[i]->hasExist)
00619 fncArrIdxs.append(i);
00620
00621
00622 for (int ii = 0; ii < fncArrIdxs.size(); ii++)
00623 {
00624 int i = fncArrIdxs[ii];
00625 double totalWt = 0;
00626 IndexClauseHashArray* indexClauses = (*fncArr)[i]->indexClauses;
00627 for (int j = 0; j < indexClauses->size(); j++)
00628 {
00629 Clause* c = (*indexClauses)[j]->clause;
00630 totalWt += c->getWt()/getNumParentFormulas(c);
00631 }
00632
00633 out.width(0); out << "// "; out.width(outprec);
00634 out << totalWt << " " << (*fncArr)[i]->formula << endl;
00635
00636 if ((*fncArr)[i]->hasExist || (*fncArr)[i]->isExistUnique)
00637 out << totalWt << " " << (*fncArr)[i]->formula <<endl;
00638 else
00639 {
00640
00641 for (int j = 0; j < indexClauses->size(); j++)
00642 {
00643 Clause* c = (*indexClauses)[j]->clause;
00644 out.width(outprec);
00645 out << c->getWt()/getNumParentFormulas(c) << " ";
00646 c->printWithoutWtWithStrVar(out, domain);
00647 out << endl;
00648 }
00649 }
00650 out << endl;
00651 }
00652 }
00653
00654
00655
00656
00657 void printMLNNonExistFormulas(ostream& out, const Domain* const & domain)
00658 {
00659 int outprec = 6;
00660 out.precision(outprec);
00661 out.setf(ios_base::left, ios_base::adjustfield);
00662
00663
00664 const FormulaAndClausesArray* fncArr = formAndClausesArray_;
00665 for (int i = 0; i < fncArr->size(); i++)
00666 {
00667 if ((*fncArr)[i]->hasExist || (*fncArr)[i]->isExistUnique) continue;
00668
00669 double totalWt = 0;
00670 IndexClauseHashArray* indexClauses = (*fncArr)[i]->indexClauses;
00671 for (int j = 0; j < indexClauses->size(); j++)
00672 {
00673 Clause* c = (*indexClauses)[j]->clause;
00674
00675 totalWt
00676 += c->getWt()/getNumNonExistNonExistUniqueParentFormulas(c);
00677 }
00678
00679 out.width(0); out << "// "; out.width(outprec);
00680 out << totalWt << " " << (*fncArr)[i]->formula << endl;
00681
00682
00683
00684 for (int j = 0; j < indexClauses->size(); j++)
00685 {
00686 Clause* c = (*indexClauses)[j]->clause;
00687 out.width(outprec);
00688 out << c->getWt()/getNumNonExistNonExistUniqueParentFormulas(c)
00689 << " ";
00690 c->printWithoutWtWithStrVar(out, domain);
00691 out << endl;
00692 }
00693 out << endl;
00694 }
00695 }
00696
00697
00698
00699
00700 void printMLNClausesFormulas(ostream& out, const Domain* const & domain,
00701 const bool& includeIdx)
00702 {
00703 int idx = 0;
00704 int* startIdx = (includeIdx) ? &idx : NULL;
00705 bool includeExistClauses = false;
00706 bool divideWtAmongExistFormulas = true;
00707 bool sortByLen = true;
00708 printClausesWithWeights(out, domain, startIdx, includeExistClauses,
00709 sortByLen, divideWtAmongExistFormulas);
00710 printExistOrExistUniqueFormulasWithWeights(out, startIdx);
00711 }
00712
00713
00714
00715
00716 void printClausesWithWeights(ostream& out, const Domain* const & domain,
00717 int* const & startIdx = NULL,
00718 const bool& includeExistClauses=true,
00719 const bool& sortByLen=false,
00720 const bool& divWtAmongExistFormulas=false) const
00721 {
00722 Array<Clause*> ca;
00723 for (int i = 0; i < clauses_->size(); i++)
00724 {
00725 if ( !includeExistClauses &&
00726 !clauseInNonExistAndNonExistUniqueFormulaCNF(i) ) continue;
00727 ca.append((*clauses_)[i]);
00728 }
00729
00730 if (sortByLen) Clause::sortByLen(ca);
00731 ClauseHashArray cha;
00732 for (int i = 0; i < ca.size(); i++) cha.append(ca[i]);
00733
00734 printClausesWithWeights(out, domain, &cha,startIdx,divWtAmongExistFormulas);
00735 }
00736
00737
00738 void printClausePriorMeans(ostream& out, const Domain* const & domain)
00739 {
00740 out.setf(ios_base::left, ios_base::adjustfield);
00741 out.precision(6);
00742 assert(clauseInfos_->size() == clauses_->size());
00743 for (int i = 0; i < clauses_->size(); i++)
00744 {
00745 out << i << ": "; out.width(14);
00746 out << (*clauseInfos_)[i]->priorMean; out.width(0); out << " ";
00747 (*clauses_)[i]->printWithoutWtWithStrVar(out, domain);
00748 out << endl;
00749 }
00750 out.width(0);
00751 }
00752
00753
00754 void printFormulaPriorMeans(ostream& out)
00755 {
00756 out.setf(ios_base::left, ios_base::adjustfield);
00757 out.precision(6);
00758 for (int i = 0; i < formAndClausesArray_->size(); i++)
00759 {
00760 FormulaAndClauses* fnc = (*formAndClausesArray_)[i];
00761 out << i << ": "; out.width(14);
00762 out << fnc->priorMean; out.width(0);
00763 out << " " << fnc->formula << endl;
00764 }
00765 out.width(0);
00766 }
00767
00768
00769 private:
00770 void appendClauseInfo(const Clause* const & clause, const int& clauseIdx,
00771 int* const& formulaIdx, int* const& clauseIdxForFormula)
00772 {
00773 assert(clauseInfos_->size() == clauseIdx);
00774
00775 MLNClauseInfo* ci = new MLNClauseInfo(clauseInfos_->size());
00776 clauseInfos_->append(ci);
00777
00778
00779 Array<PredIdClauseIndex*>& piciArr = ci->predIdsClauseIndexes;
00780 hash_set<int> seenPredIds;
00781 const Array<Predicate*>* preds = clause->getPredicates();
00782 for (int i = 0; i < preds->size(); i++)
00783 {
00784 int predId = (*preds)[i]->getId();
00785
00786 if (seenPredIds.find(predId) != seenPredIds.end()) continue;
00787 seenPredIds.insert(predId);
00788
00789 if (predId >= predIdToClausesMap_->size())
00790 predIdToClausesMap_->growToSize(predId+1, NULL);
00791 Array<IndexClause*>*& icArr = (*predIdToClausesMap_)[predId];
00792 if (icArr == NULL) icArr = new Array<IndexClause*>;
00793 IndexClause* ic = new IndexClause(icArr->size(), (Clause*)clause);
00794 icArr->append(ic);
00795
00796 piciArr.append(new PredIdClauseIndex(predId, &(ic->index)));
00797 }
00798
00799 updateClauseInfo(clauseIdx, formulaIdx, clauseIdxForFormula);
00800 }
00801
00802
00803 void updateClauseInfo(const int& clauseIdx, int* const & formulaIdx,
00804 int* const & clauseIdxForFormula)
00805 {
00806 MLNClauseInfo* clauseInfo = (*clauseInfos_)[clauseIdx];
00807
00808 assert(*clauseIdxForFormula >= 0);
00809 Array<FormulaClauseIndexes*>& fciArr = clauseInfo->formulaClauseIndexes;
00810
00811 fciArr.append(new FormulaClauseIndexes(formulaIdx, clauseIdxForFormula));
00812 }
00813
00814
00815
00816 int getNumParentFormulas(const Clause* const & c) const
00817 {
00818 int i = findClauseIdx(c);
00819 if (i < 0) return -1;
00820 return (*clauseInfos_)[i]->formulaClauseIndexes.size();
00821 }
00822
00823
00824 int getNumNonExistNonExistUniqueParentFormulas(const Clause* const & c) const
00825 {
00826 int i = findClauseIdx(c);
00827 if (i < 0) return -1;
00828 Array<FormulaClauseIndexes*>& fciArr
00829 = (*clauseInfos_)[i]->formulaClauseIndexes;
00830 int n = 0;
00831 for (int i = 0; i < fciArr.size(); i++)
00832 {
00833 int fidx = *(fciArr[i]->formulaIndex);
00834 FormulaAndClauses* fnc = (*formAndClausesArray_)[fidx];
00835 if (!fnc->hasExist && !fnc->isExistUnique) n++;
00836 }
00837 return n;
00838 }
00839
00840
00841 int getNumExistOrExistUniqueParentFormulas(const Clause* const & c) const
00842 {
00843 int i = findClauseIdx(c);
00844 if (i < 0) return -1;
00845 Array<FormulaClauseIndexes*>& fciArr
00846 = (*clauseInfos_)[i]->formulaClauseIndexes;
00847 int n = 0;
00848 for (int i = 0; i < fciArr.size(); i++)
00849 {
00850 int fidx = *(fciArr[i]->formulaIndex);
00851 FormulaAndClauses* fnc = (*formAndClausesArray_)[fidx];
00852 if (fnc->hasExist || fnc->isExistUnique) n++;
00853 }
00854 return n;
00855 }
00856
00857
00858 void printClausesWithWeights(ostream& out, const Domain* const & domain,
00859 const ClauseHashArray* const & clauses,
00860 int* const & startIdx,
00861 const bool& divideWithAmongExistFormulas) const
00862 {
00863 out.setf(ios_base::left, ios_base::adjustfield);
00864 int i;
00865 for (i = 0; i < clauses->size(); i++)
00866 {
00867 if (startIdx) { out << (*(startIdx))++ << ": "; out.width(14); }
00868 else { out.width(10); }
00869
00870 double wt = (*clauses)[i]->getWt();
00871 if (divideWithAmongExistFormulas)
00872 wt /= 1+getNumExistOrExistUniqueParentFormulas((*clauses)[i]);
00873
00874 out << wt; out.width(0); out << " ";
00875 (*clauses)[i]->printWithoutWtWithStrVar(out, domain);
00876 out << endl;
00877 }
00878 out.width(0);
00879 }
00880
00881
00882 void printExistOrExistUniqueFormulasWithWeights(ostream& out,
00883 int* const & startIdx=NULL)
00884 {
00885 int i;
00886 for (i = 0; i < formAndClausesArray_->size(); i++)
00887 {
00888 if (!(*formAndClausesArray_)[i]->hasExist &&
00889 !(*formAndClausesArray_)[i]->isExistUnique) continue;
00890 double totalWt = 0;
00891 IndexClauseHashArray* indexClauses
00892 = (*formAndClausesArray_)[i]->indexClauses;
00893 for (int j = 0; j < indexClauses->size(); j++)
00894 {
00895 Clause* c = (*indexClauses)[j]->clause;
00896 totalWt += c->getWt()/getNumParentFormulas(c);
00897 }
00898
00899 if (startIdx) { out << (*(startIdx))++ << ": "; out.width(14); }
00900 else { out.width(10); }
00901 out << totalWt; out.width(0); out << " "
00902 << (*formAndClausesArray_)[i]->formula <<endl;
00903 }
00904 }
00905
00906
00907 private:
00908 ClauseHashArray* clauses_;
00909 Array<MLNClauseInfo*>* clauseInfos_;
00910 FormulaAndClausesArray* formAndClausesArray_;
00911
00912
00913
00914
00915
00916 Array<Array<IndexClause*>*>* predIdToClausesMap_;
00917
00918 };
00919
00920 #endif