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 HVARIABLESTATE_H_
00067 #define HVARIABLESTATE_H_
00068
00069 #include "mrf.h"
00070 #include "Polynomial.h"
00071 #include "lbfgsp.h"
00072 #include "logsigmoid.h"
00073 #include "logichelper.h"
00074 #include <set>
00075
00076 #define UNSOLVABLE 1010101 // This flag indicates that the constraint is not solvable.
00077 #define FLIPDIS 1010102 // This flag indicates that the discrete part of the constraint needs to be flipped
00078
00079 #define CANNOTSATCURRENT -1000000
00080
00081 const bool hvsdebug = false;
00082 const bool wjhvsdbg = false;
00083
00084 const double SMALLVALUE = 0.0000000000001;
00085 double ABSBIG = 1111111111;
00086
00087 #define MIN(x,y) (x<y)?x:y
00088 #define MAX(x,y) (x>y)?x:y
00089
00090 enum UNSATTYPE
00091 {
00092 UNSAT_DIS0,
00093 UNSAT_DIS1,
00094 UNSAT_UNKNOWN
00095 };
00096
00097 using namespace std;
00098
00119
00120 class HVariableState
00121 {
00122 public:
00141 HVariableState(GroundPredicateHashArray* const& unknownQueries,
00142 GroundPredicateHashArray* const& knownQueries,
00143 Array<TruthValue>* const & knownQueryValues,
00144 const Array<int>* const & allPredGndingsAreQueries,
00145 const bool& markHardGndClauses,
00146 const bool& trackParentClauseWts,
00147 const MLN* const & mln, const Domain* const & domain,
00148 const bool& lazy)
00149 {
00150 stillActivating_ = true;
00151 Timer timer;
00152 double startTime = timer.time();
00153
00154 if (hvsdebug)
00155 {
00156 cout << "from hybrid vs" << endl;
00157 }
00158 this->mln_ = (MLN*)mln;
00159 this->domain_ = (Domain*)domain;
00160 this->lazy_ = lazy;
00161
00162
00163 bInitFromEvi_ = false;
00164 baseNumAtoms_ = 0;
00165 activeAtoms_ = 0;
00166 numFalseClauses_ = 0;
00167 costOfFalseClauses_ = 0.0;
00168 weightSumDis_ = 0.0;
00169 weightSumCont_ = 0.0;
00170 costOfTotalFalseConstraints_ = 0.0;
00171 totalFalseConstraintNum_ = 0;
00172 costHybridFalseConstraint_ = 0.0;
00173 hybridFalseConstraintNum_ = 0;
00174 lowCost_ = LDBL_MAX;
00175 lowBad_ = INT_MAX;
00176 lowCostAll_ = LDBL_MAX;
00177 lowBadAll_ = INT_MAX;
00178 lowCostHybrid_ = LDBL_MAX;
00179 lowBadHybrid_ = INT_MAX;
00180
00182
00184 hybridClauseNum_ = 0;
00185 hybridFormulaNum_ = 0;
00186
00187
00188 gndClauses_ = new Array<GroundClause*>;
00189 gndPreds_ = new Array<GroundPredicate*>;
00190 bMaxOnly_ = false;
00191
00192
00193 setHardClauseWeight();
00194
00195
00196 if (lazy_)
00197 {
00198
00199 domain_->computeNumNonEvidAtoms();
00200 numNonEvAtoms_ = domain_->getNumNonEvidenceAtoms();
00201
00202 domain_->getDB()->setPerformingInference(true);
00203 clauseLimit_ = INT_MAX;
00204 noApprox_ = false;
00205 haveDeactivated_ = false;
00206
00208
00209
00210
00211 initBlocksRandom();
00212
00213
00214 bool ignoreActivePreds = true;
00215 cout << "Getting initial active atoms ... " << endl;
00216 getActiveClauses(newClauses_, ignoreActivePreds);
00217 cout << "done." << endl;
00218 int defaultCnt = newClauses_.size();
00219 long double defaultCost = 0;
00220
00221 for (int i = 0; i < defaultCnt; i++)
00222 {
00223 if (newClauses_[i]->isHardClause())
00224 defaultCost += hardWt_;
00225 else
00226 defaultCost += abs(newClauses_[i]->getWt());
00227 }
00228
00229
00230 for (int i = 0; i < gndPredHashArray_.size(); i++)
00231 gndPredHashArray_[i]->removeGndClauses();
00232
00233
00234 for (int i = 0; i < newClauses_.size(); i++)
00235 delete newClauses_[i];
00236 newClauses_.clear();
00237
00238 baseNumAtoms_ = gndPredHashArray_.size();
00239 cout << "Number of Baseatoms = " << baseNumAtoms_ << endl;
00240 cout << "Default => Cost\t" << "******\t" << " Clause Cnt\t" << endl;
00241 cout << " " << defaultCost << "\t" << "******\t" << defaultCnt
00242 << "\t" << endl << endl;
00243
00244
00245 for (int i = 0; i < baseNumAtoms_; i++)
00246 {
00247 domain_->getDB()->setActiveStatus(gndPredHashArray_[i], true);
00248 activeAtoms_++;
00249 }
00250
00251
00252 ignoreActivePreds = false;
00253 cout << "Getting initial active clauses ... ";
00254 getActiveClauses(newClauses_, ignoreActivePreds);
00255 cout << "done." << endl;
00256 }
00257
00258 else
00259 {
00260 unePreds_ = unknownQueries;
00261 knePreds_ = knownQueries;
00262 knePredValues_ = knownQueryValues;
00263
00264 int size = 0;
00265 if (unknownQueries) size += unknownQueries->size();
00266 if (knownQueries) size += knownQueries->size();
00267 GroundPredicateHashArray* queries = new GroundPredicateHashArray(size);
00268 if (unknownQueries) queries->append(unknownQueries);
00269 if (knownQueries) queries->append(knownQueries);
00270
00271 mrf_ = new MRF(queries, allPredGndingsAreQueries, domain_,
00272 domain_->getDB(), mln_, true,
00273 trackParentClauseWts, -1);
00274
00275
00276
00277 mrf_->deleteGndPredsGndClauseSets();
00278
00279
00280 delete queries;
00281
00282
00283 newClauses_ = *(Array<GroundClause*>*)mrf_->getGndClauses();
00284
00285
00286
00287 const GroundPredicateHashArray* gndPreds = mrf_->getGndPreds();
00288 for (int i = 0; i < gndPreds->size(); i++)
00289 gndPredHashArray_.append((*gndPreds)[i]);
00290
00291
00292 baseNumAtoms_ = gndPredHashArray_.size();
00293 }
00294
00295
00296
00297
00298
00299
00300 bool initial = true;
00301 addNewClauses(initial);
00302
00303 cout << "[VS] ";
00304 Timer::printTime(cout,timer.time()-startTime);
00305 cout << endl;
00306 cout << ">>> DONE: Initial num. of clauses: " << getNumClauses() << endl;
00307 }
00308
00313 ~HVariableState()
00314 {
00315 if (lazy_)
00316 {
00317 if (gndClauses_)
00318 for (int i = 0; i < gndClauses_->size(); i++)
00319 delete (*gndClauses_)[i];
00320
00321 for (int i = 0; i < gndPredHashArray_.size(); i++)
00322 {
00323 gndPredHashArray_[i]->removeGndClauses();
00324 delete gndPredHashArray_[i];
00325 }
00326 }
00327 else
00328 {
00329
00330 if (mrf_)
00331 {
00332 delete mrf_;
00333 mrf_ = NULL;
00334 }
00335
00336
00337
00338 for (int i = 0; i < contsolvers_.size(); i++)
00339 {
00340 delete contsolvers_[i];
00341 }
00342 }
00343 }
00344
00352 void addNewClauses(bool initial)
00353 {
00354 if (initial) addNewClauses(ADD_CLAUSE_INITIAL, newClauses_);
00355 else addNewClauses(ADD_CLAUSE_REGULAR, newClauses_);
00356 }
00357
00364 void addNewClauses(int addType, Array<GroundClause*> & clauses)
00365 {
00366 if (hvsdebug)
00367 cout << "Adding " << clauses.size() << " new clauses.." << endl;
00368
00369
00370 if (!useThreshold_ &&
00371 (addType == ADD_CLAUSE_DEAD || addType == ADD_CLAUSE_SAT))
00372 {
00373 cout << ">>> [ERR] add_dead/sat but useThreshold_ is false" << endl;
00374 exit(0);
00375 }
00376
00377
00378 int oldNumClauses = getNumClauses();
00379 int oldNumAtoms = getNumAtoms();
00380
00381
00382 for (int i = 0; i < clauses.size(); i++)
00383 {
00384 gndClauses_->append(clauses[i]);
00385 clauses[i]->appendToGndPreds(&gndPredHashArray_);
00386 }
00387
00388 gndPreds_->growToSize(gndPredHashArray_.size());
00389
00390 int numAtoms = getNumAtoms();
00391 int numClauses = getNumClauses();
00392
00393 if (numAtoms == oldNumAtoms && numClauses == oldNumClauses) return;
00394
00395 if (hvsdebug) cout << "Clauses: " << numClauses << endl;
00396
00397 atom_.growToSize(numAtoms + 1, false);
00398
00399 makeCost_.growToSize(numAtoms + 1, 0.0);
00400 breakCost_.growToSize(numAtoms + 1, 0.0);
00401 lowAtom_.growToSize(numAtoms + 1, false);
00402 fixedAtom_.growToSize(numAtoms + 1, 0);
00403
00404
00405 for (int i = oldNumAtoms; i < gndPredHashArray_.size(); i++)
00406 {
00407 (*gndPreds_)[i] = gndPredHashArray_[i];
00408
00409 if (hvsdebug)
00410 {
00411 cout << "New pred " << i + 1 << ": ";
00412 (*gndPreds_)[i]->print(cout, domain_);
00413 cout << endl;
00414 }
00415
00416 lowAtom_[i + 1] = atom_[i + 1] =
00417 (domain_->getDB()->getValue((*gndPreds_)[i]) == TRUE) ? true : false;
00418 }
00419 clauses.clear();
00420
00421 clause_.growToSize(numClauses);
00422 clauseCost_.growToSize(numClauses);
00423 falseClause_.growToSize(numClauses);
00424 whereFalse_.growToSize(numClauses);
00425 numTrueLits_.growToSize(numClauses);
00426 falseClauseLow_.growToSize(numClauses);
00427 watch1_.growToSize(numClauses);
00428 watch2_.growToSize(numClauses);
00429 isSatisfied_.growToSize(numClauses, false);
00430 deadClause_.growToSize(numClauses, false);
00431 threshold_.growToSize(numClauses, false);
00432 occurence_.growToSize(2*numAtoms + 1);
00433
00434 for (int i = oldNumClauses; i < numClauses; i++)
00435 {
00436 GroundClause* gndClause = (*gndClauses_)[i];
00437
00438 if (hvsdebug)
00439 {
00440 cout << "New clause " << i << ": ";
00441 gndClause->print(cout, domain_, &gndPredHashArray_);
00442 cout << endl;
00443 }
00444
00445
00446 if (gndClause->isHardClause()) threshold_[i] = RAND_MAX;
00447 else
00448 {
00449 double w = gndClause->getWt();
00450 threshold_[i] = RAND_MAX*(1 - exp(-abs(w)));
00451 if (hvsdebug)
00452 {
00453 cout << "Weight: " << w << endl;
00454 }
00455 }
00456 if (hvsdebug)
00457 cout << "Threshold: " << threshold_[i] << endl;
00458
00459 int numGndPreds = gndClause->getNumGroundPredicates();
00460 clause_[i].growToSize(numGndPreds);
00461 for (int j = 0; j < numGndPreds; j++)
00462 {
00463 int lit = gndClause->getGroundPredicateIndex(j);
00464 clause_[i][j] = lit;
00465 int litIdx = 2*abs(lit) - (lit > 0);
00466 occurence_[litIdx].append(i);
00467 }
00468
00469
00470 if (inferenceMode_==MODE_SAMPLESAT)
00471 {
00472 if (gndClause->getWt()>0) clauseCost_[i] = 1;
00473 else clauseCost_[i] = -1;
00474 }
00475 else if (gndClause->isHardClause())
00476 clauseCost_[i] = hardWt_;
00477 else
00478 clauseCost_[i] = gndClause->getWt();
00479
00480
00481 if (inferenceMode_ == MODE_HARD && !gndClause->isHardClause())
00482 {
00483
00484 deadClause_[i] = true;
00485 }
00486 }
00487
00488 if (addType == ADD_CLAUSE_DEAD)
00489 {
00490
00491 for (int i = oldNumClauses; i < numClauses; i++)
00492 {
00493 deadClause_[i] = true;
00494 }
00495 }
00496 else if (addType == ADD_CLAUSE_SAT)
00497 {
00498
00499 for (int i = oldNumClauses; i < numClauses; i++)
00500 {
00501 isSatisfied_[i]=true;
00502 }
00503 }
00504 else if (addType == ADD_CLAUSE_REGULAR)
00505 {
00506 if (useThreshold_)
00507 killClauses(oldNumClauses);
00508 else
00509 initMakeBreakCostWatch(oldNumClauses);
00510 }
00511
00512 if (hvsdebug)
00513 cout << "Done adding new clauses.." << endl;
00514 }
00515
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00654 void init()
00655 {
00656 if (hvsdebug)
00657 {
00658 cout << "entering init" << endl;
00659 cout << "discrete clause number: " << getNumClauses()
00660 << ", hybrid clause number: " << hybridClauseNum_ << endl;
00661 }
00662
00663 for (int i = 0; i < getNumClauses(); i++)
00664 {
00665 numTrueLits_[i] = 0;
00666 falseClause_[i] = 0;
00667 whereFalse_[i] = 0;
00668 }
00669
00670 totalFalseConstraintNum_ = 0;
00671 costOfTotalFalseConstraints_ = 0.0;
00672 numFalseClauses_ = 0;
00673 costOfFalseClauses_ = 0.0;
00674 hybridFalseConstraintNum_ = 0;
00675 costHybridFalseConstraint_ = 0.0;
00676
00677 weightSumCont_ = 0.0;
00678 weightSumDis_ = 0.0;
00679
00680
00681 initMakeBreakCostWatch();
00682 initMakeBreakCostWatchCont();
00683 if (hvsdebug)
00684 {
00685 cout << "leaving init" << endl;
00686 }
00687 }
00688
00689 void initLowState()
00690 {
00691 lowCost_ = LDBL_MAX;
00692 lowBad_ = INT_MAX;
00693 lowCostAll_ = LDBL_MAX;
00694 lowBadAll_ = INT_MAX;
00695 lowCostHybrid_ = LDBL_MAX;
00696 lowBadHybrid_ = INT_MAX;
00697 }
00698
00699
00700 void setInitFromEvi(bool bInitFromEvi)
00701 {
00702 bInitFromEvi_ = bInitFromEvi;
00703 }
00704
00710 void initRandom()
00711 {
00712
00713 if (!bInitFromEvi_)
00714 {
00715
00716 for (int i = 1; i <= baseNumAtoms_; i++)
00717 {
00718 if (hvsdebug) cout << "Atom " << i << " not in block" << endl;
00719 setValueOfAtom(i, random() % 2, false, -1);
00720 }
00721
00722
00723 initContinuousVariableRandom();
00724
00725 if (hvsdebug)
00726 {
00727 cout << "Randomly initializing dis&cont variables to:" << endl;
00728 for(int i = 0; i < baseNumAtoms_; i++)
00729 {
00730 printDisAtom(i+1, cout);
00731 }
00732
00733 for(int i = 0; i < contAtomNum_; i++)
00734 {
00735 printContAtom(i+1, cout);
00736 }
00737 }
00738 }
00739 else
00740 {
00741 atom_.copyFrom(atomEvi_);
00742 contAtoms_.copyFrom(contAtomsEvi_);
00743 }
00744
00745
00746 init();
00747 }
00748
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00802 void initBlocksRandom()
00803 {
00804 if (hvsdebug)
00805 {
00806 cout << "Initializing blocks randomly" << endl;
00807 cout << "Num. of blocks: " << domain_->getNumPredBlocks() << endl;
00808 }
00809
00810 for (int i = 0; i < domain_->getNumPredBlocks(); i++)
00811 {
00812 int trueFixedAtom = getTrueFixedAtomInBlock(i);
00813
00814 if (trueFixedAtom >= 0)
00815 {
00816 if (hvsdebug)
00817 {
00818 cout << "True fixed atom " << trueFixedAtom << " in block "
00819 << i << endl;
00820 }
00821 setOthersInBlockToFalse(trueFixedAtom, i);
00822 continue;
00823 }
00824
00825
00826 if (domain_->getBlockEvidence(i))
00827 {
00828 if (hvsdebug) cout << "Block evidence in block " << i << endl;
00829
00830 setOthersInBlockToFalse(-1, i);
00831 continue;
00832 }
00833
00834
00835 bool ok = false;
00836 while (!ok)
00837 {
00838 const Predicate* pred = domain_->getRandomPredInBlock(i);
00839 GroundPredicate* gndPred = new GroundPredicate((Predicate*)pred);
00840 int atomIdx = gndPredHashArray_.find(gndPred);
00841 delete pred;
00842
00843 assert(lazy_ || atomIdx >= 0);
00844
00845 if (atomIdx == -1)
00846 {
00847 atomIdx = gndPredHashArray_.append(gndPred);
00848 bool initial = false;
00849 addNewClauses(initial);
00850 ok = true;
00851 }
00852
00853 else
00854 {
00855 delete gndPred;
00856 if (fixedAtom_[atomIdx + 1] == 0)
00857 {
00858 if (hvsdebug) cout << "Atom " << atomIdx + 1
00859 << " chosen in block " << i << endl;
00860 ok = true;
00861 }
00862 else
00863 {
00864 if (hvsdebug) cout << "Atom " << atomIdx + 1
00865 << " is fixed to " << fixedAtom_[atomIdx + 1]
00866 << endl;
00867
00868 continue;
00869 }
00870 }
00871 bool activate = false;
00872 setValueOfAtom(atomIdx + 1, true, activate, i);
00873 setOthersInBlockToFalse(atomIdx, i);
00874 }
00875 }
00876 if (hvsdebug) cout << "Done initializing blocks randomly" << endl;
00877 }
00878
00879
00887 void initMakeBreakCostWatch()
00888 {
00889 if (hvsdebug)
00890 {
00891 cout << "entering intiMakeBreakCostWatch()" << endl;
00892 }
00893 assert(makeCost_.size() == breakCost_.size());
00894
00895 for (int i = 0; i < makeCost_.size(); i++)
00896 {
00897 makeCost_[i] = breakCost_[i] = 0.0;
00898 }
00899 initMakeBreakCostWatch(0);
00900 if (hvsdebug)
00901 {
00902 cout << "leaving intiMakeBreakCostWatch()" << endl;
00903 }
00904 }
00905
00906 void printDisAtom(int atomIdx, ostream& os)
00907 {
00908 os << "<"; (*gndPreds_)[atomIdx - 1]->print(os, domain_); os << "," << atom_[atomIdx] <<">";
00909 }
00910
00911
00912 void printDisClause(int i, ostream& os)
00913 {
00914 GroundClause* pC = getGndClause(i);
00915 if (pC->isHardClause())
00916 {
00917 os << "H " ;
00918 }
00919 else
00920 {
00921 os << clauseCost_[i] << " ";
00922 }
00923 pC->printWithoutWtWithStrVar(os, domain_, &gndPredHashArray_);
00924 os << " Atoms are: ";
00925 for(int j = 0;j < clause_[i].size(); j++)
00926 {
00927 int predIdx = abs(clause_[i][j]);
00928 printDisAtom(predIdx, os);
00929 os << ", ";
00930 }
00931 os << endl;
00932 }
00933
00934 void initMakeBreakCostWatch(const int& startClause)
00935 {
00936 if (hvsdebug)
00937 {
00938 cout << "entering intiMakeBreakCostWatch(int)" << endl;
00939 }
00940 int theTrueLit = -1;
00941
00942 for (int i = startClause; i < getNumClauses(); i++)
00943 {
00944
00945 if (deadClause_[i]) continue;
00946 int trueLit1 = 0;
00947 int trueLit2 = 0;
00948 long double cost = clauseCost_[i];
00949 numTrueLits_[i] = 0;
00950 for (int j = 0; j < getClauseSize(i); j++)
00951 {
00952 if (isTrueLiteral(clause_[i][j]))
00953 {
00954 numTrueLits_[i]++;
00955 theTrueLit = abs(clause_[i][j]);
00956 if (!trueLit1) trueLit1 = theTrueLit;
00957 else if (trueLit1 && !trueLit2) trueLit2 = theTrueLit;
00958 }
00959 }
00960 if (numTrueLits_[i] > 0)
00961 {
00962 weightSumDis_ += clauseCost_[i];
00963 }
00964
00965
00966
00967 if ((numTrueLits_[i] == 0 && cost > 0) ||
00968 (numTrueLits_[i] > 0 && cost < 0))
00969 {
00970 whereFalse_[i] = numFalseClauses_;
00971 falseClause_[numFalseClauses_] = i;
00972 numFalseClauses_++;
00973 totalFalseConstraintNum_++;
00974 costOfFalseClauses_ += abs(cost);
00975 costOfTotalFalseConstraints_ += abs(cost);
00976
00977
00978 if (numTrueLits_[i] == 0)
00979 {
00980 for (int j = 0; j < getClauseSize(i); j++)
00981 {
00982 makeCost_[abs(clause_[i][j])] += cost;
00983 }
00984 }
00985
00986
00987 if (numTrueLits_[i] == 1)
00988 {
00989
00990 makeCost_[theTrueLit] -= cost;
00991 watch1_[i] = theTrueLit;
00992 }
00993 else if (numTrueLits_[i] > 1)
00994 {
00995 watch1_[i] = trueLit1;
00996 watch2_[i] = trueLit2;
00997 }
00998 }
00999
01000 else if (numTrueLits_[i] == 1 && cost > 0)
01001 {
01002 breakCost_[theTrueLit] += cost;
01003 watch1_[i] = theTrueLit;
01004 }
01005
01006 else if (cost > 0)
01007 {
01008 watch1_[i] = trueLit1;
01009 watch2_[i] = trueLit2;
01010 }
01011
01012 else if (numTrueLits_[i] == 0 && cost < 0)
01013 {
01014 for (int j = 0; j < getClauseSize(i); j++)
01015 breakCost_[abs(clause_[i][j])] -= cost;
01016 }
01017 }
01018 if (hvsdebug)
01019 {
01020 cout << "leaving intiMakeBreakCostWatch(int)" << endl;
01021 }
01022 }
01023
01024 int getNumAtoms() { return gndPreds_->size(); }
01025
01026 int getNumClauses() { return gndClauses_->size(); }
01027
01028 int getNumDeadClauses()
01029 {
01030 int count = 0;
01031 for (int i = 0; i < deadClause_.size(); i++)
01032 if (deadClause_[i]) count++;
01033 return count;
01034 }
01035
01041 int getIndexOfAtomInRandomFalseClause()
01042 {
01043 if (numFalseClauses_ == 0) return NOVALUE;
01044 int clauseIdx = falseClause_[random()%numFalseClauses_];
01045
01046 if (clauseCost_[clauseIdx] > 0)
01047 return abs(clause_[clauseIdx][random()%getClauseSize(clauseIdx)]);
01048
01049 else
01050 return getRandomTrueLitInClause(clauseIdx);
01051 }
01052
01057 int getRandomFalseClauseIndex()
01058 {
01059 if (numFalseClauses_ == 0) return NOVALUE;
01060 return falseClause_[random()%numFalseClauses_];
01061 }
01062
01067 int getNumFalseClauses()
01068 {
01069 return numFalseClauses_;
01070 }
01075 long double getCostOfFalseClauses()
01076 {
01077 return costOfFalseClauses_;
01078 }
01079
01080 const double getMaxClauseWeight()
01081 {
01082 double maxWeight = 0.0;
01083 for (int i = 0; i < getNumClauses(); i++)
01084 {
01085 double weight = abs(clauseCost_[i]);
01086 if (weight > maxWeight) maxWeight = weight;
01087 }
01088 return maxWeight;
01089 }
01090
01097 bool getValueOfAtom(const int& atomIdx)
01098 {
01099 return atom_[atomIdx];
01100 }
01101
01108 bool getValueOfLowAtom(const int& atomIdx)
01109 {
01110 return lowAtom_[atomIdx];
01111 }
01112
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01157 void setValueOfAtom(const int& atomIdx, const bool& value,
01158 const bool& activate, const int& blockIdx)
01159 {
01160
01161 if (atom_[atomIdx] == value) return;
01162 if (hvsdebug) cout << "Setting value of atom " << atomIdx
01163 << " to " << value << endl;
01164
01165 GroundPredicate* p = gndPredHashArray_[atomIdx - 1];
01166 if (value)
01167 domain_->getDB()->setValue(p, TRUE);
01168 else
01169 domain_->getDB()->setValue(p, FALSE);
01170
01171
01172 if (activate && lazy_ && !isActive(atomIdx))
01173 {
01174 bool ignoreActivePreds = false;
01175 bool groundOnly = false;
01176 activateAtom(atomIdx, ignoreActivePreds, groundOnly);
01177 }
01178 atom_[atomIdx] = value;
01179
01180
01181 if (blockIdx > -1 && value)
01182 {
01183 Predicate* pred = p->createEquivalentPredicate(domain_);
01184 domain_->setTruePredInBlock(blockIdx, pred);
01185 if (hvsdebug)
01186 {
01187 cout << "Set true pred in block " << blockIdx << " to ";
01188 pred->printWithStrVar(cout, domain_);
01189 cout << endl;
01190 }
01191 }
01192 }
01193
01197 Array<int>& getNegOccurenceArray(const int& atomIdx)
01198 {
01199 int litIdx = 2*atomIdx;
01200 return getOccurenceArray(litIdx);
01201 }
01202
01206 Array<int>& getPosOccurenceArray(const int& atomIdx)
01207 {
01208 int litIdx = 2*atomIdx - 1;
01209 return getOccurenceArray(litIdx);
01210 }
01211
01218 void flipAtom(const int& toFlip, const int& blockIdx)
01219 {
01220 bool toFlipValue = getValueOfAtom(toFlip);
01221 register int clauseIdx;
01222 int sign;
01223 int oppSign;
01224 int litIdx;
01225 if (toFlipValue)
01226 sign = 1;
01227 else
01228 sign = 0;
01229 oppSign = sign ^ 1;
01230
01231 flipAtomValue(toFlip, blockIdx);
01232
01233
01234 litIdx = 2*toFlip - sign;
01235 Array<int>& posOccArray = getOccurenceArray(litIdx);
01236 for (int i = 0; i < posOccArray.size(); i++)
01237 {
01238 clauseIdx = posOccArray[i];
01239
01240 if (deadClause_[clauseIdx]) continue;
01241
01242 int numTrueLits = decrementNumTrueLits(clauseIdx);
01243 long double cost = getClauseCost(clauseIdx);
01244 int watch1 = getWatch1(clauseIdx);
01245 int watch2 = getWatch2(clauseIdx);
01246
01247
01248
01249 if (numTrueLits == 0)
01250 {
01251 weightSumDis_ -= clauseCost_[clauseIdx];
01252
01253 if (cost > 0)
01254 {
01255
01256 addFalseClause(clauseIdx);
01257
01258 addBreakCost(toFlip, -cost);
01259
01260 addMakeCostToAtomsInClause(clauseIdx, cost);
01261 }
01262
01263 else
01264 {
01265 assert(cost < 0);
01266
01267 removeFalseClause(clauseIdx);
01268
01269 addBreakCostToAtomsInClause(clauseIdx, -cost);
01270
01271 addMakeCost(toFlip, cost);
01272 }
01273 }
01274
01275
01276 else if (numTrueLits == 1)
01277 {
01278 if (watch1 == toFlip)
01279 {
01280 assert(watch1 != watch2);
01281 setWatch1(clauseIdx, watch2);
01282 watch1 = getWatch1(clauseIdx);
01283 }
01284
01285
01286 if (cost > 0)
01287 {
01288 addBreakCost(watch1, cost);
01289 }
01290
01291 else
01292 {
01293 assert(cost < 0);
01294 addMakeCost(watch1, -cost);
01295 }
01296 }
01297
01298
01299 else
01300 {
01301
01302 if (watch1 == toFlip)
01303 {
01304
01305 int diffTrueLit = getTrueLiteralOtherThan(clauseIdx, watch1, watch2);
01306 setWatch1(clauseIdx, diffTrueLit);
01307 }
01308
01309 else if (watch2 == toFlip)
01310 {
01311
01312 int diffTrueLit = getTrueLiteralOtherThan(clauseIdx, watch1, watch2);
01313 setWatch2(clauseIdx, diffTrueLit);
01314 }
01315 }
01316 }
01317
01318
01319 litIdx = 2*toFlip - oppSign;
01320 Array<int>& negOccArray = getOccurenceArray(litIdx);
01321 for (int i = 0; i < negOccArray.size(); i++)
01322 {
01323 clauseIdx = negOccArray[i];
01324
01325 if (deadClause_[clauseIdx]) continue;
01326
01327 int numTrueLits = incrementNumTrueLits(clauseIdx);
01328 long double cost = getClauseCost(clauseIdx);
01329 int watch1 = getWatch1(clauseIdx);
01330
01331
01332
01333 if (numTrueLits == 1)
01334 {
01335 weightSumDis_ += clauseCost_[clauseIdx];
01336
01337 if (cost > 0)
01338 {
01339
01340 removeFalseClause(clauseIdx);
01341
01342 addBreakCost(toFlip, cost);
01343
01344 addMakeCostToAtomsInClause(clauseIdx, -cost);
01345 }
01346
01347 else
01348 {
01349 assert(cost < 0);
01350
01351 addFalseClause(clauseIdx);
01352
01353 addBreakCostToAtomsInClause(clauseIdx, cost);
01354
01355 addMakeCost(toFlip, -cost);
01356 }
01357
01358 setWatch1(clauseIdx, toFlip);
01359 }
01360
01361
01362 else if (numTrueLits == 2)
01363 {
01364 if (cost > 0)
01365 {
01366
01367
01368 addBreakCost(watch1, -cost);
01369 }
01370 else
01371 {
01372
01373 assert(cost < 0);
01374
01375 addMakeCost(watch1, cost);
01376 }
01377
01378
01379 setWatch2(clauseIdx, toFlip);
01380 }
01381 }
01382 }
01383
01388
01389
01390
01391
01392
01393
01394
01395
01403 void flipAtomValue(const int& atomIdx, const int& blockIdx)
01404 {
01405 bool opposite = !atom_[atomIdx];
01406 bool activate = true;
01407 setValueOfAtom(atomIdx, opposite, activate, blockIdx);
01408 }
01409
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01447 bool activateAtom(const int& atomIdx, const bool& ignoreActivePreds,
01448 const bool& groundOnly)
01449 {
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459 if (lazy_ && !isActive(atomIdx))
01460 {
01461 if (hvsdebug)
01462 {
01463 cout << "\tActivating ";
01464 gndPredHashArray_[atomIdx-1]->print(cout,domain_);
01465 cout << " " <<
01466 domain_->getDB()->getActiveStatus(gndPredHashArray_[atomIdx-1]) << endl;
01467 }
01468
01469
01470 bool needToFlipBack = false;
01471 if (!atom_[atomIdx])
01472 {
01473 bool activate = false;
01474 setValueOfAtom(atomIdx, true, activate, -1);
01475 updateMakeBreakCostAfterFlip(atomIdx);
01476 needToFlipBack = true;
01477 }
01478
01479
01480 Predicate* p =
01481 gndPredHashArray_[atomIdx - 1]->createEquivalentPredicate(domain_);
01482
01483 bool isFixed = false;
01484 Array<GroundClause*> unsatClauses;
01485 Array<GroundClause*> deadClauses;
01486 Array<GroundClause*> toAddClauses;
01487
01488
01489 getActiveClauses(p, unsatClauses, true, ignoreActivePreds);
01490
01491
01492 if (useThreshold_)
01493 {
01494
01495 for (int ni = 0; ni < unsatClauses.size(); ni++)
01496 {
01497 GroundClause* c = unsatClauses[ni];
01498 if (c->getWt() < 0)
01499 {
01500
01501
01502 double threshold = RAND_MAX*(1 - exp(c->getWt()));
01503 if (random() <= threshold)
01504 {
01505
01506 isFixed = true;
01507
01508
01509
01510 if (deadClauses.size() > 0)
01511 addNewClauses(ADD_CLAUSE_DEAD, deadClauses);
01512
01513 Array<GroundClause*> fixedClauses;
01514 fixedClauses.append(c);
01515 addNewClauses(ADD_CLAUSE_SAT, fixedClauses);
01516
01517
01518 for (int pi = 0; pi < c->getNumGroundPredicates(); pi++)
01519 {
01520 int lit = c->getGroundPredicateIndex(pi);
01521 fixAtom(abs(lit), (lit < 0));
01522 }
01523
01524
01525 break;
01526 }
01527 else
01528 {
01529
01530 deadClauses.append(c);
01531 }
01532 }
01533 else if (c->getNumGroundPredicates() == 1)
01534 {
01535 double threshold = RAND_MAX*(1 - exp(-c->getWt()));
01536 if (random() <= threshold)
01537 {
01538
01539 isFixed = true;
01540
01541
01542
01543 if (deadClauses.size() > 0)
01544 addNewClauses(ADD_CLAUSE_DEAD, deadClauses);
01545
01546 Array<GroundClause*> fixedClauses;
01547 fixedClauses.append(c);
01548 addNewClauses(ADD_CLAUSE_SAT, fixedClauses);
01549
01550
01551 int lit = c->getGroundPredicateIndex(0);
01552 fixAtom(abs(lit), (lit > 0));
01553
01554
01555 break;
01556 }
01557 else
01558 {
01559
01560 deadClauses.append(c);
01561 }
01562 }
01563 else toAddClauses.append(c);
01564 }
01565 }
01566
01567
01568 if (!isFixed)
01569 {
01570 if (deadClauses.size() > 0)
01571 addNewClauses(ADD_CLAUSE_DEAD, deadClauses);
01572
01573 if (useThreshold_)
01574 addNewClauses(ADD_CLAUSE_REGULAR, toAddClauses);
01575 else
01576 addNewClauses(ADD_CLAUSE_REGULAR, unsatClauses);
01577
01578
01579
01580 if (needToFlipBack)
01581 {
01582 bool activate = false;
01583 setValueOfAtom(atomIdx, false, activate, -1);
01584 updateMakeBreakCostAfterFlip(atomIdx);
01585 }
01586
01587 if (!groundOnly)
01588 {
01589
01590 domain_->getDB()->setActiveStatus(p, true);
01591 activeAtoms_++;
01592 }
01593 }
01594
01595 delete p;
01596 unsatClauses.clear();
01597 deadClauses.clear();
01598 toAddClauses.clear();
01599
01600 return !isFixed;
01601 }
01602 return true;
01603 }
01604
01608 void setInferenceMode(int mode)
01609 {
01610 if (mode == inferenceMode_) return;
01611 inferenceMode_ = mode;
01612 if (inferenceMode_ == MODE_MWS)
01613 {
01614 for (int i = 0; i < gndClauses_->size(); i++)
01615 {
01616 if ((*gndClauses_)[i]->isHardClause())
01617 clauseCost_[i] = hardWt_;
01618 else
01619 clauseCost_[i] = (*gndClauses_)[i]->getWt();
01620 }
01621 initMakeBreakCostWatch();
01622 }
01623 else
01624 {
01625 if (inferenceMode_ == MODE_HARD) eliminateSoftClauses();
01626 else if (inferenceMode_ == MODE_SAMPLESAT) makeUnitCosts();
01627 }
01628 }
01629
01636 void updateSatisfiedClauses(const int& toFix)
01637 {
01638
01639 bool toFlipValue = getValueOfAtom(toFix);
01640
01641 register int clauseIdx;
01642 int sign;
01643 int litIdx;
01644 if (toFlipValue)
01645 sign = 1;
01646 else
01647 sign = 0;
01648
01649
01650 litIdx = 2*toFix - sign;
01651 Array<int>& posOccArray = getOccurenceArray(litIdx);
01652 for (int i = 0; i < posOccArray.size(); i++)
01653 {
01654 clauseIdx = posOccArray[i];
01655
01656
01657 if (deadClause_[clauseIdx] || isSatisfied_[clauseIdx]) continue;
01658
01659 if (getClauseCost(clauseIdx) < 0)
01660 {
01661 cout << "ERR: in MC-SAT, active neg-wt clause (" << clauseIdx
01662 << ") is sat by fixed "<<endl;
01663 exit(0);
01664 }
01665 isSatisfied_[clauseIdx] = true;
01666 }
01667 }
01668
01674 void updateMakeBreakCostAfterFlip(const int& toFlip)
01675 {
01676
01677 bool toFlipValue = !getValueOfAtom(toFlip);
01678
01679 register int clauseIdx;
01680 int sign;
01681 int oppSign;
01682 int litIdx;
01683 if (toFlipValue)
01684 sign = 1;
01685 else
01686 sign = 0;
01687 oppSign = sign ^ 1;
01688
01689
01690 litIdx = 2*toFlip - sign;
01691 Array<int>& posOccArray = getOccurenceArray(litIdx);
01692
01693 for (int i = 0; i < posOccArray.size(); i++)
01694 {
01695 clauseIdx = posOccArray[i];
01696
01697 if (deadClause_[clauseIdx] || isSatisfied_[clauseIdx]) continue;
01698
01699
01700 int numTrueLits = decrementNumTrueLits(clauseIdx);
01701 long double cost = getClauseCost(clauseIdx);
01702 int watch1 = getWatch1(clauseIdx);
01703 int watch2 = getWatch2(clauseIdx);
01704
01705
01706
01707 if (numTrueLits == 0)
01708 {
01709
01710 if (cost >= 0)
01711 {
01712
01713 addFalseClause(clauseIdx);
01714
01715 addBreakCost(toFlip, -cost);
01716
01717 addMakeCostToAtomsInClause(clauseIdx, cost);
01718 }
01719
01720 else
01721 {
01722 assert(cost < 0);
01723
01724 removeFalseClause(clauseIdx);
01725
01726 addBreakCostToAtomsInClause(clauseIdx, -cost);
01727
01728 addMakeCost(toFlip, cost);
01729 }
01730 }
01731
01732
01733 else if (numTrueLits == 1)
01734 {
01735 if (watch1 == toFlip)
01736 {
01737 assert(watch1 != watch2);
01738 setWatch1(clauseIdx, watch2);
01739 watch1 = getWatch1(clauseIdx);
01740 }
01741
01742 if (cost >= 0)
01743 {
01744 addBreakCost(watch1, cost);
01745 }
01746
01747 else
01748 {
01749 assert(cost < 0);
01750 addMakeCost(watch1, -cost);
01751 }
01752 }
01753
01754
01755 else
01756 {
01757
01758
01759 if (watch1 == toFlip)
01760 {
01761
01762 int diffTrueLit = getTrueLiteralOtherThan(clauseIdx, watch1, watch2);
01763 setWatch1(clauseIdx, diffTrueLit);
01764 }
01765
01766 else if (watch2 == toFlip)
01767 {
01768
01769 int diffTrueLit = getTrueLiteralOtherThan(clauseIdx, watch1, watch2);
01770 setWatch2(clauseIdx, diffTrueLit);
01771 }
01772 }
01773 }
01774
01775
01776 litIdx = 2*toFlip - oppSign;
01777 Array<int>& negOccArray = getOccurenceArray(litIdx);
01778 for (int i = 0; i < negOccArray.size(); i++)
01779 {
01780 clauseIdx = negOccArray[i];
01781
01782 if (deadClause_[clauseIdx] || isSatisfied_[clauseIdx]) continue;
01783
01784
01785 int numTrueLits = incrementNumTrueLits(clauseIdx);
01786 long double cost = getClauseCost(clauseIdx);
01787 int watch1 = getWatch1(clauseIdx);
01788
01789
01790
01791 if (numTrueLits == 1)
01792 {
01793
01794 if (cost >= 0)
01795 {
01796
01797 removeFalseClause(clauseIdx);
01798
01799 addBreakCost(toFlip, cost);
01800
01801 addMakeCostToAtomsInClause(clauseIdx, -cost);
01802 }
01803
01804 else
01805 {
01806 assert(cost < 0);
01807
01808 addFalseClause(clauseIdx);
01809
01810 addBreakCostToAtomsInClause(clauseIdx, cost);
01811
01812 addMakeCost(toFlip, -cost);
01813 }
01814
01815 setWatch1(clauseIdx, toFlip);
01816 }
01817
01818
01819 else if (numTrueLits == 2)
01820 {
01821 if (cost >= 0)
01822 {
01823
01824
01825 addBreakCost(watch1, -cost);
01826 }
01827 else
01828 {
01829
01830 assert(cost < 0);
01831
01832 addMakeCost(watch1, cost);
01833 }
01834
01835 setWatch2(clauseIdx, toFlip);
01836 }
01837 }
01838 }
01839
01846 bool isActive(const int& atomIdx)
01847 {
01848 return domain_->getDB()->getActiveStatus(gndPredHashArray_[atomIdx-1]);
01849 }
01850
01857 bool isActive(const Predicate* pred)
01858 {
01859 return domain_->getDB()->getActiveStatus(pred);
01860 }
01861
01865 Array<int>& getOccurenceArray(const int& idx)
01866 {
01867 return occurence_[idx];
01868 }
01869
01870
01874 int incrementNumTrueLits(const int& clauseIdx)
01875 {
01876 return ++numTrueLits_[clauseIdx];
01877 }
01878
01882 int decrementNumTrueLits(const int& clauseIdx)
01883 {
01884 return --numTrueLits_[clauseIdx];
01885 }
01886
01890 int getNumTrueLits(const int& clauseIdx)
01891 {
01892 return numTrueLits_[clauseIdx];
01893 }
01894
01898 long double getClauseCost(const int& clauseIdx)
01899 {
01900 return clauseCost_[clauseIdx];
01901 }
01902
01906 Array<int>& getAtomsInClause(const int& clauseIdx)
01907 {
01908 return clause_[clauseIdx];
01909 }
01910
01914 void addBreakCost(const int& atomIdx, const long double& cost)
01915 {
01916 breakCost_[atomIdx] += cost;
01917 }
01918
01922 void subtractBreakCost(const int& atomIdx, const long double& cost)
01923 {
01924 breakCost_[atomIdx] -= cost;
01925 }
01926
01933 void addBreakCostToAtomsInClause(const int& clauseIdx,
01934 const long double& cost)
01935 {
01936 register int size = getClauseSize(clauseIdx);
01937 for (int i = 0; i < size; i++)
01938 {
01939 register int lit = clause_[clauseIdx][i];
01940 breakCost_[abs(lit)] += cost;
01941 }
01942 }
01943
01950 void subtractBreakCostFromAtomsInClause(const int& clauseIdx,
01951 const long double& cost)
01952 {
01953 register int size = getClauseSize(clauseIdx);
01954 for (int i = 0; i < size; i++)
01955 {
01956 register int lit = clause_[clauseIdx][i];
01957 breakCost_[abs(lit)] -= cost;
01958 }
01959 }
01960
01967 void addMakeCost(const int& atomIdx, const long double& cost)
01968 {
01969 makeCost_[atomIdx] += cost;
01970 }
01971
01978 void subtractMakeCost(const int& atomIdx, const long double& cost)
01979 {
01980 makeCost_[atomIdx] -= cost;
01981 }
01982
01989 void addMakeCostToAtomsInClause(const int& clauseIdx,
01990 const long double& cost)
01991 {
01992 register int size = getClauseSize(clauseIdx);
01993 for (int i = 0; i < size; i++)
01994 {
01995 register int lit = clause_[clauseIdx][i];
01996 makeCost_[abs(lit)] += cost;
01997 }
01998 }
01999
02006 void subtractMakeCostFromAtomsInClause(const int& clauseIdx,
02007 const long double& cost)
02008 {
02009 register int size = getClauseSize(clauseIdx);
02010 for (int i = 0; i < size; i++)
02011 {
02012 register int lit = clause_[clauseIdx][i];
02013 makeCost_[abs(lit)] -= cost;
02014 }
02015 }
02016
02026 const int getTrueLiteralOtherThan(const int& clauseIdx,
02027 const int& atomIdx1,
02028 const int& atomIdx2)
02029 {
02030 register int size = getClauseSize(clauseIdx);
02031 for (int i = 0; i < size; i++)
02032 {
02033 register int lit = clause_[clauseIdx][i];
02034 register int v = abs(lit);
02035 if (isTrueLiteral(lit) && v != atomIdx1 && v != atomIdx2)
02036 return v;
02037 }
02038
02039 assert(false);
02040 return -1;
02041 }
02042
02046 const bool isTrueLiteral(const int& literal)
02047 {
02048 return ((literal > 0) == atom_[abs(literal)]);
02049 }
02050
02054 const int getAtomInClause(const int& atomIdxInClause, const int& clauseIdx)
02055 {
02056 return clause_[clauseIdx][atomIdxInClause];
02057 }
02058
02062 const int getRandomAtomInClause(const int& clauseIdx)
02063 {
02064 return clause_[clauseIdx][random()%getClauseSize(clauseIdx)];
02065 }
02066
02073 const int getRandomTrueLitInClause(const int& clauseIdx)
02074 {
02075 assert(numTrueLits_[clauseIdx] > 0);
02076 int trueLit = random()%numTrueLits_[clauseIdx];
02077 int whichTrueLit = 0;
02078 for (int i = 0; i < getClauseSize(clauseIdx); i++)
02079 {
02080 int lit = clause_[clauseIdx][i];
02081 int atm = abs(lit);
02082
02083 if (isTrueLiteral(lit))
02084 if (trueLit == whichTrueLit++)
02085 return atm;
02086 }
02087
02088 assert(false);
02089 return -1;
02090 }
02091
02092
02093 const long double getMakeCost(const int& atomIdx)
02094 {
02095 return makeCost_[atomIdx];
02096 }
02097
02098 const long double getBreakCost(const int& atomIdx)
02099 {
02100 return breakCost_[atomIdx];
02101 }
02102
02103 const int getClauseSize(const int& clauseIdx)
02104 {
02105 return clause_[clauseIdx].size();
02106 }
02107
02108 const int getWatch1(const int& clauseIdx)
02109 {
02110 return watch1_[clauseIdx];
02111 }
02112
02113 void setWatch1(const int& clauseIdx, const int& atomIdx)
02114 {
02115 watch1_[clauseIdx] = atomIdx;
02116 }
02117
02118 const int getWatch2(const int& clauseIdx)
02119 {
02120 return watch2_[clauseIdx];
02121 }
02122
02123 void setWatch2(const int& clauseIdx, const int& atomIdx)
02124 {
02125 watch2_[clauseIdx] = atomIdx;
02126 }
02127
02128 const bool isBlockEvidence(const int& blockIdx)
02129 {
02130 return (*blockEvidence_)[blockIdx];
02131 }
02132
02137 const int getBlockIndex(const int& atomIdx)
02138 {
02139 for (int i = 0; i < blocks_->size(); i++)
02140 {
02141 int blockIdx = (*blocks_)[i].find(atomIdx);
02142 if (blockIdx >= 0)
02143 return i;
02144 }
02145 return -1;
02146 }
02147
02148 Array<int>& getBlockArray(const int& blockIdx)
02149 {
02150 return (*blocks_)[blockIdx];
02151 }
02152
02153 bool getBlockEvidence(const int& blockIdx)
02154 {
02155 return (*blockEvidence_)[blockIdx];
02156 }
02157
02158 int getNumBlocks()
02159 {
02160 return blocks_->size();
02161 }
02165 const long double getLowCost()
02166 {
02167 return lowCost_;
02168 }
02169
02173 const int getLowBad()
02174 {
02175 return lowBad_;
02176 }
02177
02178 void saveLowState()
02179 {
02180 if (hvsdebug) cout << "Saving low state: " << endl;
02181 for (int i = 1; i <= getNumAtoms(); i++)
02182 {
02183 lowAtom_[i] = atom_[i];
02184
02185 }
02186 lowCost_ = costOfFalseClauses_;
02187 lowBad_ = numFalseClauses_;
02188 if (lowBad_ > 0)
02189 {
02190 for (int i = 0; i < numFalseClauses_; i++)
02191 {
02192 falseClauseLow_[i] = falseClause_[i];
02193 }
02194 }
02195 }
02196
02200 int getTrueFixedAtomInBlock(const int blockIdx)
02201 {
02202 Array<int>& block = (*blocks_)[blockIdx];
02203 for (int i = 0; i < block.size(); i++)
02204 if (fixedAtom_[block[i] + 1] > 0) return i;
02205 return -1;
02206 }
02207 const GroundPredicateHashArray* getGndPredHashArrayPtr() const
02208 {
02209 return &gndPredHashArray_;
02210 }
02211
02212 const GroundPredicateHashArray* getUnePreds() const
02213 {
02214 return unePreds_;
02215 }
02216
02217 const GroundPredicateHashArray* getKnePreds() const
02218 {
02219 return knePreds_;
02220 }
02221
02222 const Array<TruthValue>* getKnePredValues() const
02223 {
02224 return knePredValues_;
02225 }
02226
02230 void setGndClausesWtsToSumOfParentWts()
02231 {
02232 for (int i = 0; i < gndClauses_->size(); i++)
02233 {
02234 GroundClause* gndClause = (*gndClauses_)[i];
02235 gndClause->setWtToSumOfParentWts(mln_);
02236 if (hvsdebug) cout << "Setting cost of clause " << i << " to "
02237 << gndClause->getWt() << endl;
02238 clauseCost_[i] = gndClause->getWt();
02239
02240
02241 if (gndClause->isHardClause()) threshold_[i] = RAND_MAX;
02242 else
02243 {
02244 double w = gndClause->getWt();
02245 threshold_[i] = RAND_MAX*(1 - exp(-abs(w)));
02246 if (hvsdebug)
02247 {
02248 cout << "Weight: " << w << endl;
02249 }
02250 }
02251 if (hvsdebug)
02252 cout << "Threshold: " << threshold_[i] << endl;
02253 }
02254 }
02255
02266 void getNumClauseGndings(Array<double>* const & numGndings, bool tv)
02267 {
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277 Array<double> lazyFalseGndings(numGndings->size(), 0);
02278 Array<double> lazyTrueGndings(numGndings->size(), 0);
02279
02280 IntBoolPairItr itr;
02281 IntBoolPair *clauseFrequencies;
02282
02283
02284 int clauseCnt = numGndings->size();
02285 assert(clauseCnt == mln_->getNumClauses());
02286 for (int clauseno = 0; clauseno < clauseCnt; clauseno++)
02287 assert ((*numGndings)[clauseno] >= 0);
02288
02289 for (int i = 0; i < gndClauses_->size(); i++)
02290 {
02291 GroundClause *gndClause = (*gndClauses_)[i];
02292 int satLitcnt = 0;
02293 for (int j = 0; j < gndClause->getNumGroundPredicates(); j++)
02294 {
02295 int lit = gndClause->getGroundPredicateIndex(j);
02296 if (isTrueLiteral(lit)) satLitcnt++;
02297 }
02298
02299 clauseFrequencies = gndClause->getClauseFrequencies();
02300 for (itr = clauseFrequencies->begin();
02301 itr != clauseFrequencies->end(); itr++)
02302 {
02303 int clauseno = itr->first;
02304 int frequency = itr->second.first;
02305 bool invertWt = itr->second.second;
02306
02307 if (invertWt)
02308 {
02309
02310 if (tv && satLitcnt > 0)
02311 {
02312
02313 if (lazy_) lazyFalseGndings[clauseno] += frequency;
02314 continue;
02315 }
02316
02317 if (!tv && satLitcnt == 0)
02318 {
02319
02320 if (lazy_) lazyTrueGndings[clauseno] += frequency;
02321 continue;
02322 }
02323 }
02324 else
02325 {
02326
02327 if (tv && satLitcnt == 0)
02328 {
02329
02330 if (lazy_) lazyFalseGndings[clauseno] += frequency;
02331 continue;
02332 }
02333
02334 if (!tv && satLitcnt > 0)
02335 {
02336
02337 if (lazy_) lazyTrueGndings[clauseno] += frequency;
02338 continue;
02339 }
02340 }
02341 (*numGndings)[clauseno] += frequency;
02342 }
02343 }
02344
02345
02346
02347
02348 if (lazy_)
02349 {
02350 for (int c = 0; c < mln_->getNumClauses(); c++)
02351 {
02352 const Clause* clause = mln_->getClause(c);
02353
02354 if (tv && clause->getWt() >= 0)
02355 {
02356 double totalGndings = domain_->getNumNonEvidGroundings(c);
02357 assert(totalGndings >= (*numGndings)[c] + lazyFalseGndings[c]);
02358 double remainingTrueGndings = totalGndings - lazyFalseGndings[c] -
02359 (*numGndings)[c];
02360 (*numGndings)[c] += remainingTrueGndings;
02361 }
02362
02363 else if (!tv && clause->getWt() < 0)
02364 {
02365 double totalGndings = domain_->getNumNonEvidGroundings(c);
02366 assert(totalGndings >= (*numGndings)[c] + lazyTrueGndings[c]);
02367 double remainingFalseGndings = totalGndings - lazyTrueGndings[c] -
02368 (*numGndings)[c];
02369 (*numGndings)[c] += remainingFalseGndings;
02370 }
02371 }
02372 }
02373
02374 }
02375
02383 void setOthersInBlockToFalse(const int& atomIdx, const int& blockIdx)
02384 {
02385 if (hvsdebug)
02386 {
02387 cout << "Set all in block " << blockIdx << " to false except "
02388 << atomIdx << endl;
02389 }
02390 int blockSize = domain_->getBlockSize(blockIdx);
02391 for (int i = 0; i < blockSize; i++)
02392 {
02393 const Predicate* pred = domain_->getPredInBlock(i, blockIdx);
02394 GroundPredicate* gndPred = new GroundPredicate((Predicate*)pred);
02395 int idx = gndPredHashArray_.find(gndPred);
02396
02397 if (hvsdebug)
02398 {
02399 cout << "Gnd pred in block ";
02400 gndPred->print(cout, domain_);
02401 cout << " (idx " << idx << ")" << endl;
02402 }
02403
02404 delete gndPred;
02405 delete pred;
02406
02407
02408 if (idx >= 0)
02409 {
02410
02411 if (idx != atomIdx && fixedAtom_[idx + 1] == 0)
02412 {
02413 if (hvsdebug)
02414 cout << "Set " << idx + 1 << " to false" << endl;
02415
02416 bool activate = true;
02417 setValueOfAtom(idx + 1, false, activate, -1);
02418 }
02419 }
02420 }
02421 }
02422
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02451 void fixAtom(const int& atomIdx, const bool& value)
02452 {
02453 assert(atomIdx > 0);
02454 if (hvsdebug)
02455 {
02456 cout << "Fixing ";
02457 (*gndPreds_)[atomIdx - 1]->print(cout, domain_);
02458 cout << " to " << value << endl;
02459 }
02460
02461
02462 if (!useThreshold_)
02463 {
02464 cout << ">>> [ERR] useThreshold_ is false" << endl;
02465 exit(0);
02466 }
02467
02468
02469 if ((fixedAtom_[atomIdx] == 1 && value == false) ||
02470 (fixedAtom_[atomIdx] == -1 && value == true))
02471 {
02472 cout << "Contradiction: Tried to fix atom " << atomIdx <<
02473 " to true and false ... exiting." << endl;
02474 exit(0);
02475 }
02476
02477
02478 if (fixedAtom_[atomIdx] != 0) return;
02479
02480 fixedAtom_[atomIdx] = (value) ? 1 : -1;
02481 if (atom_[atomIdx] != value)
02482 {
02483 bool activate = false;
02484 int blockIdx = getBlockIndex(atomIdx - 1);
02485 setValueOfAtom(atomIdx, value, activate, blockIdx);
02486 updateMakeBreakCostAfterFlip(atomIdx);
02487 }
02488
02489
02490 updateSatisfiedClauses(atomIdx);
02491
02492
02493 if (value)
02494 {
02495 int blockIdx = getBlockIndex(atomIdx - 1);
02496 if (blockIdx > -1)
02497 {
02498 int blockSize = domain_->getBlockSize(blockIdx);
02499 for (int i = 0; i < blockSize; i++)
02500 {
02501 const Predicate* pred = domain_->getPredInBlock(i, blockIdx);
02502 GroundPredicate* gndPred = new GroundPredicate((Predicate*)pred);
02503 int idx = gndPredHashArray_.find(gndPred);
02504 delete gndPred;
02505 delete pred;
02506
02507
02508 if (idx >= 0)
02509 {
02510
02511 if (idx != (atomIdx - 1))
02512 {
02513
02514 if (fixedAtom_[idx + 1] == 1)
02515 {
02516 cout << "Contradiction: Tried to fix atom " << idx + 1 <<
02517 " to true and false ... exiting." << endl;
02518 exit(0);
02519 }
02520
02521 if (fixedAtom_[idx + 1] == -1) continue;
02522 if (hvsdebug)
02523 {
02524 cout << "Fixing ";
02525 (*gndPreds_)[idx]->print(cout, domain_);
02526 cout << " to 0" << endl;
02527 }
02528 fixedAtom_[idx + 1] = -1;
02529 if (atom_[idx + 1] != false)
02530 {
02531 bool activate = false;
02532 setValueOfAtom(idx + 1, value, activate, blockIdx);
02533 updateMakeBreakCostAfterFlip(idx + 1);
02534 }
02535
02536 updateSatisfiedClauses(idx + 1);
02537 }
02538 }
02539 }
02540 }
02541 }
02542
02543
02544
02545 if (lazy_ && !isActive(atomIdx) && value)
02546 {
02547
02548
02549 Predicate* p =
02550 gndPredHashArray_[atomIdx - 1]->createEquivalentPredicate(domain_);
02551
02552 bool ignoreActivePreds = false;
02553 Array<GroundClause*> unsatClauses;
02554 getActiveClauses(p, unsatClauses, true, ignoreActivePreds);
02555
02556
02557
02558 addNewClauses(ADD_CLAUSE_REGULAR, unsatClauses);
02559
02560
02561 domain_->getDB()->setActiveStatus(p, true);
02562 activeAtoms_++;
02563
02564 delete p;
02565 }
02566 }
02567
02568
02577
02578
02579
02580
02581
02582
02583
02584
02585
02586
02587
02588
02589
02590
02591
02592
02593
02594
02595
02596
02597
02598
02599
02600
02601
02613 Array<int>* simplifyClauseFromFixedAtoms(const int& clauseIdx)
02614 {
02615 Array<int>* returnArray = new Array<int>;
02616
02617 if (isSatisfied_[clauseIdx]) return returnArray;
02618
02619
02620
02621 bool isGood = (clauseCost_[clauseIdx] > 0) ? false : true;
02622
02623 bool allFalseAtoms = (clauseCost_[clauseIdx] > 0) ? true : false;
02624
02625 for (int i = 0; i < getClauseSize(clauseIdx); i++)
02626 {
02627 int lit = clause_[clauseIdx][i];
02628 int fixedValue = fixedAtom_[abs(lit)];
02629
02630 if (clauseCost_[clauseIdx] > 0)
02631 {
02632 if ((fixedValue == 1 && lit > 0) ||
02633 (fixedValue == -1 && lit < 0))
02634 {
02635 isGood = true;
02636 allFalseAtoms = false;
02637 returnArray->clear();
02638 break;
02639 }
02640 else if (fixedValue == 0)
02641 {
02642 allFalseAtoms = false;
02643 returnArray->append(lit);
02644 }
02645 }
02646 else
02647 {
02648 assert(clauseCost_[clauseIdx] < 0);
02649 if ((fixedValue == 1 && lit > 0) ||
02650 (fixedValue == -1 && lit < 0))
02651 {
02652 cout << "Contradiction: Tried to fix atom " << abs(lit) <<
02653 " to true in a negative clause ... exiting." << endl;
02654 exit(0);
02655 }
02656 else
02657 {
02658 returnArray->append(lit);
02659
02660 if (fixedValue == 0) isGood = false;
02661 }
02662 }
02663 }
02664 if (allFalseAtoms)
02665 {
02666 cout << "Contradiction: All atoms in clause " << clauseIdx <<
02667 " fixed to false ... exiting." << endl;
02668 exit(0);
02669 }
02670 if (isGood) isSatisfied_[clauseIdx] = true;
02671 return returnArray;
02672 }
02673
02680 const bool isDeadClause(const int& clauseIdx)
02681 {
02682 return deadClause_[clauseIdx];
02683 }
02684
02688 void eliminateSoftClauses()
02689 {
02690 bool atLeastOneDead = false;
02691 for (int i = 0; i < getNumClauses(); i++)
02692 {
02693 if (!(*gndClauses_)[i]->isHardClause())
02694 {
02695 atLeastOneDead = true;
02696 deadClause_[i] = true;
02697 }
02698 }
02699 if (atLeastOneDead) initMakeBreakCostWatch();
02700 initMakeBreakCostWatchCont();
02701 }
02702
02703 void updateNumTrueLits()
02704 {
02705 for(int i = 0;i < getNumClauses(); i++)
02706 {
02707 numTrueLits_[i] = 0;
02708 for (int j = 0; j < getClauseSize(i); j++)
02709 {
02710 if (isTrueLiteral(clause_[i][j]))
02711 {
02712 numTrueLits_[i]++;
02713 }
02714 }
02715 }
02716 }
02717
02725 void killClauses(const int& startClause)
02726 {
02727 for (int i = startClause; i < getNumClauses(); i++)
02728 {
02729 GroundClause* clause = (*gndClauses_)[i];
02730 if ((clauseGoodInPrevious(i)) &&
02731 (clause->isHardClause() || random() <= threshold_[i]))
02732 {
02733 if (hvsdebug)
02734 {
02735 cout << "Keeping clause "<< i << " ";
02736 clause->print(cout, domain_, &gndPredHashArray_);
02737 cout << endl;
02738 }
02739 deadClause_[i] = false;
02740 }
02741 else
02742 {
02743 deadClause_[i] = true;
02744 }
02745 }
02746
02747 if(startClause == 0)
02748 {
02749 initMakeBreakCostWatch();
02750 }
02751 else
02752 {
02753 initMakeBreakCostWatch(startClause);
02754 }
02755
02756 initMakeBreakCostWatchCont();
02757 }
02758
02759
02767 const bool clauseGoodInPrevious(const int& clauseIdx)
02768 {
02769
02770 int numSatLits = numTrueLits_[clauseIdx];
02771
02772 if ((numSatLits > 0 && clauseCost_[clauseIdx] > 0.0) ||
02773 (numSatLits == 0 && clauseCost_[clauseIdx] < 0.0))
02774 return true;
02775 else
02776 return false;
02777 }
02778
02782 void resetDeadClauses()
02783 {
02784 for (int i = 0; i < deadClause_.size(); i++)
02785 deadClause_[i] = false;
02786 initMakeBreakCostWatch();
02787 initMakeBreakCostWatchCont();
02788 }
02789
02790 void resetDeadClausesAndInitMake()
02791 {
02792 for (int i = 0; i < deadClause_.size(); i++)
02793 deadClause_[i] = false;
02794 initMakeBreakCostWatch();
02795 }
02796
02800 void resetFixedAtoms()
02801 {
02802 for (int i = 0; i < fixedAtom_.size(); i++)
02803 fixedAtom_[i] = 0;
02804 for (int i = 0; i < isSatisfied_.size(); i++)
02805 isSatisfied_[i] = false;
02806 }
02807
02808 void setLazy(const bool& l) { lazy_ = l; }
02809 const bool getLazy() { return lazy_; }
02810
02811 void setUseThreshold(const bool& t) { useThreshold_ = t;}
02812 const bool getUseThreshold() { return useThreshold_; }
02813
02814 long double getHardWt() { return hardWt_; }
02815
02816 const Domain* getDomain() { return domain_; }
02817
02818 const MLN* getMLN() { return mln_; }
02819
02825 void printLowState(ostream& out)
02826 {
02827 for (int i = 0; i < getNumAtoms(); i++)
02828 {
02829 (*gndPreds_)[i]->print(out, domain_);
02830 out << " " << lowAtom_[i + 1] << endl;
02831 }
02832 }
02833
02834
02841 void printGndPred(const int& predIndex, ostream& out)
02842 {
02843 (*gndPreds_)[predIndex]->print(out, domain_);
02844 }
02845
02847
02854 GroundPredicate* getGndPred(const int& index)
02855 {
02856 return (*gndPreds_)[index];
02857 }
02858
02865 GroundClause* getGndClause(const int& index)
02866 {
02867 return (*gndClauses_)[index];
02868 }
02869
02873 void saveLowStateToGndPreds()
02874 {
02875
02876 for (int i = 0; i < getNumAtoms(); i++)
02877 (*gndPreds_)[i]->setTruthValue(lowAtom_[i + 1]);
02878
02879 }
02880
02884 void saveLowStateToDB()
02885 {
02886 for (int i = 0; i < getNumAtoms(); i++)
02887 {
02888 GroundPredicate* p = gndPredHashArray_[i];
02889 bool value = lowAtom_[i + 1];
02890 if (value)
02891 {
02892 domain_->getDB()->setValue(p, TRUE);
02893 }
02894 else
02895 {
02896 domain_->getDB()->setValue(p, FALSE);
02897 }
02898 }
02899 }
02900
02907 const int getGndPredIndex(GroundPredicate* const& gndPred)
02908 {
02909 return gndPreds_->find(gndPred);
02910 }
02912
02913
02915
02929 void getActiveClauses(Predicate *inputPred,
02930 Array<GroundClause*>& activeClauses,
02931 bool const & active,
02932 bool const & ignoreActivePreds)
02933 {
02934 Timer timer;
02935 double currTime;
02936
02937 Clause *fclause;
02938 GroundClause* newClause;
02939 int clauseCnt;
02940 GroundClauseHashArray clauseHashArray;
02941
02942 Array<GroundClause*>* newClauses = new Array<GroundClause*>;
02943
02944 const Array<IndexClause*>* indexClauses = NULL;
02945
02946
02947 if (inputPred == NULL)
02948 {
02949 clauseCnt = mln_->getNumClauses();
02950 }
02951
02952 else
02953 {
02954 if (domain_->getDB()->getDeactivatedStatus(inputPred)) return;
02955 int predId = inputPred->getId();
02956 indexClauses = mln_->getClausesContainingPred(predId);
02957 clauseCnt = indexClauses->size();
02958 }
02959
02960
02961 int clauseno = 0;
02962
02963 while (clauseno < clauseCnt)
02964 {
02965 if (inputPred)
02966 fclause = (Clause *) (*indexClauses)[clauseno]->clause;
02967 else
02968 fclause = (Clause *) mln_->getClause(clauseno);
02969
02970 if (hvsdebug)
02971 {
02972 cout << "Getting active clauses for FO clause: ";
02973 fclause->print(cout, domain_);
02974 cout << endl;
02975 }
02976
02977 currTime = timer.time();
02978
02979 const double* parentWtPtr = NULL;
02980 if (!fclause->isHardClause()) parentWtPtr = fclause->getWtPtr();
02981 const int clauseId = mln_->findClauseIdx(fclause);
02982 newClauses->clear();
02983
02984 if (stillActivating_)
02985 stillActivating_ = fclause->getActiveClauses(inputPred, domain_,
02986 newClauses,
02987 &gndPredHashArray_,
02988 ignoreActivePreds);
02989
02990 for (int i = 0; i < newClauses->size(); i++)
02991 {
02992 long double wt = fclause->getWt();
02993 newClause = (*newClauses)[i];
02994
02995
02996 if (gndClauses_->find(newClause) >= 0)
02997 {
02998 delete newClause;
02999 continue;
03000 }
03001
03002 bool invertWt = false;
03003
03004 if (!fclause->isHardClause() &&
03005 newClause->getNumGroundPredicates() == 1 &&
03006 !newClause->getGroundPredicateSense(0))
03007 {
03008 newClause->setGroundPredicateSense(0, true);
03009 newClause->setWt(-newClause->getWt());
03010 wt = -wt;
03011 invertWt = true;
03012 int addToIndex = gndClauses_->find(newClause);
03013 if (addToIndex >= 0)
03014 {
03015 (*gndClauses_)[addToIndex]->addWt(wt);
03016 if (parentWtPtr)
03017 (*gndClauses_)[addToIndex]->incrementClauseFrequency(clauseId, 1,
03018 invertWt);
03019 delete newClause;
03020 continue;
03021 }
03022 }
03023
03024 int pos = clauseHashArray.find(newClause);
03025
03026 if (pos >= 0)
03027 {
03028
03029
03030 if (clauseHashArray[pos]->getClauseFrequency(clauseId) > 0)
03031 {
03032 delete newClause;
03033 continue;
03034 }
03035 if (hvsdebug)
03036 {
03037 cout << "Adding weight " << wt << " to clause ";
03038 clauseHashArray[pos]->print(cout, domain_, &gndPredHashArray_);
03039 cout << endl;
03040 }
03041 clauseHashArray[pos]->addWt(wt);
03042 if (parentWtPtr)
03043 clauseHashArray[pos]->incrementClauseFrequency(clauseId, 1,
03044 invertWt);
03045 delete newClause;
03046 continue;
03047 }
03048
03049
03050 newClause->setWt(wt);
03051 if (parentWtPtr)
03052 newClause->incrementClauseFrequency(clauseId, 1, invertWt);
03053
03054 if (hvsdebug)
03055 {
03056 cout << "Appending clause ";
03057 newClause->print(cout, domain_, &gndPredHashArray_);
03058 cout << endl;
03059 }
03060 clauseHashArray.append(newClause);
03061 }
03062 clauseno++;
03063
03064 }
03065
03066 for (int i = 0; i < clauseHashArray.size(); i++)
03067 {
03068 newClause = clauseHashArray[i];
03069 activeClauses.append(newClause);
03070 }
03071
03072 newClauses->clear();
03073 delete newClauses;
03074
03075 clauseHashArray.clear();
03076 }
03077
03085 void getActiveClauses(Array<GroundClause*> &allClauses,
03086 bool const & ignoreActivePreds)
03087 {
03088 getActiveClauses(NULL, allClauses, true, ignoreActivePreds);
03089 }
03090
03091 int getNumActiveAtoms()
03092 {
03093 return activeAtoms_;
03094 }
03095
03100
03101
03102
03103
03104
03105
03106
03107
03108
03109
03110
03111
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125
03126
03127
03128
03129
03130
03131
03132
03133
03134
03135
03136
03137
03138
03139
03140
03141
03142
03143
03144
03145
03146
03150 void initLazyBlocks()
03151 {
03152 assert(lazy_);
03153 blocks_ = new Array<Array<int> >;
03154 blocks_->growToSize(domain_->getNumPredBlocks());
03155 blockEvidence_ = new Array<bool>(*(domain_->getBlockEvidenceArray()));
03156 }
03157
03161
03162
03163
03164
03165
03166
03167
03168
03169
03170
03171
03172
03173
03174
03175
03176
03177
03178
03179
03180
03181
03182
03183
03184
03185
03186
03187
03188
03189
03190
03191
03192
03193
03194
03195
03196
03197
03198
03199
03200
03201
03202
03203
03204 struct HybridConstraint
03205 {
03206 int contClauseIdx_;
03207 double vThreshold_;
03208 bool bSatisfiedLast_;
03209 int unSatType_;
03210 HybridConstraint()
03211 {
03212 contClauseIdx_ = -1;
03213 vThreshold_ = 0;
03214 bSatisfiedLast_ = false;
03215 unSatType_ = -1;
03216 }
03217 };
03218
03219 void printHybridConstraint(int i, ostream& os)
03220 {
03221 os << "Information for hybrid constraint " << i << ": threshold -- " << hybridConstraints_[i].vThreshold_ << ". weighted value -- " << HybridClauseValue(i) << ". ";
03222 os << "Polynomial: "; hybridPls_[i].PrintTo(os); os << endl;
03223 os << "Discrete variable values: " ;
03224 for (int j = 0; j < hybridDisClause_[i].size(); ++j) {
03225 int predIdx = abs(hybridDisClause_[i][j]);
03226 os << "<";(*gndPreds_)[predIdx - 1]->print(os, domain_); os << ": " << atom_[predIdx]<< ">, ";
03227 }
03228 os << endl;
03229 os << "Continuous variable values:";
03230 for (int j = 0; j < hybridContClause_[i].size(); j++)
03231 {
03232 int contVarIdx = hybridContClause_[i][j];
03233 map<int,string>::const_iterator citer = gndPredReverseCont_.find(contVarIdx);
03234 os << citer->second << ": " << contAtoms_[contVarIdx] << "; ";
03235 }
03236 os << endl;
03237 }
03238
03239 void WriteGndPredIdxMap(const char* gnd_pred_map_file) {
03240 if ( NULL != gnd_pred_map_file )
03241 {
03242 cout << "Saving ground predicate variables into file: " << gnd_pred_map_file << endl;
03243 ofstream os(gnd_pred_map_file);
03244
03245 for (int i = 0; i < getNumAtoms(); ++i) {
03246 (*gndPreds_)[i]->print(os, domain_); os << " " << i + 1<< endl;
03247 }
03248
03249 for (int i = 0; i < getNumContAtoms(); ++i) {
03250 os << gndPredReverseCont_[i + 1] << " " << i + getNumAtoms() + 1 << endl;
03251 }
03252 os.close();
03253 }
03254 }
03255
03256
03257 void initMakeBreakCostWatchCont()
03258 {
03259 if (hvsdebug)
03260 {
03261 cout << "entering initMakeBreakCostWatchCont" << endl;
03262 }
03263
03264 weightSumCont_ = 0.0;
03265 for(int i = 0; i < hybridClauseNum_; ++i)
03266 {
03267 if (0 == hybridWts_[i]) {
03268 hybridClauseValue_[i] = 0;
03269 hybridConstraints_[i].bSatisfiedLast_ = true;
03270 hybridConstraints_[i].vThreshold_ = 0;
03271
03272 continue;
03273 }
03274
03275 bool dis = false;
03276 double cont = 0.0;
03277 hybridClauseValue_[i] = HybridClauseValue(i, dis, cont);
03278 hybridClauseDisValue_[i] = dis;
03279 weightSumCont_ += hybridClauseValue_[i];
03280
03281 if (hvsdebug)
03282 {
03283 cout << "clause " << i << " value:" << hybridClauseValue_[i] << endl;
03284 }
03285 if (isSatisfied(hybridConstraints_[i], hybridClauseValue_[i]))
03286 {
03287 hybridConstraints_[i].bSatisfiedLast_ = true;
03288 } else {
03289 hybridConstraints_[i].bSatisfiedLast_ = false;
03290 hybridFalseClause_[hybridFalseConstraintNum_] = i;
03291 hybridWhereFalse_[i] = hybridFalseConstraintNum_;
03292 hybridFalseConstraintNum_ ++;
03293 totalFalseConstraintNum_++;
03294 costOfTotalFalseConstraints_ += fabs(hybridClauseCost_[i]);
03295 costHybridFalseConstraint_ += fabs(hybridClauseCost_[i]);
03296
03297 if (dis == 0)
03298 {
03299 hybridConstraints_[i].unSatType_ = UNSAT_DIS0;
03300 }
03301 else
03302 {
03303 hybridConstraints_[i].unSatType_ = UNSAT_DIS1;
03304 }
03305 }
03306 }
03307
03308 if (hvsdebug)
03309 {
03310 cout << "leaving initMakeBreakCostWatchCont" << endl;
03311 }
03312 }
03313
03314 int getNumContAtoms() { return contAtoms_.size() - 1;}
03315
03322 int getIndexOfRandomAtom()
03323 {
03324 assert(totalAtomNum_ > 0);
03325 int discreteNumAtoms = getNumAtoms();
03326 int idx = random()%totalAtomNum_;
03327 if (idx < discreteNumAtoms)
03328 {
03329 return (idx + 1);
03330 }
03331 else
03332 {
03333 return -(idx - discreteNumAtoms + 1);
03334 }
03335 }
03336
03342 int getRandomToFixClauseIdx()
03343 {
03344 int idx = random() % (numFalseClauses_ + hybridClauseNum_);
03345
03346 if (idx < numFalseClauses_)
03347 return falseClause_[idx];
03348 else return -(idx - numFalseClauses_);
03349 }
03350
03351 double getCostOfTotalFalseConstraints()
03352 {
03353 return costOfTotalFalseConstraints_;
03354 }
03355
03356 double getCostOfAllClauses(double& discost, double& hybridcost)
03357 {
03358 discost = weightSumDis_;
03359 hybridcost = weightSumCont_;
03360 return weightSumDis_ + weightSumCont_;
03361 }
03362
03363 void UpdateHybridClauseWeightSumByContAtom(const int& atomIdx, const double& atomValue)
03364 {
03365 contAtoms_[atomIdx] = atomValue;
03366 for(int i = 0; i < hybridContOccurrence_[atomIdx].size(); i++)
03367 {
03368 int contClauseIdx = hybridContOccurrence_[atomIdx][i];
03369 double vOld = hybridClauseValue_[contClauseIdx];
03370 hybridClauseValue_[contClauseIdx] = HybridClauseValue(contClauseIdx);
03371 weightSumCont_ = weightSumCont_ - vOld + hybridClauseValue_[contClauseIdx];
03372 }
03373 }
03374
03375 void UpdateHybridClauseWeightSumByDisAtom(const int& atomIdx, bool atomValue)
03376 {
03377 setValueOfAtom(atomIdx, atomValue, false, -1);
03378 for(int i = 0; i < hybridDisOccurrence_[atomIdx].size(); i++)
03379 {
03380 int contClauseIdx = hybridDisOccurrence_[atomIdx][i];
03381 double vOld = hybridClauseValue_[contClauseIdx];
03382 double cont;
03383 bool dis;
03384 hybridClauseValue_[contClauseIdx] = HybridClauseValue(contClauseIdx,dis,cont);
03385 hybridClauseDisValue_[contClauseIdx] = dis;
03386 weightSumCont_ = weightSumCont_ - vOld + hybridClauseValue_[contClauseIdx];
03387 }
03388 }
03389
03390
03391
03392 void UpdateHybridClauseInfoByContAtom(const int& atomIdx, const double& atomValue)
03393 {
03394 contAtoms_[atomIdx] = atomValue;
03395 for(int i = 0; i < hybridContOccurrence_[atomIdx].size(); i++)
03396 {
03397 UpdateHybridClause(hybridContOccurrence_[atomIdx][i]);
03398 }
03399 }
03400
03401 void UpdateHybridClauseInfoByDisAtom(const int& atomIdx, const bool& atomValue)
03402 {
03403 setValueOfAtom(atomIdx, atomValue, false, -1);
03404
03405 for(int i = 0; i < hybridDisOccurrence_[atomIdx].size(); i++)
03406 {
03407 UpdateHybridClause(hybridDisOccurrence_[atomIdx][i]);
03408 }
03409 }
03410
03411
03412
03413
03414
03415 void UpdateHybridClause(const int& contClauseIdx)
03416 {
03417 double cont;
03418 bool dis;
03419 double vOld = hybridClauseValue_[contClauseIdx];
03420 hybridClauseValue_[contClauseIdx] = HybridClauseValue(contClauseIdx, dis, cont);
03421 hybridClauseDisValue_[contClauseIdx] = dis;
03422 weightSumCont_ = weightSumCont_ - vOld + hybridClauseValue_[contClauseIdx];
03423
03424
03425 bool bSatLast = hybridConstraints_[contClauseIdx].bSatisfiedLast_;
03426 hybridConstraints_[contClauseIdx].bSatisfiedLast_ =
03427 isSatisfied(hybridConstraints_[contClauseIdx], hybridClauseValue_[contClauseIdx]);
03428
03429 if (!hybridConstraints_[contClauseIdx].bSatisfiedLast_)
03430 {
03431 if (dis == 0 && hybridConstraints_[contClauseIdx].vThreshold_ > 0)
03432 {
03433 hybridConstraints_[contClauseIdx].unSatType_ = UNSAT_DIS0;
03434 }
03435 else if(dis == 1)
03436 {
03437 hybridConstraints_[contClauseIdx].unSatType_ = UNSAT_DIS1;
03438 }
03439 }
03440
03441 if(bSatLast && !hybridConstraints_[contClauseIdx].bSatisfiedLast_)
03442 {
03443 addFalseHybridConstraint(contClauseIdx);
03444 }
03445
03446 if (!bSatLast && hybridConstraints_[contClauseIdx].bSatisfiedLast_)
03447 {
03448 removeFalseHybridConstraint(contClauseIdx);
03449 }
03450 }
03451
03452
03453 long double getImprovementRandomMoveCont(const int& atomIdx, const double& atomValue)
03454 {
03455 double improvement = 0;
03456 Array<int>& occCont = getContContOccurenceArray(atomIdx);
03457 double atomVarOrg = contAtoms_[atomIdx];
03458 contAtoms_[atomIdx] = atomValue;
03459 for(int i = 0;i < occCont.size(); i++)
03460 {
03461 int clauseIdx = occCont[i];
03462 if (hybridWts_[clauseIdx] == 0 || hybridClauseDisValue_[clauseIdx] == false) {
03463 continue;
03464 }
03465 double cont;
03466 bool dis;
03467 double vCur = HybridClauseValue(clauseIdx,dis,cont);
03468 double vOld = hybridClauseValue_[clauseIdx];
03469 improvement += vCur - vOld;
03470 }
03471 contAtoms_[atomIdx] = atomVarOrg;
03472 return improvement;
03473 }
03474
03475 long double getImprovementInWeightSumByFlipping(const int& atomIdx)
03476 {
03477 double improvement = 0;
03478
03479 bool toFlipValue = getValueOfAtom(atomIdx);
03480 int sign;
03481 int oppSign;
03482 int litIdx;
03483 if (toFlipValue)
03484 sign = 1;
03485 else
03486 sign = 0;
03487 oppSign = sign ^ 1;
03488
03489
03490
03491
03492 litIdx = 2*atomIdx - sign;
03493 Array<int>& posOccArray = getOccurenceArray(litIdx);
03494
03495 litIdx = 2*atomIdx - oppSign;
03496 Array<int>& negOccArray = getOccurenceArray(litIdx);
03497
03498
03499 for(int i = 0; i < posOccArray.size(); i++)
03500 {
03501 int clauseIdx = posOccArray[i];
03502 int numTrueLitsOrg = getNumTrueLits(clauseIdx);
03503 if (numTrueLitsOrg == 1)
03504 {
03505 improvement -= clauseCost_[clauseIdx];
03506 }
03507 }
03508
03509 for(int i = 0; i < negOccArray.size(); i++)
03510 {
03511 int clauseIdx = negOccArray[i];
03512 int numTrueLitsOrg = getNumTrueLits(clauseIdx);
03513 if (numTrueLitsOrg == 0)
03514 {
03515 improvement += clauseCost_[clauseIdx];
03516 }
03517 }
03518
03519 setValueOfAtom(atomIdx, !toFlipValue, false, -1);
03520 Array<int>& occCont = getContDisOccurenceArray(atomIdx);
03521 for(int i = 0; i < occCont.size(); i++)
03522 {
03523 int clauseIdx = occCont[i];
03524 if (hybridWts_[clauseIdx] == 0)
03525 {
03526 continue;
03527 }
03528
03529 double vOrg = hybridClauseValue_[clauseIdx];
03530 double cont;
03531 bool dis;
03532 double vCur = HybridClauseValue(clauseIdx,dis,cont);
03533 improvement += vCur - vOrg;
03534 }
03535 setValueOfAtom(atomIdx, toFlipValue, false, -1);
03536 return improvement;
03537
03538 }
03539
03540
03542
03544
03545
03546 double SolveConstraintAndRandomSample(const int& contClauseIdx, const int& inIdx)
03547 {
03548 double dis = HybridClauseDisPartValue(contClauseIdx);
03549
03550 if (fabs(dis) < 0.0001 && hybridConstraints_[contClauseIdx].vThreshold_ > 0)
03551 {
03552
03553 return FLIPDIS;
03554 }
03555
03556 else if (fabs(dis) < 0.0001 && hybridConstraints_[contClauseIdx].vThreshold_ <= 0)
03557 {
03558 return 0;
03559 }
03560 else
03561 {
03562 DoubleRange r = SolveHybridConstraintToContVar(contClauseIdx, inIdx);
03563 if (r.iType == 3)
03564 {
03565 return UNSOLVABLE;
03566 }
03567 double d = randomSampleRange(r);
03568
03569 return d;
03570 }
03571 }
03572
03582 long double getImprovementByFlippingDisHMCS(const int& atomIdx)
03583 {
03584 if (hvsdebug) {
03585 cout << "Entering HVariableState::getImprovementByFlippingDisHMCS" << endl;
03586 }
03587 assert(atomIdx > 0);
03588
03589 long double improvementDis = makeCost_[atomIdx] - breakCost_[atomIdx];
03590 double improvementHybrid = getDisImproveInHybridByFlippingMCSAT(atomIdx);
03591 if (hvsdebug) {
03592 cout << "Leaving HVariableState::getImprovementByFlippingDisHMCS" << endl;
03593 }
03594 return improvementDis + improvementHybrid;
03595 }
03596
03597
03598
03599 double getDisImproveInHybridByFlippingMCSAT(const int& atomIdx)
03600 {
03601 if (hvsdebug) {
03602 cout << "Entering HVariableState::getDisImproveInHybridByFlippingMCSAT" << endl;
03603 }
03604 double improvement = 0;
03605 atom_[atomIdx] = !atom_[atomIdx];
03606 for(int i = 0; i < hybridDisOccurrence_[atomIdx].size(); i++)
03607 {
03608 int contClauseIdx = hybridDisOccurrence_[atomIdx][i];
03609 if (0 == hybridWts_[contClauseIdx]) continue;
03610 double contClauseValue = HybridClauseValue(contClauseIdx);
03611 HybridConstraint& cst = hybridConstraints_[contClauseIdx];
03612 if (!isSatisfied(cst, contClauseValue) && cst.bSatisfiedLast_) {
03613
03614
03615 improvement = improvement - fabs(hybridClauseCost_[contClauseIdx]);
03616 } else if (isSatisfied(cst, contClauseValue) && !cst.bSatisfiedLast_) {
03617
03618 improvement = improvement + fabs(hybridClauseCost_[contClauseIdx]);
03619 }
03620 }
03621 atom_[atomIdx] = !atom_[atomIdx];
03622 if (hvsdebug) {
03623 cout << "Leaving HVariableState::getDisImproveInHybridByFlippingMCSAT" << endl;
03624 }
03625 return improvement;
03626 }
03627
03628
03629
03630 double SolveHybridConstraintToContVarSample(int contClauseIdx, int inIdx, int maxIter = 100)
03631 {
03632 PolyNomial pl = hybridPls_[contClauseIdx];
03633 int pickAtomIdx = hybridContClause_[contClauseIdx][inIdx];
03634 if (pl.GetHighestOrder(inIdx) <= 2.0)
03635 {
03636
03637 return SolveConstraintAndRandomSample(contClauseIdx, inIdx);
03638 }
03639 else
03640 {
03641
03642 PolyNomial plOneVar = pl;
03643 plOneVar.ReduceToOneVar(inIdx);
03644 if (hybridClauseCost_[contClauseIdx] > 0)
03645 {
03646 plOneVar.MultiplyConst(-1.0);
03647 }
03648
03649 LBFGSP lbfgsp(-1,-1,1);
03650 double low, high;
03651 low = contAtomRange_[pickAtomIdx-1].low;
03652 high = contAtomRange_[pickAtomIdx-1].high;
03653 lbfgsp.setLowerBounds(&low);
03654 lbfgsp.setUpperBounds(&high);
03655
03656 lbfgsp.startLBFGS(plOneVar);
03657 double plValue = plOneVar.ComputePlValue();
03658 if (hybridClauseCost_[contClauseIdx] > 0)
03659 {
03660 plValue *= -1.0;
03661 }
03662
03663 bool dis = HybridClauseDisPartValue(contClauseIdx);
03664
03665 int iter = 0;
03666 while (!isSatisfied(hybridConstraints_[contClauseIdx], hybridClauseCost_[contClauseIdx] * plValue * double(dis)))
03667 {
03668 lbfgsp.proceedOneStep(plOneVar);
03669 ++ iter;
03670 if (iter > maxIter) break;
03671 }
03672
03673 if (iter <= maxIter)
03674 {
03675
03676 return plOneVar.varValue_[0];
03677 }
03678 else
03679 {
03680 return UNSOLVABLE;
03681 }
03682 }
03683 }
03684
03685
03686
03687
03688 double GetImprovementBySolvingHybridConstraintToContVar(const int& contClauseIdx, const int& inIdx, double& cont_var_val)
03689 {
03690
03691 cont_var_val = SolveHybridConstraintToContVarSample(contClauseIdx, inIdx);
03692 double improvement = 0;
03693 if (cont_var_val == UNSOLVABLE)
03694 {
03695 return CANNOTSATCURRENT;
03696 }
03697
03698
03699 int atomIdx = hybridContClause_[contClauseIdx][inIdx];
03700 double old_val = contAtoms_[atomIdx];
03701 contAtoms_[atomIdx] = cont_var_val;
03702 for(int i = 0; i < hybridContOccurrence_[atomIdx].size(); i++)
03703 {
03704 int hClause = hybridContOccurrence_[atomIdx][i];
03705 double hclause_val = HybridClauseValue(hClause);
03706
03707 if (!isSatisfied(hybridConstraints_[hClause], hclause_val) && hybridConstraints_[hClause].bSatisfiedLast_)
03708 {
03709
03710 improvement = improvement - fabs(hybridClauseCost_[hClause]);
03711 }
03712 else if (isSatisfied(hybridConstraints_[hClause], hclause_val) && !hybridConstraints_[hClause].bSatisfiedLast_)
03713 {
03714
03715 improvement = improvement + fabs(hybridClauseCost_[hClause]);
03716 }
03717 }
03718
03719 contAtoms_[atomIdx] = old_val;
03720 return improvement;
03721 }
03722
03723 bool isConstraintSolvableByCont(const int& contClauseIdx)
03724 {
03725 double dis = HybridClauseDisPartValue(contClauseIdx);
03726
03727
03728
03729 if (fabs(dis) < SMALLVALUE && hybridConstraints_[contClauseIdx].vThreshold_ > 0)
03730 {
03731 return false;
03732 }
03733
03734 else if (fabs(dis) < SMALLVALUE && hybridConstraints_[contClauseIdx].vThreshold_ < 0)
03735 {
03736 return true;
03737 }
03738
03739
03740
03741
03742 double optValue;
03743 map<int,double>::const_iterator citer;
03744 if ((citer = contOptimum_.find(contClauseIdx)) != contOptimum_.end())
03745 {
03746 optValue = citer->second;
03747 }
03748 else
03749 {
03750 PolyNomial& pl = hybridPls_[contClauseIdx];
03751 Array<double> ar;
03752 int ret = pl.Optimize2(&ar, &optValue);
03753 if (ret == 0)
03754 {
03755 contOptimum_.insert(map<int,double>::value_type(contClauseIdx, optValue));
03756 contOptimumAssignment_.insert(map<int,Array<double> >::value_type(contClauseIdx, ar));
03757 }
03758 else
03759 {
03760 pl.PrintTo(cout);
03761 contOptimum_.insert(map<int,double>::value_type(contClauseIdx, optValue));
03762 contOptimumAssignment_.insert(map<int,Array<double> >::value_type(contClauseIdx, ar));
03763 }
03764 }
03765
03766 if (fabs(dis) == 1
03767 && optValue * hybridWts_[contClauseIdx] >= hybridConstraints_[contClauseIdx].vThreshold_)
03768 {
03769 return true;
03770 }
03771 else if (fabs(dis) == 1
03772 && optValue * hybridWts_[contClauseIdx] < hybridConstraints_[contClauseIdx].vThreshold_)
03773 {
03774 return false;
03775 }
03776 return true;
03777 }
03778
03779
03780
03781 int getRandomFalseClauseIndexHMCS()
03782 {
03783 if (totalFalseConstraintNum_ == 0) return NOVALUE;
03784
03785 int idx = random() % totalFalseConstraintNum_;
03786
03787 if (idx < numFalseClauses_)
03788 {
03789 return falseClause_[idx] + 1;
03790 }
03791 else
03792 {
03793 return -(hybridFalseClause_[idx - numFalseClauses_] + 1);
03794 }
03795 }
03796
03797
03798 double GetImprovementByMovingContVar(const int& atomIdx, double& vContAtomFlipped)
03799 {
03800 double vLastCont = contAtoms_[atomIdx];
03801 double stdev = proposalStdev_[atomIdx];
03802 vContAtomFlipped = ExtRandom::gaussRandom(vLastCont, stdev);
03803
03804 double improvement = 0;
03805
03806 double vOldContAtomValue = contAtoms_[atomIdx];
03807 contAtoms_[atomIdx] = vContAtomFlipped;
03808
03809 for(int i = 0; i < hybridContOccurrence_[atomIdx].size(); i++)
03810 {
03811 int contClauseIdx = hybridContOccurrence_[atomIdx][i];
03812 double cont;
03813 bool dis;
03814 double vContClause = HybridClauseValue(hybridContOccurrence_[atomIdx][i],dis,cont);
03815
03816 if (!isSatisfied(hybridConstraints_[contClauseIdx], vContClause) && hybridConstraints_[contClauseIdx].bSatisfiedLast_)
03817 {
03818
03819 improvement = improvement - fabs(hybridClauseCost_[contClauseIdx]);
03820 }
03821 else if (isSatisfied(hybridConstraints_[contClauseIdx], vContClause) && !hybridConstraints_[contClauseIdx].bSatisfiedLast_)
03822 {
03823
03824 improvement = improvement + fabs(hybridClauseCost_[contClauseIdx]);
03825 }
03826 }
03827
03828 contAtoms_[atomIdx] = vOldContAtomValue;
03829 return improvement;
03830 }
03831
03832
03833
03834 void addFalseHybridConstraint(const int& contClauseIdx)
03835 {
03836 hybridFalseClause_[hybridFalseConstraintNum_] = contClauseIdx;
03837 hybridWhereFalse_[contClauseIdx] = hybridFalseConstraintNum_;
03838 hybridFalseConstraintNum_++;
03839 totalFalseConstraintNum_++;
03840 costOfTotalFalseConstraints_ += fabs(hybridClauseCost_[contClauseIdx]);
03841 costHybridFalseConstraint_ += fabs(hybridClauseCost_[contClauseIdx]);
03842 }
03843
03844 void removeFalseHybridConstraint(const int& contClauseIdx)
03845 {
03846 hybridFalseConstraintNum_--;
03847 totalFalseConstraintNum_--;
03848 hybridFalseClause_[hybridWhereFalse_[contClauseIdx]] = hybridFalseClause_[hybridFalseConstraintNum_];
03849 hybridWhereFalse_[hybridFalseClause_[hybridFalseConstraintNum_]] = hybridWhereFalse_[contClauseIdx];
03850 costOfTotalFalseConstraints_ -= fabs(hybridClauseCost_[contClauseIdx]);
03851 costHybridFalseConstraint_ -= fabs(hybridClauseCost_[contClauseIdx]);
03852 }
03853
03854
03855 void UpdateHybridConstraintTh()
03856 {
03857 for(int i = 0; i < hybridClauseNum_; i++)
03858 {
03859 hybridConstraints_[i].vThreshold_ = hybridClauseValue_[i] + log((double(random()) + 0.1)/double(RAND_MAX));
03860 }
03861 }
03862
03863 void addFalseClause(const int& clauseIdx)
03864 {
03865 falseClause_[numFalseClauses_] = clauseIdx;
03866 whereFalse_[clauseIdx] = numFalseClauses_;
03867 numFalseClauses_++;
03868 totalFalseConstraintNum_++;
03869 costOfFalseClauses_ += fabs(clauseCost_[clauseIdx]);
03870 costOfTotalFalseConstraints_ += fabs(clauseCost_[clauseIdx]);
03871 }
03872
03876 void removeFalseClause(const int& clauseIdx)
03877 {
03878 numFalseClauses_--;
03879 totalFalseConstraintNum_--;
03880 falseClause_[whereFalse_[clauseIdx]] = falseClause_[numFalseClauses_];
03881 whereFalse_[falseClause_[numFalseClauses_]] = whereFalse_[clauseIdx];
03882 costOfFalseClauses_ -= abs(clauseCost_[clauseIdx]);
03883 costOfTotalFalseConstraints_ -= abs(clauseCost_[clauseIdx]);
03884 }
03885
03890 void makeUnitCosts()
03891 {
03892 for (int i = 0; i < clauseCost_.size(); i++)
03893 {
03894
03895 if (clauseCost_[i] > 0) clauseCost_[i] = 1.0;
03896 else {
03897 assert(clauseCost_[i] < 0);
03898 clauseCost_[i] = -1.0;
03899 }
03900 }
03901
03902 for(int i = 0; i < hybridClauseCost_.size(); i++)
03903 {
03904 if (hybridClauseCost_[i] > 0) hybridClauseCost_[i] = 1.0;
03905 else
03906 {
03907 assert(hybridClauseCost_[i] < 0);
03908 hybridClauseCost_[i] = -1.0;
03909 }
03910 }
03911 }
03912
03913
03914
03915
03916
03917
03919
03921
03922
03923 void optimizeIndividualNumTerm()
03924 {
03925
03926 for (int i = 0; i < hybridClauseNum_; i++)
03927 {
03928 PolyNomial pl = hybridPls_[i];
03929 int varNum = pl.GetVarNum();
03930 LBFGSP lbfgsp(-1,-1,varNum);
03931 double* upper = new double[varNum];
03932 double* lower = new double[varNum];
03933 for(int k = 0; k < varNum; k++)
03934 {
03935 upper[k] = contAtomRange_[hybridContClause_[i][k]-1].high;
03936 lower[k] = contAtomRange_[hybridContClause_[i][k]-1].low;
03937 }
03938 lbfgsp.setUpperBounds(upper);
03939 lbfgsp.setLowerBounds(lower);
03940
03941
03942
03943
03944 if (hybridClauseCost_[i] > 0)
03945 {
03946 pl.MultiplyConst(-1.0);
03947 }
03948
03949 int iter;
03950 bool berror;
03951 double f = lbfgsp.minimize(iter, berror, pl);
03952
03953 lbfgsCache_[i].copyFrom(pl.GetVarValue());
03954 if(hybridClauseCost_[i] > 0) f *= -1.0;
03955 hmwsContOptimal_[i] = f;
03956 if ((f > 0 && hybridClauseCost_[i] > 0) || (hybridClauseCost_[i] < 0 && f < 0))
03957 {
03958 hmwsDisOptimal_[i] = true;
03959 }
03960 else if ((f > 0 && hybridClauseCost_[i] < 0) || (hybridClauseCost_[i] > 0 && f < 0))
03961 {
03962 hmwsDisOptimal_[i] = false;
03963 }
03964
03965 delete[] upper;
03966 delete[] lower;
03967 }
03968 }
03969
03970
03971
03972
03973
03974
03975 double ReduceClauseAndOptimize(const Array<int>& contVarIdx, Array<double>& assign)
03976 {
03977 if (hvsdebug) {
03978 cout << "Entering ReduceClauseAndOptimize ...." << endl;
03979 }
03980 set<int> occ;
03981 for(int i = 0; i < contVarIdx.size(); i++)
03982 {
03983 Array<int>& ar = getContContOccurenceArray(contVarIdx[i]);
03984 for(int j = 0; j < ar.size(); j++)
03985 {
03986 if (occ.find(ar[j]) == occ.end())
03987 {
03988 occ.insert(ar[j]);
03989 }
03990 }
03991 }
03992
03993 PolyNomial pl;
03994 double orgSum = 0;
03995 for(set<int>::iterator it = occ.begin(); it != occ.end(); ++it)
03996 {
03997 int contClauseIdx = *it;
03998 if (hybridClauseDisValue_[contClauseIdx] == false) {
03999 continue;
04000 }
04001 PolyNomial pltmp = hybridPls_[contClauseIdx];
04002 pltmp.MultiplyConst(hybridWts_[contClauseIdx]);
04003 pl.AddPl(pltmp);
04004 orgSum += hybridClauseValue_[contClauseIdx];
04005 }
04006
04007 if (pl.GetVarNum() == 0)
04008 {
04009 cout << "No hybrid rule is activated ..." << endl;
04010 return NOVALUE;
04011 }
04012
04013
04014 pl.MultiplyConst(-1.0);
04015 LBFGSP lbfgsp(-1, -1, pl.GetVarNum());
04016 double* upper = new double[pl.GetVarNum()];
04017 double* lower = new double[pl.GetVarNum()];
04018 for (int k = 0; k < pl.GetVarNum(); ++k)
04019 {
04020 upper[k] = 10000;
04021 lower[k] = -10000;
04022 }
04023
04024 lbfgsp.setUpperBounds(upper);
04025 lbfgsp.setLowerBounds(lower);
04026
04027 int iter;
04028 bool berror;
04029 double f = lbfgsp.minimize(iter, berror, pl);
04030 delete[] upper;
04031 delete[] lower;
04032
04033 assign.clear();
04034 assign.copyFrom(pl.GetVarValue());
04035
04036 if (hvsdebug) {
04037 cout << "Leaving ReduceClauseAndOptimize ...." << endl;
04038 }
04039
04040 return f*(-1.0) - orgSum;
04041 }
04042
04043
04044
04045 double ReduceClauseAndOptimize(const int& contVarIdx, double* assign)
04046 {
04047 if (hvsdebug) {
04048 cout << "Entering ReduceClauseAndOptimize ...." << endl;
04049 }
04050 set<int> occ;
04051 Array<int>& ar = getContContOccurenceArray(contVarIdx);
04052 for(int j = 0; j < ar.size(); ++j)
04053 {
04054 if (occ.find(ar[j]) == occ.end())
04055 {
04056 occ.insert(ar[j]);
04057 }
04058 }
04059
04060 PolyNomial pl;
04061 double orgSum = 0;
04062 for(set<int>::iterator it = occ.begin(); it != occ.end(); ++it)
04063 {
04064 int contClauseIdx = *it;
04065 if (hybridClauseDisValue_[contClauseIdx] == false || hybridWts_[contClauseIdx] == 0) {
04066 continue;
04067 }
04068 int curInIdx = -1;
04069 Array<double> var_value;
04070 for (int i = 0; i < hybridContClause_[contClauseIdx].size(); ++i) {
04071 int cont_var_idx = hybridContClause_[contClauseIdx][i];
04072 var_value.append(contAtoms_[cont_var_idx]);
04073 if (hybridContClause_[contClauseIdx][i] == contVarIdx) {
04074 curInIdx = i;
04075 }
04076 }
04077
04078 if (curInIdx == -1) {
04079 return NOVALUE;
04080 }
04081
04082 PolyNomial pltmp = hybridPls_[contClauseIdx];
04083 pltmp.MultiplyConst(hybridWts_[contClauseIdx]);
04084 pltmp.ReduceToOneVar(var_value, curInIdx);
04085
04086 pl.AddPl(pltmp);
04087 orgSum += hybridClauseValue_[contClauseIdx];
04088 }
04089
04090 if (pl.GetVarNum() != 1) {
04091
04092 return NOVALUE;
04093 }
04094
04095 pl.MultiplyConst(-1.0);
04096 LBFGSP lbfgsp(-1, -1, 1);
04097 double upper = 10000000;
04098 double lower = -10000000;
04099
04100 lbfgsp.setUpperBounds(&upper);
04101 lbfgsp.setLowerBounds(&lower);
04102
04103 int iter;
04104 bool berror;
04105 double f = lbfgsp.minimize(iter, berror, pl);
04106
04107 *assign = pl.GetVarValue(0);
04108 if (hvsdebug) {
04109 cout << "Leaving ReduceClauseAndOptimize ...." << endl;
04110 }
04111
04112 return f*(-1.0) - orgSum;
04113 }
04114
04115 double OptimizeHybridClauseToContVar(int clause_idx, int cont_var_inIdx) {
04116
04117 PolyNomial pl = hybridPls_[clause_idx];
04118 Array<double> var_value;
04119 for (int i = 0; i < hybridContClause_[clause_idx].size(); ++i) {
04120 int cont_var_idx = hybridContClause_[clause_idx][i];
04121 var_value.append(contAtoms_[cont_var_idx]);
04122 }
04123 pl.SetVarValue(var_value);
04124 pl.ReduceToOneVar(cont_var_inIdx);
04125 LBFGSP lbfgsp(-1,-1, pl.GetVarNum());
04126 double* upper = new double[pl.GetVarNum()];
04127 double* lower = new double[pl.GetVarNum()];
04128 for(int k = 0; k < pl.GetVarNum(); k++)
04129 {
04130 upper[k] = 10000;
04131 lower[k] = -10000;
04132 }
04133 lbfgsp.setUpperBounds(upper);
04134 lbfgsp.setLowerBounds(lower);
04135
04136 int iter;
04137 bool berror;
04138 lbfgsp.minimize(iter, berror, pl);
04139
04140 delete[] upper;
04141 delete[] lower;
04142 return pl.varValue_[0];
04143 }
04144
04145 long double getImprovementByFlippingDisHMWS(const int& atomIdx)
04146 {
04147 assert(atomIdx > 0);
04148 long double improvementDis = makeCost_[atomIdx] - breakCost_[atomIdx];
04149 double improvementCont = getDisImproveInHybridByFlippingHMWS(atomIdx);
04150 return improvementDis + improvementCont;
04151 }
04152
04153
04154
04155 double getDisImproveInHybridByFlippingHMWS(const int& atomIdx)
04156 {
04157 double improvement = 0;
04158 for(int i = 0; i < hybridDisOccurrence_[atomIdx].size(); i++)
04159 {
04160 int contClauseIdx = hybridDisOccurrence_[atomIdx][i];
04161 if (hybridWts_[contClauseIdx] == 0) continue;
04162 double hybridClauseValueBeforeFlip = HybridClauseValue(contClauseIdx);
04163 atom_[atomIdx] = !atom_[atomIdx];
04164 double hybridClauseValueAfterFlip = HybridClauseValue(contClauseIdx);
04165 improvement += hybridClauseValueAfterFlip - hybridClauseValueBeforeFlip;
04166 atom_[atomIdx] = !atom_[atomIdx];
04167 }
04168 return improvement;
04169 }
04170
04171 int getRandomFalseClauseIndexHMWS()
04172 {
04173 int totalFalseClauseNum = numFalseClauses_ + hybridClauseNum_;
04174 int idx = random() % totalFalseClauseNum;
04175
04176 if (idx < numFalseClauses_)
04177 {
04178 return falseClause_[idx] + 1;
04179 }
04180 else
04181 {
04182 return -(idx - numFalseClauses_ + 1);
04183 }
04184 }
04185
04186
04187 double getContVarValueByRandomMove(const int& atomIdx)
04188 {
04189 double vLastCont = contAtoms_[atomIdx];
04190 double stdev = proposalStdev_[atomIdx];
04191 double vContAtomFlipped = ExtRandom::gaussRandom(vLastCont, stdev);
04192 return vContAtomFlipped;
04193 }
04194
04195
04196 Array<int>& getContDisOccurenceArray(const int& idx)
04197 {
04198 return hybridDisOccurrence_[idx];
04199 }
04200
04201
04202 Array<int>& getContContOccurenceArray(const int& idx)
04203 {
04204 return hybridContOccurrence_[idx];
04205 }
04206
04207
04211 const double getMaxClauseWeightTotal()
04212 {
04213 double maxWeight = 0.0;
04214 for (int i = 0; i < getNumClauses(); i++)
04215 {
04216 double weight = abs(clauseCost_[i]);
04217 if (weight > maxWeight) maxWeight = weight;
04218 }
04219
04220 for(int i = 0; i < hybridClauseNum_; i++)
04221 {
04222 double weight = abs(hybridClauseCost_[i]);
04223 if (weight > maxWeight) maxWeight = weight;
04224 }
04225 return maxWeight;
04226 }
04227
04231 const long double getLowCostAll()
04232 {
04233 return lowCostAll_;
04234 }
04235
04239 const int getLowBadAll()
04240 {
04241 return lowBadAll_;
04242 }
04243
04244
04245 const long double getLowCostCont()
04246 {
04247 return lowCostHybrid_;
04248 }
04249
04253 const int getLowBadCont()
04254 {
04255 return lowBadHybrid_;
04256 }
04257
04258 void printFalseClauses(ostream& os)
04259 {
04260 os << "dis false clauses:" << endl;
04261 for(int i = 0; i < numFalseClauses_; i++)
04262 {
04263 int fcIdx = falseClause_[i];
04264 GroundClause* pC = getGndClause(fcIdx);
04265 os << "clause " << fcIdx << ":";pC->printWithWtAndStrVar(os, domain_, &gndPredHashArray_);
04266 os << " ";
04267 for(int j = 0; j < clause_[fcIdx].size(); j++)
04268 {
04269 int predIdx = abs(clause_[fcIdx][j]);
04270 (*gndPreds_)[predIdx-1]->print(os, domain_);
04271 os << ": " << atom_[predIdx] <<"; ";
04272 }
04273 os << endl;
04274 }
04275 os << "cont false clauses:" << endl;
04276 for(int i = 0;i < hybridFalseConstraintNum_; i++)
04277 {
04278 int fcIdx = hybridFalseClause_[i];
04279 printHybridConstraint(fcIdx, os);
04280 os << endl;
04281 }
04282
04283 }
04284
04285
04286
04287
04288 void saveLowToCurrentAll()
04289 {
04290 saveLowToCurrentDis();
04291 saveLowToCurrentCont();
04292 costOfTotalFalseConstraints_ = lowCostAll_;
04293 totalFalseConstraintNum_ = lowBadAll_;
04294 }
04295
04296 void saveLowToCurrentDis()
04297 {
04298
04299 atom_.copyFrom(lowAtom_);
04300 costOfFalseClauses_= lowCost_;
04301 numFalseClauses_ = lowBad_;
04302 falseClause_.copyFrom(falseClauseLow_);
04303
04304
04305 }
04306
04307 void saveLowToCurrentCont()
04308 {
04309 contAtomsBackup_.copyFrom(contAtoms_);
04310 contAtoms_.copyFrom(contAtomsLow_);
04311 costHybridFalseConstraint_ = lowCostHybrid_;
04312 hybridFalseConstraintNum_ = lowBadHybrid_;
04313 hybridFalseClause_.copyFrom(hybridFalseClauseLow_);
04314 }
04315
04316
04317 void saveLowStateAll()
04318 {
04319 saveLowState();
04320 saveLowStateCont();
04321
04322 lowCostAll_ = costOfTotalFalseConstraints_ ;
04323 lowBadAll_ = totalFalseConstraintNum_ ;
04324 }
04325 void saveLowStateCont()
04326 {
04327 for (int i = 1; i <= contAtomNum_; i++)
04328 {
04329 contAtomsLow_[i] = contAtoms_[i];
04330 if (hvsdebug) cout << contAtomsLow_[i] << endl;
04331 }
04332 lowCostHybrid_ = costHybridFalseConstraint_;
04333 lowBadHybrid_ = hybridFalseConstraintNum_;
04334 hybridFalseClauseLow_.copyFrom(hybridFalseClause_);
04335 }
04339
04340 void saveCurrentAsLastAssignment()
04341 {
04342 atomsLast_.copyFrom(atom_);
04343 contAtomsLast_.copyFrom(contAtoms_);
04344 }
04345
04346 void saveLastAsCurrentAssignment()
04347 {
04348 atom_.copyFrom(atomsLast_);
04349 contAtoms_.copyFrom(contAtomsLast_);
04350 }
04351 void updateCost()
04352 {
04353 hybridFalseConstraintNum_ = 0;
04354 costHybridFalseConstraint_ = 0;
04355 totalFalseConstraintNum_ = 0;
04356 costOfTotalFalseConstraints_ = 0;
04357 numFalseClauses_ = 0;
04358 costOfFalseClauses_ = 0;
04359 weightSumCont_ = 0;
04360 weightSumDis_ = 0;
04361 initMakeBreakCostWatch();
04362 initMakeBreakCostWatchCont();
04363 }
04364
04365
04366
04367 void getContClauseGndings(Array<double>* const & numGndings)
04368 {
04369 assert(numGndings->size() == hybridFormulaNum_);
04370 for(int i = 0; i < hybridFormulaNum_; i++)
04371 {
04372 Array<int>& ar = hybridFormulaGndClauseIdx_[i];
04373 double v = 0;
04374 for(int j = 0; j < ar.size(); j++)
04375 {
04376 v += hybridClauseValue_[ar[j]];
04377
04378 }
04379 (*numGndings)[i] += v;
04380 }
04381 }
04382
04383 void getContClauseGndingsWithUnknown(double numGndings[], int contClauseCnt, const Array<bool>* const& unknownPred)
04384 {
04385 assert(unknownPred->size() == getNumAtoms());
04386 assert(contClauseCnt == getNumContFormulas());
04387
04388 for (int clauseno = 0; clauseno < contClauseCnt; clauseno++)
04389 numGndings[clauseno] = 0;
04390 for(int i = 0; i < contClauseCnt; i++)
04391 {
04392 Array<int>& ar = hybridFormulaGndClauseIdx_[i];
04393 for(int j = 0;j < ar.size(); j++)
04394 {
04395 int contClauseIdx = ar[j];
04396 Array<int>& contDis = hybridDisClause_[contClauseIdx];
04397 bool bUnknown = false;
04398 int satLitcnt = 0;
04399 for(int k = 0; k < contDis.size(); k++)
04400 {
04401 int lit = contDis[k];
04402 if ((*unknownPred)[abs(lit) - 1])
04403 {
04404 bUnknown = true;
04405 continue;
04406 }
04407 if (isTrueLiteral(lit)) satLitcnt++;
04408 }
04409 if (hybridConjunctionDisjunction_[contClauseIdx])
04410 {
04411 if (bUnknown)
04412 {
04413 cout << "unknown, shouldn't be here" << endl;
04414 continue;
04415 }
04416 else if (satLitcnt < contDis.size())
04417 {
04418 numGndings[i] += 0;
04419 }
04420 else
04421 {
04422 numGndings[i] += HybridClauseValueNonWt(contClauseIdx);
04423 }
04424 }
04425 else
04426 {
04427 if (satLitcnt > 0)
04428 {
04429 numGndings[i] += HybridClauseValueNonWt(contClauseIdx);
04430 }
04431 else if (bUnknown)
04432 {
04433 cout << "unknown, shouldn't be here" << endl;
04434 continue;
04435 }
04436 else
04437 {
04438 numGndings[i] += 0;
04439 }
04440 }
04441 }
04442 }
04443 }
04444
04456 void getNumClauseGndingsWithUnknown(double numGndings[], int clauseCnt,
04457 bool tv,
04458 const Array<bool>* const& unknownPred)
04459 {
04460
04461 assert(unknownPred->size() == getNumAtoms());
04462 IntBoolPairItr itr;
04463 IntBoolPair *clauseFrequencies;
04464
04465 for (int clauseno = 0; clauseno < clauseCnt; clauseno++)
04466 numGndings[clauseno] = 0;
04467
04468 for (int i = 0; i < gndClauses_->size(); i++)
04469 {
04470 GroundClause *gndClause = (*gndClauses_)[i];
04471 int satLitcnt = 0;
04472 bool unknown = false;
04473 for (int j = 0; j < gndClause->getNumGroundPredicates(); j++)
04474 {
04475 int lit = gndClause->getGroundPredicateIndex(j);
04476 if ((*unknownPred)[abs(lit) - 1])
04477 {
04478 unknown = true;
04479 continue;
04480 }
04481 if (isTrueLiteral(lit)) satLitcnt++;
04482 }
04483
04484 clauseFrequencies = gndClause->getClauseFrequencies();
04485 for (itr = clauseFrequencies->begin();
04486 itr != clauseFrequencies->end(); itr++)
04487 {
04488 int clauseno = itr->first;
04489 int frequency = itr->second.first;
04490 bool invertWt = itr->second.second;
04491
04492 if (invertWt)
04493 {
04494
04495 if (tv && (satLitcnt > 0 || unknown))
04496 continue;
04497
04498 if (!tv && satLitcnt == 0)
04499 continue;
04500 }
04501 else
04502 {
04503
04504 if (tv && satLitcnt == 0)
04505 continue;
04506
04507 if (!tv && (satLitcnt > 0 || unknown))
04508 continue;
04509 }
04510 numGndings[clauseno] += frequency;
04511 }
04512 }
04513 }
04514
04515
04527
04528
04529
04530
04531
04532
04533
04534
04535
04536
04537
04538
04539
04540
04541
04542
04543
04544
04545
04546
04547
04548
04549
04550
04551
04552
04553
04554
04555
04556
04557
04558
04559
04560
04561
04562
04563
04564
04565
04566
04567
04568
04569
04570
04571
04572
04573
04574 void printLowStateCont(ostream& os)
04575 {
04576 for(int i = 0; i < contAtomNum_; i++)
04577 {
04578 map<int,string>::const_iterator citer = gndPredReverseCont_.find(i+1);
04579 os << citer->second << " " <<contAtoms_[i+1] << endl;
04580 }
04581 }
04582
04583 void printLowStateAll(ostream& os)
04584 {
04585 printLowState(os);
04586 printLowStateCont(os);
04587 }
04588
04589
04591
04593
04595
04596
04597
04598 void recordAtomMakeDisClauseFalse(int clauseIdx, Array<int>* record)
04599 {
04600 RecordAtomMakeClauseFalse(hybridDisClause_[clauseIdx], atom_, hybridConjunctionDisjunction_[clauseIdx], record);
04601 }
04602
04603
04604
04605
04606 void recordAtomMakeDisClauseTrue(int clauseIdx, Array<int>* record)
04607 {
04608 RecordAtomMakeClauseTrue(hybridDisClause_[clauseIdx], atom_, hybridConjunctionDisjunction_[clauseIdx], record);
04609 }
04610
04611 double HybridClauseValueNonWt(int contClauseIdx)
04612 {
04613 return HybridClauseContPartValue(contClauseIdx) * double(HybridClauseDisPartValue(contClauseIdx));
04614 }
04615 double HybridClauseValue(int contClauseIdx, bool& dis, double& cont)
04616 {
04617 dis = HybridClauseDisPartValue(contClauseIdx);
04618 cont = HybridClauseContPartValue(contClauseIdx);
04619 if (0 == dis)
04620 {
04621 return 0;
04622 }
04623
04624 return hybridWts_[contClauseIdx] * double(dis) * cont;
04625 }
04626
04627 double HybridClauseValue(int contClauseIdx)
04628 {
04629 bool dis = 0;
04630 double cont = 0;
04631 return HybridClauseValue(contClauseIdx, dis, cont);
04632 }
04633
04634 double HybridClauseContPartValue(int contClauseIdx)
04635 {
04636 PolyNomial& pl = GetHybridClausePolynomial(contClauseIdx);
04637 assert(hybridContClause_[contClauseIdx].size() == pl.GetVarNum());
04638 Array<double> cont_var_values;
04639 for(int i = 0; i < hybridContClause_[contClauseIdx].size(); i++)
04640 {
04641 cont_var_values.append(contAtoms_[hybridContClause_[contClauseIdx][i]]);
04642 }
04643 return pl.ComputePlValue(cont_var_values);
04644 }
04645
04646 bool HybridClauseDisPartValue(int contClauseIdx)
04647 {
04648 Array<int>& contDisClause = hybridDisClause_[contClauseIdx];
04649 bool bClause;
04650 if (hybridConjunctionDisjunction_[contClauseIdx])
04651 {
04652 bClause = true;
04653 for(int i = 0; i < contDisClause.size(); i++)
04654 {
04655 bool b = (atom_[abs(contDisClause[i])] == (contDisClause[i] > 0));
04656 if (!b)
04657 {
04658 bClause = false;
04659 break;
04660 }
04661 }
04662 }
04663 else
04664 {
04665 bClause = false;
04666 for(int i = 0; i < contDisClause.size(); i++)
04667 {
04668 bool b = (atom_[abs(contDisClause[i])] == (contDisClause[i] > 0));
04669 if (b)
04670 {
04671 bClause = true;
04672 break;
04673 }
04674 }
04675 }
04676
04677 return bClause;
04678 }
04679
04680 PolyNomial& GetHybridClausePolynomial(int contClauseIdx)
04681 {
04682 return hybridPls_[contClauseIdx];
04683 }
04684
04685
04686
04687 bool isSatisfied(int iContClauseIdx)
04688 {
04689 return isSatisfied(hybridConstraints_[iContClauseIdx]);
04690 }
04691
04692
04693 bool isSatisfied(const HybridConstraint& cst, double currentValue)
04694 {
04695 assert(hybridWts_[cst.contClauseIdx_] != 0);
04696 if (currentValue >= cst.vThreshold_)
04697 {
04698 return true;
04699 }
04700 else return false;
04701 }
04702
04703
04704 bool CheckIfLBFGSCacheSatisfied(int contClauseIdx)
04705 {
04706
04707 PolyNomial pl = hybridPls_[contClauseIdx];
04708 pl.SetVarValue(lbfgsCache_[contClauseIdx]);
04709 double plValue = pl.ComputePlValue();
04710 bool dis = HybridClauseDisPartValue(contClauseIdx);
04711 return isSatisfied(hybridConstraints_[contClauseIdx], plValue * double(dis));
04712 }
04713
04714
04715 bool isSatisfied(const HybridConstraint& cst)
04716 {
04717
04718 double cont;
04719 bool dis;
04720 double currentValue = HybridClauseValue(cst.contClauseIdx_,dis, cont);
04721 return isSatisfied(cst, currentValue);
04722 }
04723
04724 void LoadDisPartAtoms(const string & str, Array<int>& arDis, map<string, int>& gndPredCont, const int& clauseIdx)
04725 {
04726 stringstream s(str);
04727 string strPred;
04728 while(getline(s, strPred, ';'))
04729 {
04730 bool bFalse = false;
04731 if (strPred[0] == '!')
04732 {
04733 strPred = strPred.substr(1, strPred.length() - 1);
04734 bFalse = true;
04735 }
04736
04737 map<string, int>::const_iterator citer;
04738 citer = gndPredCont.find(strPred);
04739
04740
04741 if (citer == gndPredCont.end())
04742 {
04743 cout << "unseen dis predicate:" <<strPred << endl;
04744 }
04745
04746 assert(citer != gndPredCont.end());
04747
04748 if (bFalse)
04749 {
04750 arDis.append(-1*citer->second);
04751 }
04752 else
04753 {
04754 arDis.append(citer->second);
04755 }
04756 hybridDisOccurrence_[citer->second].append(clauseIdx);
04757 }
04758 }
04759
04760 void LoadContPartAtoms(const string & str, Array<int>& arDis)
04761 {
04762 stringstream s(str);
04763 string strPred;
04764 while(getline(s, strPred, ';'))
04765 {
04766 int contAtomNum = gndPredCont_.size();
04767 map<string, int>::const_iterator citer;
04768 if ((citer = gndPredCont_.find(strPred)) != gndPredCont_.end())
04769 {
04770 arDis.append(citer->second);
04771 }
04772 else
04773 {
04774 gndPredCont_.insert(map<string,int>::value_type(strPred, contAtomNum+1));
04775 gndPredReverseCont_.insert(map<int,string>::value_type(contAtomNum+1, strPred));
04776 arDis.append(contAtomNum+1);
04777 }
04778 }
04779 }
04780
04781 void printContAtom(int conAtomIdx, ostream& os)
04782 {
04783 map<int, string>::const_iterator citer;
04784 citer = gndPredReverseCont_.find(conAtomIdx);
04785 os << citer->second << ": " << contAtoms_[citer->first] << "; ";
04786 }
04787
04788 void printContAtoms(ostream& os)
04789 {
04790 map<int, string>::const_iterator citer;
04791 for(citer = gndPredReverseCont_.begin(); citer != gndPredReverseCont_.end(); ++citer)
04792 {
04793 os << citer->second << ": " << contAtoms_[citer->first] << "; ";
04794 }
04795 }
04796
04797 void PrintDisAtoms(ostream& os)
04798 {
04799 for(int i = 0; i < getNumAtoms(); i++)
04800 {
04801 (*gndPreds_)[i]->print(os, domain_);
04802 os << ": " << atom_[i+1] <<"; ";
04803 }
04804 }
04805
04806 void PrintContPartMLN(ostream& os)
04807 {
04808 for(int i = 0;i < hybridClauseNum_; i++)
04809 {
04810 os << hybridConjunctionDisjunction_[i] << '|' << hybridWts_[i] << '|';
04811 for(int j = 0; j < hybridDisClause_[i].size(); j++)
04812 {
04813 (*gndPreds_)[abs(hybridDisClause_[i][j])-1]->print(os, domain_);
04814 os << ';';
04815 }
04816 os << '|';
04817 for(int j = 0; j < hybridContClause_[i].size(); j++)
04818 {
04819 os << gndPredReverseCont_[hybridContClause_[i][j]] <<';';
04820 }
04821 os << '|';
04822 hybridPls_[i].PrintTo(os);
04823 os << endl;
04824 }
04825 }
04826
04827 void printContOccurrence(ostream& os)
04828 {
04829 os << "Dis occur, atoms: " << hybridDisOccurrence_.size() - 1 << endl;
04830 for(int i = 1; i < hybridDisOccurrence_.size(); i++)
04831 {
04832 os << "atom " << i << " occurs at " << hybridDisOccurrence_[i].size() << " different cont clauses; ";
04833 for(int j = 0; j < hybridDisOccurrence_[i].size(); j++)
04834 {
04835 os << hybridDisOccurrence_[i][j] << " ";
04836 }
04837 os << endl;
04838 }
04839
04840 os << "Cont occur, atoms: " << hybridContOccurrence_.size() - 1 << endl;
04841 for(int i = 1; i < hybridContOccurrence_.size(); i++)
04842 {
04843 os << "atom " << i << " occurs at " << hybridContOccurrence_[i].size() << " different cont clauses; ";
04844 for(int j = 0; j < hybridContOccurrence_[i].size(); j++)
04845 {
04846 os << hybridContOccurrence_[i][j] << " ";
04847 }
04848 os << endl;
04849 }
04850 }
04851
04852 void buildContOccurrence()
04853 {
04854 for(int i = 0; i < hybridContClause_.size(); i++)
04855 {
04856 for(int j = 0; j < hybridContClause_[i].size(); j++)
04857 {
04858 hybridContOccurrence_[hybridContClause_[i][j]].append(i);
04859 }
04860 }
04861 }
04862
04863 void setDisVarValueFromEvi()
04864 {
04865 for(int i = 0; i < getNumAtoms(); i++)
04866 {
04867 atom_[i+1] = atomEvi_[i+1];
04868 }
04869 }
04870 void setContVarValueFromEvi()
04871 {
04872 for(int i = 0; i < contAtomNum_; i++)
04873 {
04874 contAtoms_[i+1] = contAtomsEvi_[i+1];
04875
04876 }
04877 }
04878
04879 void LoadDisEviValuesFromRst(const char* szDisEvi)
04880 {
04881 for(int i = 1; i < atomEvi_.size(); i++)
04882 {
04883 atomEvi_[i] = false;
04884 }
04885 map<string, int> gndPredCont;
04886 for(int i = 0; i < gndPreds_->size(); i++)
04887 {
04888 string str = (*gndPreds_)[i]->getPredicateStr(domain_);
04889 gndPredCont.insert(map<string, int>::value_type(str, i+1));
04890 }
04891 ifstream is(szDisEvi);
04892 string strLine;
04893 while (getline(is, strLine))
04894 {
04895 stringstream ss(strLine);
04896 string strtmp;
04897 getline(ss,strtmp, ' ');
04898
04899
04900 map<string, int>::const_iterator citer;
04901 citer = gndPredCont.find(strtmp);
04902 if (citer == gndPredCont.end())
04903 {
04904 cout << "dis evi file error, non-existent query gndings" << endl;
04905 cout << strLine << endl;
04906 exit(1);
04907 }
04908 int atomIdx = citer->second;
04909
04910
04911 getline(ss, strtmp);
04912 int b = atoi(strtmp.c_str());
04913 if (b==1)
04914 {
04915 atomEvi_[atomIdx] = true;
04916 }
04917 else
04918 {
04919 atomEvi_[atomIdx] = false;
04920 }
04921 }
04922 }
04923 void LoadDisEviValues(const char* szDisEvi)
04924 {
04925 for(int i = 1; i < atomEvi_.size(); i++)
04926 {
04927 atomEvi_[i] = false;
04928 }
04929 map<string, int> gndPredCont;
04930 for(int i = 0; i < gndPreds_->size(); i++)
04931 {
04932 string str = (*gndPreds_)[i]->getPredicateStr(domain_);
04933 gndPredCont.insert(map<string, int>::value_type(str, i+1));
04934 }
04935 ifstream is(szDisEvi);
04936 string strLine;
04937 while (getline(is, strLine))
04938 {
04939
04940
04941
04942
04943
04944 map<string, int>::const_iterator citer;
04945 citer = gndPredCont.find(strLine);
04946 if (citer == gndPredCont.end())
04947 {
04948 cout << "dis evi file error, non-existent query gndings" << endl;
04949 cout << strLine << endl;
04950 exit(1);
04951 }
04952 int atomIdx = citer->second;
04953 atomEvi_[atomIdx] = true;
04954
04955
04956
04957
04958
04959
04960
04961
04962
04963
04964
04965 }
04966 }
04967
04968
04969 void LoadContEviValues(const char* szContEvi)
04970 {
04971 map<string, int>::const_iterator citer;
04972 string strLine;
04973 ifstream is(szContEvi);
04974 while (getline(is, strLine))
04975 {
04976 stringstream ss(strLine);
04977 string strTmp;
04978 getline(ss, strTmp, ' ');
04979 citer = gndPredCont_.find(strTmp);
04980 if (citer == gndPredCont_.end())
04981 {
04982 cout << "cont evi file error, non-existent query gndings" << endl;
04983 exit(1);
04984 }
04985 getline(ss, strTmp);
04986 contAtomsEvi_[citer->second] = atof(strTmp.c_str());
04987 }
04988 }
04989
04990 void LoadContGroundedMLN(const char* szContFile)
04991 {
04992 ifstream is(szContFile);
04993 if(!is.good())
04994 {
04995 cout << "cont file error" << endl;
04996 exit(0);
04997 }
04998 string strLine;
04999
05000 for(int i = 0; i < gndPreds_->size(); i++)
05001 {
05002 string str = (*gndPreds_)[i]->getPredicateStr(domain_);
05003 gndPredDis_.insert(map<string, int>::value_type(str, i+1));
05004 }
05005
05006 hybridDisOccurrence_.growToSize(getNumAtoms() + 1);
05007 while (getline(is, strLine))
05008 {
05009 stringstream ss(strLine);
05010 string str;
05011 getline(ss, str, '|');
05012 hybridGndClauseToFormulaMap_.append(atoi(str.c_str()));
05013 getline(ss, str, '|');
05014 if (str == "1")
05015 {
05016 hybridConjunctionDisjunction_.append(true);
05017 }
05018 else hybridConjunctionDisjunction_.append(false);
05019
05020 getline(ss, str, '|');
05021 hybridWts_.append(atof(str.c_str()));
05022 hybridClauseCost_.append(atof(str.c_str()));
05023
05024 Array<int> arDis;
05025 getline(ss, str, '|');
05026 LoadDisPartAtoms(str, arDis, gndPredDis_, hybridClauseNum_);
05027 hybridDisClause_.append(arDis);
05028 arDis.clear();
05029 getline(ss, str, '|');
05030 LoadContPartAtoms(str, arDis);
05031 hybridContClause_.append(arDis);
05032
05033 getline(ss, str, '|');
05034 PolyNomial pl;
05035 istringstream iss(str);
05036 pl.ReadFrom(iss);
05037 hybridPls_.append(pl);
05038
05039
05040 HybridConstraint cst;
05041 cst.contClauseIdx_ = hybridClauseNum_;
05042
05043
05044 cst.vThreshold_ = -BigValue;
05045 cst.bSatisfiedLast_ = true;
05046 cst.unSatType_ = UNKNOWN;
05047 hybridConstraints_.append(cst);
05048 hybridClauseNum_++;
05049 }
05050
05051 contAtomNum_ = gndPredCont_.size();
05052 contAtomRange_.growToSize(contAtomNum_);
05053 proposalStdev_.growToSize(contAtomNum_+1,0);
05054 contAtoms_.growToSize(contAtomNum_ + 1, 0);
05055 contAtomsLast_.growToSize(contAtomNum_ + 1, 0);
05056 contAtomsEvi_.growToSize(contAtomNum_ + 1, NOVALUE);
05057 hybridContOccurrence_.growToSize(contAtomNum_ + 1);
05058
05059 buildContOccurrence();
05060 set<int> contFormulaSet;
05061 for(int i = 0; i < hybridGndClauseToFormulaMap_.size(); i++)
05062 {
05063 contFormulaSet.insert(hybridGndClauseToFormulaMap_[i]);
05064 }
05065
05066 hybridFormulaNum_ = contFormulaSet.size();
05067 hybridFormulaGndClauseIdx_.growToSize(hybridFormulaNum_);
05068
05069 for(int i = 0; i < hybridGndClauseToFormulaMap_.size(); i++)
05070 {
05071 hybridFormulaGndClauseIdx_[hybridGndClauseToFormulaMap_[i]].append(i);
05072 }
05073
05074
05075 hybridFalseClause_.growToSize(hybridClauseNum_);
05076 hybridWhereFalse_.growToSize(hybridClauseNum_);
05077 lbfgsCache_.growToSize(hybridClauseNum_);
05078 hmwsContOptimal_.growToSize(hybridClauseNum_);
05079 hmwsDisOptimal_.growToSize(hybridClauseNum_);
05080 contAtomsLow_.growToSize(contAtomNum_ + 1, 0);
05081 hybridClauseValue_.growToSize(hybridClauseNum_, 0);
05082 hybridClauseDisValue_.growToSize(hybridClauseNum_, false);
05083 totalAtomNum_ = contAtomNum_ + getNumAtoms();
05084 numFalseClauses_ = 0;
05085 initRange();
05086
05087 if (hvsdebug)
05088 {
05089 cout << "cont atom number: " << contAtomNum_ << endl;
05090 printContOccurrence(cout);
05091 }
05092 }
05093
05094 int getNumContFormulas()
05095 {
05096 return hybridFormulaNum_;
05097 }
05098
05099
05100
05101 void initRange()
05102 {
05103 if(contAtomRange_.size() < contAtomNum_)
05104 {
05105 contAtomRange_.growToSize(contAtomNum_);
05106 }
05107 else if (contAtomRange_.size() > contAtomNum_)
05108 {
05109 contAtomRange_.shrinkToSize(contAtomNum_);
05110 }
05111 for(int i = 0; i < contAtomRange_.size(); i++)
05112 {
05113 contAtomRange_[i].low = 0;
05114 contAtomRange_[i].high = 2;
05115 contAtomRange_[i].iType = 0;
05116 }
05117 }
05118
05119 double randomSampleRange(const DoubleRange& r)
05120 {
05121
05122 if (r.iType == 0)
05123 {
05124 return double(random())*(r.high-r.low)/double(RAND_MAX) + r.low;
05125 }
05126 else if (r.iType == 1)
05127 {
05128
05129 double leftR,rightR;
05130 if (r.low < -ABSBIG && r.high < ABSBIG)
05131 {
05132
05133 DoubleRange rt;
05134 rt.iType = 0;
05135 rt.high = ABSBIG;
05136 rt.low = max(r.high, -ABSBIG);
05137
05138 return randomSampleRange(rt);
05139
05140 }
05141 else if (r.low < -ABSBIG && r.high > ABSBIG)
05142 {
05143 return 0;
05144 }
05145 else if (r.low > -ABSBIG && r.high > ABSBIG)
05146 {
05147 DoubleRange rt;
05148 rt.iType = 0;
05149 rt.low = -ABSBIG;
05150 rt.high = MIN(r.low, ABSBIG);
05151
05152 return randomSampleRange(rt);
05153
05154 }
05155 else if (r.low > -ABSBIG && r.high < ABSBIG)
05156 {
05157 leftR = r.low + ABSBIG;
05158 rightR = ABSBIG - r.high;
05159 double rs = double(random())/ double(RAND_MAX);
05160
05161 if (rs < leftR /(leftR + rightR))
05162 {
05163 return -ABSBIG + (leftR + rightR)*rs;
05164 }
05165 else
05166 {
05167 rs = rs - leftR /(leftR + rightR);
05168 return r.high + rs* (leftR + rightR);
05169 }
05170 }
05171 }
05172 return 0;
05173 }
05174
05175
05176 double computeMaxValue(PolyNomial& pl,int contClauseIdx, int i)
05177 {
05178 if (contClauseIdx >= hybridClauseNum_)
05179 {
05180 cout << "Cont clause Exceed, " << contClauseIdx << ", " << i << endl;
05181 }
05182
05183 if(i >= hybridContClause_[contClauseIdx].size())
05184 cout << "Cont Atom Exceed, " << contClauseIdx << ", " << i << endl;
05185
05186
05187 int atomIdx = hybridContClause_[contClauseIdx][i];
05188 double m1, m2;
05189
05190 if (i < pl.GetVarNum() -1 )
05191 {
05192 (pl.GetVarValue())[i] = contAtomRange_[atomIdx].low;
05193 m1 = computeMaxValue(pl, contClauseIdx, i+1);
05194
05195 (pl.GetVarValue())[i] = contAtomRange_[atomIdx].high;
05196 m2 = computeMaxValue(pl, contClauseIdx,i+1);
05197 }
05198
05199
05200 if (i == pl.GetVarNum() - 1)
05201 {
05202 (pl.GetVarValue())[i] = contAtomRange_[atomIdx].low;
05203 m1 = pl.ComputePlValue();
05204
05205 (pl.GetVarValue())[i] = contAtomRange_[atomIdx].high;
05206 m2 = pl.ComputePlValue();
05207 }
05208
05209 if (m1 > m2)
05210 {
05211 return m1;
05212 }
05213 else
05214 return m2;
05215 }
05216
05217 void setProposalStdev(const char* szStdev)
05218 {
05219 ifstream is(szStdev);
05220 if (!is.good())
05221 {
05222 cout << "proposal stdev file error." << endl;
05223 exit(0);
05224 }
05225 string strLine;
05226 int i = 0;
05227 while (getline(is, strLine) && i < getNumContAtoms())
05228 {
05229 stringstream ss(strLine);
05230 ss >> contAtomRange_[i].low >> contAtomRange_[i].high >> proposalStdev_[i+1];
05231
05232 i++;
05233 }
05234
05235 if ( i != contAtomNum_)
05236 {
05237 cout << "propos stdev file not match!" << endl;
05238 cout << i << "\t" << contAtomNum_ << endl;
05239 for (int j = 0; j < contAtomNum_; j++)
05240 {
05241 printContAtom(j + 1,cout);cout << endl;
05242 }
05243 }
05244
05245
05246 for(int j = 0;j < hybridClauseNum_; j++)
05247 {
05248 int varNum = hybridPls_[j].GetVarNum();
05249 LBFGSP* lbfgsp = new LBFGSP(-1,-1,varNum);
05250 double* upper = new double[varNum];
05251 double* lower = new double[varNum];
05252 for(int k = 0; k < hybridContClause_[j].size(); k++)
05253 {
05254 upper[k] = contAtomRange_[hybridContClause_[j][k]-1].high;
05255 lower[k] = contAtomRange_[hybridContClause_[j][k]-1].low;
05256 }
05257 lbfgsp->setUpperBounds(upper);
05258 lbfgsp->setLowerBounds(lower);
05259 PolyNomial pl = hybridPls_[j];
05260
05261 if (hybridClauseCost_[j] > 0)
05262 {
05263 pl.MultiplyConst(-1.0);
05264 }
05265
05266 lbfgsp->startLBFGS(pl);
05267 lbfgsCache_[j].copyFrom(pl.GetVarValue());
05268 contsolvers_.append(lbfgsp);
05269 delete[] upper;
05270 delete[] lower;
05271 }
05272 }
05273
05274 void proceedOneStepAndCache(int contClauseIdx, PolyNomial& pl)
05275 {
05276 if(wjhvsdbg)
05277 {
05278 cout << "begin proceedOneStepAndCache" << endl;
05279 }
05280
05281 LBFGSP* lbfgsp = contsolvers_[contClauseIdx];
05282 pl.SetVarValue(lbfgsCache_[contClauseIdx]);
05283 lbfgsp->proceedOneStep(pl);
05284
05285 lbfgsCache_[contClauseIdx].copyFrom(pl.GetVarValue());
05286
05287 if(wjhvsdbg)
05288 {
05289 cout << "end proceedOneStepAndCache" << endl;
05290 }
05291 }
05292
05293 bool SolveContByLBFGS(int contClauseIdx, int maxIter)
05294 {
05295
05296
05297 PolyNomial pl = hybridPls_[contClauseIdx];
05298 pl.MultiplyConst(-1.0);
05299 bool bSat = false;
05300 for(int i = 0; i < maxIter; i++)
05301 {
05302 proceedOneStepAndCache(contClauseIdx, pl);
05303 double plValue = pl.ComputePlValue();
05304 cout << "step " << i << ", polynomial value " << plValue << endl;
05305 if(isSatisfied(hybridConstraints_[contClauseIdx], -1*plValue))
05306 {
05307 bSat = true;
05308 break;
05309 }
05310 }
05311 return bSat;
05312 }
05313
05314 void initContinuousVariableRandom()
05315 {
05316 if(hvsdebug)
05317 {
05318 cout << "entering init continuous random" << endl;
05319 }
05320
05321 assert(contAtomNum_ == contAtomRange_.size());
05322
05323 for (int i = 0; i < contAtomNum_; i++)
05324 {
05325 contAtoms_[i+1] = contAtomRange_[i].low + (contAtomRange_[i].high - contAtomRange_[i].low)*double(random()) / double(RAND_MAX);
05326 }
05327
05328 if(hvsdebug)
05329 {
05330 cout << "leaving init continuous random" << endl;
05331 }
05332 }
05333
05334
05335 private:
05336
05337
05338
05339
05341
05343
05344
05345 DoubleRange SolveHybridConstraintToContVar(const int& contClauseIdx, const int& inIdx)
05346 {
05347
05348 PolyNomial pl = hybridPls_[contClauseIdx];
05349 pl.MultiplyConst(hybridWts_[contClauseIdx]);
05350 double d = hybridConstraints_[contClauseIdx].vThreshold_;
05351
05352 Array<double> currentVars;
05353 int i;
05354 for( i = 0; i < hybridContClause_[contClauseIdx].size(); ++i)
05355 {
05356 currentVars.append(contAtoms_[hybridContClause_[contClauseIdx][i]]);
05357 }
05358
05359 assert(inIdx >= 0 && inIdx < hybridContClause_[contClauseIdx].size());
05360 pl.ReduceToOneVar(currentVars, inIdx);
05361 DoubleRange r = pl.SolvePoly2(d);
05362 return r;
05363 }
05364
05366
05368
05374 void setHardClauseWeight()
05375 {
05376
05377 long double sumSoftWts = 0.0;
05378
05379 int clauseCnt = mln_->getNumClauses();
05380
05381 for (int i = 0; i < clauseCnt; i++)
05382 {
05383 Clause* fclause = (Clause *) mln_->getClause(i);
05384
05385 if (fclause->isHardClause()) continue;
05386
05387 long double wt = abs(fclause->getWt());
05388 long double numGndings = fclause->getNumGroundings(domain_);
05389 sumSoftWts += wt*numGndings;
05390 }
05391
05392 assert(sumSoftWts >= 0);
05393
05394 hardWt_ = sumSoftWts + 10.0;
05395
05396 }
05397
05398
05399 public:
05400
05401
05402
05403
05404 const static int MODE_MWS = 0;
05405 const static int MODE_HARD = 1;
05406 const static int MODE_SAMPLESAT = 2;
05407
05408 const static int ADD_CLAUSE_INITIAL = 0;
05409 const static int ADD_CLAUSE_REGULAR = 1;
05410 const static int ADD_CLAUSE_DEAD = 2;
05411 const static int ADD_CLAUSE_SAT = 3;
05412
05413
05414
05415
05416 Array<GroundPredicate*>* gndPreds_;
05417 Array<GroundClause*>* gndClauses_;
05418
05419
05420 GroundPredicateHashArray* unePreds_;
05421
05422
05423 GroundPredicateHashArray* knePreds_;
05424
05425 Array<TruthValue>* knePredValues_;
05426
05427 Array<GroundClause*> newClauses_;
05428
05429 Array<GroundPredicate*> newPreds_;
05430
05431
05432 GroundPredicateHashArray gndPredHashArray_;
05433
05434
05435 Array<Array<int> > clause_;
05436
05437 Array<long double> clauseCost_;
05438
05439 Array<int> falseClause_;
05440 Array<int> falseClauseLow_;
05441
05442 Array<int> whereFalse_;
05443
05444 Array<int> numTrueLits_;
05445
05446 Array<int> watch1_;
05447
05448 Array<int> watch2_;
05449
05450 Array<bool> isSatisfied_;
05451
05452 Array<bool> deadClause_;
05453
05454 bool useThreshold_;
05455
05456 Array<long double> threshold_;
05457
05458
05459
05460 Array<Array<int> > occurence_;
05461
05462
05463 Array<long double> makeCost_;
05464
05465 Array<long double> breakCost_;
05466
05467
05468 Array<int> fixedAtom_;
05469
05470 Array<bool> lowAtom_;
05471
05472 long double lowCost_;
05473
05474
05475 Array<bool> atom_;
05476
05478
05480
05481 bool bInitFromEvi_;
05482
05483
05484 Array<bool> atomEvi_;
05485 Array<bool> atomsLast_;
05486
05487
05488 Array<LBFGSP*> contsolvers_;
05489 Array<HybridConstraint> hybridConstraints_;
05490 Array<PolyNomial> hybridPls_;
05491 Array<double> hybridWts_;
05492 map<int, double> contOptimum_;
05493 map<int, Array<double> > contOptimumAssignment_;
05494
05495 Array<double> contAtomsLast_;
05496 Array<double> contAtoms_;
05497 Array<double> contAtomsBackup_;
05498 Array<double> contAtomsEvi_;
05499 Array<double> contAtomsLow_;
05500
05501 double lowCostHybrid_;
05502 int lowBadHybrid_;
05503
05504 Array<Array<int> > hybridDisClause_;
05505 Array<Array<int> > hybridContClause_;
05506 Array<Array<int> > hybridDisOccurrence_;
05507 Array<Array<int> > hybridContOccurrence_;
05508 Array<DoubleRange> contAtomRange_;
05509 Array<bool> hybridConjunctionDisjunction_;
05510 Array<double> hybridClauseCost_;
05511 Array<int> hybridGndClauseToFormulaMap_;
05512 Array<Array<int> > hybridFormulaGndClauseIdx_;
05513
05514 int hybridFormulaNum_;
05515 int hybridClauseNum_;
05516 int contAtomNum_;
05517 int totalAtomNum_;
05518 int totalFalseConstraintNum_;
05519 int hybridFalseConstraintNum_;
05520
05521 Array<int> hybridFalseClause_;
05522 Array<int> hybridFalseClauseLow_;
05523
05524 Array<int> hybridWhereFalse_;
05525
05526 Array<double> hybridClauseValue_;
05527 Array<bool> hybridClauseDisValue_;
05528
05529 map<string ,int> gndPredCont_;
05530 map<int, string> gndPredReverseCont_;
05531
05532 double costOfTotalFalseConstraints_;
05533 int lowBadAll_;
05534 double lowCostAll_;
05535 double costHybridFalseConstraint_;
05536 bool bMaxOnly_;
05537
05538 Array<double> proposalStdev_;
05539 map<string,int> gndPredDis_;
05540
05541 double weightSumDis_;
05542 double weightSumCont_;
05543
05544 Array<Array<double> > lbfgsCache_;
05545 Array<double> hmwsContOptimal_;
05546 Array<bool> hmwsDisOptimal_;
05547
05548 string strHybridDis_;
05549
05550 private:
05551
05552 bool lazy_;
05553
05554
05555 long double hardWt_;
05556
05557
05558
05559 MLN* mln_;
05560 Domain* domain_;
05561
05563
05564 int baseNumAtoms_;
05565
05566 bool noApprox_;
05567
05568 bool haveDeactivated_;
05569
05570 int memLimit_;
05571
05572 int clauseLimit_;
05574
05576
05577 MRF* mrf_;
05579
05580
05581
05582
05583
05584
05585
05586
05587
05588 int lowBad_;
05589
05590
05591 int numFalseClauses_;
05592
05593 long double costOfFalseClauses_;
05594
05595
05596
05597 Array<Array<int> >* blocks_;
05598
05599
05600 Array<bool >* blockEvidence_;
05601
05602
05603 int activeAtoms_;
05604
05605
05606 int numNonEvAtoms_;
05607
05608
05609
05610 int inferenceMode_;
05611
05612
05613
05614
05615 bool stillActivating_;
05616
05617 };
05618
05619 #endif