3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-10-16 04:20:25 +00:00

elaborating on local-search rephase strategy

This commit is contained in:
Nikolaj Bjorner 2023-02-07 03:17:52 -08:00
parent f3ae7692ca
commit 90a75866fb
9 changed files with 131 additions and 56 deletions

View file

@ -40,6 +40,26 @@ Revision History:
namespace sat {
/**
* Special cases of kissat style general backoff calculation.
* The version here calculates
* limit := value*log(C)^2*n*log(n)
* (effort calculation in kissat is based on ticks not clauses)
*
* respectively
* limit := conflicts + value*log(C)^2*n*log(n)
*/
void backoff::delta_effort(solver& s) {
count++;
unsigned d = value * count * log2(count + 1);
unsigned cl = log2(s.num_clauses() + 2);
limit = cl * cl * d;
}
void backoff::delta_conflicts(solver& s) {
delta_effort(s);
limit += s.m_conflicts_since_init;
}
solver::solver(params_ref const & p, reslimit& l):
solver_core(l),
@ -1349,16 +1369,43 @@ namespace sat {
m_local_search->updt_params(m_params);
m_local_search->set_seed(m_rand());
scoped_rl.push_child(&(m_local_search->rlimit()));
m_local_search->rlimit().push(500000);
m_backoffs.m_local_search.delta_effort(*this);
m_local_search->rlimit().push(m_backoffs.m_local_search.limit);
m_local_search->reinit(*this);
lbool r = m_local_search->check(_lits.size(), _lits.data(), nullptr);
for (unsigned i = 0; i < m_phase.size(); ++i)
m_best_phase[i] = m_local_search->get_value(i);
if (r == l_true) {
m_conflicts_since_restart = 0;
m_conflicts_since_gc = 0;
m_next_simplify = std::max(m_next_simplify, m_conflicts_since_init + 1);
auto const& mdl = m_local_search->get_model();
if (mdl.size() == m_best_phase.size()) {
for (unsigned i = 0; i < m_best_phase.size(); ++i)
m_best_phase[i] = l_true == mdl[i];
if (r == l_true) {
m_conflicts_since_restart = 0;
m_conflicts_since_gc = 0;
m_next_simplify = std::max(m_next_simplify, m_conflicts_since_init + 1);
}
do_restart(true);
#if 0
// move higher priority variables to front
// eg., move the first 10% variables to front
svector<std::pair<double, bool_var>> priorities(mdl.size());
for (unsigned i = 0; i < mdl.size(); ++i)
priorities[i] = { m_local_search->get_priority(i), i };
std::sort(priorities.begin(), priorities.end(), [](auto& x, auto& y) { return x.first > y.first; });
for (unsigned i = priorities.size() / 10; i-- > 0; )
move_to_front(priorities[i].second);
#endif
if (l_true == r) {
for (clause const* cp : m_clauses) {
bool is_true = any_of(*cp, [&](auto lit) { return lit.sign() != m_best_phase[lit.var()]; });
if (!is_true) {
verbose_stream() << "clause is false " << *cp << "\n";
}
}
}
}
}
@ -1693,7 +1740,7 @@ namespace sat {
if (!is_pos)
next_lit.neg();
TRACE("sat_decide", tout << scope_lvl() << ": next-case-split: " << next_lit << "\n";);
assign_scoped(next_lit);
return true;
@ -1913,6 +1960,7 @@ namespace sat {
m_rephase_lim = 0;
m_rephase_inc = 0;
m_reorder_lim = m_config.m_reorder_base;
m_backoffs.m_local_search.value = 500;
m_reorder_inc = 0;
m_conflicts_since_restart = 0;
m_force_conflict_analysis = false;
@ -1928,6 +1976,7 @@ namespace sat {
m_next_simplify = m_config.m_simplify_delay;
m_min_d_tk = 1.0;
m_search_lvl = 0;
if (m_learned.size() <= 2*m_clauses.size())
m_conflicts_since_gc = 0;
m_restart_next_out = 0;
@ -2030,9 +2079,7 @@ namespace sat {
if (m_par) {
m_par->from_solver(*this);
if (m_par->to_solver(*this)) {
m_activity_inc = 128;
}
m_par->to_solver(*this);
}
if (m_config.m_binspr && !inconsistent()) {
@ -2944,14 +2991,19 @@ namespace sat {
case PS_SAT_CACHING:
if (m_search_state == s_sat)
for (unsigned i = 0; i < m_phase.size(); ++i)
m_phase[i] = m_best_phase[i];
m_phase[i] = m_best_phase[i];
break;
case PS_RANDOM:
for (auto& p : m_phase) p = (m_rand() % 2) == 0;
break;
case PS_LOCAL_SEARCH:
if (m_search_state == s_sat)
bounded_local_search();
if (m_search_state == s_sat) {
if (m_rand() % 2 == 0)
bounded_local_search();
for (unsigned i = 0; i < m_phase.size(); ++i)
m_phase[i] = m_best_phase[i];
}
break;
default:
UNREACHABLE();