3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-08 18:31:49 +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_simplex(m.limit()),
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_conflict_frequency = p.m_pb_conflict_frequency;
@ -942,6 +943,7 @@ namespace smt {
m_card_lim.reset();
m_stats.reset();
m_to_compile.reset();
m_card_reinit = false;
}
void theory_pb::new_eq_eh(theory_var v1, theory_var v2) {
@ -1526,6 +1528,9 @@ namespace smt {
}
m_card_lim.resize(new_lim);
add_cardinality_lemma();
}
void theory_pb::clear_watch(ineq& c) {
@ -1719,11 +1724,10 @@ namespace smt {
return arg_max;
}
literal theory_pb::cardinality_reduction(card*& c) {
literal theory_pb::cardinality_reduction(literal prop_lit) {
normalize_active_coeffs();
SASSERT(m_seen.empty());
SASSERT(m_seen_trail.empty());
c = 0;
int s = 0;
int new_bound = 0;
while (s < m_bound) {
@ -1762,8 +1766,6 @@ namespace smt {
slack -= coeff;
m_coeffs[v] = 0; // deactivate coefficient.
}
// create cardinality constraint
literal card_lit = null_literal;
for (unsigned i = 0; i < m_active_coeffs.size(); ++i) {
bool_var v = m_active_coeffs[i];
int coeff = get_coeff(v);
@ -1777,59 +1779,34 @@ namespace smt {
m_bound = new_bound;
if (validate_lemma()) {
ast_manager& m = get_manager();
context& ctx = get_context();
pb_util pb(m);
expr_ref atom(pb.mk_fresh_bool(), m);
bool_var abv = ctx.mk_bool_var(atom);
ctx.set_var_theory(abv, get_id());
card_lit = literal(abv);
c = alloc(card, card_lit, new_bound);
for (unsigned i = 0; i < m_active_coeffs.size(); ++i) {
bool_var v = m_active_coeffs[i];
int coeff = get_coeff(v);
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);
SASSERT(m_bound > 0);
if (m_bound > static_cast<int>(m_active_coeffs.size())) {
return false_literal;
}
if (m_bound == m_active_coeffs.size()) {
prop_lit = null_literal;
context& ctx = get_context();
for (unsigned i = 0; i < m_active_coeffs.size(); ++i) {
bool_var v = m_active_coeffs[i];
literal lit(get_coeff(v) < 0);
unsigned lvl = UINT_MAX;
if (ctx.get_assignment(lit) == l_false && ctx.get_assign_level(lit) < lvl) {
prop_lit = lit;
lvl = ctx.get_assign_level(lit);
card_lit = lit;
}
}
SASSERT(card_lit != null_literal);
dealloc(c);
c = 0;
SASSERT(prop_lit != null_literal);
}
else {
init_watch(abv);
m_var_infos[abv].m_card = c;
m_card_trail.push_back(abv);
m_card_reinit = true;
return prop_lit;
}
}
else {
TRACE("pb", display_resolved_lemma(tout););
}
return card_lit;
return null_literal;
}
void theory_pb::normalize_active_coeffs() {
@ -1915,7 +1892,45 @@ namespace smt {
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) {
TRACE("pb", display(tout, c, true); );
@ -1923,6 +1938,7 @@ namespace smt {
bool_var v;
context& ctx = get_context();
m_conflict_lvl = 0;
m_card_reinit = false;
for (unsigned i = 0; i < confl.size(); ++i) {
literal lit = confl[i];
SASSERT(ctx.get_assignment(lit) == l_false);
@ -1993,6 +2009,7 @@ namespace smt {
switch(js.get_kind()) {
case b_justification::CLAUSE: {
inc_coeff(conseq, offset);
clause& cls = *js.get_clause();
justification* cjs = cls.get_justification();
if (cjs && !is_proof_justification(*cjs)) {
@ -2080,32 +2097,25 @@ namespace smt {
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";
card* cr = 0;
literal card_lit = cardinality_reduction(cr);
literal prop_lit = cardinality_reduction(~conseq);
if (card_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)));
}
if (cr != 0) {
m_antecedents.reset();
m_antecedents.push_back(card_lit);
unsigned slack = cr ? (cr->size() - cr->k()) : 0;
for (unsigned i = 0; 0 < slack; ++i) {
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) {
if (prop_lit != null_literal) {
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;
for (unsigned i = 0; i < slack; ++i) {
bool_var v = m_active_coeffs[i];
literal lit(v, get_coeff(v) < 0);
SASSERT(lit.var() != prop_lit.var() || lit == prop_lit);
if (lit != prop_lit && ctx.get_assignment(lit) == l_false) {
m_antecedents.push_back(~lit);
--slack;
}
}
SASSERT(slack == 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";
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)));
}
return card_lit != null_literal;
return prop_lit != null_literal;
}
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;
@ -293,6 +302,8 @@ namespace smt {
bool m_enable_compilation;
rational m_max_compiled_coeff;
bool m_card_reinit;
// internalize_atom:
literal compile_arg(expr* arg);
void init_watch(bool_var v);
@ -381,7 +392,8 @@ namespace smt {
int arg_max(uint_set& seen, int& coeff);
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);
void process_antecedent(literal l, int offset);