dlinear  0.0.1
Delta-complete SMT solver for linear programming
Loading...
Searching...
No Matches
CadicalSatSolver.cpp
1
6#include "CadicalSatSolver.h"
7
8#include "dlinear/util/exception.h"
9#include "dlinear/util/logging.h"
10
11namespace dlinear {
12
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());
19 }
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());
23}
24
25void CadicalSatSolver::MakeSatVar(const Variable &var) {
26 auto it = var_to_sat_.find(var.get_id());
27 // Found, no need to create the mapping
28 if (it != var_to_sat_.end()) return;
29
30 // It's not in the maps, let's make one and add it.
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);
36}
37
38void CadicalSatSolver::AddLearnedClause(const LiteralSet &literals) {
39 for (const Literal &lit : literals) AddLiteral(!lit, true);
40 sat_.add(0);
41}
42void CadicalSatSolver::AddLearnedClause(const Literal &lit) {
43 AddLiteral(!lit, true);
44 sat_.add(0);
45}
46
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");
50 // f = b or f = ¬b.
51 const int lit = truth ? var_to_sat_[var.get_id()] : -var_to_sat_[var.get_id()];
52 sat_.add(lit);
53 // If the literal is from the original formula, update the mapping lookup.
54 if (!learned) UpdateLookup(lit);
55}
56
57std::set<int> CadicalSatSolver::GetMainActiveLiterals() {
58 std::set<int> lits;
59 for (int i = 1; i <= sat_.vars(); ++i) {
60 const int lit = sat_.val(i);
61 if (lit == 0) continue;
62 lits.insert(lit);
63 }
64 SatSolver::GetMainActiveLiterals(lits);
65 return lits;
66}
67
68std::optional<Model> CadicalSatSolver::CheckSat() {
69 TimerGuard timer_guard(&stats_.m_timer(), stats_.enabled());
70 stats_.Increase();
71
72 DLINEAR_DEBUG_FMT("CadicalSatSolver::CheckSat(#vars = {}, #active = {})", sat_.vars(), sat_.active());
73
74 // Call SAT solver.
75 const int ret = sat_.solve();
76
77 if (ret == CaDiCaL::Status::SATISFIABLE) {
78 return OnSatResult();
79 } else if (ret == CaDiCaL::Status::UNSATISFIABLE) {
80 DLINEAR_DEBUG("CadicalSatSolver::CheckSat() No solution.");
81 return {};
82 } else {
83 DLINEAR_ASSERT(ret == CaDiCaL::Status::UNKNOWN, "ret must be UNKNOWN");
84 DLINEAR_RUNTIME_ERROR("CaDiCaL returned UNKNOWN.");
85 }
86}
87
88void CadicalSatSolver::AddClauseToSat(const Formula &f) {
89 cur_clause_start_ = main_clauses_copy_.size();
90 if (is_disjunction(f)) {
91 // f = l₁ ∨ ... ∨ lₙ
92 for (const Formula &l : get_operands(f)) SatSolver::AddLiteral(l);
93 } else {
94 // f = b or f = ¬b.
95 SatSolver::AddLiteral(f);
96 }
97 sat_.add(0);
98 main_clauses_copy_.push_back(0);
99}
100
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);
107 }
108 DLINEAR_TRACE_FMT("CadicalSatSolver::FixedTheoryLiterals({})", fixed_literals);
109}
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()]);
113}
114
115void CadicalSatSolver::Push() {
116 DLINEAR_DEBUG("CadicalSatSolver::Push()");
117 // TODO(tend): push
118 var_to_sat_.push();
119 sat_to_var_.push();
120 cnf_variables_.push();
121 DLINEAR_RUNTIME_ERROR("cadical pop is not implemented.");
122}
123void CadicalSatSolver::Pop() {
124 DLINEAR_DEBUG("CadicalSatSolver::Pop()");
125 cnf_variables_.pop();
126 var_to_sat_.pop();
127 sat_to_var_.pop();
128 // TODO(tend): pop
129 DLINEAR_RUNTIME_ERROR("cadical pop is not implemented.");
130}
131
132} // namespace dlinear
The TimeGuard wraps a timer object and pauses it when the guard object is destructed.
Definition Timer.h:129
Represents a symbolic form of a first-order logic formula.
Represents a symbolic variable.
Global namespace for the dlinear library.
std::set< Literal > LiteralSet
A set of literals.
Definition literal.h:28
A literal is a variable with an associated truth value, indicating whether it is true or false.
Definition literal.h:24
bool truth
Truth value.
Definition literal.h:26
Variable var
Variable.
Definition literal.h:25