mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 01:25:31 +00:00
revise unit walk
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
5fe40a25dc
commit
6d893e0599
3 changed files with 308 additions and 104 deletions
|
@ -226,6 +226,8 @@ namespace sat {
|
|||
void mk_clause(literal l1, literal l2, bool learned = false);
|
||||
void mk_clause(literal l1, literal l2, literal l3, bool learned = false);
|
||||
|
||||
random_gen& rand() { return m_rand; }
|
||||
|
||||
protected:
|
||||
inline clause_allocator& cls_allocator() { return m_cls_allocator[m_cls_allocator_idx]; }
|
||||
inline clause_allocator const& cls_allocator() const { return m_cls_allocator[m_cls_allocator_idx]; }
|
||||
|
|
|
@ -8,6 +8,7 @@ Module Name:
|
|||
Abstract:
|
||||
|
||||
unit walk local search procedure.
|
||||
|
||||
A variant of UnitWalk. Hirsch and Kojevinkov, SAT 2001.
|
||||
This version uses a trail to reset assignments and integrates directly with the
|
||||
watch list structure. Thus, assignments are not delayed and we avoid treating
|
||||
|
@ -16,11 +17,9 @@ Abstract:
|
|||
It uses standard DPLL approach for backracking, flipping the last decision literal that
|
||||
lead to a conflict. It restarts after evern 100 conflicts.
|
||||
|
||||
It does not attempt to add conflict clauses or alternate with
|
||||
walksat.
|
||||
It does not attempt to add conflict clauses
|
||||
|
||||
It can receive conflict clauses from a concurrent CDCL solver and does not
|
||||
create its own conflict clauses.
|
||||
It can receive conflict clauses from a concurrent CDCL solver
|
||||
|
||||
The phase of variables is optionally sticky between rounds. We use a decay rate
|
||||
to compute stickiness of a variable.
|
||||
|
@ -31,20 +30,52 @@ Author:
|
|||
|
||||
Revision History:
|
||||
|
||||
2018-11-5:
|
||||
change reinitialization to use local search with limited timeouts to find phase and ordering of variables.
|
||||
|
||||
--*/
|
||||
|
||||
#include "sat_unit_walk.h"
|
||||
#include "sat/sat_unit_walk.h"
|
||||
#include "util/luby.h"
|
||||
|
||||
|
||||
namespace sat {
|
||||
|
||||
bool_var unit_walk::var_priority::peek(solver& s) {
|
||||
while (m_head < m_vars.size()) {
|
||||
bool_var v = m_vars[m_head];
|
||||
unsigned idx = literal(v, false).index();
|
||||
if (s.m_assignment[idx] == l_undef)
|
||||
return v;
|
||||
++m_head;
|
||||
}
|
||||
for (bool_var v : m_vars) {
|
||||
if (s.m_assignment[literal(v, false).index()] == l_undef) {
|
||||
IF_VERBOSE(0, verbose_stream() << "unassigned: " << v << "\n");
|
||||
}
|
||||
}
|
||||
IF_VERBOSE(0, verbose_stream() << "(sat.unit-walk sat)\n");
|
||||
return null_bool_var;
|
||||
}
|
||||
|
||||
void unit_walk::var_priority::set_vars(solver& s) {
|
||||
m_vars.reset();
|
||||
for (unsigned v = 0; v < s.num_vars(); ++v) {
|
||||
if (!s.was_eliminated(v) && s.m_assignment[v] == l_undef) {
|
||||
add(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool_var unit_walk::var_priority::next(solver& s) {
|
||||
bool_var v = peek(s);
|
||||
++m_head;
|
||||
return v;
|
||||
}
|
||||
|
||||
unit_walk::unit_walk(solver& s):
|
||||
s(s)
|
||||
{
|
||||
m_runs = 0;
|
||||
m_periods = 0;
|
||||
m_max_runs = UINT_MAX;
|
||||
m_max_periods = 5000; // UINT_MAX; // TBD configure
|
||||
m_max_conflicts = 100;
|
||||
s(s) {
|
||||
m_max_conflicts = 10000;
|
||||
m_sticky_phase = s.get_config().m_phase_sticky;
|
||||
m_flips = 0;
|
||||
}
|
||||
|
@ -63,67 +94,177 @@ namespace sat {
|
|||
lbool unit_walk::operator()() {
|
||||
scoped_set_unit_walk _scoped_set(this, s);
|
||||
init_runs();
|
||||
for (m_runs = 0; m_runs < m_max_runs || m_max_runs == UINT_MAX; ++m_runs) {
|
||||
init_propagation();
|
||||
init_phase();
|
||||
for (m_periods = 0; m_periods < m_max_periods || m_max_periods == UINT_MAX; ++m_periods) {
|
||||
if (!s.rlimit().inc()) return l_undef;
|
||||
lbool r = unit_propagation();
|
||||
if (r != l_undef) return r;
|
||||
}
|
||||
}
|
||||
return l_undef;
|
||||
}
|
||||
|
||||
lbool unit_walk::unit_propagation() {
|
||||
init_propagation();
|
||||
while (!m_freevars.empty() && !inconsistent()) {
|
||||
bool_var v = m_freevars.begin()[m_rand(m_freevars.size())];
|
||||
init_propagation();
|
||||
init_phase();
|
||||
while (true) {
|
||||
if (!s.rlimit().inc()) {
|
||||
log_status();
|
||||
return l_undef;
|
||||
}
|
||||
bool_var v = pqueue().next(s);
|
||||
if (v == null_bool_var) {
|
||||
log_status();
|
||||
return l_true;
|
||||
}
|
||||
literal lit(v, !m_phase[v]);
|
||||
++s.m_stats.m_decision;
|
||||
m_decisions.push_back(lit);
|
||||
// IF_VERBOSE(0, verbose_stream() << "push " << lit << " " << m_decisions.size() << "\n");
|
||||
pqueue().push();
|
||||
assign(lit);
|
||||
propagate();
|
||||
while (inconsistent() && !m_decisions.empty()) {
|
||||
++m_conflicts;
|
||||
backtrack();
|
||||
update_max_trail();
|
||||
++s.m_stats.m_conflict;
|
||||
pop();
|
||||
pqueue().pop();
|
||||
propagate();
|
||||
}
|
||||
if (m_conflicts >= m_max_conflicts && !m_freevars.empty()) {
|
||||
set_conflict();
|
||||
break;
|
||||
if (inconsistent()) {
|
||||
log_status();
|
||||
return l_false;
|
||||
}
|
||||
bool do_reinit = s.m_stats.m_conflict >= m_max_conflicts;
|
||||
if (do_reinit || pqueue().depth() > m_decisions.size()) { // || pqueue().depth() <= 10
|
||||
switch (update_priority()) {
|
||||
case l_true: return l_true;
|
||||
case l_false: break; // TBD
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
if (do_reinit) {
|
||||
refresh_solver();
|
||||
}
|
||||
}
|
||||
if (!inconsistent()) {
|
||||
log_status();
|
||||
IF_VERBOSE(1, verbose_stream() << "(sat-unit-walk sat)\n";);
|
||||
s.mk_model();
|
||||
return l_true;
|
||||
}
|
||||
|
||||
void unit_walk::pop() {
|
||||
SASSERT (!m_decisions.empty());
|
||||
literal dlit = m_decisions.back();
|
||||
pop_decision();
|
||||
m_inconsistent = false;
|
||||
assign(~dlit);
|
||||
}
|
||||
|
||||
void unit_walk::pop_decision() {
|
||||
SASSERT (!m_decisions.empty());
|
||||
literal dlit = m_decisions.back();
|
||||
// IF_VERBOSE(0, verbose_stream() << "pop " << dlit << " " << m_decisions.size() << "\n");
|
||||
literal lit;
|
||||
do {
|
||||
SASSERT(!m_trail.empty());
|
||||
lit = m_trail.back();
|
||||
s.m_assignment[lit.index()] = l_undef;
|
||||
s.m_assignment[(~lit).index()] = l_undef;
|
||||
m_trail.pop_back();
|
||||
}
|
||||
return l_undef;
|
||||
while (lit != dlit);
|
||||
m_qhead = m_trail.size();
|
||||
m_decisions.pop_back();
|
||||
}
|
||||
|
||||
void unit_walk::init_runs() {
|
||||
m_freevars.reset();
|
||||
m_luby_index = 0;
|
||||
m_restart_threshold = 1000;
|
||||
m_max_trail = 0;
|
||||
m_trail.reset();
|
||||
m_decisions.reset();
|
||||
m_phase.resize(s.num_vars());
|
||||
double2 d2;
|
||||
d2.t = 1.0;
|
||||
d2.f = 1.0;
|
||||
m_phase_tf.resize(s.num_vars(), d2);
|
||||
for (unsigned i = 0; i < s.num_vars(); ++i) {
|
||||
literal l(i, false);
|
||||
if (!s.was_eliminated(l.var()) && s.m_assignment[l.index()] == l_undef)
|
||||
m_freevars.insert(l.var());
|
||||
m_phase_tf.resize(s.num_vars(), ema(1e-5));
|
||||
pqueue().reset();
|
||||
pqueue().set_vars(s);
|
||||
for (unsigned v = 0; v < s.num_vars(); ++v) {
|
||||
m_phase_tf[v].update(50);
|
||||
}
|
||||
IF_VERBOSE(1, verbose_stream() << "num vars: " << s.num_vars() << " free vars: " << m_freevars.size() << "\n";);
|
||||
m_ls.import(s, true);
|
||||
m_rand.set_seed(s.rand()());
|
||||
update_priority();
|
||||
}
|
||||
|
||||
lbool unit_walk::update_priority() {
|
||||
unsigned prefix_length = 0;
|
||||
if (pqueue().depth() > m_decisions.size()) {
|
||||
while (pqueue().depth() > m_decisions.size()) {
|
||||
pqueue().dec_depth();
|
||||
}
|
||||
prefix_length = m_trail.size();
|
||||
SASSERT(pqueue().depth() == m_decisions.size());
|
||||
}
|
||||
else if (pqueue().depth() == m_decisions.size()) {
|
||||
prefix_length = m_trail.size();
|
||||
}
|
||||
else {
|
||||
literal last = m_decisions[pqueue().depth()];
|
||||
while (m_trail[prefix_length++] != last) {}
|
||||
pqueue().inc_depth();
|
||||
}
|
||||
log_status();
|
||||
IF_VERBOSE(1, verbose_stream() << "(sat.unit-walk :update-priority " << pqueue().depth() << ")\n");
|
||||
for (unsigned v = 0; v < s.num_vars(); ++v) {
|
||||
m_ls.set_bias(v, m_phase_tf[v] >= 50 ? l_true : l_false);
|
||||
}
|
||||
for (literal lit : m_trail) {
|
||||
m_ls.set_bias(lit.var(), lit.sign() ? l_false : l_true);
|
||||
}
|
||||
m_ls.rlimit().push(std::max(1u, pqueue().depth()));
|
||||
lbool is_sat = m_ls.check(0, m_trail.c_ptr(), nullptr);
|
||||
m_ls.rlimit().pop();
|
||||
|
||||
TRACE("sat", tout << "result of running bounded local search " << is_sat << "\n";);
|
||||
IF_VERBOSE(0, verbose_stream() << "result of running local search " << is_sat << "\n";);
|
||||
if (is_sat != l_undef) {
|
||||
restart();
|
||||
}
|
||||
if (is_sat == l_true) {
|
||||
for (unsigned v = 0; v < s.num_vars(); ++v) {
|
||||
s.m_assignment[v] = m_ls.get_phase(v) ? l_true : l_false;
|
||||
}
|
||||
}
|
||||
|
||||
struct compare_break {
|
||||
local_search& ls;
|
||||
compare_break(local_search& ls): ls(ls) {}
|
||||
int operator()(bool_var v, bool_var w) const {
|
||||
double diff = ls.break_count(v) - ls.break_count(w);
|
||||
return diff > 0;
|
||||
}
|
||||
};
|
||||
compare_break cb(m_ls);
|
||||
std::sort(pqueue().begin(), pqueue().end(), cb);
|
||||
pqueue().rewind();
|
||||
// assert variables are sorted from highest to lowest value.
|
||||
|
||||
for (bool_var v : pqueue()) {
|
||||
if (m_ls.cur_solution(v))
|
||||
m_phase_tf[v].update(100);
|
||||
else
|
||||
m_phase_tf[v].update(0);
|
||||
}
|
||||
init_phase();
|
||||
|
||||
// restart
|
||||
bool_var v = pqueue().peek(s);
|
||||
if (is_sat == l_undef && v != null_bool_var && false) {
|
||||
unsigned num_levels = 0;
|
||||
while (m_decisions.size() > 0 && num_levels <= 50) {
|
||||
bool_var w = m_decisions.back().var();
|
||||
if (num_levels >= 15 && m_ls.break_count(w) >= m_ls.break_count(v)) {
|
||||
break;
|
||||
}
|
||||
++num_levels;
|
||||
pop_decision();
|
||||
if (pqueue().depth() > m_decisions.size()) {
|
||||
pqueue().pop();
|
||||
}
|
||||
}
|
||||
IF_VERBOSE(0, verbose_stream() << "backtrack levels " << num_levels << "\n");
|
||||
}
|
||||
return is_sat;
|
||||
}
|
||||
|
||||
void unit_walk::init_phase() {
|
||||
m_max_trail = 0;
|
||||
if (m_sticky_phase) {
|
||||
for (bool_var v : m_freevars) {
|
||||
for (bool_var v : pqueue()) {
|
||||
if (s.m_phase[v] == POS_PHASE) {
|
||||
m_phase[v] = true;
|
||||
}
|
||||
|
@ -131,35 +272,73 @@ namespace sat {
|
|||
m_phase[v] = false;
|
||||
}
|
||||
else {
|
||||
m_phase[v] = m_rand(100 * static_cast<unsigned>(m_phase_tf[v].t + m_phase_tf[v].f)) <= 100 * m_phase_tf[v].t;
|
||||
m_phase[v] = m_rand(100) <= m_phase_tf[v];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (bool_var v : m_freevars)
|
||||
for (bool_var v : pqueue())
|
||||
m_phase[v] = (m_rand(2) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void unit_walk::refresh_solver() {
|
||||
m_max_conflicts += m_conflict_offset ;
|
||||
m_conflict_offset += 100; // 00;
|
||||
if (s.m_par && s.m_par->copy_solver(s)) {
|
||||
IF_VERBOSE(1, verbose_stream() << "(sat.unit-walk fresh copy)\n";);
|
||||
if (s.get_extension()) s.get_extension()->set_unit_walk(this);
|
||||
init_runs();
|
||||
init_phase();
|
||||
}
|
||||
if (should_restart()) {
|
||||
restart();
|
||||
}
|
||||
}
|
||||
|
||||
bool unit_walk::should_restart() {
|
||||
if (s.m_stats.m_conflict >= m_restart_threshold) {
|
||||
m_restart_threshold = s.get_config().m_restart_initial * get_luby(m_luby_index);
|
||||
++m_luby_index;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void unit_walk::restart() {
|
||||
IF_VERBOSE(1, verbose_stream() << "restart\n");
|
||||
while (!m_decisions.empty()) {
|
||||
pop_decision();
|
||||
}
|
||||
pqueue().reset();
|
||||
}
|
||||
|
||||
void unit_walk::update_max_trail() {
|
||||
if (m_max_trail == 0 || m_trail.size() > m_max_trail) {
|
||||
m_max_trail = m_trail.size();
|
||||
m_restart_threshold += 10000;
|
||||
m_max_conflicts = s.m_stats.m_conflict + 20000;
|
||||
log_status();
|
||||
}
|
||||
}
|
||||
|
||||
void unit_walk::init_propagation() {
|
||||
if (s.m_par && s.m_par->copy_solver(s)) {
|
||||
IF_VERBOSE(1, verbose_stream() << "(sat-unit-walk fresh copy)\n";);
|
||||
IF_VERBOSE(1, verbose_stream() << "(sat.unit-walk fresh copy)\n";);
|
||||
if (s.get_extension()) s.get_extension()->set_unit_walk(this);
|
||||
init_runs();
|
||||
init_phase();
|
||||
}
|
||||
if (m_max_trail == 0 || m_trail.size() > m_max_trail) {
|
||||
m_max_trail = m_trail.size();
|
||||
log_status();
|
||||
}
|
||||
for (literal lit : m_trail) {
|
||||
s.m_assignment[lit.index()] = l_undef;
|
||||
s.m_assignment[(~lit).index()] = l_undef;
|
||||
m_freevars.insert(lit.var());
|
||||
}
|
||||
m_flips = 0;
|
||||
m_trail.reset();
|
||||
m_conflicts = 0;
|
||||
s.m_stats.m_conflict = 0;
|
||||
m_conflict_offset = 10000;
|
||||
m_decisions.reset();
|
||||
m_qhead = 0;
|
||||
m_inconsistent = false;
|
||||
|
@ -171,6 +350,20 @@ namespace sat {
|
|||
// IF_VERBOSE(1, verbose_stream() << m_trail.size() << " " << inconsistent() << "\n";);
|
||||
}
|
||||
|
||||
std::ostream& unit_walk::display(std::ostream& out) const {
|
||||
unsigned i = 0;
|
||||
out << "num decisions: " << m_decisions.size() << "\n";
|
||||
for (literal lit : m_trail) {
|
||||
if (i < m_decisions.size() && m_decisions[i] == lit) {
|
||||
out << "d " << i << ": ";
|
||||
++i;
|
||||
}
|
||||
out << lit << "\n";
|
||||
}
|
||||
s.display(verbose_stream());
|
||||
return out;
|
||||
}
|
||||
|
||||
void unit_walk::propagate(literal l) {
|
||||
++s.m_stats.m_propagate;
|
||||
literal not_l = ~l;
|
||||
|
@ -289,11 +482,12 @@ namespace sat {
|
|||
}
|
||||
|
||||
void unit_walk::assign(literal lit) {
|
||||
SASSERT(value(lit) == l_undef);
|
||||
VERIFY(value(lit) == l_undef);
|
||||
//VERIFY(!m_trail.contains(lit));
|
||||
//VERIFY(!m_trail.contains(~lit));
|
||||
s.m_assignment[lit.index()] = l_true;
|
||||
s.m_assignment[(~lit).index()] = l_false;
|
||||
m_trail.push_back(lit);
|
||||
m_freevars.remove(lit.var());
|
||||
if (s.get_extension() && s.is_external(lit.var())) {
|
||||
s.get_extension()->asserted(lit);
|
||||
}
|
||||
|
@ -307,28 +501,23 @@ namespace sat {
|
|||
bool_var v = l.var();
|
||||
m_phase[v] = !m_phase[v];
|
||||
if (m_sticky_phase) {
|
||||
m_phase_tf[v].f *= 0.98;
|
||||
m_phase_tf[v].t *= 0.98;
|
||||
if (m_phase[v]) m_phase_tf[v].t += 1; else m_phase_tf[v].f += 1;
|
||||
if (m_phase[v]) m_phase_tf[v].update(100); else m_phase_tf[v].update(0);
|
||||
}
|
||||
}
|
||||
|
||||
void unit_walk::log_status() {
|
||||
IF_VERBOSE(1, verbose_stream() << "(sat-unit-walk :trail " << m_max_trail
|
||||
<< " :branches " << m_decisions.size()
|
||||
<< " :free " << m_freevars.size()
|
||||
<< " :periods " << m_periods
|
||||
IF_VERBOSE(1, verbose_stream()
|
||||
<< "(sat.unit-walk"
|
||||
<< " :trail " << m_trail.size()
|
||||
<< " :depth " << m_decisions.size()
|
||||
<< " :decisions " << s.m_stats.m_decision
|
||||
<< " :propagations " << s.m_stats.m_propagate
|
||||
<< " :conflicts " << s.m_stats.m_conflict
|
||||
<< ")\n";);
|
||||
}
|
||||
|
||||
literal unit_walk::choose_literal() {
|
||||
SASSERT(m_qhead < m_trail.size());
|
||||
unsigned idx = m_rand(m_trail.size() - m_qhead);
|
||||
std::swap(m_trail[m_qhead], m_trail[m_qhead + idx]);
|
||||
literal lit = m_trail[m_qhead++];
|
||||
return lit;
|
||||
return m_trail[m_qhead++];
|
||||
}
|
||||
|
||||
void unit_walk::set_conflict(literal l1, literal l2) {
|
||||
|
@ -346,25 +535,6 @@ namespace sat {
|
|||
void unit_walk::set_conflict() {
|
||||
m_inconsistent = true;
|
||||
}
|
||||
|
||||
void unit_walk::backtrack() {
|
||||
if (m_decisions.empty()) return;
|
||||
literal dlit = m_decisions.back();
|
||||
literal lit;
|
||||
do {
|
||||
SASSERT(!m_trail.empty());
|
||||
lit = m_trail.back();
|
||||
s.m_assignment[lit.index()] = l_undef;
|
||||
s.m_assignment[(~lit).index()] = l_undef;
|
||||
m_freevars.insert(lit.var());
|
||||
m_trail.pop_back();
|
||||
}
|
||||
while (lit != dlit);
|
||||
m_inconsistent = false;
|
||||
m_decisions.pop_back();
|
||||
m_qhead = m_trail.size();
|
||||
assign(~dlit);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -20,43 +20,74 @@ Revision History:
|
|||
#define SAT_UNIT_WALK_H_
|
||||
|
||||
#include "sat/sat_solver.h"
|
||||
#include "sat/sat_local_search.h"
|
||||
#include "util/ema.h"
|
||||
|
||||
namespace sat {
|
||||
|
||||
class unit_walk {
|
||||
#if 0
|
||||
struct double2 {
|
||||
double t, f;
|
||||
};
|
||||
#endif
|
||||
class var_priority {
|
||||
svector<bool_var> m_vars;
|
||||
unsigned_vector m_lim;
|
||||
unsigned m_head;
|
||||
unsigned m_depth;
|
||||
public:
|
||||
var_priority() { m_depth = 0; m_head = 0; }
|
||||
void rewind() { m_head = 0; for (unsigned& l : m_lim) l = 0; }
|
||||
unsigned depth() const { return m_depth; }
|
||||
void inc_depth() { ++m_depth; }
|
||||
void dec_depth() { --m_depth; }
|
||||
void reset() { m_lim.reset(); m_head = 0; m_depth = 0; }
|
||||
void add(bool_var v) { m_vars.push_back(v); }
|
||||
bool_var next(solver& s);
|
||||
bool_var peek(solver& s);
|
||||
void set_vars(solver& s);
|
||||
void push() { m_lim.push_back(m_head); }
|
||||
void pop() { m_head = m_lim.back(); m_lim.pop_back(); }
|
||||
bool empty() const { return m_lim.empty(); }
|
||||
bool_var const* begin() const { return m_vars.begin(); }
|
||||
bool_var const* end() const { return m_vars.end(); }
|
||||
bool_var* begin() { return m_vars.begin(); }
|
||||
bool_var* end() { return m_vars.end(); }
|
||||
};
|
||||
|
||||
solver& s;
|
||||
local_search m_ls;
|
||||
random_gen m_rand;
|
||||
svector<bool> m_phase;
|
||||
svector<double2> m_phase_tf;
|
||||
indexed_uint_set m_freevars;
|
||||
unsigned m_runs;
|
||||
unsigned m_periods;
|
||||
svector<ema> m_phase_tf;
|
||||
var_priority m_priorities;
|
||||
unsigned m_luby_index;
|
||||
unsigned m_restart_threshold;
|
||||
|
||||
// settings
|
||||
unsigned m_max_runs;
|
||||
unsigned m_max_periods;
|
||||
unsigned m_max_conflicts;
|
||||
bool m_sticky_phase;
|
||||
|
||||
unsigned m_propagations;
|
||||
unsigned m_flips;
|
||||
unsigned m_max_trail;
|
||||
unsigned m_qhead;
|
||||
literal_vector m_trail;
|
||||
bool m_inconsistent;
|
||||
literal_vector m_decisions;
|
||||
unsigned m_conflicts;
|
||||
unsigned m_conflict_offset;
|
||||
|
||||
void push();
|
||||
void backtrack();
|
||||
bool should_restart();
|
||||
void restart();
|
||||
void pop();
|
||||
void pop_decision();
|
||||
void init_runs();
|
||||
lbool update_priority();
|
||||
void init_phase();
|
||||
void init_propagation();
|
||||
void refresh_solver();
|
||||
void update_max_trail();
|
||||
void flip_phase(literal l);
|
||||
lbool unit_propagation();
|
||||
void propagate();
|
||||
void propagate(literal lit);
|
||||
literal choose_literal();
|
||||
|
@ -65,6 +96,7 @@ namespace sat {
|
|||
void set_conflict(clause const& c);
|
||||
inline lbool value(literal lit) { return s.value(lit); }
|
||||
void log_status();
|
||||
var_priority& pqueue() { return m_priorities; }
|
||||
public:
|
||||
|
||||
unit_walk(solver& s);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue