00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _cvc3__include__search_sat_h_
00023 #define _cvc3__include__search_sat_h_
00024
00025 #include <vector>
00026 #include <set>
00027 #include "search.h"
00028 #include "smartcdo.h"
00029 #include "cdlist.h"
00030 #include "cnf_manager.h"
00031 #include "expr.h"
00032 #include "dpllt.h"
00033 #include "theory_core.h"
00034 #include "formula_value.h"
00035
00036 namespace CVC3 {
00037
00038
00039
00040 class SearchSat :public SearchEngine {
00041
00042
00043 std::string d_name;
00044
00045
00046 CDO<int> d_bottomScope;
00047
00048
00049 CDO<Expr> d_lastCheck;
00050
00051
00052
00053 CDO<Theorem> d_lastValid;
00054
00055
00056 CDList<Theorem> d_userAssumptions;
00057
00058
00059 CDList<Theorem> d_intAssumptions;
00060
00061
00062 CDO<unsigned> d_idxUserAssump;
00063
00064 TheoryCore::CoreSatAPI* d_coreSatAPI;
00065
00066
00067 SAT::DPLLT* d_dpllt;
00068
00069
00070 SAT::DPLLT::TheoryAPI* d_theoryAPI;
00071
00072
00073 SAT::DPLLT::Decider* d_decider;
00074
00075
00076 CDMap<Expr, Theorem> d_theorems;
00077
00078
00079 SAT::CNF_Manager *d_cnfManager;
00080
00081
00082 SAT::CNF_Manager::CNFCallback *d_cnfCallback;
00083
00084
00085 std::vector<SAT::Var::Val> d_vars;
00086
00087
00088 bool d_inCheckSat;
00089
00090
00091 SAT::CD_CNF_Formula d_lemmas;
00092
00093
00094 std::vector<std::pair<Theorem, int> > d_pendingLemmas;
00095
00096
00097 std::vector<bool> d_pendingScopes;
00098
00099
00100 CDO<unsigned> d_pendingLemmasSize;
00101
00102
00103 CDO<unsigned> d_pendingLemmasNext;
00104
00105
00106 CDO<unsigned> d_lemmasNext;
00107
00108
00109 std::vector<unsigned> d_varsUndoList;
00110
00111
00112 CDO<unsigned> d_varsUndoListSize;
00113
00114 public:
00115
00116 class LitPriorityPair {
00117 SAT::Lit d_lit;
00118 int d_priority;
00119 LitPriorityPair() {}
00120 public:
00121 LitPriorityPair(SAT::Lit lit, int priority)
00122 : d_lit(lit), d_priority(priority) {}
00123 SAT::Lit getLit() const { return d_lit; }
00124 int getPriority() const { return d_priority; }
00125 friend bool operator<(const LitPriorityPair& p1,
00126 const LitPriorityPair& p2);
00127 };
00128
00129 private:
00130
00131 std::set<LitPriorityPair> d_prioritySet;
00132
00133 CDO<std::set<LitPriorityPair>::const_iterator> d_prioritySetStart;
00134
00135 CDO<unsigned> d_prioritySetEntriesSize;
00136
00137 std::vector<std::set<LitPriorityPair>::iterator> d_prioritySetEntries;
00138
00139 std::vector<unsigned> d_prioritySetBottomEntriesSizeStack;
00140
00141 unsigned d_prioritySetBottomEntriesSize;
00142
00143 std::vector<std::set<LitPriorityPair>::iterator> d_prioritySetBottomEntries;
00144
00145
00146 CDO<unsigned> d_lastRegisteredVar;
00147
00148
00149 CDO<bool> d_dplltReady;
00150
00151 CDO<unsigned> d_nextImpliedLiteral;
00152
00153
00154
00155
00156
00157
00158 friend class Restorer;
00159 class Restorer :public ContextNotifyObj {
00160 SearchSat* d_ss;
00161 public:
00162 Restorer(Context* context, SearchSat* ss)
00163 : ContextNotifyObj(context), d_ss(ss) {}
00164 void notifyPre() { d_ss->restorePre(); }
00165 void notify() { d_ss->restore(); }
00166 };
00167
00168 Restorer d_restorer;
00169
00170 private:
00171
00172
00173 void restorePre();
00174
00175 void restore();
00176
00177 bool recordNewRootLit(SAT::Lit lit, int priority = 0, bool atBottomScope = false);
00178
00179 friend class SearchSatCoreSatAPI;
00180 friend class SearchSatCNFCallback;
00181
00182 void addLemma(const Theorem& thm, int priority = 0, bool atBotomScope = false);
00183
00184 int getBottomScope() { return d_bottomScope; }
00185
00186 void addSplitter(const Expr& e, int priority);
00187
00188 friend class SearchSatTheoryAPI;
00189
00190 void assertLit(SAT::Lit l);
00191
00192 SAT::DPLLT::ConsistentResult checkConsistent(SAT::CNF_Formula& cnf, bool fullEffort);
00193
00194 SAT::Lit getImplication();
00195
00196 void getExplanation(SAT::Lit l, SAT::CNF_Formula& cnf);
00197
00198 bool getNewClauses(SAT::CNF_Formula& cnf);
00199
00200 friend class SearchSatDecider;
00201
00202 SAT::Lit makeDecision();
00203
00204
00205
00206
00207
00208
00209
00210 bool findSplitterRec(SAT::Lit lit, SAT::Var::Val value,
00211 SAT::Lit* litDecision);
00212
00213
00214 SAT::Var::Val getValue(SAT::Lit c) {
00215 DebugAssert(!c.isNull() &&
00216 (!c.isVar() || unsigned(c.getVar()) < d_vars.size()),
00217 "Lit out of bounds in getValue");
00218 return c.isPositive() ? d_vars[c.getVar()] :
00219 c.isInverted() ? SAT::Var::invertValue(d_vars[c.getVar()]) :
00220 c.isTrue() ? SAT::Var::TRUE_VAL : SAT::Var::FALSE_VAL;
00221 }
00222
00223 SAT::Var::Val getValue(SAT::Var v) {
00224 DebugAssert(v.isVar() && unsigned(v) < d_vars.size(), "Var out of bounds in getValue");
00225 return d_vars[v];
00226 }
00227
00228
00229 void setValue(SAT::Var v, SAT::Var::Val val) {
00230 DebugAssert(!v.isNull(), "expected non-null Var");
00231 DebugAssert(unsigned(v) < d_vars.size(), "Var out of bounds in getValue");
00232 DebugAssert(d_vars[v] == SAT::Var::UNKNOWN, "Expected unknown");
00233 DebugAssert(val != SAT::Var::UNKNOWN, "Expected set to non-unknown");
00234 d_vars[v] = val;
00235 DebugAssert(d_varsUndoListSize == d_varsUndoList.size(), "Size mismatch");
00236 d_varsUndoList.push_back(unsigned(v));
00237 d_varsUndoListSize = d_varsUndoListSize + 1;
00238 }
00239
00240
00241 bool checkJustified(SAT::Var v)
00242 { return d_cnfManager->concreteLit(SAT::Lit(v)).isJustified(); }
00243
00244
00245 void setJustified(SAT::Var v)
00246 { d_cnfManager->concreteLit(SAT::Lit(v)).setJustified(); }
00247
00248
00249 QueryResult check(const Expr& e, Theorem& result, bool isRestart = false);
00250
00251
00252 void newUserAssumptionIntHelper(const Theorem& thm, SAT::CNF_Formula_Impl& cnf,
00253 bool atBottomScope);
00254
00255 Theorem newUserAssumptionInt(const Expr& e, SAT::CNF_Formula_Impl& cnf,
00256 bool atBottomScope);
00257
00258 public:
00259
00260
00261
00262 SearchSat(TheoryCore* core, const std::string& name);
00263
00264
00265 virtual ~SearchSat();
00266
00267
00268 virtual const std::string& getName() { return d_name; }
00269 virtual void registerAtom(const Expr& e);
00270 virtual Theorem getImpliedLiteral();
00271 virtual void push() { d_dpllt->push(); }
00272 virtual void pop() { d_dpllt->pop(); }
00273 virtual QueryResult checkValid(const Expr& e, Theorem& result)
00274 { return check(e, result); }
00275 virtual QueryResult restart(const Expr& e, Theorem& result)
00276 { return check(e, result, true); }
00277 virtual void returnFromCheck();
00278 virtual Theorem lastThm() { return d_lastValid; }
00279 virtual Theorem newUserAssumption(const Expr& e);
00280 virtual void getUserAssumptions(std::vector<Expr>& assumptions);
00281 virtual void getInternalAssumptions(std::vector<Expr>& assumptions);
00282 virtual void getAssumptions(std::vector<Expr>& assumptions);
00283 virtual bool isAssumption(const Expr& e);
00284 virtual void getCounterExample(std::vector<Expr>& assertions,
00285 bool inOrder = true);
00286 virtual Proof getProof();
00287
00288
00289 virtual FormulaValue getValue(const CVC3::Expr& e) {
00290 SAT::Lit l = d_cnfManager->getCNFLit(e);
00291
00292 if (l.isNull()) {
00293
00294 std::cout << "No lit for expr: " << e.toString() << std::endl;
00295 FatalAssert(false, "getValue");
00296 return UNKNOWN_VAL;
00297 } else {
00298 switch (getValue(l)) {
00299 case SAT::Var::TRUE_VAL: return TRUE_VAL;
00300 case SAT::Var::FALSE_VAL: return FALSE_VAL;
00301 case SAT::Var::UNKNOWN: return UNKNOWN_VAL;
00302 default:
00303 DebugAssert(false, "unreachable");
00304 return UNKNOWN_VAL;
00305 }
00306 }
00307 }
00308
00309 };
00310
00311 inline bool operator<(const SearchSat::LitPriorityPair& p1,
00312 const SearchSat::LitPriorityPair& p2)
00313 {
00314 if (p1.d_priority > p2.d_priority) return true;
00315 if (p1.d_priority < p2.d_priority) return false;
00316 return abs(p1.d_lit.getID()) < abs(p2.d_lit.getID()) ||
00317 (abs(p1.d_lit.getID()) == abs(p2.d_lit.getID()) && p1.d_lit.getID() > 0 && (!(p2.d_lit.getID() > 0)));
00318 }
00319
00320 }
00321
00322 #endif