6#include "CadicalSatSolver.h"
8#include "dlinear/util/exception.h"
9#include "dlinear/util/logging.h"
13CadicalSatSolver::CadicalSatSolver(PredicateAbstractor &predicate_abstractor,
const std::string &class_name)
14 : SatSolver(predicate_abstractor, class_name), next_var_id_{1} {
15 if (config_.random_seed() != 0) {
16 [[maybe_unused]]
const bool res = sat_.set(
"seed",
static_cast<int>(config_.random_seed()));
17 DLINEAR_ASSERT(res,
"Failed to set random seed.");
18 DLINEAR_DEBUG_FMT(
"CadicalSatSolver::Set Random Seed {}", config_.random_seed());
20 [[maybe_unused]]
const bool res = sat_.set(
"phase", config_.sat_default_phase() != Config::SatDefaultPhase::False);
21 DLINEAR_ASSERT(res,
"Failed to set default phase.");
22 DLINEAR_DEBUG_FMT(
"CadicalSatSolver::Set Default Phase {}", config_.sat_default_phase());
25void CadicalSatSolver::MakeSatVar(
const Variable &var) {
26 auto it = var_to_sat_.find(var.get_id());
28 if (it != var_to_sat_.end())
return;
31 const int sat_var = next_var_id_++;
32 sat_.add_observed_var(sat_var);
33 var_to_sat_.insert(var.get_id(), sat_var);
34 sat_to_var_.insert(sat_var, var);
35 DLINEAR_DEBUG_FMT(
"CadicalSatSolver::MakeSatVar({} ↦ {})", var, sat_var);
38void CadicalSatSolver::AddLearnedClause(
const LiteralSet &literals) {
39 for (
const Literal &lit : literals) AddLiteral(!lit,
true);
42void CadicalSatSolver::AddLearnedClause(
const Literal &lit) {
43 AddLiteral(!lit,
true);
47void CadicalSatSolver::AddLiteral(
const Literal &l,
bool learned) {
48 const auto &[var, truth] = l;
49 DLINEAR_ASSERT(var.get_type() == Variable::Type::BOOLEAN,
"var must be Boolean");
51 const int lit = truth ? var_to_sat_[var.get_id()] : -var_to_sat_[var.get_id()];
54 if (!learned) UpdateLookup(lit);
57std::set<int> CadicalSatSolver::GetMainActiveLiterals() {
59 for (
int i = 1; i <= sat_.vars(); ++i) {
60 const int lit = sat_.val(i);
61 if (lit == 0)
continue;
64 SatSolver::GetMainActiveLiterals(lits);
68std::optional<Model> CadicalSatSolver::CheckSat() {
69 TimerGuard timer_guard(&stats_.m_timer(), stats_.enabled());
72 DLINEAR_DEBUG_FMT(
"CadicalSatSolver::CheckSat(#vars = {}, #active = {})", sat_.vars(), sat_.active());
75 const int ret = sat_.solve();
77 if (ret == CaDiCaL::Status::SATISFIABLE) {
79 }
else if (ret == CaDiCaL::Status::UNSATISFIABLE) {
80 DLINEAR_DEBUG(
"CadicalSatSolver::CheckSat() No solution.");
83 DLINEAR_ASSERT(ret == CaDiCaL::Status::UNKNOWN,
"ret must be UNKNOWN");
84 DLINEAR_RUNTIME_ERROR(
"CaDiCaL returned UNKNOWN.");
88void CadicalSatSolver::AddClauseToSat(
const Formula &f) {
89 cur_clause_start_ = main_clauses_copy_.size();
90 if (is_disjunction(f)) {
92 for (
const Formula &l : get_operands(f)) SatSolver::AddLiteral(l);
95 SatSolver::AddLiteral(f);
98 main_clauses_copy_.push_back(0);
101void CadicalSatSolver::FixedTheoryLiterals(
LiteralSet &fixed_literals) {
102 for (
int i = 1; i <= sat_.vars(); ++i) {
103 const int lit = sat_.fixed(i);
104 if (lit == 0)
continue;
105 const Variable &var = sat_to_var_[i];
106 if (predicate_abstractor_.var_to_formula_map().contains(var)) fixed_literals.emplace(var, lit > 0);
108 DLINEAR_TRACE_FMT(
"CadicalSatSolver::FixedTheoryLiterals({})", fixed_literals);
110void CadicalSatSolver::Assume(
const Literal &l) {
111 DLINEAR_TRACE_FMT(
"CadicalSatSolver::Assume({})", l);
112 sat_.assume(l.
truth ? var_to_sat_[l.
var.get_id()] : -var_to_sat_[l.
var.get_id()]);
115void CadicalSatSolver::Push() {
116 DLINEAR_DEBUG(
"CadicalSatSolver::Push()");
120 cnf_variables_.push();
121 DLINEAR_RUNTIME_ERROR(
"cadical pop is not implemented.");
123void CadicalSatSolver::Pop() {
124 DLINEAR_DEBUG(
"CadicalSatSolver::Pop()");
125 cnf_variables_.pop();
129 DLINEAR_RUNTIME_ERROR(
"cadical pop is not implemented.");
The TimeGuard wraps a timer object and pauses it when the guard object is destructed.
Represents a symbolic variable.
Global namespace for the dlinear library.
std::set< Literal > LiteralSet
A set of literals.
A literal is a variable with an associated truth value, indicating whether it is true or false.