3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-10 19:27:06 +00:00

fix drat checker

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2017-02-10 18:04:54 -05:00
parent 6b4aec9b74
commit 8b4f3ac6f0
16 changed files with 201 additions and 166 deletions

View file

@ -14,7 +14,7 @@ z3_add_component(sat
sat_integrity_checker.cpp
sat_model_converter.cpp
sat_mus.cpp
sat_par.cpp
sat_parallel.cpp
sat_probing.cpp
sat_scc.cpp
sat_simplifier.cpp

View file

@ -266,12 +266,6 @@ namespace sat {
m_active_vars.reset();
}
void card_extension::reset_marked_literals() {
for (unsigned i = 0; i < m_marked_literals.size(); ++i) {
s().unmark_lit(m_marked_literals[i]);
}
m_marked_literals.reset();
}
bool card_extension::resolve_conflict() {
if (0 == m_num_propagations_since_pop)
@ -280,7 +274,7 @@ namespace sat {
m_num_marks = 0;
m_bound = 0;
m_lemma.reset();
m_lemma.push_back(null_literal);
// m_lemma.push_back(null_literal);
literal consequent = s().m_not_l;
justification js = s().m_conflict;
m_conflict_lvl = s().get_max_lvl(consequent, js);
@ -292,8 +286,6 @@ namespace sat {
unsigned idx = lits.size()-1;
int offset = 1;
unsigned num_card = 0;
unsigned num_steps = 0;
DEBUG_CODE(active2pb(m_A););
unsigned init_marks = m_num_marks;
@ -305,11 +297,13 @@ namespace sat {
}
// TBD: need proper check for overflow.
if (offset > (1 << 12)) {
IF_VERBOSE(2, verbose_stream() << "offset: " << offset << "\n";
active2pb(m_A);
display(verbose_stream(), m_A);
);
goto bail_out;
}
++num_steps;
// TRACE("sat", display(tout, m_A););
TRACE("sat", tout << "process consequent: " << consequent << ":\n"; s().display_justification(tout, js) << "\n";);
SASSERT(offset > 0);
@ -320,9 +314,7 @@ namespace sat {
switch(js.get_kind()) {
case justification::NONE:
SASSERT (consequent != null_literal);
m_lemma.push_back(~consequent);
m_bound += offset;
inc_coeff(consequent, offset);
break;
case justification::BINARY:
m_bound += offset;
@ -358,14 +350,10 @@ namespace sat {
break;
}
case justification::EXT_JUSTIFICATION: {
++num_card;
unsigned index = js.get_ext_justification_idx();
card& c = *m_constraints[index];
m_bound += offset * c.k();
if (!process_card(c, offset)) {
TRACE("sat", tout << "failed to process card\n";);
goto bail_out;
}
process_card(c, offset);
break;
}
default:
@ -394,7 +382,7 @@ namespace sat {
v = consequent.var();
if (s().is_marked(v)) break;
if (idx == 0) {
std::cout << num_steps << " " << init_marks << "\n";
IF_VERBOSE(2, verbose_stream() << "did not find marked literal\n";);
goto bail_out;
}
SASSERT(idx > 0);
@ -421,65 +409,45 @@ namespace sat {
SASSERT(validate_lemma());
normalize_active_coeffs();
reset_marked_literals();
if (consequent == null_literal) {
return false;
}
int slack = -m_bound;
for (unsigned i = 0; i < m_active_vars.size(); ++i) {
bool_var v = m_active_vars[i];
slack += get_abs_coeff(v);
}
consequent = null_literal;
++idx;
unsigned num_atoms = m_lemma.size();
while (0 <= slack) {
literal lit = lits[idx];
bool_var v = lit.var();
if (m_active_var_set.contains(v)) {
int coeff = get_coeff(v);
bool append = false;
if (coeff < 0 && !lit.sign()) {
slack += coeff;
append = true;
m_lemma.push_back(~lit);
}
else if (coeff > 0 && lit.sign()) {
slack -= coeff;
append = true;
}
if (append) {
if (consequent == null_literal) {
consequent = ~lit;
}
else {
m_lemma.push_back(~lit);
}
m_lemma.push_back(~lit);
}
}
if (idx == 0 && slack >= 0) {
IF_VERBOSE(2, verbose_stream() << "(sat.card non-asserting)\n";);
goto bail_out;
}
SASSERT(idx > 0 || slack < 0);
--idx;
}
for (unsigned i = 1; i < std::min(m_lemma.size(), num_atoms + 1); ++i) {
if (lvl(m_lemma[i]) == m_conflict_lvl) {
TRACE("sat", tout << "Bail out on no progress " << lit << "\n";);
IF_VERBOSE(3, verbose_stream() << "(sat.card bail resolve)\n";);
return false;
}
if (m_lemma.size() >= 2 && lvl(m_lemma[1]) == m_conflict_lvl) {
// TRACE("sat", tout << "Bail out on no progress " << lit << "\n";);
IF_VERBOSE(2, verbose_stream() << "(sat.card bail non-asserting resolvent)\n";);
goto bail_out;
}
SASSERT(slack < 0);
if (consequent == null_literal) {
if (!m_lemma.empty()) return false;
}
else {
m_lemma[0] = consequent;
SASSERT(validate_conflict(m_lemma, m_A));
}
SASSERT(validate_conflict(m_lemma, m_A));
TRACE("sat", tout << m_lemma << "\n";);
if (s().m_config.m_drat) {
@ -498,8 +466,6 @@ namespace sat {
return true;
bail_out:
reset_marked_literals();
std::cout << "bail num marks: " << m_num_marks << " idx: " << idx << "\n";
while (m_num_marks > 0 && idx >= 0) {
bool_var v = lits[idx].var();
if (s().is_marked(v)) {
@ -511,22 +477,18 @@ namespace sat {
return false;
}
bool card_extension::process_card(card& c, int offset) {
void card_extension::process_card(card& c, int offset) {
literal lit = c.lit();
SASSERT(c.k() <= c.size());
SASSERT(value(lit) == l_true);
SASSERT(0 < offset);
for (unsigned i = c.k(); i < c.size(); ++i) {
process_antecedent(c[i], offset);
}
for (unsigned i = 0; i < c.k(); ++i) {
inc_coeff(c[i], offset);
}
if (lvl(lit) > 0 && !s().is_marked_lit(lit)) {
m_lemma.push_back(~lit);
s().mark_lit(lit);
m_marked_literals.push_back(lit);
}
return (lvl(lit) <= m_conflict_lvl);
process_antecedent(~lit, c.k() * offset);
}
void card_extension::process_antecedent(literal l, int offset) {
@ -900,6 +862,7 @@ namespace sat {
for (unsigned i = 0; i < c.size(); ++i) {
p.push(c[i], offset);
}
p.push(~c.lit(), offset*c.k());
break;
}
default:
@ -977,7 +940,10 @@ namespace sat {
bool card_extension::validate_conflict(literal_vector const& lits, ineq& p) {
for (unsigned i = 0; i < lits.size(); ++i) {
if (value(lits[i]) != l_false) return false;
if (value(lits[i]) != l_false) {
TRACE("sat", tout << "literal " << lits[i] << " is not false\n";);
return false;
}
}
unsigned value = 0;
for (unsigned i = 0; i < p.m_lits.size(); ++i) {
@ -986,6 +952,9 @@ namespace sat {
value += coeff;
}
}
CTRACE("sat", value >= p.m_k, tout << "slack: " << value << " bound " << p.m_k << "\n";
display(tout, p);
tout << lits << "\n";);
return value < p.m_k;
}

View file

@ -98,8 +98,7 @@ namespace sat {
int m_bound;
tracked_uint_set m_active_var_set;
literal_vector m_lemma;
literal_vector m_literals;
literal_vector m_marked_literals;
// literal_vector m_literals;
unsigned m_num_propagations_since_pop;
solver& s() const { return *m_solver; }
@ -125,10 +124,9 @@ namespace sat {
int get_coeff(bool_var v) const;
int get_abs_coeff(bool_var v) const;
literal_vector& get_literals() { m_literals.reset(); return m_literals; }
literal get_asserting_literal(literal conseq);
void process_antecedent(literal l, int offset);
bool process_card(card& c, int offset);
void process_card(card& c, int offset);
void cut();
// validation utilities

View file

@ -169,7 +169,9 @@ namespace sat {
literal l = c[i];
switch (s.value(l)) {
case l_undef:
c[j] = l;
if (i != j) {
std::swap(c[i], c[j]);
}
j++;
break;
case l_false:
@ -201,6 +203,8 @@ namespace sat {
default:
c.shrink(new_sz);
s.attach_clause(c);
if (s.m_config.m_drat) s.m_drat.add(c, true);
// if (s.m_config.m_drat) s.m_drat.del(c0); // TBD
SASSERT(s.m_qhead == s.m_trail.size());
return true;
}

View file

@ -99,7 +99,9 @@ namespace sat {
m_elim_literals++;
break;
case l_undef:
c[j] = c[i];
if (i != j) {
std::swap(c[j], c[i]);
}
j++;
break;
}

View file

@ -35,7 +35,7 @@ namespace sat {
m_glue("glue"),
m_glue_psm("glue_psm"),
m_psm_glue("psm_glue") {
m_num_parallel = 1;
m_num_threads = 1;
updt_params(p);
}
@ -78,7 +78,7 @@ namespace sat {
m_burst_search = p.burst_search();
m_max_conflicts = p.max_conflicts();
m_num_parallel = p.parallel_threads();
m_num_threads = p.threads();
// These parameters are not exposed
m_simplify_mult1 = _p.get_uint("simplify_mult1", 300);
@ -113,7 +113,7 @@ namespace sat {
m_minimize_lemmas = p.minimize_lemmas();
m_core_minimize = p.core_minimize();
m_core_minimize_partial = p.core_minimize_partial();
m_drat = p.drat();
m_drat = p.drat() && p.threads() == 1;
m_drat_check = p.drat_check();
m_drat_file = p.drat_file();
m_dyn_sub_res = p.dyn_sub_res();

View file

@ -57,7 +57,7 @@ namespace sat {
unsigned m_random_seed;
unsigned m_burst_search;
unsigned m_max_conflicts;
unsigned m_num_parallel;
unsigned m_num_threads;
unsigned m_simplify_mult1;
double m_simplify_mult2;

View file

@ -79,7 +79,6 @@ namespace sat {
out << st << " ";
literal last = null_literal;
for (unsigned i = 0; i < n; ++i) {
declare(c[i]);
if (c[i] != last) {
out << c[i] << " ";
last = c[i];
@ -89,7 +88,7 @@ namespace sat {
}
void drat::append(literal l, status st) {
trace(std::cout, 1, &l, st);
IF_VERBOSE(10, trace(verbose_stream(), 1, &l, st););
if (st == status::learned) {
verify(1, &l);
}
@ -101,7 +100,7 @@ namespace sat {
void drat::append(literal l1, literal l2, status st) {
literal lits[2] = { l1, l2 };
trace(std::cout, 2, lits, st);
IF_VERBOSE(10, trace(verbose_stream(), 2, lits, st););
if (st == status::deleted) {
// noop
// don't record binary as deleted.
@ -132,7 +131,7 @@ namespace sat {
void drat::append(clause& c, status st) {
unsigned n = c.size();
trace(std::cout, n, c.begin(), st);
IF_VERBOSE(10, trace(verbose_stream(), n, c.begin(), st););
if (st == status::learned) {
verify(n, c.begin());
@ -205,8 +204,12 @@ namespace sat {
assign_propagate(~c[i]);
}
if (!m_inconsistent) {
TRACE("sat", display(tout););
DEBUG_CODE(validate_propagation(););
}
for (unsigned i = 0; i < m_units.size(); ++i) {
SASSERT(m_assignment[m_units[i].var()] != l_undef);
}
for (unsigned i = num_units; i < m_units.size(); ++i) {
m_assignment[m_units[i].var()] = l_undef;
}
@ -218,9 +221,37 @@ namespace sat {
bool drat::is_drat(unsigned n, literal const* c) {
if (m_inconsistent || n == 0) return true;
literal l = c[0];
literal_vector lits(n - 1, c + 1);
for (unsigned i = 0; m_proof.size(); ++i) {
for (unsigned i = 0; i < n; ++i) {
if (is_drat(n, c, i)) return true;
}
return false;
}
void drat::validate_propagation() const {
for (unsigned i = 0; i < m_proof.size(); ++i) {
status st = m_status[i];
if (m_proof[i] && st != status::deleted) {
clause& c = *m_proof[i];
unsigned num_undef = 0, num_true = 0;
for (unsigned j = 0; j < c.size(); ++j) {
switch (value(c[j])) {
case l_false: break;
case l_true: num_true++; break;
case l_undef: num_undef++; break;
}
}
CTRACE("sat", num_true == 0 && num_undef == 1, display(tout););
SASSERT(num_true != 0 || num_undef != 1);
}
}
}
bool drat::is_drat(unsigned n, literal const* c, unsigned pos) {
SASSERT(pos < n);
literal l = c[pos];
literal_vector lits(n, c);
SASSERT(lits.size() == n);
for (unsigned i = 0; i < m_proof.size(); ++i) {
status st = m_status[i];
if (m_proof[i] && (st == status::asserted || st == status::external)) {
clause& c = *m_proof[i];
@ -230,21 +261,22 @@ namespace sat {
lits.append(j, c.begin());
lits.append(c.size() - j - 1, c.begin() + j + 1);
if (!is_drup(lits.size(), lits.c_ptr())) return false;
lits.resize(n - 1);
lits.resize(n);
}
}
}
return true;
}
void drat::verify(unsigned n, literal const* c) {
if (is_drup(n, c) || is_drat(n, c)) {
std::cout << "Verified\n";
}
else {
if (!is_drup(n, c) && !is_drat(n, c)) {
std::cout << "Verification failed\n";
display(std::cout);
TRACE("sat", display(tout); s.display(tout););
TRACE("sat",
tout << literal_vector(n, c) << "\n";
display(tout);
s.display(tout););
UNREACHABLE();
exit(0);
}
@ -252,12 +284,10 @@ namespace sat {
void drat::display(std::ostream& out) const {
out << "units: " << m_units << "\n";
#if 1
for (unsigned i = 0; i < m_assignment.size(); ++i) {
lbool v = value(literal(i, false));
if (v != l_undef) out << i << ": " << v << "\n";
}
#endif
for (unsigned i = 0; i < m_proof.size(); ++i) {
clause* c = m_proof[i];
if (m_status[i] != status::deleted && c) {
@ -276,10 +306,9 @@ namespace sat {
if (num_true == 0 && num_undef == 1) {
out << "Unit ";
}
out << i << ": " << *c << "\n";
out << m_status[i] << " " << i << ": " << *c << "\n";
}
}
#if 1
for (unsigned i = 0; i < m_assignment.size(); ++i) {
watch const& w1 = m_watches[2*i];
watch const& w2 = m_watches[2*i + 1];
@ -294,25 +323,27 @@ namespace sat {
out << "\n";
}
}
#endif
}
lbool drat::value(literal l) const {
lbool v = m_assignment[l.var()];
return v == l_undef || !l.sign() ? v : ~v;
lbool val = m_assignment.get(l.var(), l_undef);
return val == l_undef || !l.sign() ? val : ~val;
}
void drat::assign(literal l) {
lbool new_value = l.sign() ? l_false : l_true;
lbool old_value = value(l);
if (new_value != old_value) {
if (old_value == l_undef) {
m_assignment[l.var()] = new_value;
m_units.push_back(l);
}
else {
m_inconsistent = true;
}
// TRACE("sat", tout << "assign " << l << " := " << new_value << " from " << old_value << "\n";);
switch (old_value) {
case l_false:
m_inconsistent = true;
break;
case l_true:
break;
case l_undef:
m_assignment.setx(l.var(), new_value, l_undef);
m_units.push_back(l);
break;
}
}
@ -334,14 +365,11 @@ namespace sat {
watched_clause& wc = m_watched_clauses[idx];
clause& c = *wc.m_clause;
TRACE("sat", tout << "Propagate " << l << " " << c << " watch: " << wc.m_l1 << " " << wc.m_l2 << "\n";);
//TRACE("sat", tout << "Propagate " << l << " " << c << " watch: " << wc.m_l1 << " " << wc.m_l2 << "\n";);
if (wc.m_l1 == ~l) {
std::swap(wc.m_l1, wc.m_l2);
}
if (wc.m_l2 != ~l) {
std::cout << wc.m_l1 << " " << wc.m_l2 << " ~l: " << ~l << "\n";
std::cout << *wc.m_clause << "\n";
}
SASSERT(wc.m_l2 == ~l);
if (value(wc.m_l1) == l_true) {
*it2 = *it;
@ -358,7 +386,6 @@ namespace sat {
}
}
if (done) {
it2++;
continue;
}
else if (value(wc.m_l1) == l_false) {
@ -385,22 +412,26 @@ namespace sat {
void drat::add() {
if (m_out) (*m_out) << "0\n";
if (s.m_config.m_drat_check) {
if (m_inconsistent) std::cout << "Verified\n";
else std::cout << "Failed to verify\n";
SASSERT(m_inconsistent);
}
}
void drat::add(literal l, bool learned) {
declare(l);
status st = get_status(learned);
if (m_out) dump(1, &l, st);
if (s.m_config.m_drat_check) append(l, st);
}
void drat::add(literal l1, literal l2, bool learned) {
declare(l1);
declare(l2);
literal ls[2] = {l1, l2};
status st = get_status(learned);
if (m_out) dump(2, ls, st);
if (s.m_config.m_drat_check) append(l1, l2, st);
}
void drat::add(clause& c, bool learned) {
TRACE("sat", tout << "add: " << c << "\n";);
for (unsigned i = 0; i < c.size(); ++i) declare(c[i]);
status st = get_status(learned);
if (m_out) dump(c.size(), c.begin(), st);
if (s.m_config.m_drat_check) append(c, get_status(learned));
@ -429,9 +460,11 @@ namespace sat {
append(l1, l2, status::deleted);
}
void drat::del(clause& c) {
TRACE("sat", tout << "del: " << c << "\n";);
if (m_out) dump(c.size(), c.begin(), status::deleted);
if (s.m_config.m_drat_check)
append(c, status::deleted);
else s.m_cls_allocator.del_clause(&c);
if (s.m_config.m_drat_check) {
clause* c1 = s.m_cls_allocator.mk_clause(c.size(), c.begin(), c.is_learned());
append(*c1, status::deleted);
}
}
}

View file

@ -68,9 +68,11 @@ namespace sat {
void verify(unsigned n, literal const* c);
bool is_drup(unsigned n, literal const* c);
bool is_drat(unsigned n, literal const* c);
bool is_drat(unsigned n, literal const* c, unsigned pos);
lbool value(literal l) const;
void trace(std::ostream& out, unsigned n, literal const* c, status st);
void display(std::ostream& out) const;
void validate_propagation() const;
public:
drat(solver& s);

View file

@ -117,7 +117,9 @@ namespace sat {
break; // clause was satisfied
if (val == l_false)
continue; // skip
c[j] = l;
if (i != j) {
std::swap(c[i], c[j]);
}
j++;
}
if (i < sz) {
@ -136,16 +138,7 @@ namespace sat {
return;
}
TRACE("elim_eqs", tout << "after removing duplicates: " << c << " j: " << j << "\n";);
if (j < sz)
c.shrink(j);
else
c.update_approx();
SASSERT(c.size() == j);
DEBUG_CODE({
for (unsigned i = 0; i < c.size(); i++) {
SASSERT(c[i] == norm(roots, c[i]));
}
});
SASSERT(j >= 1);
switch (j) {
case 1:
@ -160,8 +153,22 @@ namespace sat {
SASSERT(*it == &c);
*it2 = *it;
it2++;
if (!c.frozen())
if (j < sz) {
if (m_solver.m_config.m_drat) m_solver.m_drat.del(c);
c.shrink(j);
if (m_solver.m_config.m_drat) m_solver.m_drat.add(c, true);
}
else
c.update_approx();
DEBUG_CODE({
for (unsigned i = 0; i < sz; i++) {
SASSERT(c[i] == norm(roots, c[i]));
} });
if (!c.frozen()) {
m_solver.attach_clause(c);
}
break;
}
}

View file

@ -3,9 +3,9 @@ Copyright (c) 2017 Microsoft Corporation
Module Name:
sat_par.cpp
sat_parallel.cpp
Abstract:
Abstract:
Utilities for parallel SAT solving.
@ -16,14 +16,14 @@ Author:
Revision History:
--*/
#include "sat_par.h"
#include "sat_parallel.h"
#include "sat_clause.h"
#include "sat_solver.h"
namespace sat {
void par::vector_pool::next(unsigned& index) {
void parallel::vector_pool::next(unsigned& index) {
SASSERT(index < m_size);
unsigned n = index + 2 + get_length(index);
if (n >= m_size) {
@ -34,7 +34,7 @@ namespace sat {
}
}
void par::vector_pool::reserve(unsigned num_threads, unsigned sz) {
void parallel::vector_pool::reserve(unsigned num_threads, unsigned sz) {
m_vectors.reset();
m_vectors.resize(sz, 0);
m_heads.reset();
@ -43,7 +43,7 @@ namespace sat {
m_size = sz;
}
void par::vector_pool::begin_add_vector(unsigned owner, unsigned n) {
void parallel::vector_pool::begin_add_vector(unsigned owner, unsigned n) {
unsigned capacity = n + 2;
m_vectors.reserve(m_size + capacity, 0);
IF_VERBOSE(3, verbose_stream() << owner << ": begin-add " << n << " tail: " << m_tail << " size: " << m_size << "\n";);
@ -71,11 +71,11 @@ namespace sat {
m_vectors[m_tail++] = n;
}
void par::vector_pool::add_vector_elem(unsigned e) {
void parallel::vector_pool::add_vector_elem(unsigned e) {
m_vectors[m_tail++] = e;
}
bool par::vector_pool::get_vector(unsigned owner, unsigned& n, unsigned const*& ptr) {
bool parallel::vector_pool::get_vector(unsigned owner, unsigned& n, unsigned const*& ptr) {
unsigned head = m_heads[owner];
unsigned iterations = 0;
while (head != m_tail) {
@ -97,15 +97,15 @@ namespace sat {
return false;
}
par::par(solver& s): m_scoped_rlimit(s.rlimit()) {}
parallel::parallel(solver& s): m_scoped_rlimit(s.rlimit()) {}
par::~par() {
parallel::~parallel() {
for (unsigned i = 0; i < m_solvers.size(); ++i) {
dealloc(m_solvers[i]);
}
}
void par::init_solvers(solver& s, unsigned num_extra_solvers) {
void parallel::init_solvers(solver& s, unsigned num_extra_solvers) {
unsigned num_threads = num_extra_solvers + 1;
m_solvers.resize(num_extra_solvers, 0);
symbol saved_phase = s.m_params.get_sym("phase", symbol("caching"));
@ -127,7 +127,7 @@ namespace sat {
}
void par::exchange(solver& s, literal_vector const& in, unsigned& limit, literal_vector& out) {
void parallel::exchange(solver& s, literal_vector const& in, unsigned& limit, literal_vector& out) {
if (s.m_par_syncing_clauses) return;
flet<bool> _disable_sync_clause(s.m_par_syncing_clauses, true);
#pragma omp critical (par_solver)
@ -147,7 +147,7 @@ namespace sat {
}
}
void par::share_clause(solver& s, literal l1, literal l2) {
void parallel::share_clause(solver& s, literal l1, literal l2) {
if (s.m_par_syncing_clauses) return;
flet<bool> _disable_sync_clause(s.m_par_syncing_clauses, true);
#pragma omp critical (par_solver)
@ -159,7 +159,7 @@ namespace sat {
}
}
void par::share_clause(solver& s, clause const& c) {
void parallel::share_clause(solver& s, clause const& c) {
if (!enable_add(c) || s.m_par_syncing_clauses) return;
flet<bool> _disable_sync_clause(s.m_par_syncing_clauses, true);
unsigned n = c.size();
@ -174,7 +174,7 @@ namespace sat {
}
}
void par::get_clauses(solver& s) {
void parallel::get_clauses(solver& s) {
if (s.m_par_syncing_clauses) return;
flet<bool> _disable_sync_clause(s.m_par_syncing_clauses, true);
#pragma omp critical (par_solver)
@ -183,7 +183,7 @@ namespace sat {
}
}
void par::_get_clauses(solver& s) {
void parallel::_get_clauses(solver& s) {
unsigned n;
unsigned const* ptr;
unsigned owner = s.m_par_id;
@ -198,7 +198,7 @@ namespace sat {
}
}
bool par::enable_add(clause const& c) const {
bool parallel::enable_add(clause const& c) const {
// plingeling, glucose heuristic:
return (c.size() <= 40 && c.glue() <= 8) || c.glue() <= 2;
}

View file

@ -3,7 +3,7 @@ Copyright (c) 2017 Microsoft Corporation
Module Name:
sat_par.h
sat_parallel.h
Abstract:
@ -26,7 +26,7 @@ Revision History:
namespace sat {
class par {
class parallel {
// shared pool of learned clauses.
class vector_pool {
@ -61,9 +61,9 @@ namespace sat {
public:
par(solver& s);
parallel(solver& s);
~par();
~parallel();
void init_solvers(solver& s, unsigned num_extra_solvers);

View file

@ -22,7 +22,7 @@ def_module_params('sat',
('dyn_sub_res', BOOL, True, 'dynamic subsumption resolution for minimizing learned clauses'),
('core.minimize', BOOL, False, 'minimize computed core'),
('core.minimize_partial', BOOL, False, 'apply partial (cheap) core minimization'),
('parallel_threads', UINT, 1, 'number of parallel threads to use'),
('threads', UINT, 1, 'number of parallel threads to use'),
('dimacs.core', BOOL, False, 'extract core from DIMACS benchmarks'),
('drat', BOOL, False, 'produce DRAT proofs'),
('drat.file', SYMBOL, '', 'file to dump DRAT proofs'),

View file

@ -554,7 +554,9 @@ namespace sat {
literal l = c[i];
switch (value(l)) {
case l_undef:
c[j] = l;
if (i != j) {
std::swap(c[j], c[i]);
}
j++;
break;
case l_false:
@ -567,12 +569,18 @@ namespace sat {
break;
case l_true:
r = true;
c[j] = l;
if (i != j) {
std::swap(c[j], c[i]);
}
j++;
break;
}
}
c.shrink(j);
if (j < sz) {
if (s.m_config.m_drat) s.m_drat.del(c);
c.shrink(j);
if (s.m_config.m_drat) s.m_drat.add(c, true);
}
return r;
}
@ -588,7 +596,9 @@ namespace sat {
literal l = c[i];
switch (value(l)) {
case l_undef:
c[j] = l;
if (i != j) {
std::swap(c[j], c[i]);
}
j++;
break;
case l_false:
@ -597,7 +607,7 @@ namespace sat {
return true;
}
}
c.shrink(j);
c.shrink(j);
return false;
}
@ -642,6 +652,8 @@ namespace sat {
m_num_elim_lits++;
insert_elim_todo(l.var());
c.elim(l);
if (s.m_config.m_drat) s.m_drat.add(c, true);
// if (s.m_config.m_drat) s.m_drat.del(c0); // can delete previous version
clause_use_list & occurs = m_use_list.get(l);
occurs.erase_not_removed(c);
m_sub_counter -= occurs.size()/2;
@ -1418,6 +1430,7 @@ namespace sat {
else
s.m_stats.m_mk_clause++;
clause * new_c = s.m_cls_allocator.mk_clause(m_new_cls.size(), m_new_cls.c_ptr(), false);
if (s.m_config.m_drat) s.m_drat.add(*new_c, true);
s.m_clauses.push_back(new_c);
m_use_list.insert(*new_c);
if (m_sub_counter > 0)

View file

@ -212,9 +212,7 @@ namespace sat {
if (m_config.m_drat && !m_drat.is_cleaned(c)) {
m_drat.del(c);
}
else if (!m_config.m_drat || !m_config.m_drat_check || m_drat.is_cleaned(c)) {
m_cls_allocator.del_clause(&c);
}
m_cls_allocator.del_clause(&c);
m_stats.m_del_clause++;
}
@ -769,7 +767,7 @@ namespace sat {
pop_to_base_level();
IF_VERBOSE(2, verbose_stream() << "(sat.sat-solver)\n";);
SASSERT(at_base_lvl());
if (m_config.m_num_parallel > 1 && !m_par) {
if (m_config.m_num_threads > 1 && !m_par) {
return check_par(num_lits, lits);
}
flet<bool> _searching(m_searching, true);
@ -842,9 +840,9 @@ namespace sat {
};
lbool solver::check_par(unsigned num_lits, literal const* lits) {
int num_threads = static_cast<int>(m_config.m_num_parallel);
int num_threads = static_cast<int>(m_config.m_num_threads);
int num_extra_solvers = num_threads - 1;
sat::par par(*this);
sat::parallel par(*this);
// par.reserve(num_threads, 1 << 16);
par.reserve(num_threads, 1 << 9);
par.init_solvers(*this, num_extra_solvers);
@ -956,7 +954,7 @@ namespace sat {
}
}
void solver::set_par(par* p, unsigned id) {
void solver::set_par(parallel* p, unsigned id) {
m_par = p;
m_par_num_vars = num_vars();
m_par_limit_in = 0;
@ -1662,7 +1660,9 @@ namespace sat {
case l_false:
break;
case l_undef:
c[j] = c[i];
if (i != j) {
std::swap(c[i], c[j]);
}
j++;
break;
}
@ -1680,7 +1680,12 @@ namespace sat {
mk_bin_clause(c[0], c[1], true);
return false;
default:
c.shrink(new_sz);
if (new_sz != sz) {
std::cout << "shrinking " << c << "\n";
if (m_config.m_drat) m_drat.del(c);
c.shrink(new_sz);
if (m_config.m_drat) m_drat.add(c, true);
}
attach_clause(c);
return true;
}
@ -1749,7 +1754,6 @@ namespace sat {
if (m_ext && m_ext->resolve_conflict()) {
learn_lemma_and_backjump();
m_stats.m_conflict--;
return true;
}
@ -2815,7 +2819,10 @@ namespace sat {
literal lit = m_trail[i];
if (lvl(lit) > level) {
level = lvl(lit);
out << "level: " << level << " - ";
out << level << ": ";
}
else {
out << " ";
}
out << lit << " ";
display_justification(out, m_justification[lit.var()]) << "\n";

View file

@ -34,7 +34,7 @@ Revision History:
#include"sat_probing.h"
#include"sat_mus.h"
#include"sat_drat.h"
#include"sat_par.h"
#include"sat_parallel.h"
#include"params.h"
#include"statistics.h"
#include"stopwatch.h"
@ -76,7 +76,7 @@ namespace sat {
config m_config;
stats m_stats;
scoped_ptr<extension> m_ext;
par* m_par;
parallel* m_par;
random_gen m_rand;
clause_allocator m_cls_allocator;
cleaner m_cleaner;
@ -153,7 +153,7 @@ namespace sat {
friend class mus;
friend class drat;
friend class card_extension;
friend class par;
friend class parallel;
friend struct mk_stat;
public:
solver(params_ref const & p, reslimit& l);
@ -260,7 +260,7 @@ namespace sat {
m_num_checkpoints = 0;
if (memory::get_allocation_size() > m_config.m_max_memory) throw solver_exception(Z3_MAX_MEMORY_MSG);
}
void set_par(par* p, unsigned id);
void set_par(parallel* p, unsigned id);
bool canceled() { return !m_rlimit.inc(); }
config const& get_config() { return m_config; }
extension* get_extension() const { return m_ext.get(); }