3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 09:05:31 +00:00

fix local search initialization of units, encode offset in clauses

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2018-04-28 22:26:01 +02:00
parent 38888b5e5c
commit 2f025f52c0
6 changed files with 47 additions and 18 deletions

View file

@ -95,7 +95,6 @@ namespace sat {
}
}
bool clause::satisfied_by(model const & m) const {
for (literal l : *this) {
if (l.sign()) {
@ -110,6 +109,23 @@ namespace sat {
return false;
}
clause_offset clause::get_new_offset() const {
unsigned o1 = m_lits[0].index();
if (sizeof(clause_offset) == 8) {
unsigned o2 = m_lits[1].index();
return (clause_offset)o1 + (((clause_offset)o2) << 32);
}
return (clause_offset)o1;
}
void clause::set_new_offset(clause_offset offset) {
m_lits[0] = to_literal(static_cast<unsigned>(offset));
if (sizeof(offset) == 8) {
m_lits[1] = to_literal(static_cast<unsigned>(offset >> 32));
}
}
void tmp_clause::set(unsigned num_lits, literal const * lits, bool learned) {
if (m_clause && m_clause->m_capacity < num_lits) {
dealloc_svect(m_clause);

View file

@ -98,6 +98,8 @@ namespace sat {
unsigned glue() const { return m_glue; }
void set_psm(unsigned psm) { m_psm = psm > 255 ? 255 : psm; }
unsigned psm() const { return m_psm; }
clause_offset get_new_offset() const;
void set_new_offset(clause_offset off);
bool on_reinit_stack() const { return m_reinit_stack; }
void set_reinit_stack(bool f) { m_reinit_stack = f; }

View file

@ -79,11 +79,13 @@ namespace sat {
void local_search::init_cur_solution() {
for (var_info& vi : m_vars) {
// use bias with a small probability
if (m_rand() % 10 < 5 || m_config.phase_sticky()) {
vi.m_value = ((unsigned)(m_rand() % 100) < vi.m_bias);
}
else {
vi.m_value = (m_rand() % 2) == 0;
if (!vi.m_unit) {
if (m_rand() % 10 < 5 || m_config.phase_sticky()) {
vi.m_value = ((unsigned)(m_rand() % 100) < vi.m_bias);
}
else {
vi.m_value = (m_rand() % 2) == 0;
}
}
}
}
@ -149,7 +151,7 @@ namespace sat {
void local_search::reinit() {
IF_VERBOSE(0, verbose_stream() << "(sat-local-search reinit)\n";);
IF_VERBOSE(1, verbose_stream() << "(sat-local-search reinit)\n";);
if (true || !m_is_pb) {
//
// the following methods does NOT converge for pseudo-boolean
@ -216,13 +218,15 @@ namespace sat {
for (unsigned i = 0; i < m_prop_queue.size() && i < m_vars.size(); ++i) {
literal lit2 = m_prop_queue[i];
if (!is_true(lit2)) {
if (is_unit(lit2)) return false;
if (is_unit(lit2)) {
return false;
}
flip_walksat(lit2.var());
add_propagation(lit2);
}
}
if (m_prop_queue.size() >= m_vars.size()) {
IF_VERBOSE(0, verbose_stream() << "failed literal\n");
IF_VERBOSE(0, verbose_stream() << "propagation loop\n");
return false;
}
if (unit) {
@ -328,6 +332,7 @@ namespace sat {
return;
}
if (k == 1 && sz == 2) {
// IF_VERBOSE(0, verbose_stream() << "bin: " << ~c[0] << " + " << ~c[1] << " <= 1\n");
for (unsigned i = 0; i < 2; ++i) {
literal t(c[i]), s(c[1-i]);
m_vars.reserve(t.var() + 1);
@ -750,11 +755,12 @@ namespace sat {
IF_VERBOSE(1, verbose_stream() << "(sat.local_search :unsat)\n");
return;
}
if (is_unit(best_var)) {
goto reflip;
}
flip_walksat(best_var);
literal lit(best_var, !cur_solution(best_var));
if (!propagate(lit)) {
IF_VERBOSE(0, verbose_stream() << "failed literal " << lit << "\n");
if (is_true(lit)) {
flip_walksat(best_var);
}
@ -774,6 +780,7 @@ namespace sat {
}
void local_search::flip_walksat(bool_var flipvar) {
VERIFY(!is_unit(flipvar));
m_vars[flipvar].m_value = !cur_solution(flipvar);
bool flip_is_true = cur_solution(flipvar);

View file

@ -529,26 +529,26 @@ namespace sat {
IF_VERBOSE(1, verbose_stream() << "(sat-defrag)\n");
clause_allocator& alloc = m_cls_allocator[!m_cls_allocator_idx];
ptr_vector<clause> new_clauses, new_learned;
ptr_addr_map<clause, clause_offset> cls2offset;
for (clause* c : m_clauses) c->unmark_used();
for (clause* c : m_learned) c->unmark_used();
#if 0
svector<bool_var> vars;
for (unsigned i = 0; i < num_vars(); ++i) vars.push_back(i);
std::stable_sort(vars.begin(), vars.end(), cmp_activity(*this));
literal_vector lits;
for (bool_var v : vars) lits.push_back(to_literal(v)), lits.push_back(~to_literal(v));
// walk clauses, reallocate them in an order that defragments memory and creates locality.
//for (literal lit : lits) {
//watch_list& wlist = m_watches[lit.index()];
#endif
for (watch_list& wlist : m_watches) {
for (watched& w : wlist) {
if (w.is_clause()) {
clause& c1 = get_clause(w);
clause_offset offset;
if (c1.was_used()) {
offset = cls2offset[&c1];
offset = c1.get_new_offset();
}
else {
clause* c2 = alloc.copy_clause(c1);
@ -560,7 +560,7 @@ namespace sat {
new_clauses.push_back(c2);
}
offset = get_offset(*c2);
cls2offset.insert(&c1, offset);
c1.set_new_offset(offset);
}
w = watched(w.get_blocked_literal(), offset);
}