3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-18 20:03:38 +00:00

working on conflict resolution

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2017-01-20 07:44:00 -08:00
parent 13099b1590
commit d68cb5aee7
2 changed files with 91 additions and 69 deletions

View file

@ -446,7 +446,8 @@ namespace smt {
m_params(p), m_params(p),
m_simplex(m.limit()), m_simplex(m.limit()),
m_util(m), m_util(m),
m_max_compiled_coeff(rational(8)) m_max_compiled_coeff(rational(8)),
m_card_reinit(false)
{ {
m_learn_complements = p.m_pb_learn_complements; m_learn_complements = p.m_pb_learn_complements;
m_conflict_frequency = p.m_pb_conflict_frequency; m_conflict_frequency = p.m_pb_conflict_frequency;
@ -942,6 +943,7 @@ namespace smt {
m_card_lim.reset(); m_card_lim.reset();
m_stats.reset(); m_stats.reset();
m_to_compile.reset(); m_to_compile.reset();
m_card_reinit = false;
} }
void theory_pb::new_eq_eh(theory_var v1, theory_var v2) { void theory_pb::new_eq_eh(theory_var v1, theory_var v2) {
@ -1526,6 +1528,9 @@ namespace smt {
} }
m_card_lim.resize(new_lim); m_card_lim.resize(new_lim);
add_cardinality_lemma();
} }
void theory_pb::clear_watch(ineq& c) { void theory_pb::clear_watch(ineq& c) {
@ -1719,11 +1724,10 @@ namespace smt {
return arg_max; return arg_max;
} }
literal theory_pb::cardinality_reduction(card*& c) { literal theory_pb::cardinality_reduction(literal prop_lit) {
normalize_active_coeffs(); normalize_active_coeffs();
SASSERT(m_seen.empty()); SASSERT(m_seen.empty());
SASSERT(m_seen_trail.empty()); SASSERT(m_seen_trail.empty());
c = 0;
int s = 0; int s = 0;
int new_bound = 0; int new_bound = 0;
while (s < m_bound) { while (s < m_bound) {
@ -1762,8 +1766,6 @@ namespace smt {
slack -= coeff; slack -= coeff;
m_coeffs[v] = 0; // deactivate coefficient. m_coeffs[v] = 0; // deactivate coefficient.
} }
// create cardinality constraint
literal card_lit = null_literal;
for (unsigned i = 0; i < m_active_coeffs.size(); ++i) { for (unsigned i = 0; i < m_active_coeffs.size(); ++i) {
bool_var v = m_active_coeffs[i]; bool_var v = m_active_coeffs[i];
int coeff = get_coeff(v); int coeff = get_coeff(v);
@ -1777,59 +1779,34 @@ namespace smt {
m_bound = new_bound; m_bound = new_bound;
if (validate_lemma()) { if (validate_lemma()) {
ast_manager& m = get_manager(); SASSERT(m_bound > 0);
context& ctx = get_context(); if (m_bound > static_cast<int>(m_active_coeffs.size())) {
pb_util pb(m); return false_literal;
expr_ref atom(pb.mk_fresh_bool(), m); }
bool_var abv = ctx.mk_bool_var(atom); if (m_bound == m_active_coeffs.size()) {
ctx.set_var_theory(abv, get_id()); prop_lit = null_literal;
card_lit = literal(abv); context& ctx = get_context();
c = alloc(card, card_lit, new_bound); for (unsigned i = 0; i < m_active_coeffs.size(); ++i) {
for (unsigned i = 0; i < m_active_coeffs.size(); ++i) { bool_var v = m_active_coeffs[i];
bool_var v = m_active_coeffs[i]; literal lit(get_coeff(v) < 0);
int coeff = get_coeff(v); unsigned lvl = UINT_MAX;
if (coeff < 0) {
c->add_arg(literal(v, true));
}
else if (coeff > 0) {
c->add_arg(literal(v, false));
}
else {
UNREACHABLE();
}
}
m_stats.m_num_predicates++;
// display(std::cout, *c, true);
if (c->k() == 0) {
UNREACHABLE();
}
else if (c->size() < c->k()) {
card_lit = false_literal;
dealloc(c);
c = 0;
}
else if (c->size() == c->k()) {
card_lit = null_literal;
unsigned lvl = UINT_MAX;
for (unsigned i = 0; i < c->size(); ++i) {
literal lit = c->lit(i);
if (ctx.get_assignment(lit) == l_false && ctx.get_assign_level(lit) < lvl) { if (ctx.get_assignment(lit) == l_false && ctx.get_assign_level(lit) < lvl) {
prop_lit = lit;
lvl = ctx.get_assign_level(lit); lvl = ctx.get_assign_level(lit);
card_lit = lit;
} }
} }
SASSERT(card_lit != null_literal); SASSERT(prop_lit != null_literal);
dealloc(c);
c = 0;
} }
else { else {
init_watch(abv); m_card_reinit = true;
m_var_infos[abv].m_card = c; return prop_lit;
m_card_trail.push_back(abv);
} }
} }
else {
TRACE("pb", display_resolved_lemma(tout););
}
return card_lit; return null_literal;
} }
void theory_pb::normalize_active_coeffs() { void theory_pb::normalize_active_coeffs() {
@ -1915,7 +1892,45 @@ namespace smt {
TRACE("pb", display_resolved_lemma(tout << "cut\n");); TRACE("pb", display_resolved_lemma(tout << "cut\n"););
} }
} }
void theory_pb::add_cardinality_lemma() {
context& ctx = get_context();
ast_manager& m = get_manager();
if (ctx.inconsistent() || !m_card_reinit) {
return;
}
m_card_reinit = false;
pb_util pb(m);
expr_ref pred(pb.mk_fresh_bool(), m);
bool_var abv = ctx.mk_bool_var(pred);
ctx.set_var_theory(abv, get_id());
literal lit(abv);
card* c = alloc(card, lit, m_bound);
for (unsigned i = 0; i < m_active_coeffs.size(); ++i) {
bool_var v = m_active_coeffs[i];
int coeff = get_coeff(v);
SASSERT(coeff != 0);
c->add_arg(literal(v, coeff < 0));
}
init_watch(abv);
m_var_infos[abv].m_card = c;
m_card_trail.push_back(abv);
for (unsigned i = 0; i < m_antecedents.size(); ++i) {
m_antecedents[i].neg();
}
m_antecedents.push_back(lit);
TRACE("pb", tout << m_antecedents << "\n";);
justification* js = 0;
if (proofs_enabled()) {
js = 0; //
}
++m_stats.m_num_predicates;
ctx.mk_clause(m_antecedents.size(), m_antecedents.c_ptr(), js, CLS_AUX_LEMMA, 0);
}
bool theory_pb::resolve_conflict(card& c, literal_vector const& confl) { bool theory_pb::resolve_conflict(card& c, literal_vector const& confl) {
TRACE("pb", display(tout, c, true); ); TRACE("pb", display(tout, c, true); );
@ -1923,6 +1938,7 @@ namespace smt {
bool_var v; bool_var v;
context& ctx = get_context(); context& ctx = get_context();
m_conflict_lvl = 0; m_conflict_lvl = 0;
m_card_reinit = false;
for (unsigned i = 0; i < confl.size(); ++i) { for (unsigned i = 0; i < confl.size(); ++i) {
literal lit = confl[i]; literal lit = confl[i];
SASSERT(ctx.get_assignment(lit) == l_false); SASSERT(ctx.get_assignment(lit) == l_false);
@ -1993,6 +2009,7 @@ namespace smt {
switch(js.get_kind()) { switch(js.get_kind()) {
case b_justification::CLAUSE: { case b_justification::CLAUSE: {
inc_coeff(conseq, offset);
clause& cls = *js.get_clause(); clause& cls = *js.get_clause();
justification* cjs = cls.get_justification(); justification* cjs = cls.get_justification();
if (cjs && !is_proof_justification(*cjs)) { if (cjs && !is_proof_justification(*cjs)) {
@ -2080,32 +2097,25 @@ namespace smt {
count += coeff; count += coeff;
} }
// std::cout << "New " << count << "(" << sz << ") >= " << m_bound << " " << c.size() << " >= " << c.k() << " new diff: " << count - m_bound << " old diff: " << c.size() - c.k() << "\n"; // std::cout << "New " << count << "(" << sz << ") >= " << m_bound << " " << c.size() << " >= " << c.k() << " new diff: " << count - m_bound << " old diff: " << c.size() - c.k() << "\n";
card* cr = 0; literal prop_lit = cardinality_reduction(~conseq);
literal card_lit = cardinality_reduction(cr);
if (card_lit != null_literal) { if (prop_lit != null_literal) {
ctx.assign(card_lit, ctx.mk_justification(theory_propagation_justification(get_id(), ctx.get_region(), m_antecedents.size(), m_antecedents.c_ptr(), card_lit, 0, 0))); TRACE("pb", tout << "cardinality literal: " << prop_lit << "\n";);
} SASSERT(static_cast<int>(m_active_coeffs.size()) >= m_bound);
unsigned slack = m_active_coeffs.size() - m_bound;
if (cr != 0) { for (unsigned i = 0; i < slack; ++i) {
m_antecedents.reset(); bool_var v = m_active_coeffs[i];
m_antecedents.push_back(card_lit); literal lit(v, get_coeff(v) < 0);
unsigned slack = cr ? (cr->size() - cr->k()) : 0; SASSERT(lit.var() != prop_lit.var() || lit == prop_lit);
for (unsigned i = 0; 0 < slack; ++i) { if (lit != prop_lit && ctx.get_assignment(lit) == l_false) {
SASSERT(i < cr->size());
literal lit = cr->lit(i);
SASSERT(lit.var() != conseq.var() || lit == ~conseq);
if (lit.var() != conseq.var() && ctx.get_assignment(lit) == l_false) {
m_antecedents.push_back(~lit); m_antecedents.push_back(~lit);
--slack; --slack;
} }
} }
SASSERT(slack == 0); ctx.assign(prop_lit, ctx.mk_justification(theory_propagation_justification(get_id(), ctx.get_region(), m_antecedents.size(), m_antecedents.c_ptr(), prop_lit, 0, 0)));
ctx.assign(~conseq, ctx.mk_justification(theory_propagation_justification(get_id(), ctx.get_region(), m_antecedents.size(), m_antecedents.c_ptr(), ~conseq, 0, 0)));
// std::cout << "slack " << slack << " " << conseq << " " << ctx.get_assignment(conseq) << "\n";
} }
return card_lit != null_literal; return prop_lit != null_literal;
} }
bool theory_pb::is_proof_justification(justification const& j) const { bool theory_pb::is_proof_justification(justification const& j) const {

View file

@ -270,6 +270,15 @@ namespace smt {
} }
}; };
struct card_reinit {
literal_vector m_lits;
card* m_card;
card_reinit(literal_vector const& lits, card* c):
m_lits(lits),
m_card(c)
{}
};
theory_pb_params m_params; theory_pb_params m_params;
@ -293,6 +302,8 @@ namespace smt {
bool m_enable_compilation; bool m_enable_compilation;
rational m_max_compiled_coeff; rational m_max_compiled_coeff;
bool m_card_reinit;
// internalize_atom: // internalize_atom:
literal compile_arg(expr* arg); literal compile_arg(expr* arg);
void init_watch(bool_var v); void init_watch(bool_var v);
@ -381,7 +392,8 @@ namespace smt {
int arg_max(uint_set& seen, int& coeff); int arg_max(uint_set& seen, int& coeff);
void reset_coeffs(); void reset_coeffs();
literal cardinality_reduction(card*& c); literal cardinality_reduction(literal propagation_lit);
void add_cardinality_lemma();
bool resolve_conflict(card& c, literal_vector const& conflict_clause); bool resolve_conflict(card& c, literal_vector const& conflict_clause);
void process_antecedent(literal l, int offset); void process_antecedent(literal l, int offset);