mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 09:05:31 +00:00
bug fixes to pb; working on model extraction
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
26bf64a0c3
commit
2c577a304d
15 changed files with 348 additions and 197 deletions
|
@ -348,13 +348,24 @@ namespace smt {
|
|||
context & ctx = get_context();
|
||||
simplifier & s = ctx.get_simplifier();
|
||||
expr_ref s_ante(m), s_conseq(m);
|
||||
expr* s_conseq_n, * s_ante_n;
|
||||
bool negated;
|
||||
proof_ref pr(m);
|
||||
|
||||
s(ante, s_ante, pr);
|
||||
negated = m.is_not(s_ante, s_ante_n);
|
||||
if (negated) s_ante = s_ante_n;
|
||||
ctx.internalize(s_ante, false);
|
||||
literal l_ante = ctx.get_literal(s_ante);
|
||||
if (negated) l_ante.neg();
|
||||
|
||||
s(conseq, s_conseq, pr);
|
||||
negated = m.is_not(s_conseq, s_conseq_n);
|
||||
if (negated) s_conseq = s_conseq_n;
|
||||
ctx.internalize(s_conseq, false);
|
||||
literal l_conseq = ctx.get_literal(s_conseq);
|
||||
if (negated) l_conseq.neg();
|
||||
|
||||
literal lits[2] = {l_ante, l_conseq};
|
||||
ctx.mk_th_axiom(get_id(), 2, lits);
|
||||
if (ctx.relevancy()) {
|
||||
|
|
|
@ -38,9 +38,9 @@ namespace smt {
|
|||
}
|
||||
|
||||
void theory_pb::ineq::reset() {
|
||||
m_max_coeff.reset();
|
||||
m_max_watch.reset();
|
||||
m_watch_sz = 0;
|
||||
m_max_sum.reset();
|
||||
m_watch_sum.reset();
|
||||
m_num_propagations = 0;
|
||||
m_compilation_threshold = UINT_MAX;
|
||||
m_compiled = l_false;
|
||||
|
@ -341,10 +341,10 @@ namespace smt {
|
|||
// TBD: special cases: args.size() == 1
|
||||
|
||||
// maximal coefficient:
|
||||
numeral& max_coeff = c->m_max_coeff;
|
||||
max_coeff = numeral::zero();
|
||||
numeral& max_watch = c->m_max_watch;
|
||||
max_watch = numeral::zero();
|
||||
for (unsigned i = 0; i < args.size(); ++i) {
|
||||
max_coeff = std::max(max_coeff, args[i].second);
|
||||
max_watch = std::max(max_watch, args[i].second);
|
||||
}
|
||||
|
||||
|
||||
|
@ -448,13 +448,13 @@ namespace smt {
|
|||
std::swap(c.m_args[ineq_index], c.m_args[c.watch_size()-1]);
|
||||
}
|
||||
--c.m_watch_sz;
|
||||
c.m_max_sum -= coeff;
|
||||
if (c.max_coeff() == coeff) {
|
||||
c.m_watch_sum -= coeff;
|
||||
if (c.max_watch() == coeff) {
|
||||
coeff = c.coeff(0);
|
||||
for (unsigned i = 1; coeff != c.max_coeff() && i < c.m_watch_sz; ++i) {
|
||||
for (unsigned i = 1; coeff != c.max_watch() && i < c.watch_size(); ++i) {
|
||||
if (coeff < c.coeff(i)) coeff = c.coeff(i);
|
||||
}
|
||||
c.set_max_coeff(coeff);
|
||||
c.set_max_watch(coeff);
|
||||
}
|
||||
|
||||
// current index of unwatched literal is c.watch_size().
|
||||
|
@ -463,12 +463,18 @@ namespace smt {
|
|||
void theory_pb::add_watch(ineq& c, unsigned i) {
|
||||
literal lit = c.lit(i);
|
||||
bool_var v = lit.var();
|
||||
c.m_max_sum += c.coeff(i);
|
||||
numeral coeff = c.coeff(i);
|
||||
c.m_watch_sum += coeff;
|
||||
SASSERT(i >= c.watch_size());
|
||||
|
||||
if (i > c.watch_size()) {
|
||||
std::swap(c.m_args[i], c.m_args[c.watch_size()]);
|
||||
}
|
||||
++c.m_watch_sz;
|
||||
if (coeff > c.max_watch()) {
|
||||
c.set_max_watch(coeff);
|
||||
}
|
||||
|
||||
ptr_vector<ineq>* ineqs;
|
||||
if (!m_watch.find(lit.index(), ineqs)) {
|
||||
ineqs = alloc(ptr_vector<ineq>);
|
||||
|
@ -515,43 +521,6 @@ namespace smt {
|
|||
return FC_DONE;
|
||||
}
|
||||
|
||||
void theory_pb::validate_final_check() {
|
||||
u_map<ineq*>::iterator itc = m_ineqs.begin(), endc = m_ineqs.end();
|
||||
for (; itc != endc; ++itc) {
|
||||
validate_final_check(*itc->m_value);
|
||||
}
|
||||
}
|
||||
|
||||
void theory_pb::validate_final_check(ineq& c) {
|
||||
context& ctx = get_context();
|
||||
|
||||
if (ctx.get_assignment(c.lit()) == l_undef) {
|
||||
return;
|
||||
}
|
||||
if (!ctx.is_relevant(c.lit())) {
|
||||
return;
|
||||
}
|
||||
numeral sum = numeral::zero(), maxsum = numeral::zero();
|
||||
for (unsigned i = 0; i < c.size(); ++i) {
|
||||
switch(ctx.get_assignment(c.lit(i))) {
|
||||
case l_true:
|
||||
sum += c.coeff(i);
|
||||
case l_undef:
|
||||
maxsum += c.coeff(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
TRACE("pb", display(tout << "validate: ", c, true);
|
||||
tout << "sum: " << sum << " " << maxsum << " ";
|
||||
tout << ctx.get_assignment(c.lit()) << "\n";
|
||||
);
|
||||
|
||||
SASSERT(sum <= maxsum);
|
||||
SASSERT((sum >= c.k()) == (ctx.get_assignment(c.lit()) == l_true));
|
||||
SASSERT((maxsum < c.k()) == (ctx.get_assignment(c.lit()) == l_false));
|
||||
}
|
||||
|
||||
|
||||
void theory_pb::assign_eh(bool_var v, bool is_true) {
|
||||
context& ctx = get_context();
|
||||
ptr_vector<ineq>* ineqs = 0;
|
||||
|
@ -636,15 +605,17 @@ namespace smt {
|
|||
add_clause(c, lits);
|
||||
}
|
||||
else {
|
||||
c.m_max_sum = numeral::zero();
|
||||
c.m_watch_sum = numeral::zero();
|
||||
c.m_watch_sz = 0;
|
||||
for (unsigned i = 0; c.max_sum() < c.k() + c.max_coeff() && i < c.size(); ++i) {
|
||||
c.m_max_watch = numeral::zero();
|
||||
for (unsigned i = 0; c.watch_sum() < c.k() + c.max_watch() && i < c.size(); ++i) {
|
||||
if (ctx.get_assignment(c.lit(i)) != l_false) {
|
||||
add_watch(c, i);
|
||||
}
|
||||
}
|
||||
SASSERT(c.max_sum() >= c.k());
|
||||
SASSERT(c.watch_sum() >= c.k());
|
||||
m_assign_ineqs_trail.push_back(&c);
|
||||
DEBUG_CODE(validate_watch(c););
|
||||
}
|
||||
|
||||
// perform unit propagation
|
||||
|
@ -653,7 +624,7 @@ namespace smt {
|
|||
lits.push_back(c.lit());
|
||||
for (unsigned i = 0; i < c.size(); ++i) {
|
||||
if (ctx.get_assignment(c.lit(i)) == l_undef) {
|
||||
SASSERT(validate_assign(c, lits, c.lit(i)));
|
||||
DEBUG_CODE(validate_assign(c, lits, c.lit(i)););
|
||||
add_assign(c, lits, c.lit(i));
|
||||
}
|
||||
}
|
||||
|
@ -677,20 +648,20 @@ namespace smt {
|
|||
SASSERT(is_true == c.lit(w).sign());
|
||||
|
||||
//
|
||||
// max_sum is decreased.
|
||||
// watch_sum is decreased.
|
||||
// Adjust set of watched literals.
|
||||
//
|
||||
|
||||
numeral k = c.k();
|
||||
numeral coeff = c.coeff(w);
|
||||
|
||||
for (unsigned i = c.watch_size(); c.max_sum() - coeff < k + c.max_coeff() && i < c.size(); ++i) {
|
||||
for (unsigned i = c.watch_size(); c.watch_sum() - coeff < k + c.max_watch() && i < c.size(); ++i) {
|
||||
if (ctx.get_assignment(c.lit(i)) != l_false) {
|
||||
add_watch(c, i);
|
||||
}
|
||||
}
|
||||
|
||||
if (c.max_sum() - coeff < k) {
|
||||
if (c.watch_sum() - coeff < k) {
|
||||
//
|
||||
// L: 3*x1 + 2*x2 + x4 >= 3, but x1 <- 0, x2 <- 0
|
||||
// create clause x1 or x2 or ~L
|
||||
|
@ -702,12 +673,13 @@ namespace smt {
|
|||
else {
|
||||
del_watch(watch, watch_index, c, w);
|
||||
removed = true;
|
||||
if (c.max_sum() < k + c.max_coeff()) {
|
||||
SASSERT(c.watch_sum() >= k);
|
||||
if (c.watch_sum() < k + c.max_watch()) {
|
||||
|
||||
//
|
||||
// opportunities for unit propagation for unassigned
|
||||
// literals whose coefficients satisfy
|
||||
// c.max_sum() < k
|
||||
// c.watch_sum() < k
|
||||
//
|
||||
// L: 3*x1 + 2*x2 + x4 >= 3, but x1 <- 0
|
||||
// Create clauses x1 or ~L or x2
|
||||
|
@ -717,18 +689,14 @@ namespace smt {
|
|||
literal_vector& lits = get_unhelpful_literals(c, true);
|
||||
lits.push_back(c.lit());
|
||||
for (unsigned i = 0; i < c.size(); ++i) {
|
||||
if (c.max_sum() - c.coeff(i) < k && ctx.get_assignment(c.lit(i)) == l_undef) {
|
||||
SASSERT(validate_assign(c, lits, c.lit(i)));
|
||||
if (c.watch_sum() - c.coeff(i) < k && ctx.get_assignment(c.lit(i)) == l_undef) {
|
||||
DEBUG_CODE(validate_assign(c, lits, c.lit(i)););
|
||||
add_assign(c, lits, c.lit(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// else: c.max_sum() >= k + c.max_coeff()
|
||||
// we might miss opportunities for unit propagation if
|
||||
// max_coeff is not the maximal coefficient
|
||||
// of the current unassigned literal, but we can
|
||||
// rely on eventually learning this from propagations.
|
||||
// else: c.watch_sum() >= k + c.max_watch()
|
||||
//
|
||||
}
|
||||
|
||||
|
@ -875,12 +843,10 @@ namespace smt {
|
|||
|
||||
void theory_pb::inc_propagations(ineq& c) {
|
||||
++c.m_num_propagations;
|
||||
#if 1
|
||||
if (c.m_compiled == l_false && c.m_num_propagations > c.m_compilation_threshold) {
|
||||
c.m_compiled = l_undef;
|
||||
m_to_compile.push_back(&c);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void theory_pb::restart_eh() {
|
||||
|
@ -970,69 +936,6 @@ namespace smt {
|
|||
m_ineqs_lim.resize(new_lim);
|
||||
}
|
||||
|
||||
void theory_pb::display(std::ostream& out) const {
|
||||
u_map<ptr_vector<ineq>*>::iterator it = m_watch.begin(), end = m_watch.end();
|
||||
for (; it != end; ++it) {
|
||||
out << "watch: " << to_literal(it->m_key) << " |-> ";
|
||||
watch_list const& wl = *it->m_value;
|
||||
for (unsigned i = 0; i < wl.size(); ++i) {
|
||||
out << wl[i]->lit() << " ";
|
||||
}
|
||||
out << "\n";
|
||||
}
|
||||
u_map<ineq*>::iterator itc = m_ineqs.begin(), endc = m_ineqs.end();
|
||||
for (; itc != endc; ++itc) {
|
||||
ineq& c = *itc->m_value;
|
||||
display(out, c);
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& theory_pb::display(std::ostream& out, ineq const& c, bool values) const {
|
||||
ast_manager& m = get_manager();
|
||||
context& ctx = get_context();
|
||||
out << c.lit();
|
||||
if (c.lit() != null_literal) {
|
||||
if (values) {
|
||||
out << "@(" << ctx.get_assignment(c.lit());
|
||||
if (ctx.get_assignment(c.lit()) != l_undef) {
|
||||
out << ":" << ctx.get_assign_level(c.lit());
|
||||
}
|
||||
out << ")";
|
||||
}
|
||||
expr_ref tmp(m);
|
||||
ctx.literal2expr(c.lit(), tmp);
|
||||
out << " " << tmp << "\n";
|
||||
}
|
||||
else {
|
||||
out << " ";
|
||||
}
|
||||
for (unsigned i = 0; i < c.size(); ++i) {
|
||||
literal l(c.lit(i));
|
||||
if (!c.coeff(i).is_one()) {
|
||||
out << c.coeff(i) << "*";
|
||||
}
|
||||
out << l;
|
||||
if (values) {
|
||||
out << "@(" << ctx.get_assignment(l);
|
||||
if (ctx.get_assignment(l) != l_undef) {
|
||||
out << ":" << ctx.get_assign_level(l);
|
||||
}
|
||||
out << ")";
|
||||
}
|
||||
if (i + 1 < c.size()) {
|
||||
out << " + ";
|
||||
}
|
||||
}
|
||||
out << " >= " << c.m_k << "\n";
|
||||
if (c.m_num_propagations) out << "propagations: " << c.m_num_propagations << " ";
|
||||
if (c.max_coeff().is_pos()) out << "max_coeff: " << c.max_coeff() << " ";
|
||||
if (c.watch_size()) out << "watch size: " << c.watch_size() << " ";
|
||||
if (c.max_sum().is_pos()) out << "max-sum: " << c.max_sum() << " ";
|
||||
if (c.m_num_propagations || c.max_coeff().is_pos() || c.watch_size() || c.max_sum().is_pos()) out << "\n";
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
literal_vector& theory_pb::get_lits() {
|
||||
m_literals.reset();
|
||||
return m_literals;
|
||||
|
@ -1087,34 +990,6 @@ namespace smt {
|
|||
verbose_stream() << "\n";);
|
||||
}
|
||||
|
||||
bool theory_pb::validate_assign(ineq const& c, literal_vector const& lits, literal l) const {
|
||||
uint_set nlits;
|
||||
context& ctx = get_context();
|
||||
for (unsigned i = 0; i < lits.size(); ++i) {
|
||||
SASSERT(ctx.get_assignment(lits[i]) == l_false);
|
||||
nlits.insert((~lits[i]).index());
|
||||
}
|
||||
SASSERT(ctx.get_assignment(l) == l_undef);
|
||||
SASSERT(ctx.get_assignment(c.lit()) == l_true);
|
||||
nlits.insert(l.index());
|
||||
numeral sum = numeral::zero();
|
||||
for (unsigned i = 0; i < c.size(); ++i) {
|
||||
literal lit = c.lit(i);
|
||||
if (!nlits.contains(lit.index())) {
|
||||
sum += c.coeff(i);
|
||||
}
|
||||
}
|
||||
if (sum >= c.k()) {
|
||||
IF_VERBOSE(0,
|
||||
display(verbose_stream(), c, true);
|
||||
for (unsigned i = 0; i < lits.size(); ++i) {
|
||||
verbose_stream() << lits[i] << " ";
|
||||
}
|
||||
verbose_stream() << " => " << l << "\n";);
|
||||
}
|
||||
SASSERT(sum < c.k());
|
||||
return true;
|
||||
}
|
||||
|
||||
void theory_pb::set_mark(bool_var v, unsigned idx) {
|
||||
SASSERT(v != null_bool_var);
|
||||
|
@ -1149,7 +1024,12 @@ namespace smt {
|
|||
}
|
||||
else if (lvl > ctx.get_base_level()) {
|
||||
if (is_marked(v)) {
|
||||
m_lemma.m_args[m_conseq_index[v]].second += coeff;
|
||||
numeral& lcoeff = m_lemma.m_args[m_conseq_index[v]].second;
|
||||
lcoeff += coeff;
|
||||
if (lcoeff.is_zero()) {
|
||||
IF_VERBOSE(1, display(verbose_stream() << "remove 0 consequence", m_lemma, true););
|
||||
remove_from_lemma(m_lemma, m_conseq_index[v]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (lvl == m_conflict_lvl) {
|
||||
|
@ -1243,10 +1123,9 @@ namespace smt {
|
|||
|
||||
while (m_num_marks > 0) {
|
||||
|
||||
m_lemma.normalize();
|
||||
lbool is_sat = m_lemma.normalize();
|
||||
if (is_sat != l_undef) {
|
||||
IF_VERBOSE(0, display(verbose_stream() << "created non-tautology lemma: ", m_lemma, true););
|
||||
IF_VERBOSE(0, display(verbose_stream() << "lemma already evaluated ", m_lemma, true););
|
||||
return false;
|
||||
}
|
||||
TRACE("pb", display(tout, m_lemma, true););
|
||||
|
@ -1261,11 +1140,22 @@ namespace smt {
|
|||
--idx;
|
||||
}
|
||||
while (!is_marked(v) && idx > 0);
|
||||
if (idx == 0) {
|
||||
IF_VERBOSE(1, verbose_stream() << "BUG?!\n";);
|
||||
if (idx == 0 && !is_marked(v)) {
|
||||
//
|
||||
// Yes, this can (currently) happen because
|
||||
// the decisions for performing unit propagation
|
||||
// are made asynchronously.
|
||||
// In other words, PB unit propagation does not follow the
|
||||
// same order as the assignment stack.
|
||||
// It is not a correctness bug but causes to miss lemmas.
|
||||
//
|
||||
IF_VERBOSE(1, display_resolved_lemma(verbose_stream()););
|
||||
for (unsigned i = 0; i < m_lemma.size(); ++i) {
|
||||
unset_mark(m_lemma.lit(i));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
unsigned conseq_index = m_conseq_index[v];
|
||||
numeral conseq_coeff = m_lemma.coeff(conseq_index);
|
||||
|
||||
|
@ -1274,16 +1164,8 @@ namespace smt {
|
|||
|
||||
SASSERT(~conseq == m_lemma.lit(conseq_index));
|
||||
|
||||
// Remove conseq from lemma:
|
||||
unsigned last = m_lemma.size()-1;
|
||||
if (conseq_index != last) {
|
||||
m_lemma.m_args[conseq_index] = m_lemma.m_args[last];
|
||||
m_conseq_index[m_lemma.lit(conseq_index).var()] = conseq_index;
|
||||
}
|
||||
m_lemma.m_args.pop_back();
|
||||
unset_mark(conseq);
|
||||
remove_from_lemma(m_lemma, conseq_index);
|
||||
|
||||
--m_num_marks;
|
||||
b_justification js = ctx.get_justification(v);
|
||||
|
||||
//
|
||||
|
@ -1359,14 +1241,19 @@ namespace smt {
|
|||
|
||||
lbool is_true = m_lemma.normalize();
|
||||
|
||||
IF_VERBOSE(1, display(verbose_stream() << "lemma: ", m_lemma););
|
||||
IF_VERBOSE(2, display(verbose_stream() << "lemma: ", m_lemma););
|
||||
switch(is_true) {
|
||||
case l_true:
|
||||
UNREACHABLE();
|
||||
return false;
|
||||
case l_false:
|
||||
//add_assign(c, m_ineq_literals, false_literal);
|
||||
//break;
|
||||
case l_false:
|
||||
inc_propagations(c);
|
||||
m_stats.m_num_conflicts++;
|
||||
for (unsigned i = 0; i < m_ineq_literals.size(); ++i) {
|
||||
m_ineq_literals[i].neg();
|
||||
}
|
||||
ctx.mk_clause(m_ineq_literals.size(), m_ineq_literals.c_ptr(), 0, CLS_AUX_LEMMA, 0);
|
||||
break;
|
||||
default: {
|
||||
app_ref tmp = m_lemma.to_expr(ctx, get_manager());
|
||||
internalize_atom(tmp, false);
|
||||
|
@ -1389,4 +1276,204 @@ namespace smt {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void theory_pb::remove_from_lemma(ineq& c, unsigned idx) {
|
||||
// Remove conseq from lemma:
|
||||
literal lit = c.lit(idx);
|
||||
unsigned last = c.size()-1;
|
||||
if (idx != last) {
|
||||
c.m_args[idx] = c.m_args[last];
|
||||
m_conseq_index[c.lit(idx).var()] = idx;
|
||||
}
|
||||
c.m_args.pop_back();
|
||||
unset_mark(lit);
|
||||
--m_num_marks;
|
||||
}
|
||||
|
||||
|
||||
// debug methods
|
||||
|
||||
void theory_pb::validate_watch(ineq const& c) const {
|
||||
context& ctx = get_context();
|
||||
numeral sum = numeral::zero();
|
||||
numeral max = numeral::zero();
|
||||
for (unsigned i = 0; i < c.watch_size(); ++i) {
|
||||
sum += c.coeff(i);
|
||||
if (c.coeff(i) > max) {
|
||||
max = c.coeff(i);
|
||||
}
|
||||
}
|
||||
SASSERT(c.watch_sum() == sum);
|
||||
SASSERT(sum >= c.k());
|
||||
SASSERT(max == c.max_watch());
|
||||
}
|
||||
|
||||
void theory_pb::validate_assign(ineq const& c, literal_vector const& lits, literal l) const {
|
||||
uint_set nlits;
|
||||
context& ctx = get_context();
|
||||
for (unsigned i = 0; i < lits.size(); ++i) {
|
||||
SASSERT(ctx.get_assignment(lits[i]) == l_true);
|
||||
nlits.insert((~lits[i]).index());
|
||||
}
|
||||
SASSERT(ctx.get_assignment(l) == l_undef);
|
||||
SASSERT(ctx.get_assignment(c.lit()) == l_true);
|
||||
nlits.insert(l.index());
|
||||
numeral sum = numeral::zero();
|
||||
for (unsigned i = 0; i < c.size(); ++i) {
|
||||
literal lit = c.lit(i);
|
||||
if (!nlits.contains(lit.index())) {
|
||||
sum += c.coeff(i);
|
||||
}
|
||||
}
|
||||
if (sum >= c.k()) {
|
||||
IF_VERBOSE(0,
|
||||
display(verbose_stream(), c, true);
|
||||
for (unsigned i = 0; i < lits.size(); ++i) {
|
||||
verbose_stream() << lits[i] << " ";
|
||||
}
|
||||
verbose_stream() << " => " << l << "\n";);
|
||||
}
|
||||
SASSERT(sum < c.k());
|
||||
}
|
||||
|
||||
void theory_pb::validate_final_check() {
|
||||
u_map<ineq*>::iterator itc = m_ineqs.begin(), endc = m_ineqs.end();
|
||||
for (; itc != endc; ++itc) {
|
||||
validate_final_check(*itc->m_value);
|
||||
}
|
||||
}
|
||||
|
||||
void theory_pb::validate_final_check(ineq& c) {
|
||||
context& ctx = get_context();
|
||||
|
||||
if (ctx.get_assignment(c.lit()) == l_undef) {
|
||||
return;
|
||||
}
|
||||
if (!ctx.is_relevant(c.lit())) {
|
||||
return;
|
||||
}
|
||||
numeral sum = numeral::zero(), maxsum = numeral::zero();
|
||||
for (unsigned i = 0; i < c.size(); ++i) {
|
||||
switch(ctx.get_assignment(c.lit(i))) {
|
||||
case l_true:
|
||||
sum += c.coeff(i);
|
||||
case l_undef:
|
||||
maxsum += c.coeff(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
TRACE("pb", display(tout << "validate: ", c, true);
|
||||
tout << "sum: " << sum << " " << maxsum << " ";
|
||||
tout << ctx.get_assignment(c.lit()) << "\n";
|
||||
);
|
||||
|
||||
SASSERT(sum <= maxsum);
|
||||
SASSERT((sum >= c.k()) == (ctx.get_assignment(c.lit()) == l_true));
|
||||
SASSERT((maxsum < c.k()) == (ctx.get_assignment(c.lit()) == l_false));
|
||||
}
|
||||
|
||||
// display methods
|
||||
|
||||
void theory_pb::display_resolved_lemma(std::ostream& out) const {
|
||||
context& ctx = get_context();
|
||||
literal_vector const& lits = ctx.assigned_literals();
|
||||
bool_var v;
|
||||
unsigned lvl;
|
||||
out << "num marks: " << m_num_marks << "\n";
|
||||
out << "conflict level: " << m_conflict_lvl << "\n";
|
||||
for (unsigned i = 0; i < lits.size(); ++i) {
|
||||
v = lits[i].var();
|
||||
lvl = ctx.get_assign_level(v);
|
||||
out << lits[i]
|
||||
<< "@ " << lvl
|
||||
<< " " << (is_marked(v)?"m":"u")
|
||||
<< "\n";
|
||||
|
||||
if (lvl == m_conflict_lvl && is_marked(v)) {
|
||||
out << "skipped: " << lits[i] << ":"<< i << "\n";
|
||||
}
|
||||
}
|
||||
display(out, m_lemma, true);
|
||||
|
||||
unsigned nc = 0;
|
||||
for (unsigned i = 0; i < m_lemma.size(); ++i) {
|
||||
v = m_lemma.lit(i).var();
|
||||
lvl = ctx.get_assign_level(v);
|
||||
if (lvl == m_conflict_lvl) ++nc;
|
||||
out << m_lemma.lit(i)
|
||||
<< "@" << lvl
|
||||
<< " " << (is_marked(v)?"m":"u")
|
||||
<< " " << ctx.get_assignment(m_lemma.lit(i))
|
||||
<< "\n";
|
||||
}
|
||||
out << "num conflicts: " << nc << "\n";
|
||||
}
|
||||
|
||||
|
||||
std::ostream& theory_pb::display(std::ostream& out, ineq const& c, bool values) const {
|
||||
ast_manager& m = get_manager();
|
||||
context& ctx = get_context();
|
||||
out << c.lit();
|
||||
if (c.lit() != null_literal) {
|
||||
if (values) {
|
||||
out << "@(" << ctx.get_assignment(c.lit());
|
||||
if (ctx.get_assignment(c.lit()) != l_undef) {
|
||||
out << ":" << ctx.get_assign_level(c.lit());
|
||||
}
|
||||
out << ")";
|
||||
}
|
||||
expr_ref tmp(m);
|
||||
ctx.literal2expr(c.lit(), tmp);
|
||||
out << " " << tmp << "\n";
|
||||
}
|
||||
else {
|
||||
out << " ";
|
||||
}
|
||||
for (unsigned i = 0; i < c.size(); ++i) {
|
||||
literal l(c.lit(i));
|
||||
if (!c.coeff(i).is_one()) {
|
||||
out << c.coeff(i) << "*";
|
||||
}
|
||||
out << l;
|
||||
if (values) {
|
||||
out << "@(" << ctx.get_assignment(l);
|
||||
if (ctx.get_assignment(l) != l_undef) {
|
||||
out << ":" << ctx.get_assign_level(l);
|
||||
}
|
||||
out << ")";
|
||||
}
|
||||
if (i + 1 == c.watch_size()) {
|
||||
out << " .w ";
|
||||
}
|
||||
if (i + 1 < c.size()) {
|
||||
out << " + ";
|
||||
}
|
||||
}
|
||||
out << " >= " << c.m_k << "\n";
|
||||
if (c.m_num_propagations) out << "propagations: " << c.m_num_propagations << " ";
|
||||
if (c.max_watch().is_pos()) out << "max_watch: " << c.max_watch() << " ";
|
||||
if (c.watch_size()) out << "watch size: " << c.watch_size() << " ";
|
||||
if (c.watch_sum().is_pos()) out << "watch-sum: " << c.watch_sum() << " ";
|
||||
if (c.m_num_propagations || c.max_watch().is_pos() || c.watch_size() || c.watch_sum().is_pos()) out << "\n";
|
||||
return out;
|
||||
}
|
||||
|
||||
void theory_pb::display(std::ostream& out) const {
|
||||
u_map<ptr_vector<ineq>*>::iterator it = m_watch.begin(), end = m_watch.end();
|
||||
for (; it != end; ++it) {
|
||||
out << "watch: " << to_literal(it->m_key) << " |-> ";
|
||||
watch_list const& wl = *it->m_value;
|
||||
for (unsigned i = 0; i < wl.size(); ++i) {
|
||||
out << wl[i]->lit() << " ";
|
||||
}
|
||||
out << "\n";
|
||||
}
|
||||
u_map<ineq*>::iterator itc = m_ineqs.begin(), endc = m_ineqs.end();
|
||||
for (; itc != endc; ++itc) {
|
||||
ineq& c = *itc->m_value;
|
||||
display(out, c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -48,11 +48,11 @@ namespace smt {
|
|||
numeral m_k; // invariants: m_k > 0, coeffs[i] > 0
|
||||
|
||||
// Watch the first few positions until the sum satisfies:
|
||||
// sum coeffs[i] >= m_lower + max_coeff
|
||||
// sum coeffs[i] >= m_lower + max_watch
|
||||
|
||||
numeral m_max_coeff; // maximal coefficient.
|
||||
numeral m_max_watch; // maximal coefficient.
|
||||
unsigned m_watch_sz; // number of literals being watched.
|
||||
numeral m_max_sum; // maximal sum of watch literals.
|
||||
numeral m_watch_sum; // maximal sum of watch literals.
|
||||
unsigned m_num_propagations;
|
||||
unsigned m_compilation_threshold;
|
||||
lbool m_compiled;
|
||||
|
@ -69,9 +69,9 @@ namespace smt {
|
|||
|
||||
unsigned size() const { return m_args.size(); }
|
||||
|
||||
numeral const& max_sum() const { return m_max_sum; }
|
||||
numeral const& max_coeff() const { return m_max_coeff; }
|
||||
void set_max_coeff(numeral const& n) { m_max_coeff = n; }
|
||||
numeral const& watch_sum() const { return m_watch_sum; }
|
||||
numeral const& max_watch() const { return m_max_watch; }
|
||||
void set_max_watch(numeral const& n) { m_max_watch = n; }
|
||||
|
||||
unsigned watch_size() const { return m_watch_sz; }
|
||||
|
||||
|
@ -118,6 +118,7 @@ namespace smt {
|
|||
|
||||
std::ostream& display(std::ostream& out, ineq const& c, bool values = false) const;
|
||||
virtual void display(std::ostream& out) const;
|
||||
void display_resolved_lemma(std::ostream& out) const;
|
||||
|
||||
void add_clause(ineq& c, literal_vector const& lits);
|
||||
void add_assign(ineq& c, literal_vector const& lits, literal l);
|
||||
|
@ -152,12 +153,14 @@ namespace smt {
|
|||
bool resolve_conflict(ineq& c);
|
||||
void process_antecedent(literal l, numeral coeff);
|
||||
void process_ineq(ineq& c, literal conseq, numeral coeff);
|
||||
void remove_from_lemma(ineq& c, unsigned idx);
|
||||
|
||||
void hoist_maximal_values();
|
||||
|
||||
void validate_final_check();
|
||||
void validate_final_check(ineq& c);
|
||||
bool validate_assign(ineq const& c, literal_vector const& lits, literal l) const;
|
||||
void validate_assign(ineq const& c, literal_vector const& lits, literal l) const;
|
||||
void validate_watch(ineq const& c) const;
|
||||
public:
|
||||
theory_pb(ast_manager& m);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue