3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-28 08:58:44 +00:00

pb solver

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2013-11-19 00:54:30 -08:00
parent 1a8ff9cea4
commit 96921355cc
2 changed files with 55 additions and 60 deletions

View file

@ -42,7 +42,6 @@ namespace smt {
void theory_pb::ineq::reset() { void theory_pb::ineq::reset() {
m_max_coeff = 0; m_max_coeff = 0;
m_watch_sz = 0; m_watch_sz = 0;
m_sum = 0;
m_max_sum = 0; m_max_sum = 0;
m_num_propagations = 0; m_num_propagations = 0;
m_compilation_threshold = UINT_MAX; m_compilation_threshold = UINT_MAX;
@ -476,7 +475,6 @@ namespace smt {
void theory_pb::assign_eh(bool_var v, bool is_true) { void theory_pb::assign_eh(bool_var v, bool is_true) {
context& ctx = get_context(); context& ctx = get_context();
ptr_vector<ineq>* ineqs = 0; ptr_vector<ineq>* ineqs = 0;
TRACE("pb", tout << "assign: " << literal(v, !is_true) << "\n";);
if (m_watch.find(v, ineqs)) { if (m_watch.find(v, ineqs)) {
for (unsigned i = 0; i < ineqs->size(); ++i) { for (unsigned i = 0; i < ineqs->size(); ++i) {
@ -549,7 +547,7 @@ namespace smt {
if (maxsum < c.k()) { if (maxsum < c.k()) {
literal_vector& lits = get_unhelpful_literals(c, false); literal_vector& lits = get_unhelpful_literals(c, false);
lits.push_back(~c.lit()); lits.push_back(~c.lit());
add_clause(c, ~c.lit(), lits); add_clause(c, ~lits[0], lits);
} }
else { else {
c.m_max_sum = 0; c.m_max_sum = 0;
@ -602,7 +600,7 @@ namespace smt {
// //
literal_vector& lits = get_unhelpful_literals(c, false); literal_vector& lits = get_unhelpful_literals(c, false);
lits.push_back(~c.lit()); lits.push_back(~c.lit());
add_clause(c, ~literal(v, !is_true), lits); add_clause(c, literal(v, !is_true), lits);
} }
else { else {
del_watch(watch, watch_index, c, w); del_watch(watch, watch_index, c, w);
@ -919,13 +917,12 @@ namespace smt {
out << " + "; out << " + ";
} }
} }
out << " >= " << c.m_k << "\n" out << " >= " << c.m_k << "\n";
<< "propagations: " << c.m_num_propagations if (c.m_num_propagations) out << "propagations: " << c.m_num_propagations << " ";
<< " max_coeff: " << c.max_coeff() if (c.max_coeff()) out << "max_coeff: " << c.max_coeff() << " ";
<< " watch size: " << c.watch_size() if (c.watch_size()) out << "watch size: " << c.watch_size() << " ";
<< " sum: " << c.sum() if (c.max_sum()) out << "max-sum: " << c.max_sum() << " ";
<< " max-sum: " << c.max_sum() if (c.m_num_propagations || c.max_coeff() || c.watch_size() || c.max_sum()) out << "\n";
<< "\n";
return out; return out;
} }
@ -992,13 +989,16 @@ namespace smt {
context& ctx = get_context(); context& ctx = get_context();
bool_var v = l.var(); bool_var v = l.var();
unsigned lvl = ctx.get_assign_level(v); unsigned lvl = ctx.get_assign_level(v);
IF_VERBOSE(0, verbose_stream() << "ante: " << l << "*" << coeff << " " << lvl << "\n";); IF_VERBOSE(2, verbose_stream() << "ante: " << l << "*" << coeff << " " << lvl << "\n";);
if (lvl > ctx.get_base_level()) {
if (ctx.get_assignment(l) != l_false) {
m_lemma.m_k -= coeff;
}
else if (lvl > ctx.get_base_level()) {
if (!ctx.is_marked(v)) { if (!ctx.is_marked(v)) {
ctx.set_mark(v); ctx.set_mark(v);
m_unmark.push_back(v); m_unmark.push_back(v);
if (lvl == m_conflict_lvl) { if (lvl == m_conflict_lvl) {
IF_VERBOSE(0, verbose_stream() << "new mark\n";);
++m_num_marks; ++m_num_marks;
if (v >= static_cast<bool_var>(m_conseq_index.size())) { if (v >= static_cast<bool_var>(m_conseq_index.size())) {
m_conseq_index.resize(v+1); m_conseq_index.resize(v+1);
@ -1013,9 +1013,6 @@ namespace smt {
m_lemma.m_args[m_lemma_index] = std::make_pair(l, coeff); m_lemma.m_args[m_lemma_index] = std::make_pair(l, coeff);
m_lemma_index = m_lemma.size(); m_lemma_index = m_lemma.size();
} }
else if (ctx.get_assignment(l) != l_false) {
m_lemma.m_k += coeff;
}
} }
void theory_pb::process_ineq(ineq& c, literal conseq, numeral coeff1) { void theory_pb::process_ineq(ineq& c, literal conseq, numeral coeff1) {
@ -1054,22 +1051,21 @@ namespace smt {
} }
g = lc/coeff2; g = lc/coeff2;
for (unsigned i = 0; i < c.size(); ++i) { for (unsigned i = 0; i < c.size(); ++i) {
if (ctx.get_assignment(c.lit(i)) == l_false) { if (conseq == c.lit(i)) {
process_antecedent(c.lit(i), g*c.coeff(i));
}
else if (conseq == c.lit(i)) {
// skip this one. // skip this one.
SASSERT(ctx.get_assignment(c.lit(i)) == l_true);
} }
else { else {
m_lemma.m_k += g*c.coeff(i); process_antecedent(c.lit(i), g*c.coeff(i));
} }
} }
m_lemma.m_k += g*c.k(); m_lemma.m_k += g*c.k();
// //
// we most likely want c.lit() to be // TBD: we want c.lit() to be
// an antecedent in a real clause. // an antecedent in a real clause.
// process_antecedent(~c.lit(), 1); // The coefficient 'g' is also incorrect.
// //
// process_antecedent(~c.lit(), g);
} }
// //
@ -1077,23 +1073,19 @@ namespace smt {
// //
void theory_pb::resolve_conflict(literal conseq, ineq& c) { void theory_pb::resolve_conflict(literal conseq, ineq& c) {
IF_VERBOSE(0, verbose_stream() << conseq << "\n"; display(verbose_stream(), c, true);); IF_VERBOSE(0, verbose_stream() << "RESOLVE: " << conseq << "\n"; display(verbose_stream(), c, true););
bool_var v; bool_var v;
context& ctx = get_context(); context& ctx = get_context();
unsigned& lvl = m_conflict_lvl = 0; unsigned& lvl = m_conflict_lvl = 0;
unsigned conseq_index = 0;
for (unsigned i = 0; i < c.size(); ++i) { for (unsigned i = 0; i < c.size(); ++i) {
if (ctx.get_assignment(c.lit(i)) == l_false) { if (ctx.get_assignment(c.lit(i)) == l_false) {
lvl = std::max(lvl, ctx.get_assign_level(c.lit(i))); lvl = std::max(lvl, ctx.get_assign_level(c.lit(i)));
} }
if (~conseq == c.lit(i)) {
conseq_index = i;
}
} }
SASSERT(lvl >= ctx.get_assign_level(c.lit())); SASSERT(lvl >= ctx.get_assign_level(c.lit()));
SASSERT(ctx.get_assignment(conseq) == l_true); SASSERT(ctx.get_assignment(conseq) == l_true);
SASSERT(conseq_index > 0 || ~conseq == c.lit(0)); // conseq is negative in c
if (lvl == ctx.get_base_level()) { if (lvl == ctx.get_base_level()) {
return; return;
@ -1104,22 +1096,39 @@ namespace smt {
m_lemma_index = 0; m_lemma_index = 0;
process_ineq(c, null_literal, 1); // add consequent to lemma. process_ineq(c, null_literal, 1); // add consequent to lemma.
SASSERT(c.lit(conseq_index) == ~conseq);
// point into stack of assigned literals // point into stack of assigned literals
literal_vector const& lits = ctx.assigned_literals(); literal_vector const& lits = ctx.assigned_literals();
SASSERT(!lits.empty()); SASSERT(!lits.empty());
unsigned idx = lits.size()-1; unsigned idx = lits.size()-1;
b_justification js = ctx.get_justification(conseq.var());
do { do {
TRACE("pb", display(tout, m_lemma, true););
IF_VERBOSE(0, display(verbose_stream(), m_lemma, true););
//
// find the next marked variable in the assignment stack
//
do {
conseq = lits[idx];
v = conseq.var();
--idx;
}
while (!ctx.is_marked(v));
unsigned conseq_index = m_conseq_index[v];
numeral conseq_coeff = m_lemma.coeff(conseq_index);
m_lemma_index = conseq_index;
SASSERT(~conseq == m_lemma.lit(conseq_index));
--m_num_marks;
b_justification js = ctx.get_justification(v);
// //
// Resolve selected conseq with antecedents. // Resolve selected conseq with antecedents.
// //
IF_VERBOSE(0, verbose_stream() << conseq << " " << js.get_kind() << "\n";); IF_VERBOSE(0, verbose_stream() << "conseq: " << conseq << " at index: " << conseq_index << "\n";);
numeral conseq_coeff = m_lemma.coeff(conseq_index);
m_lemma_index = conseq_index;
switch(js.get_kind()) { switch(js.get_kind()) {
case b_justification::CLAUSE: { case b_justification::CLAUSE: {
@ -1136,6 +1145,7 @@ namespace smt {
process_antecedent(cls.get_literal(i), conseq_coeff); process_antecedent(cls.get_literal(i), conseq_coeff);
} }
m_lemma.m_k += conseq_coeff; m_lemma.m_k += conseq_coeff;
TRACE("pb", for (unsigned i = 0; i < num_lits; ++i) tout << cls.get_literal(i) << " "; tout << "\n";);
justification* cjs = cls.get_justification(); justification* cjs = cls.get_justification();
if (cjs) { if (cjs) {
// TBD // TBD
@ -1146,6 +1156,7 @@ namespace smt {
case b_justification::BIN_CLAUSE: case b_justification::BIN_CLAUSE:
m_lemma.m_k += conseq_coeff; m_lemma.m_k += conseq_coeff;
process_antecedent(~js.get_literal(), conseq_coeff); process_antecedent(~js.get_literal(), conseq_coeff);
TRACE("pb", tout << "binary: " << js.get_literal() << "\n";);
break; break;
case b_justification::AXIOM: case b_justification::AXIOM:
break; break;
@ -1156,39 +1167,25 @@ namespace smt {
pb_justification& pbj = dynamic_cast<pb_justification&>(j); pb_justification& pbj = dynamic_cast<pb_justification&>(j);
// weaken the lemma and resolve. // weaken the lemma and resolve.
process_ineq(pbj.get_ineq(), conseq, conseq_coeff); process_ineq(pbj.get_ineq(), conseq, conseq_coeff);
TRACE("pb", display(tout, pbj.get_ineq()););
break; break;
} }
default: default:
UNREACHABLE(); UNREACHABLE();
} }
m_lemma.normalize();
//
// find the next marked variable in the assignment stack
//
SASSERT(idx > 0);
SASSERT(m_num_marks > 0);
do {
conseq = lits[idx];
v = conseq.var();
--idx;
}
while (!ctx.is_marked(v));
conseq_index = m_conseq_index[v];
js = ctx.get_justification(v);
--m_num_marks;
} }
while (m_num_marks > 0); while (m_num_marks > 0);
m_lemma.normalize();
// unset the marks on lemmas // unset the marks on lemmas
while (!m_unmark.empty()) { while (!m_unmark.empty()) {
ctx.unset_mark(m_unmark.back()); ctx.unset_mark(m_unmark.back());
m_unmark.pop_back(); m_unmark.pop_back();
} }
TRACE("pb", display(tout, m_lemma);); TRACE("pb", display(tout << "lemma: ", m_lemma););
IF_VERBOSE(1, display(verbose_stream(), m_lemma);); IF_VERBOSE(1, display(verbose_stream() << "lemma: ", m_lemma););
} }
} }

View file

@ -52,7 +52,6 @@ namespace smt {
numeral m_max_coeff; // maximal coefficient. numeral m_max_coeff; // maximal coefficient.
unsigned m_watch_sz; // number of literals being watched. unsigned m_watch_sz; // number of literals being watched.
numeral m_sum; // sum of coefficients so far.
numeral m_max_sum; // maximal sum of watch literals. numeral m_max_sum; // maximal sum of watch literals.
unsigned m_num_propagations; unsigned m_num_propagations;
unsigned m_compilation_threshold; unsigned m_compilation_threshold;
@ -70,7 +69,6 @@ namespace smt {
unsigned size() const { return m_args.size(); } unsigned size() const { return m_args.size(); }
numeral const& sum() const { return m_sum; }
numeral const& max_sum() const { return m_max_sum; } numeral const& max_sum() const { return m_max_sum; }
numeral const& max_coeff() const { return m_max_coeff; } numeral const& max_coeff() const { return m_max_coeff; }