00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #define _CVC3_TRUSTED_
00022
00023 #include "dpllt_minisat.h"
00024 #include "minisat_solver.h"
00025 #include "sat_proof.h"
00026 #include "theorem_producer.h"
00027 #include "exception.h"
00028
00029 using namespace std;
00030 using namespace CVC3;
00031 using namespace SAT;
00032
00033
00034 DPLLTMiniSat::DPLLTMiniSat(TheoryAPI* theoryAPI, Decider* decider,
00035 bool printStats, bool createProof)
00036 : DPLLT(theoryAPI, decider), d_printStats(printStats),
00037 d_createProof(createProof), d_proof(NULL) {
00038 pushSolver();
00039 }
00040
00041 DPLLTMiniSat::~DPLLTMiniSat() {
00042 while (!d_solvers.empty()) {
00043
00044 delete (d_solvers.top());
00045 d_solvers.pop();
00046 }
00047 delete d_proof;
00048 }
00049
00050 MiniSat::Solver* DPLLTMiniSat::getActiveSolver() {
00051 DebugAssert(!d_solvers.empty(), "DPLLTMiniSat::getActiveSolver: no solver");
00052 return d_solvers.top();
00053 }
00054
00055
00056 void DPLLTMiniSat::pushSolver() {
00057 if (d_solvers.empty()) {
00058 d_solvers.push(new MiniSat::Solver(d_theoryAPI, d_decider, d_createProof));
00059 }
00060 else {
00061 d_solvers.push(MiniSat::Solver::createFrom(getActiveSolver()));
00062 }
00063 }
00064
00065 QueryResult DPLLTMiniSat::search()
00066 {
00067 DebugAssert(d_solvers.size() > 0, "DPLLTMiniSat::search: no solver");
00068 DebugAssert(getActiveSolver()->inPush(), "DPLLTMiniSat::search: solver not pushed");
00069
00070
00071 MiniSat::Solver* solver = getActiveSolver();
00072 QueryResult result = solver->search();
00073
00074
00075 if (d_printStats) {
00076 switch (result) {
00077 case SATISFIABLE:
00078 break;
00079 case UNSATISFIABLE:
00080 cout << "Instance unsatisfiable" << endl;
00081 break;
00082 case ABORT:
00083 cout << "aborted, unable to determine the satisfiablility of the instance" << endl;
00084 break;
00085 case UNKNOWN:
00086 cout << "unknown, unable to determing the satisfiablility of the instance" << endl;
00087 break;
00088 default:
00089 FatalAssert(false, "DPLTBasic::handle_result: Unknown outcome");
00090 }
00091
00092 cout << "Number of Decisions\t\t\t" << solver->getStats().decisions << endl;
00093 cout << "Number of Propagations\t\t\t" << solver->getStats().propagations << endl;
00094 cout << "Number of Propositional Conflicts\t"
00095 << (solver->getStats().conflicts - solver->getStats().theory_conflicts) << endl;
00096 cout << "Number of Theory Conflicts\t\t" << solver->getStats().theory_conflicts << endl;
00097 cout << "Number of Variables\t\t\t" << solver->nVars() << endl;
00098 cout << "Number of Literals\t\t\t"
00099 << (solver->getStats().clauses_literals + solver->getStats().learnts_literals) << endl;
00100 cout << "Max. Number of Literals\t\t\t" << solver->getStats().max_literals << endl;
00101 cout << "Number of Clauses\t\t\t" << solver->getClauses().size() << endl;
00102 cout << "Number of Lemmas\t\t\t" << solver->getLemmas().size() << endl;
00103 cout << "Max. Decision Level\t\t\t" << solver->getStats().max_level << endl;
00104 cout << "Number of Deleted Clauses\t\t" << solver->getStats().del_clauses << endl;
00105 cout << "Number of Deleted Lemmas\t\t" << solver->getStats().del_lemmas << endl;
00106 cout << "Number of Database Simplifications\t" << solver->getStats().db_simpl << endl;
00107 cout << "Number of Lemma Cleanups\t\t" << solver->getStats().lm_simpl << endl;
00108
00109 cout << "Debug\t\t\t\t\t" << solver->getStats().debug << endl;
00110 }
00111
00112
00113
00114 if (result == UNSATISFIABLE) {
00115
00116
00117 if (d_createProof ) {
00118 delete d_proof;
00119
00120 DebugAssert(d_solvers.top()->getDerivation() != NULL, "DplltMiniSat::search: no proof");
00121 d_proof = d_solvers.top()->getDerivation()->createProof();
00122 }
00123 d_solvers.top()->popTheories();
00124 d_theoryAPI->pop();
00125 }
00126
00127 return result;
00128 }
00129
00130
00131 QueryResult DPLLTMiniSat::checkSat(const CNF_Formula& cnf)
00132 {
00133 DebugAssert(d_solvers.size() > 0, "DPLLTMiniSat::checkSat: no solver");
00134
00135
00136 getActiveSolver()->doPops();
00137
00138 DebugAssert(!getActiveSolver()->inSearch(), "DPLLTMiniSat::checkSat: solver already in search");
00139
00140
00141 d_theoryAPI->push();
00142
00143
00144 if (getActiveSolver()->inSearch()) {
00145 pushSolver();
00146 }
00147
00148
00149 getActiveSolver()->addFormula(cnf, false);
00150 return search();
00151 }
00152
00153
00154 QueryResult DPLLTMiniSat::continueCheck(const CNF_Formula& cnf)
00155 {
00156 DebugAssert(d_solvers.size() > 0, "DPLLTMiniSat::continueCheck: no solver");
00157
00158
00159
00160 if (!getActiveSolver()->inPush()) {
00161 DebugAssert(!getActiveSolver()->inSearch(), "DPLLTMiniSat::continueCheck: solver without push in search");
00162 delete getActiveSolver();
00163 d_solvers.pop();
00164 }
00165
00166
00167 getActiveSolver()->doPops();
00168
00169 DebugAssert(d_solvers.size() > 0, "DPLLTMiniSat::continueCheck: no solver (2)");
00170 DebugAssert(getActiveSolver()->inPush(), "DPLLTMiniSat::continueCheck: solver not in push");
00171 DebugAssert(getActiveSolver()->inSearch(), "DPLLTMiniSat::continueCheck: solver not in search");
00172
00173
00174 getActiveSolver()->addFormula(cnf, false);
00175 return search();
00176 }
00177
00178
00179 void DPLLTMiniSat::push() {
00180
00181 getActiveSolver()->doPops();
00182
00183
00184 if (getActiveSolver()->inSearch()) {
00185 pushSolver();
00186 }
00187
00188 getActiveSolver()->push();
00189 d_theoryAPI->push();
00190 }
00191
00192 void DPLLTMiniSat::pop() {
00193 DebugAssert(d_solvers.size() > 0, "DPLLTMiniSat::pop: no solver");
00194
00195
00196
00197 if (!getActiveSolver()->inPush()) {
00198 DebugAssert(!getActiveSolver()->inSearch(), "DPLLTMiniSat::pop: solver without push in search");
00199 delete getActiveSolver();
00200 d_solvers.pop();
00201 }
00202
00203 DebugAssert(d_solvers.size() > 0, "DPLLTMiniSat::pop: no solver 2");
00204 DebugAssert(getActiveSolver()->inPush(), "DPLLTMiniSat::pop: solver not in push");
00205
00206
00207
00208 if (getActiveSolver()->inSearch() && getActiveSolver()->isConsistent()) {
00209 d_theoryAPI->pop();
00210 }
00211 getActiveSolver()->requestPop();
00212 d_theoryAPI->pop();
00213 }
00214
00215 std::vector<SAT::Lit> DPLLTMiniSat::getCurAssignments(){
00216 return getActiveSolver()->curAssigns();
00217 }
00218
00219 std::vector<std::vector<SAT::Lit> > DPLLTMiniSat::getCurClauses(){
00220 return getActiveSolver()->curClauses();
00221 }
00222
00223 void DPLLTMiniSat::addAssertion(const CNF_Formula& cnf) {
00224
00225 getActiveSolver()->doPops();
00226
00227
00228 if (getActiveSolver()->inSearch()) {
00229 pushSolver();
00230 }
00231
00232 getActiveSolver()->addFormula(cnf, false);
00233
00234
00235
00236 for (CNF_Formula::const_iterator i = cnf.begin(); i != cnf.end(); ++i) {
00237 if ((*i).isUnit() && getActiveSolver()->isConsistent()) {
00238 d_theoryAPI->assertLit(*(*i).begin());
00239 }
00240 }
00241 }
00242
00243
00244 Var::Val DPLLTMiniSat::getValue(Var var) {
00245 DebugAssert(d_solvers.size() > 0,
00246 "DPLLTMiniSat::getValue: should be called after a previous satisfiable result");
00247
00248 MiniSat::lbool value = getActiveSolver()->getValue(MiniSat::cvcToMiniSat(var));
00249 if (value == MiniSat::l_True)
00250 return Var::TRUE_VAL;
00251 else if (value == MiniSat::l_False)
00252 return Var::FALSE_VAL;
00253 else
00254 return Var::UNKNOWN;
00255 }
00256
00257
00258 CVC3::Proof generateSatProof(SAT::SatProofNode* node, CNF_Manager* cnfManager, TheoremProducer* thmProducer){
00259 if(node->hasNodeProof()) {
00260 return node->getNodeProof();
00261 }
00262 if (node->isLeaf()){
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 const CVC3::Theorem clauseThm = node->getLeaf();
00278
00279
00280
00281
00282
00283 DebugAssert(!clauseThm.isNull(), "Null thm found in generateSatProof");
00284 node->setNodeProof(clauseThm.getProof());
00285
00286
00287 return clauseThm.getProof();
00288 }
00289 else{
00290 CVC3::Proof leftProof = generateSatProof(node->getLeftParent(), cnfManager, thmProducer);
00291 CVC3::Proof rightProof = generateSatProof(node->getRightParent(), cnfManager, thmProducer);
00292
00293 if(node->getLeftParent() == node->getRightParent() ) cout<<"***error ********"<<endl;
00294 vector<Proof> pfs;
00295 pfs.push_back(leftProof);
00296 pfs.push_back(rightProof);
00297
00298
00299 Lit lit = node->getLit();
00300 Expr e = cnfManager->concreteLit(lit);
00301 Expr e_trans = cnfManager->concreteLit(lit,false);
00302
00303
00304 if(e != e_trans){
00305
00306
00307 }
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321 Proof pf;
00322 pf = thmProducer->newPf("bool_resolution", e_trans, pfs);
00323 node->setNodeProof(pf);
00324 return pf;
00325
00326 }
00327
00328 }
00329
00330 void printSatProof(SAT::SatProofNode* node){
00331 if (node->isLeaf()){
00332 CVC3::Theorem theorem = node->getLeaf();
00333
00334 if(theorem.isNull()){
00335 cout<<"theorem null"<<endl;
00336 }
00337 else{
00338 cout<<"====================" << endl;
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364 }
00365 }
00366 else{
00367 SAT::SatProofNode * leftNode = node->getLeftParent();
00368 SAT::SatProofNode * rightNode = node->getRightParent();
00369
00370 printSatProof(leftNode);
00371 printSatProof(rightNode);
00372 }
00373
00374 }
00375
00376
00377
00378 CVC3::Proof DPLLTMiniSat::getSatProof(CNF_Manager* cnfManager, CVC3::TheoryCore* core){
00379 SAT::SatProof* proof = getProof();
00380 SAT::SatProofNode * rootNode = proof->getRoot();
00381
00382
00383
00384 CVC3::TheoremProducer* thmProducer = new TheoremProducer(core->getTM());
00385
00386 return generateSatProof(rootNode, cnfManager, thmProducer);
00387 }
00388