mirror of
https://github.com/Z3Prover/z3
synced 2025-04-22 16:45:31 +00:00
recover shift-weight loop
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
1765141261
commit
609c46395f
4 changed files with 73 additions and 5 deletions
|
@ -62,7 +62,7 @@ namespace sat {
|
|||
unsigned steps = 0;
|
||||
save_best_values();
|
||||
try {
|
||||
while (m_min_sz != 0 && m_steps_since_progress++ <= 1500000) {
|
||||
while (m_min_sz != 0 && m_steps_since_progress++ <= 1500000 && m_limit.inc()) {
|
||||
if (should_reinit_weights()) do_reinit_weights();
|
||||
else if (steps % 5000 == 0) shift_weights(), m_plugin->on_rescale();
|
||||
else if (should_restart()) do_restart(), m_plugin->on_restart();
|
||||
|
@ -268,6 +268,10 @@ namespace sat {
|
|||
// cls becomes false: flip any variable in clause to receive reward w
|
||||
switch (ci.m_num_trues) {
|
||||
case 0: {
|
||||
#if 0
|
||||
if (ci.m_clause.size() == 1)
|
||||
verbose_stream() << "flipping unit clause " << ci << "\n";
|
||||
#endif
|
||||
m_unsat.insert_fresh(cls_idx);
|
||||
auto const& c = get_clause(cls_idx);
|
||||
for (literal l : c) {
|
||||
|
@ -512,15 +516,20 @@ namespace sat {
|
|||
}
|
||||
|
||||
unsigned ddfw::select_random_true_clause() {
|
||||
unsigned num_clauses = m_clauses.size();
|
||||
unsigned rounds = 100 * num_clauses;
|
||||
for (unsigned i = 0; i < rounds; ++i) {
|
||||
unsigned num_clauses = m_clauses.size();
|
||||
for (unsigned i = 0; i < num_clauses; ++i) {
|
||||
unsigned idx = (m_rand() * m_rand()) % num_clauses;
|
||||
auto & cn = m_clauses[idx];
|
||||
if (cn.is_true() && cn.m_weight >= m_init_weight)
|
||||
return idx;
|
||||
}
|
||||
return UINT_MAX;
|
||||
unsigned n = 0, idx = UINT_MAX;
|
||||
for (unsigned i = 0; i < num_clauses; ++i) {
|
||||
auto& cn = m_clauses[i];
|
||||
if (cn.is_true() && cn.m_weight >= m_init_weight && (m_rand() % (++n)) == 0)
|
||||
idx = i;
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
// 1% chance to disregard neighbor
|
||||
|
@ -534,6 +543,7 @@ namespace sat {
|
|||
|
||||
void ddfw::shift_weights() {
|
||||
++m_shifts;
|
||||
bool shifted = false;
|
||||
for (unsigned to_idx : m_unsat) {
|
||||
SASSERT(!m_clauses[to_idx].is_true());
|
||||
unsigned from_idx = select_max_same_sign(to_idx);
|
||||
|
@ -541,14 +551,62 @@ namespace sat {
|
|||
from_idx = select_random_true_clause();
|
||||
if (from_idx == UINT_MAX)
|
||||
continue;
|
||||
shifted = true;
|
||||
auto & cn = m_clauses[from_idx];
|
||||
SASSERT(cn.is_true());
|
||||
double w = calculate_transfer_weight(cn.m_weight);
|
||||
transfer_weight(from_idx, to_idx, w);
|
||||
}
|
||||
if (!shifted)
|
||||
m_reinit_next = m_flips;
|
||||
// DEBUG_CODE(invariant(););
|
||||
}
|
||||
|
||||
// apply unit propagation.
|
||||
void ddfw::simplify() {
|
||||
verbose_stream() << "simplify\n";
|
||||
sat::literal_vector units;
|
||||
uint_set unit_set;
|
||||
for (unsigned i = 0; i < m_clauses.size(); ++i) {
|
||||
auto& ci = m_clauses[i];
|
||||
if (ci.m_clause.size() != 1)
|
||||
continue;
|
||||
auto lit = ci.m_clause[0];
|
||||
units.push_back(lit);
|
||||
unit_set.insert(lit.index());
|
||||
m_use_list[lit.index()].reset();
|
||||
m_use_list[lit.index()].push_back(i);
|
||||
}
|
||||
auto is_unit = [&](sat::literal lit) {
|
||||
return unit_set.contains(lit.index());
|
||||
};
|
||||
|
||||
sat::literal_vector new_clause;
|
||||
for (unsigned i = 0; i < units.size(); ++i) {
|
||||
auto lit = units[i];
|
||||
for (auto cidx : m_use_list[(~lit).index()]) {
|
||||
auto& ci = m_clauses[cidx];
|
||||
if (ci.m_clause.size() == 1)
|
||||
continue;
|
||||
new_clause.reset();
|
||||
for (auto l : ci) {
|
||||
if (!is_unit(~l))
|
||||
new_clause.push_back(l);
|
||||
}
|
||||
if (new_clause.size() == 1) {
|
||||
verbose_stream() << "new unit " << lit << " " << ci << " -> " << new_clause << "\n";
|
||||
}
|
||||
m_clauses[cidx] = sat::clause_info(new_clause.size(), new_clause.data(), m_config.m_init_clause_weight);
|
||||
if (new_clause.size() == 1) {
|
||||
units.push_back(new_clause[0]);
|
||||
unit_set.insert(new_clause[0].index());
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto unit : units)
|
||||
m_use_list[(~unit).index()].reset();
|
||||
}
|
||||
|
||||
std::ostream& ddfw::display(std::ostream& out) const {
|
||||
unsigned num_cls = m_clauses.size();
|
||||
for (unsigned i = 0; i < num_cls; ++i) {
|
||||
|
|
|
@ -271,6 +271,8 @@ namespace sat {
|
|||
|
||||
inline unsigned num_vars() const { return m_vars.size(); }
|
||||
|
||||
void simplify();
|
||||
|
||||
|
||||
ptr_iterator<unsigned> use_list(literal lit) {
|
||||
unsigned i = lit.index();
|
||||
|
|
|
@ -98,6 +98,7 @@ namespace sls {
|
|||
g.begin_explain();
|
||||
g.explain<size_t>(explain, nullptr);
|
||||
g.end_explain();
|
||||
double reward = -1;
|
||||
TRACE("enf",
|
||||
for (auto p : explain) {
|
||||
sat::literal l = to_literal(p);
|
||||
|
@ -111,6 +112,10 @@ namespace sls {
|
|||
if (ctx.is_unit(l))
|
||||
continue;
|
||||
lits.push_back(~l);
|
||||
//verbose_stream() << "reward " << l << " " << ctx.reward(l.var()) << "\n";
|
||||
|
||||
if (ctx.reward(l.var()) > reward)
|
||||
n = 0, reward = ctx.reward(l.var());
|
||||
if (ctx.rand(++n) == 0)
|
||||
flit = l;
|
||||
}
|
||||
|
|
|
@ -35,9 +35,11 @@ namespace sls {
|
|||
solver_ctx(ast_manager& m, sat::ddfw& d) :
|
||||
m(m), m_ddfw(d), m_context(m, *this) {
|
||||
m_ddfw.set_plugin(this);
|
||||
m.limit().push_child(&m_ddfw.rlimit());
|
||||
}
|
||||
|
||||
~solver_ctx() override {
|
||||
m.limit().pop_child();
|
||||
}
|
||||
|
||||
void init_search() override {}
|
||||
|
@ -61,6 +63,7 @@ namespace sls {
|
|||
if (!m_new_constraint)
|
||||
break;
|
||||
TRACE("sls", display(tout));
|
||||
//m_ddfw.simplify();
|
||||
m_ddfw.reinit();
|
||||
m_new_constraint = false;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue