mirror of
https://github.com/Z3Prover/z3
synced 2025-04-15 13:28:47 +00:00
n/a
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
7580644d15
commit
bcf0ee7709
|
@ -69,6 +69,14 @@ namespace sat {
|
||||||
SASSERT(m_size >= m_k && m_k > 0);
|
SASSERT(m_size >= m_k && m_k > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ba_solver::card::is_watching(literal l) const {
|
||||||
|
unsigned sz = std::min(k() + 1, size());
|
||||||
|
for (unsigned i = 0; i < sz; ++i) {
|
||||||
|
if ((*this)[i] == l) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& out, ba_solver::constraint const& cnstr) {
|
std::ostream& operator<<(std::ostream& out, ba_solver::constraint const& cnstr) {
|
||||||
if (cnstr.lit() != null_literal) out << cnstr.lit() << " == ";
|
if (cnstr.lit() != null_literal) out << cnstr.lit() << " == ";
|
||||||
switch (cnstr.tag()) {
|
switch (cnstr.tag()) {
|
||||||
|
@ -135,6 +143,14 @@ namespace sat {
|
||||||
m_k = w - m_k + 1;
|
m_k = w - m_k + 1;
|
||||||
SASSERT(w >= m_k && m_k > 0);
|
SASSERT(w >= m_k && m_k > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ba_solver::pb::is_watching(literal l) const {
|
||||||
|
for (unsigned i = 0; i < m_num_watch; ++i) {
|
||||||
|
if ((*this)[i].second == l) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ba_solver::xor::xor(literal lit, literal_vector const& lits):
|
ba_solver::xor::xor(literal lit, literal_vector const& lits):
|
||||||
constraint(xor_t, lit, lits.size(), get_obj_size(lits.size())) {
|
constraint(xor_t, lit, lits.size(), get_obj_size(lits.size())) {
|
||||||
|
@ -143,6 +159,12 @@ namespace sat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ba_solver::xor::is_watching(literal l) const {
|
||||||
|
return
|
||||||
|
l == (*this)[0] || l == (*this)[1] ||
|
||||||
|
~l == (*this)[0] || ~l == (*this)[1];
|
||||||
|
}
|
||||||
|
|
||||||
void ba_solver::init_watch(card& c, bool is_true) {
|
void ba_solver::init_watch(card& c, bool is_true) {
|
||||||
clear_watch(c);
|
clear_watch(c);
|
||||||
if (c.lit() != null_literal && c.lit().sign() == is_true) {
|
if (c.lit() != null_literal && c.lit().sign() == is_true) {
|
||||||
|
@ -211,14 +233,6 @@ namespace sat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ba_solver::unwatch_literal(literal lit, constraint& c) {
|
|
||||||
get_wlist(~lit).erase(watched(c.index()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ba_solver::watch_literal(literal lit, constraint& c) {
|
|
||||||
get_wlist(~lit).push_back(watched(c.index()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ba_solver::set_conflict(constraint& c, literal lit) {
|
void ba_solver::set_conflict(constraint& c, literal lit) {
|
||||||
m_stats.m_num_conflicts++;
|
m_stats.m_num_conflicts++;
|
||||||
TRACE("sat", display(tout, c, true); );
|
TRACE("sat", display(tout, c, true); );
|
||||||
|
@ -510,7 +524,6 @@ namespace sat {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ba_solver::simplify(pb& p) {
|
void ba_solver::simplify(pb& p) {
|
||||||
s().pop_to_base_level();
|
|
||||||
if (p.lit() != null_literal && value(p.lit()) == l_false) {
|
if (p.lit() != null_literal && value(p.lit()) == l_false) {
|
||||||
TRACE("sat", tout << "pb: flip sign " << p << "\n";);
|
TRACE("sat", tout << "pb: flip sign " << p << "\n";);
|
||||||
return;
|
return;
|
||||||
|
@ -629,6 +642,8 @@ namespace sat {
|
||||||
void ba_solver::clear_watch(xor& x) {
|
void ba_solver::clear_watch(xor& x) {
|
||||||
unwatch_literal(x[0], x);
|
unwatch_literal(x[0], x);
|
||||||
unwatch_literal(x[1], x);
|
unwatch_literal(x[1], x);
|
||||||
|
unwatch_literal(~x[0], x);
|
||||||
|
unwatch_literal(~x[1], x);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ba_solver::parity(xor const& x, unsigned offset) const {
|
bool ba_solver::parity(xor const& x, unsigned offset) const {
|
||||||
|
@ -678,6 +693,8 @@ namespace sat {
|
||||||
SASSERT(j == 2);
|
SASSERT(j == 2);
|
||||||
watch_literal(x[0], x);
|
watch_literal(x[0], x);
|
||||||
watch_literal(x[1], x);
|
watch_literal(x[1], x);
|
||||||
|
watch_literal(~x[0], x);
|
||||||
|
watch_literal(~x[1], x);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1157,6 +1174,14 @@ namespace sat {
|
||||||
s().set_external(lit.var());
|
s().set_external(lit.var());
|
||||||
get_wlist(lit).push_back(c->index());
|
get_wlist(lit).push_back(c->index());
|
||||||
get_wlist(~lit).push_back(c->index());
|
get_wlist(~lit).push_back(c->index());
|
||||||
|
if (!validate_watched_constraint(*c)) {
|
||||||
|
std::cout << "wrong: " << *c << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lit.var() == 102770) {
|
||||||
|
display(std::cout, *c, true);
|
||||||
|
display_watch_list(std::cout, s().m_cls_allocator, get_wlist(lit)) << "\n";
|
||||||
|
display_watch_list(std::cout, s().m_cls_allocator, get_wlist(~lit)) << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1208,6 +1233,7 @@ namespace sat {
|
||||||
if (c.lit() != null_literal && l.var() == c.lit().var()) {
|
if (c.lit() != null_literal && l.var() == c.lit().var()) {
|
||||||
init_watch(c, !l.sign());
|
init_watch(c, !l.sign());
|
||||||
keep = true;
|
keep = true;
|
||||||
|
if (!inconsistent()) validate_watched_constraint(c);
|
||||||
}
|
}
|
||||||
else if (c.lit() != null_literal && value(c.lit()) != l_true) {
|
else if (c.lit() != null_literal && value(c.lit()) != l_true) {
|
||||||
keep = false;
|
keep = false;
|
||||||
|
@ -1215,6 +1241,7 @@ namespace sat {
|
||||||
else {
|
else {
|
||||||
keep = l_undef != add_assign(c, ~l);
|
keep = l_undef != add_assign(c, ~l);
|
||||||
}
|
}
|
||||||
|
std::cout << c.lit() << " " << l << " " << keep << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1444,10 +1471,21 @@ namespace sat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------
|
||||||
|
// constraint generic methods
|
||||||
|
|
||||||
void ba_solver::get_antecedents(literal l, ext_justification_idx idx, literal_vector & r) {
|
void ba_solver::get_antecedents(literal l, ext_justification_idx idx, literal_vector & r) {
|
||||||
get_antecedents(l, index2constraint(idx), r);
|
get_antecedents(l, index2constraint(idx), r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ba_solver::unwatch_literal(literal lit, constraint& c) {
|
||||||
|
get_wlist(~lit).erase(watched(c.index()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ba_solver::watch_literal(literal lit, constraint& c) {
|
||||||
|
get_wlist(~lit).push_back(watched(c.index()));
|
||||||
|
}
|
||||||
|
|
||||||
void ba_solver::get_antecedents(literal l, constraint const& c, literal_vector& r) {
|
void ba_solver::get_antecedents(literal l, constraint const& c, literal_vector& r) {
|
||||||
switch (c.tag()) {
|
switch (c.tag()) {
|
||||||
case card_t: get_antecedents(l, c.to_card(), r); break;
|
case card_t: get_antecedents(l, c.to_card(), r); break;
|
||||||
|
@ -1457,7 +1495,38 @@ namespace sat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ba_solver::nullify_tracking_literal(constraint& c) {
|
||||||
|
if (c.lit() != null_literal) {
|
||||||
|
get_wlist(c.lit()).erase(watched(c.index()));
|
||||||
|
get_wlist(~c.lit()).erase(watched(c.index()));
|
||||||
|
c.nullify_literal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ba_solver::remove_constraint(constraint& c) {
|
||||||
|
nullify_tracking_literal(c);
|
||||||
|
switch (c.tag()) {
|
||||||
|
case card_t:
|
||||||
|
clear_watch(c.to_card());
|
||||||
|
break;
|
||||||
|
case pb_t:
|
||||||
|
clear_watch(c.to_pb());
|
||||||
|
break;
|
||||||
|
case xor_t:
|
||||||
|
clear_watch(c.to_xor());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
c.remove();
|
||||||
|
m_constraint_removed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------
|
||||||
|
// validation
|
||||||
|
|
||||||
bool ba_solver::validate_unit_propagation(constraint const& c, literal l) const {
|
bool ba_solver::validate_unit_propagation(constraint const& c, literal l) const {
|
||||||
|
return true;
|
||||||
switch (c.tag()) {
|
switch (c.tag()) {
|
||||||
case card_t: return validate_unit_propagation(c.to_card(), l);
|
case card_t: return validate_unit_propagation(c.to_card(), l);
|
||||||
case pb_t: return validate_unit_propagation(c.to_pb(), l);
|
case pb_t: return validate_unit_propagation(c.to_pb(), l);
|
||||||
|
@ -1468,6 +1537,7 @@ namespace sat {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ba_solver::validate_conflict(constraint const& c) const {
|
bool ba_solver::validate_conflict(constraint const& c) const {
|
||||||
|
return true;
|
||||||
switch (c.tag()) {
|
switch (c.tag()) {
|
||||||
case card_t: return validate_conflict(c.to_card());
|
case card_t: return validate_conflict(c.to_card());
|
||||||
case pb_t: return validate_conflict(c.to_pb());
|
case pb_t: return validate_conflict(c.to_pb());
|
||||||
|
@ -1477,6 +1547,133 @@ namespace sat {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ba_solver::is_true(constraint const& c) const {
|
||||||
|
lbool v1 = c.lit() == null_literal ? l_true : value(c.lit());
|
||||||
|
if (v1 == l_undef) return false;
|
||||||
|
switch (c.tag()) {
|
||||||
|
case card_t: return v1 == value(c.to_card());
|
||||||
|
case pb_t: return v1 == value(c.to_pb());
|
||||||
|
case xor_t: return v1 == value(c.to_xor());
|
||||||
|
default: UNREACHABLE(); break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
lbool ba_solver::value(card const& c) const {
|
||||||
|
unsigned trues = 0, undefs = 0;
|
||||||
|
for (literal l : c) {
|
||||||
|
switch (value(l)) {
|
||||||
|
case l_true: trues++; break;
|
||||||
|
case l_undef: undefs++; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (trues + undefs < c.k()) return l_false;
|
||||||
|
if (trues >= c.k()) return l_true;
|
||||||
|
return l_undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
lbool ba_solver::value(pb const& p) const {
|
||||||
|
unsigned trues = 0, undefs = 0;
|
||||||
|
for (wliteral wl : p) {
|
||||||
|
switch (value(wl.second)) {
|
||||||
|
case l_true: trues += wl.first; break;
|
||||||
|
case l_undef: undefs += wl.first; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (trues + undefs < p.k()) return l_false;
|
||||||
|
if (trues >= p.k()) return l_true;
|
||||||
|
return l_undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
lbool ba_solver::value(xor const& x) const {
|
||||||
|
bool odd = false;
|
||||||
|
|
||||||
|
for (auto l : x) {
|
||||||
|
switch (value(l)) {
|
||||||
|
case l_true: odd = !odd; break;
|
||||||
|
case l_false: break;
|
||||||
|
default: return l_undef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return odd ? l_true : l_false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ba_solver::validate() {
|
||||||
|
if (validate_watch_literals()) {
|
||||||
|
for (constraint* c : m_constraints) {
|
||||||
|
if (!validate_watched_constraint(*c)) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ba_solver::validate_watch_literals() const {
|
||||||
|
for (unsigned v = 0; v < s().num_vars(); ++v) {
|
||||||
|
literal lit(v, false);
|
||||||
|
if (lvl(lit) == 0) continue;
|
||||||
|
if (!validate_watch_literal(lit)) return false;
|
||||||
|
if (!validate_watch_literal(~lit)) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ba_solver::validate_watch_literal(literal lit) const {
|
||||||
|
if (lvl(lit) == 0) return true;
|
||||||
|
for (auto const & w : get_wlist(lit)) {
|
||||||
|
if (w.get_kind() == watched::EXT_CONSTRAINT) {
|
||||||
|
constraint const& c = index2constraint(w.get_ext_constraint_idx());
|
||||||
|
if (!c.is_watching(~lit)) {
|
||||||
|
std::cout << lit << " " << lvl(lit) << " is not watched in " << c << "\n";
|
||||||
|
display(std::cout, c, true);
|
||||||
|
UNREACHABLE();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ba_solver::validate_watched_constraint(constraint const& c) const {
|
||||||
|
if (c.lit() != null_literal && value(c.lit()) != l_true) return true;
|
||||||
|
if (c.lit() != null_literal && lvl(c.lit()) != 0) {
|
||||||
|
if (!is_watching(c.lit(), c) || !is_watching(~c.lit(), c)) {
|
||||||
|
std::cout << "Definition literal is not watched " << c.lit() << " " << c << "\n";
|
||||||
|
display_watch_list(std::cout, s().m_cls_allocator, get_wlist(c.lit())) << "\n";
|
||||||
|
display_watch_list(std::cout, s().m_cls_allocator, get_wlist(~c.lit())) << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_true(c)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
literal_vector lits(c.literals());
|
||||||
|
for (literal l : lits) {
|
||||||
|
if (lvl(l) == 0) continue;
|
||||||
|
bool found = is_watching(l, c);
|
||||||
|
if (found != c.is_watching(l)) {
|
||||||
|
std::cout << "Discrepancy of watched literal: " << l << ": " << c.index() << " " << c << (found?" is watched, but shouldn't be":" not watched, but should be") << "\n";
|
||||||
|
display_watch_list(std::cout << l << ": ", s().m_cls_allocator, get_wlist(l)) << "\n";
|
||||||
|
display_watch_list(std::cout << ~l << ": ", s().m_cls_allocator, get_wlist(~l)) << "\n";
|
||||||
|
std::cout << "value: " << value(l) << " level: " << lvl(l) << "\n";
|
||||||
|
display(std::cout, c, true);
|
||||||
|
if (c.lit() != null_literal) std::cout << value(c.lit()) << "\n";
|
||||||
|
UNREACHABLE();
|
||||||
|
exit(1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ba_solver::is_watching(literal lit, constraint const& c) const {
|
||||||
|
for (auto w : get_wlist(~lit)) {
|
||||||
|
if (w.get_kind() == watched::EXT_CONSTRAINT && w.get_ext_constraint_idx() == c.index())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Lex on (glue, size)
|
\brief Lex on (glue, size)
|
||||||
*/
|
*/
|
||||||
|
@ -1507,33 +1704,6 @@ namespace sat {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ba_solver::nullify_tracking_literal(constraint& c) {
|
|
||||||
if (c.lit() != null_literal) {
|
|
||||||
get_wlist(c.lit()).erase(watched(c.index()));
|
|
||||||
get_wlist(~c.lit()).erase(watched(c.index()));
|
|
||||||
c.nullify_literal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ba_solver::remove_constraint(constraint& c) {
|
|
||||||
nullify_tracking_literal(c);
|
|
||||||
switch (c.tag()) {
|
|
||||||
case card_t:
|
|
||||||
clear_watch(c.to_card());
|
|
||||||
break;
|
|
||||||
case pb_t:
|
|
||||||
clear_watch(c.to_pb());
|
|
||||||
break;
|
|
||||||
case xor_t:
|
|
||||||
clear_watch(c.to_xor());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
c.remove();
|
|
||||||
m_constraint_removed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ba_solver::simplify(card& c) {
|
void ba_solver::simplify(card& c) {
|
||||||
SASSERT(c.lit() == null_literal || value(c.lit()) != l_false);
|
SASSERT(c.lit() == null_literal || value(c.lit()) != l_false);
|
||||||
if (c.lit() != null_literal && value(c.lit()) == l_false) {
|
if (c.lit() != null_literal && value(c.lit()) == l_false) {
|
||||||
|
@ -1722,7 +1892,7 @@ namespace sat {
|
||||||
|
|
||||||
void ba_solver::simplify() {
|
void ba_solver::simplify() {
|
||||||
return;
|
return;
|
||||||
if (!s().at_base_lvl()) s().pop_to_base_level();
|
SASSERT(s().at_base_lvl());
|
||||||
unsigned trail_sz;
|
unsigned trail_sz;
|
||||||
do {
|
do {
|
||||||
m_simplify_change = false;
|
m_simplify_change = false;
|
||||||
|
@ -1760,6 +1930,10 @@ namespace sat {
|
||||||
|
|
||||||
void ba_solver::flush_roots() {
|
void ba_solver::flush_roots() {
|
||||||
if (m_roots.empty()) return;
|
if (m_roots.empty()) return;
|
||||||
|
|
||||||
|
std::cout << "pre\n";
|
||||||
|
validate();
|
||||||
|
|
||||||
m_visited.resize(s().num_vars()*2, false);
|
m_visited.resize(s().num_vars()*2, false);
|
||||||
m_constraint_removed = false;
|
m_constraint_removed = false;
|
||||||
for (constraint* c : m_constraints) {
|
for (constraint* c : m_constraints) {
|
||||||
|
@ -1778,6 +1952,8 @@ namespace sat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cleanup_constraints();
|
cleanup_constraints();
|
||||||
|
std::cout << "post\n";
|
||||||
|
validate();
|
||||||
// display(std::cout << "flush roots\n");
|
// display(std::cout << "flush roots\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1907,7 +2083,7 @@ namespace sat {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ba_solver::recompile(pb& p) {
|
void ba_solver::recompile(pb& p) {
|
||||||
// IF_VERBOSE(0, verbose_stream() << "re: " << p << "\n";);
|
IF_VERBOSE(0, verbose_stream() << "re: " << p << "\n";);
|
||||||
m_weights.resize(2*s().num_vars(), 0);
|
m_weights.resize(2*s().num_vars(), 0);
|
||||||
for (wliteral wl : p) {
|
for (wliteral wl : p) {
|
||||||
m_weights[wl.second.index()] += wl.first;
|
m_weights[wl.second.index()] += wl.first;
|
||||||
|
@ -1965,11 +2141,10 @@ namespace sat {
|
||||||
p.update_k(k);
|
p.update_k(k);
|
||||||
p.update_max_sum();
|
p.update_max_sum();
|
||||||
|
|
||||||
|
|
||||||
literal root = null_literal;
|
literal root = null_literal;
|
||||||
if (p.lit() != null_literal) root = m_roots[p.lit().index()];
|
if (p.lit() != null_literal) root = m_roots[p.lit().index()];
|
||||||
|
|
||||||
// IF_VERBOSE(0, verbose_stream() << "new: " << p << "\n";);
|
IF_VERBOSE(0, verbose_stream() << "new: " << p << "\n";);
|
||||||
|
|
||||||
// std::cout << "simplified " << p << "\n";
|
// std::cout << "simplified " << p << "\n";
|
||||||
if (p.lit() != root) {
|
if (p.lit() != root) {
|
||||||
|
|
|
@ -74,6 +74,7 @@ namespace sat {
|
||||||
void nullify_literal() { m_lit = null_literal; }
|
void nullify_literal() { m_lit = null_literal; }
|
||||||
unsigned glue() const { return m_glue; }
|
unsigned glue() const { return m_glue; }
|
||||||
void set_glue(unsigned g) { m_glue = g; }
|
void set_glue(unsigned g) { m_glue = g; }
|
||||||
|
|
||||||
|
|
||||||
size_t obj_size() const { return m_obj_size; }
|
size_t obj_size() const { return m_obj_size; }
|
||||||
card& to_card();
|
card& to_card();
|
||||||
|
@ -85,6 +86,9 @@ namespace sat {
|
||||||
bool is_card() const { return m_tag == card_t; }
|
bool is_card() const { return m_tag == card_t; }
|
||||||
bool is_pb() const { return m_tag == pb_t; }
|
bool is_pb() const { return m_tag == pb_t; }
|
||||||
bool is_xor() const { return m_tag == xor_t; }
|
bool is_xor() const { return m_tag == xor_t; }
|
||||||
|
|
||||||
|
virtual bool is_watching(literal l) const { return false; };
|
||||||
|
virtual literal_vector literals() const { return literal_vector(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream& out, constraint const& c);
|
friend std::ostream& operator<<(std::ostream& out, constraint const& c);
|
||||||
|
@ -103,7 +107,8 @@ namespace sat {
|
||||||
void swap(unsigned i, unsigned j) { std::swap(m_lits[i], m_lits[j]); }
|
void swap(unsigned i, unsigned j) { std::swap(m_lits[i], m_lits[j]); }
|
||||||
void negate();
|
void negate();
|
||||||
void update_k(unsigned k) { m_k = k; }
|
void update_k(unsigned k) { m_k = k; }
|
||||||
literal_vector literals() const { return literal_vector(m_size, m_lits); }
|
virtual literal_vector literals() const { return literal_vector(m_size, m_lits); }
|
||||||
|
virtual bool is_watching(literal l) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -122,7 +127,7 @@ namespace sat {
|
||||||
wliteral operator[](unsigned i) const { return m_wlits[i]; }
|
wliteral operator[](unsigned i) const { return m_wlits[i]; }
|
||||||
wliteral& operator[](unsigned i) { return m_wlits[i]; }
|
wliteral& operator[](unsigned i) { return m_wlits[i]; }
|
||||||
wliteral const* begin() const { return m_wlits; }
|
wliteral const* begin() const { return m_wlits; }
|
||||||
wliteral const* end() const { return static_cast<wliteral const*>(m_wlits) + m_size; }
|
wliteral const* end() const { return begin() + m_size; }
|
||||||
|
|
||||||
unsigned k() const { return m_k; }
|
unsigned k() const { return m_k; }
|
||||||
unsigned slack() const { return m_slack; }
|
unsigned slack() const { return m_slack; }
|
||||||
|
@ -134,7 +139,8 @@ namespace sat {
|
||||||
void negate();
|
void negate();
|
||||||
void update_k(unsigned k) { m_k = k; }
|
void update_k(unsigned k) { m_k = k; }
|
||||||
void update_max_sum();
|
void update_max_sum();
|
||||||
literal_vector literals() const { literal_vector lits; for (auto wl : *this) lits.push_back(wl.second); return lits; }
|
virtual literal_vector literals() const { literal_vector lits; for (auto wl : *this) lits.push_back(wl.second); return lits; }
|
||||||
|
virtual bool is_watching(literal l) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class xor : public constraint {
|
class xor : public constraint {
|
||||||
|
@ -144,9 +150,11 @@ namespace sat {
|
||||||
xor(literal lit, literal_vector const& lits);
|
xor(literal lit, literal_vector const& lits);
|
||||||
literal operator[](unsigned i) const { return m_lits[i]; }
|
literal operator[](unsigned i) const { return m_lits[i]; }
|
||||||
literal const* begin() const { return m_lits; }
|
literal const* begin() const { return m_lits; }
|
||||||
literal const* end() const { return static_cast<literal const*>(m_lits) + m_size; }
|
literal const* end() const { return begin() + m_size; }
|
||||||
void swap(unsigned i, unsigned j) { std::swap(m_lits[i], m_lits[j]); }
|
void swap(unsigned i, unsigned j) { std::swap(m_lits[i], m_lits[j]); }
|
||||||
void negate() { m_lits[0].neg(); }
|
void negate() { m_lits[0].neg(); }
|
||||||
|
virtual bool is_watching(literal l) const;
|
||||||
|
virtual literal_vector literals() const { return literal_vector(size(), begin()); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -244,6 +252,9 @@ namespace sat {
|
||||||
void get_antecedents(literal l, constraint const& c, literal_vector & r);
|
void get_antecedents(literal l, constraint const& c, literal_vector & r);
|
||||||
bool validate_conflict(constraint const& c) const;
|
bool validate_conflict(constraint const& c) const;
|
||||||
bool validate_unit_propagation(constraint const& c, literal alit) const;
|
bool validate_unit_propagation(constraint const& c, literal alit) const;
|
||||||
|
void attach_constraint(constraint const& c);
|
||||||
|
void detach_constraint(constraint const& c);
|
||||||
|
bool is_true(constraint const& c) const;
|
||||||
|
|
||||||
// cardinality
|
// cardinality
|
||||||
void init_watch(card& c, bool is_true);
|
void init_watch(card& c, bool is_true);
|
||||||
|
@ -256,6 +267,7 @@ namespace sat {
|
||||||
void unit_propagation_simplification(literal lit, literal_vector const& lits);
|
void unit_propagation_simplification(literal lit, literal_vector const& lits);
|
||||||
void flush_roots(card& c);
|
void flush_roots(card& c);
|
||||||
void recompile(card& c);
|
void recompile(card& c);
|
||||||
|
lbool value(card const& c) const;
|
||||||
|
|
||||||
// xor specific functionality
|
// xor specific functionality
|
||||||
void clear_watch(xor& x);
|
void clear_watch(xor& x);
|
||||||
|
@ -266,6 +278,7 @@ namespace sat {
|
||||||
void get_antecedents(literal l, xor const& x, literal_vector & r);
|
void get_antecedents(literal l, xor const& x, literal_vector & r);
|
||||||
void simplify(xor& x);
|
void simplify(xor& x);
|
||||||
void flush_roots(xor& x);
|
void flush_roots(xor& x);
|
||||||
|
lbool value(xor const& x) const;
|
||||||
|
|
||||||
// pb functionality
|
// pb functionality
|
||||||
unsigned m_a_max;
|
unsigned m_a_max;
|
||||||
|
@ -279,6 +292,7 @@ namespace sat {
|
||||||
bool is_cardinality(pb const& p);
|
bool is_cardinality(pb const& p);
|
||||||
void flush_roots(pb& p);
|
void flush_roots(pb& p);
|
||||||
void recompile(pb& p);
|
void recompile(pb& p);
|
||||||
|
lbool value(pb const& p) const;
|
||||||
|
|
||||||
// access solver
|
// access solver
|
||||||
inline lbool value(literal lit) const { return m_lookahead ? m_lookahead->value(lit) : m_solver->value(lit); }
|
inline lbool value(literal lit) const { return m_lookahead ? m_lookahead->value(lit) : m_solver->value(lit); }
|
||||||
|
@ -286,6 +300,7 @@ namespace sat {
|
||||||
inline unsigned lvl(bool_var v) const { return m_solver->lvl(v); }
|
inline unsigned lvl(bool_var v) const { return m_solver->lvl(v); }
|
||||||
inline bool inconsistent() const { return m_lookahead ? m_lookahead->inconsistent() : m_solver->inconsistent(); }
|
inline bool inconsistent() const { return m_lookahead ? m_lookahead->inconsistent() : m_solver->inconsistent(); }
|
||||||
inline watch_list& get_wlist(literal l) { return m_lookahead ? m_lookahead->get_wlist(l) : m_solver->get_wlist(l); }
|
inline watch_list& get_wlist(literal l) { return m_lookahead ? m_lookahead->get_wlist(l) : m_solver->get_wlist(l); }
|
||||||
|
inline watch_list const& get_wlist(literal l) const { return m_lookahead ? m_lookahead->get_wlist(l) : m_solver->get_wlist(l); }
|
||||||
inline void assign(literal l, justification j) { if (m_lookahead) m_lookahead->assign(l); else m_solver->assign(l, j); }
|
inline void assign(literal l, justification j) { if (m_lookahead) m_lookahead->assign(l); else m_solver->assign(l, j); }
|
||||||
inline void set_conflict(justification j, literal l) { if (m_lookahead) m_lookahead->set_conflict(); else m_solver->set_conflict(j, l); }
|
inline void set_conflict(justification j, literal l) { if (m_lookahead) m_lookahead->set_conflict(); else m_solver->set_conflict(j, l); }
|
||||||
inline config const& get_config() const { return m_solver->get_config(); }
|
inline config const& get_config() const { return m_solver->get_config(); }
|
||||||
|
@ -312,6 +327,10 @@ namespace sat {
|
||||||
bool validate_unit_propagation(pb const& p, literal alit) const;
|
bool validate_unit_propagation(pb const& p, literal alit) const;
|
||||||
bool validate_unit_propagation(xor const& x, literal alit) const;
|
bool validate_unit_propagation(xor const& x, literal alit) const;
|
||||||
bool validate_conflict(literal_vector const& lits, ineq& p);
|
bool validate_conflict(literal_vector const& lits, ineq& p);
|
||||||
|
bool validate_watch_literals() const;
|
||||||
|
bool validate_watch_literal(literal lit) const;
|
||||||
|
bool validate_watched_constraint(constraint const& c) const;
|
||||||
|
bool is_watching(literal lit, constraint const& c) const;
|
||||||
|
|
||||||
ineq m_A, m_B, m_C;
|
ineq m_A, m_B, m_C;
|
||||||
void active2pb(ineq& p);
|
void active2pb(ineq& p);
|
||||||
|
@ -358,6 +377,8 @@ namespace sat {
|
||||||
|
|
||||||
ptr_vector<constraint> const & constraints() const { return m_constraints; }
|
ptr_vector<constraint> const & constraints() const { return m_constraints; }
|
||||||
|
|
||||||
|
virtual void validate();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -53,6 +53,7 @@ namespace sat {
|
||||||
virtual extension* copy(solver* s) = 0;
|
virtual extension* copy(solver* s) = 0;
|
||||||
virtual void find_mutexes(literal_vector& lits, vector<literal_vector> & mutexes) = 0;
|
virtual void find_mutexes(literal_vector& lits, vector<literal_vector> & mutexes) = 0;
|
||||||
virtual void gc() = 0;
|
virtual void gc() = 0;
|
||||||
|
virtual void validate() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -372,6 +372,7 @@ namespace sat {
|
||||||
void attach_ternary(ternary const& t);
|
void attach_ternary(ternary const& t);
|
||||||
void attach_ternary(literal l1, literal l2, literal l3);
|
void attach_ternary(literal l1, literal l2, literal l3);
|
||||||
watch_list& get_wlist(literal l) { return m_watches[l.index()]; }
|
watch_list& get_wlist(literal l) { return m_watches[l.index()]; }
|
||||||
|
watch_list const& get_wlist(literal l) const { return m_watches[l.index()]; }
|
||||||
|
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
// initialization
|
// initialization
|
||||||
|
|
|
@ -1391,6 +1391,7 @@ namespace sat {
|
||||||
|
|
||||||
*/
|
*/
|
||||||
void solver::simplify_problem() {
|
void solver::simplify_problem() {
|
||||||
|
if (m_ext) m_ext->validate();
|
||||||
if (m_conflicts_since_init < m_next_simplify) {
|
if (m_conflicts_since_init < m_next_simplify) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1403,12 +1404,15 @@ namespace sat {
|
||||||
SASSERT(at_base_lvl());
|
SASSERT(at_base_lvl());
|
||||||
|
|
||||||
m_cleaner();
|
m_cleaner();
|
||||||
|
if (m_ext) m_ext->validate();
|
||||||
CASSERT("sat_simplify_bug", check_invariant());
|
CASSERT("sat_simplify_bug", check_invariant());
|
||||||
|
|
||||||
m_scc();
|
m_scc();
|
||||||
|
if (m_ext) m_ext->validate();
|
||||||
CASSERT("sat_simplify_bug", check_invariant());
|
CASSERT("sat_simplify_bug", check_invariant());
|
||||||
|
|
||||||
m_simplifier(false);
|
m_simplifier(false);
|
||||||
|
if (m_ext) m_ext->validate();
|
||||||
CASSERT("sat_simplify_bug", check_invariant());
|
CASSERT("sat_simplify_bug", check_invariant());
|
||||||
CASSERT("sat_missed_prop", check_missed_propagation());
|
CASSERT("sat_missed_prop", check_missed_propagation());
|
||||||
|
|
||||||
|
@ -1417,6 +1421,7 @@ namespace sat {
|
||||||
CASSERT("sat_missed_prop", check_missed_propagation());
|
CASSERT("sat_missed_prop", check_missed_propagation());
|
||||||
CASSERT("sat_simplify_bug", check_invariant());
|
CASSERT("sat_simplify_bug", check_invariant());
|
||||||
}
|
}
|
||||||
|
if (m_ext) m_ext->validate();
|
||||||
|
|
||||||
if (m_config.m_lookahead_simplify) {
|
if (m_config.m_lookahead_simplify) {
|
||||||
{
|
{
|
||||||
|
@ -1435,10 +1440,12 @@ namespace sat {
|
||||||
CASSERT("sat_simplify_bug", check_invariant());
|
CASSERT("sat_simplify_bug", check_invariant());
|
||||||
|
|
||||||
m_probing();
|
m_probing();
|
||||||
|
if (m_ext) m_ext->validate();
|
||||||
CASSERT("sat_missed_prop", check_missed_propagation());
|
CASSERT("sat_missed_prop", check_missed_propagation());
|
||||||
CASSERT("sat_simplify_bug", check_invariant());
|
CASSERT("sat_simplify_bug", check_invariant());
|
||||||
|
|
||||||
m_asymm_branch();
|
m_asymm_branch();
|
||||||
|
if (m_ext) m_ext->validate();
|
||||||
CASSERT("sat_missed_prop", check_missed_propagation());
|
CASSERT("sat_missed_prop", check_missed_propagation());
|
||||||
CASSERT("sat_simplify_bug", check_invariant());
|
CASSERT("sat_simplify_bug", check_invariant());
|
||||||
|
|
||||||
|
@ -1460,21 +1467,7 @@ namespace sat {
|
||||||
m_next_simplify = m_conflicts_since_init + m_config.m_simplify_max;
|
m_next_simplify = m_conflicts_since_init + m_config.m_simplify_max;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static unsigned file_no = 0;
|
|
||||||
#pragma omp critical (print_sat)
|
|
||||||
{
|
|
||||||
++file_no;
|
|
||||||
std::ostringstream ostrm;
|
|
||||||
ostrm << "s" << file_no << ".txt";
|
|
||||||
std::ofstream ous(ostrm.str());
|
|
||||||
display(ous);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (m_par) m_par->set_phase(*this);
|
if (m_par) m_par->set_phase(*this);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool solver::set_root(literal l, literal r) {
|
bool solver::set_root(literal l, literal r) {
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace sat {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_watch_list(std::ostream & out, clause_allocator const & ca, watch_list const & wlist) {
|
std::ostream& display_watch_list(std::ostream & out, clause_allocator const & ca, watch_list const & wlist) {
|
||||||
watch_list::const_iterator it = wlist.begin();
|
watch_list::const_iterator it = wlist.begin();
|
||||||
watch_list::const_iterator end = wlist.end();
|
watch_list::const_iterator end = wlist.end();
|
||||||
for (bool first = true; it != end; ++it) {
|
for (bool first = true; it != end; ++it) {
|
||||||
|
@ -66,6 +66,7 @@ namespace sat {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -130,7 +130,7 @@ namespace sat {
|
||||||
inline void erase_ternary_watch(watch_list & wlist, literal l1, literal l2) { wlist.erase(watched(l1, l2)); }
|
inline void erase_ternary_watch(watch_list & wlist, literal l1, literal l2) { wlist.erase(watched(l1, l2)); }
|
||||||
|
|
||||||
class clause_allocator;
|
class clause_allocator;
|
||||||
void display_watch_list(std::ostream & out, clause_allocator const & ca, watch_list const & wlist);
|
std::ostream& display_watch_list(std::ostream & out, clause_allocator const & ca, watch_list const & wlist);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue