-
Notifications
You must be signed in to change notification settings - Fork 274
Add CaDiCaL support to CMake #4758
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,7 @@ Author: Michael Tautschnig | |
|
||
#include <util/exception_utils.h> | ||
#include <util/invariant.h> | ||
#include <util/narrow.h> | ||
#include <util/threeval.h> | ||
|
||
#ifdef HAVE_CADICAL | ||
|
@@ -23,7 +24,7 @@ tvt satcheck_cadicalt::l_get(literalt a) const | |
|
||
tvt result; | ||
|
||
if(a.var_no() > static_cast<unsigned>(solver->max())) | ||
if(a.var_no() > narrow<unsigned>(solver->vars())) | ||
return tvt(tvt::tv_enumt::TV_UNKNOWN); | ||
|
||
const int val = solver->val(a.dimacs()); | ||
|
@@ -62,6 +63,23 @@ void satcheck_cadicalt::lcnf(const bvt &bv) | |
} | ||
solver->add(0); // terminate clause | ||
|
||
with_solver_hardness([this, &bv](solver_hardnesst &hardness) { | ||
// To map clauses to lines of program code, track clause indices in the | ||
// dimacs cnf output. Dimacs output is generated after processing | ||
// clauses to remove duplicates and clauses that are trivially true. | ||
// Here, a clause is checked to see if it can be thus eliminated. If | ||
// not, add the clause index to list of clauses in | ||
// solver_hardnesst::register_clause(). | ||
static size_t cnf_clause_index = 0; | ||
bvt cnf; | ||
bool clause_removed = process_clause(bv, cnf); | ||
|
||
if(!clause_removed) | ||
cnf_clause_index++; | ||
|
||
hardness.register_clause(bv, cnf, cnf_clause_index, !clause_removed); | ||
}); | ||
|
||
clause_counter++; | ||
} | ||
|
||
|
@@ -72,31 +90,37 @@ propt::resultt satcheck_cadicalt::do_prop_solve() | |
log.statistics() << (no_variables() - 1) << " variables, " << clause_counter | ||
<< " clauses" << messaget::eom; | ||
|
||
if(status == statust::UNSAT) | ||
// if assumptions contains false, we need this to be UNSAT | ||
for(const auto &a : assumptions) | ||
{ | ||
log.status() << "SAT checker inconsistent: instance is UNSATISFIABLE" | ||
<< messaget::eom; | ||
} | ||
else | ||
{ | ||
switch(solver->solve()) | ||
if(a.is_false()) | ||
{ | ||
case 10: | ||
log.status() << "SAT checker: instance is SATISFIABLE" << messaget::eom; | ||
status = statust::SAT; | ||
return resultt::P_SATISFIABLE; | ||
case 20: | ||
log.status() << "SAT checker: instance is UNSATISFIABLE" | ||
<< messaget::eom; | ||
break; | ||
default: | ||
log.status() << "SAT checker: solving returned without solution" | ||
<< messaget::eom; | ||
throw analysis_exceptiont( | ||
"solving inside CaDiCaL SAT solver has been interrupted"); | ||
log.status() << "got FALSE as assumption: instance is UNSATISFIABLE" | ||
<< messaget::eom; | ||
status = statust::UNSAT; | ||
return resultt::P_UNSATISFIABLE; | ||
} | ||
} | ||
|
||
for(const auto &a : assumptions) | ||
solver->assume(a.dimacs()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need to do this now? This wasn't here previously? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Support for assumptions simply was missing before. |
||
|
||
switch(solver->solve()) | ||
{ | ||
case 10: | ||
log.status() << "SAT checker: instance is SATISFIABLE" << messaget::eom; | ||
status = statust::SAT; | ||
return resultt::P_SATISFIABLE; | ||
case 20: | ||
log.status() << "SAT checker: instance is UNSATISFIABLE" << messaget::eom; | ||
break; | ||
default: | ||
log.status() << "SAT checker: solving returned without solution" | ||
<< messaget::eom; | ||
throw analysis_exceptiont( | ||
"solving inside CaDiCaL SAT solver has been interrupted"); | ||
} | ||
|
||
status = statust::UNSAT; | ||
return resultt::P_UNSATISFIABLE; | ||
} | ||
|
@@ -107,8 +131,8 @@ void satcheck_cadicalt::set_assignment(literalt a, bool value) | |
INVARIANT(false, "method not supported"); | ||
} | ||
|
||
satcheck_cadicalt::satcheck_cadicalt() : | ||
solver(new CaDiCaL::Solver()) | ||
satcheck_cadicalt::satcheck_cadicalt(message_handlert &message_handler) | ||
: cnf_solvert(message_handler), solver(new CaDiCaL::Solver()) | ||
{ | ||
solver->set("quiet", 1); | ||
} | ||
|
@@ -120,13 +144,20 @@ satcheck_cadicalt::~satcheck_cadicalt() | |
|
||
void satcheck_cadicalt::set_assumptions(const bvt &bv) | ||
{ | ||
INVARIANT(false, "method not supported"); | ||
// We filter out 'true' assumptions which cause spurious results with CaDiCaL. | ||
assumptions.clear(); | ||
for(const auto &assumption : bv) | ||
{ | ||
if(!assumption.is_true()) | ||
{ | ||
assumptions.push_back(assumption); | ||
} | ||
} | ||
} | ||
|
||
bool satcheck_cadicalt::is_in_conflict(literalt a) const | ||
{ | ||
INVARIANT(false, "method not supported"); | ||
return false; | ||
return solver->failed(a.dimacs()); | ||
} | ||
|
||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will only work on Linux, is that OK? If cadical also works on Windows/OSX it'd be nice if just used something like
find_library
here to get a more portable library path.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cadical's makefile hard-codes this, so I don't think it'll work out of the box on other platforms.