498b31ce58965de2acedc8ab3569734606bbd89a
1 /********************* */
2 /*! \file bvminisat.cpp
4 ** Original author: dejan
6 ** Minor contributors (to current version):
7 ** This file is part of the CVC4 prototype.
8 ** Copyright (c) 2009-2014 The Analysis of Computer Systems Group (ACSys)
9 ** Courant Institute of Mathematical Sciences
10 ** New York University
11 ** See the file COPYING in the top-level source directory for licensing
12 ** information.\endverbatim
16 ** Implementation of the minisat for cvc4 (bitvectors).
19 #include "prop/bvminisat/bvminisat.h"
20 #include "prop/bvminisat/simp/SimpSolver.h"
25 BVMinisatSatSolver::BVMinisatSatSolver(context::Context
* mainSatContext
, const std::string
& name
)
26 : context::ContextNotifyObj(mainSatContext
, false),
27 d_minisat(new BVMinisat::SimpSolver(mainSatContext
)),
30 d_assertionsRealCount(mainSatContext
, 0),
31 d_lastPropagation(mainSatContext
, 0),
34 d_statistics
.init(d_minisat
);
38 BVMinisatSatSolver::~BVMinisatSatSolver() throw(AssertionException
) {
40 delete d_minisatNotify
;
43 void BVMinisatSatSolver::setNotify(Notify
* notify
) {
44 d_minisatNotify
= new MinisatNotify(notify
);
45 d_minisat
->setNotify(d_minisatNotify
);
48 void BVMinisatSatSolver::addClause(SatClause
& clause
, bool removable
, uint64_t proof_id
) {
49 Debug("sat::minisat") << "Add clause " << clause
<<"\n";
50 BVMinisat::vec
<BVMinisat::Lit
> minisat_clause
;
51 toMinisatClause(clause
, minisat_clause
);
52 // for(unsigned i = 0; i < minisat_clause.size(); ++i) {
53 // d_minisat->setFrozen(BVMinisat::var(minisat_clause[i]), true);
55 d_minisat
->addClause(minisat_clause
);
58 SatValue
BVMinisatSatSolver::propagate() {
59 return toSatLiteralValue(d_minisat
->propagateAssumptions());
62 void BVMinisatSatSolver::addMarkerLiteral(SatLiteral lit
) {
63 d_minisat
->addMarkerLiteral(BVMinisat::var(toMinisatLit(lit
)));
67 void BVMinisatSatSolver::explain(SatLiteral lit
, std::vector
<SatLiteral
>& explanation
) {
68 std::vector
<BVMinisat::Lit
> minisat_explanation
;
69 d_minisat
->explain(toMinisatLit(lit
), minisat_explanation
);
70 for (unsigned i
= 0; i
< minisat_explanation
.size(); ++i
) {
71 explanation
.push_back(toSatLiteral(minisat_explanation
[i
]));
75 SatValue
BVMinisatSatSolver::assertAssumption(SatLiteral lit
, bool propagate
) {
77 d_assertionsRealCount
= d_assertionsRealCount
+ 1;
78 return toSatLiteralValue(d_minisat
->assertAssumption(toMinisatLit(lit
), propagate
));
81 void BVMinisatSatSolver::contextNotifyPop() {
82 while (d_assertionsCount
> d_assertionsRealCount
) {
88 void BVMinisatSatSolver::popAssumption() {
89 d_minisat
->popAssumption();
92 SatVariable
BVMinisatSatSolver::newVar(bool isTheoryAtom
, bool preRegister
, bool canErase
){
93 return d_minisat
->newVar(true, true, !canErase
);
96 void BVMinisatSatSolver::markUnremovable(SatLiteral lit
){
97 d_minisat
->setFrozen(BVMinisat::var(toMinisatLit(lit
)), true);
100 void BVMinisatSatSolver::spendResource(){
101 // do nothing for the BV solver
104 void BVMinisatSatSolver::interrupt(){
105 d_minisat
->interrupt();
108 SatValue
BVMinisatSatSolver::solve(){
109 ++d_statistics
.d_statCallsToSolve
;
110 return toSatLiteralValue(d_minisat
->solve());
113 SatValue
BVMinisatSatSolver::solve(long unsigned int& resource
){
114 Trace("limit") << "MinisatSatSolver::solve(): have limit of " << resource
<< " conflicts" << std::endl
;
115 ++d_statistics
.d_statCallsToSolve
;
117 d_minisat
->budgetOff();
119 d_minisat
->setConfBudget(resource
);
121 // BVMinisat::vec<BVMinisat::Lit> empty;
122 unsigned long conflictsBefore
= d_minisat
->conflicts
;
123 SatValue result
= toSatLiteralValue(d_minisat
->solveLimited());
124 d_minisat
->clearInterrupt();
125 resource
= d_minisat
->conflicts
- conflictsBefore
;
126 Trace("limit") << "<MinisatSatSolver::solve(): it took " << resource
<< " conflicts" << std::endl
;
130 void BVMinisatSatSolver::getUnsatCore(SatClause
& unsatCore
) {
131 // TODO add assertion to check the call was after an unsat call
132 for (int i
= 0; i
< d_minisat
->conflict
.size(); ++i
) {
133 unsatCore
.push_back(toSatLiteral(d_minisat
->conflict
[i
]));
137 SatValue
BVMinisatSatSolver::value(SatLiteral l
){
138 return toSatLiteralValue(d_minisat
->value(toMinisatLit(l
)));
141 SatValue
BVMinisatSatSolver::modelValue(SatLiteral l
){
142 return toSatLiteralValue(d_minisat
->modelValue(toMinisatLit(l
)));
145 void BVMinisatSatSolver::unregisterVar(SatLiteral lit
) {
146 // this should only be called when user context is implemented
147 // in the BVSatSolver
151 void BVMinisatSatSolver::renewVar(SatLiteral lit
, int level
) {
152 // this should only be called when user context is implemented
153 // in the BVSatSolver
158 unsigned BVMinisatSatSolver::getAssertionLevel() const {
159 // we have no user context implemented so far
163 // converting from internal Minisat representation
165 SatVariable
BVMinisatSatSolver::toSatVariable(BVMinisat::Var var
) {
166 if (var
== var_Undef
) {
167 return undefSatVariable
;
169 return SatVariable(var
);
172 BVMinisat::Lit
BVMinisatSatSolver::toMinisatLit(SatLiteral lit
) {
173 if (lit
== undefSatLiteral
) {
174 return BVMinisat::lit_Undef
;
176 return BVMinisat::mkLit(lit
.getSatVariable(), lit
.isNegated());
179 SatLiteral
BVMinisatSatSolver::toSatLiteral(BVMinisat::Lit lit
) {
180 if (lit
== BVMinisat::lit_Undef
) {
181 return undefSatLiteral
;
184 return SatLiteral(SatVariable(BVMinisat::var(lit
)),
185 BVMinisat::sign(lit
));
188 SatValue
BVMinisatSatSolver::toSatLiteralValue(bool res
) {
189 if(res
) return SAT_VALUE_TRUE
;
190 else return SAT_VALUE_FALSE
;
193 SatValue
BVMinisatSatSolver::toSatLiteralValue(BVMinisat::lbool res
) {
194 if(res
== (BVMinisat::lbool((uint8_t)0))) return SAT_VALUE_TRUE
;
195 if(res
== (BVMinisat::lbool((uint8_t)2))) return SAT_VALUE_UNKNOWN
;
196 Assert(res
== (BVMinisat::lbool((uint8_t)1)));
197 return SAT_VALUE_FALSE
;
200 void BVMinisatSatSolver::toMinisatClause(SatClause
& clause
,
201 BVMinisat::vec
<BVMinisat::Lit
>& minisat_clause
) {
202 for (unsigned i
= 0; i
< clause
.size(); ++i
) {
203 minisat_clause
.push(toMinisatLit(clause
[i
]));
205 Assert(clause
.size() == (unsigned)minisat_clause
.size());
208 void BVMinisatSatSolver::toSatClause(BVMinisat::vec
<BVMinisat::Lit
>& clause
,
209 SatClause
& sat_clause
) {
210 for (int i
= 0; i
< clause
.size(); ++i
) {
211 sat_clause
.push_back(toSatLiteral(clause
[i
]));
213 Assert((unsigned)clause
.size() == sat_clause
.size());
217 // Satistics for BVMinisatSatSolver
219 BVMinisatSatSolver::Statistics::Statistics(const std::string
& prefix
) :
220 d_statStarts("theory::bv::"+prefix
+"bvminisat::starts"),
221 d_statDecisions("theory::bv::"+prefix
+"bvminisat::decisions"),
222 d_statRndDecisions("theory::bv::"+prefix
+"bvminisat::rnd_decisions"),
223 d_statPropagations("theory::bv::"+prefix
+"bvminisat::propagations"),
224 d_statConflicts("theory::bv::"+prefix
+"bvminisat::conflicts"),
225 d_statClausesLiterals("theory::bv::"+prefix
+"bvminisat::clauses_literals"),
226 d_statLearntsLiterals("theory::bv::"+prefix
+"bvminisat::learnts_literals"),
227 d_statMaxLiterals("theory::bv::"+prefix
+"bvminisat::max_literals"),
228 d_statTotLiterals("theory::bv::"+prefix
+"bvminisat::tot_literals"),
229 d_statEliminatedVars("theory::bv::"+prefix
+"bvminisat::eliminated_vars"),
230 d_statCallsToSolve("theory::bv::"+prefix
+"bvminisat::calls_to_solve", 0),
231 d_statSolveTime("theory::bv::"+prefix
+"bvminisat::solve_time", 0),
232 d_registerStats(!prefix
.empty())
234 if (!d_registerStats
)
237 StatisticsRegistry::registerStat(&d_statStarts
);
238 StatisticsRegistry::registerStat(&d_statDecisions
);
239 StatisticsRegistry::registerStat(&d_statRndDecisions
);
240 StatisticsRegistry::registerStat(&d_statPropagations
);
241 StatisticsRegistry::registerStat(&d_statConflicts
);
242 StatisticsRegistry::registerStat(&d_statClausesLiterals
);
243 StatisticsRegistry::registerStat(&d_statLearntsLiterals
);
244 StatisticsRegistry::registerStat(&d_statMaxLiterals
);
245 StatisticsRegistry::registerStat(&d_statTotLiterals
);
246 StatisticsRegistry::registerStat(&d_statEliminatedVars
);
247 StatisticsRegistry::registerStat(&d_statCallsToSolve
);
248 StatisticsRegistry::registerStat(&d_statSolveTime
);
251 BVMinisatSatSolver::Statistics::~Statistics() {
252 if (!d_registerStats
)
254 StatisticsRegistry::unregisterStat(&d_statStarts
);
255 StatisticsRegistry::unregisterStat(&d_statDecisions
);
256 StatisticsRegistry::unregisterStat(&d_statRndDecisions
);
257 StatisticsRegistry::unregisterStat(&d_statPropagations
);
258 StatisticsRegistry::unregisterStat(&d_statConflicts
);
259 StatisticsRegistry::unregisterStat(&d_statClausesLiterals
);
260 StatisticsRegistry::unregisterStat(&d_statLearntsLiterals
);
261 StatisticsRegistry::unregisterStat(&d_statMaxLiterals
);
262 StatisticsRegistry::unregisterStat(&d_statTotLiterals
);
263 StatisticsRegistry::unregisterStat(&d_statEliminatedVars
);
264 StatisticsRegistry::unregisterStat(&d_statCallsToSolve
);
265 StatisticsRegistry::unregisterStat(&d_statSolveTime
);
268 void BVMinisatSatSolver::Statistics::init(BVMinisat::SimpSolver
* minisat
){
269 if (!d_registerStats
)
272 d_statStarts
.setData(minisat
->starts
);
273 d_statDecisions
.setData(minisat
->decisions
);
274 d_statRndDecisions
.setData(minisat
->rnd_decisions
);
275 d_statPropagations
.setData(minisat
->propagations
);
276 d_statConflicts
.setData(minisat
->conflicts
);
277 d_statClausesLiterals
.setData(minisat
->clauses_literals
);
278 d_statLearntsLiterals
.setData(minisat
->learnts_literals
);
279 d_statMaxLiterals
.setData(minisat
->max_literals
);
280 d_statTotLiterals
.setData(minisat
->tot_literals
);
281 d_statEliminatedVars
.setData(minisat
->eliminated_vars
);