mirror of
https://github.com/Z3Prover/z3
synced 2025-06-18 20:03:38 +00:00
working on card extension
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
92e2d920fd
commit
32b5e54c8d
2 changed files with 204 additions and 70 deletions
|
@ -50,7 +50,7 @@ namespace sat {
|
||||||
if (c.lit().sign() == is_true) {
|
if (c.lit().sign() == is_true) {
|
||||||
c.negate();
|
c.negate();
|
||||||
}
|
}
|
||||||
SASSERT(s().value(c.lit()) == l_true);
|
SASSERT(value(c.lit()) == l_true);
|
||||||
unsigned j = 0, sz = c.size(), bound = c.k();
|
unsigned j = 0, sz = c.size(), bound = c.k();
|
||||||
if (bound == sz) {
|
if (bound == sz) {
|
||||||
for (unsigned i = 0; i < sz && !s().inconsistent(); ++i) {
|
for (unsigned i = 0; i < sz && !s().inconsistent(); ++i) {
|
||||||
|
@ -60,7 +60,7 @@ namespace sat {
|
||||||
}
|
}
|
||||||
// put the non-false literals into the head.
|
// put the non-false literals into the head.
|
||||||
for (unsigned i = 0; i < sz; ++i) {
|
for (unsigned i = 0; i < sz; ++i) {
|
||||||
if (s().value(c[i]) != l_false) {
|
if (value(c[i]) != l_false) {
|
||||||
if (j != i) {
|
if (j != i) {
|
||||||
c.swap(i, j);
|
c.swap(i, j);
|
||||||
}
|
}
|
||||||
|
@ -70,8 +70,8 @@ namespace sat {
|
||||||
DEBUG_CODE(
|
DEBUG_CODE(
|
||||||
bool is_false = false;
|
bool is_false = false;
|
||||||
for (unsigned k = 0; k < sz; ++k) {
|
for (unsigned k = 0; k < sz; ++k) {
|
||||||
SASSERT(!is_false || s().value(c[k]) == l_false);
|
SASSERT(!is_false || value(c[k]) == l_false);
|
||||||
is_false = s().value(c[k]) == l_false;
|
is_false = value(c[k]) == l_false;
|
||||||
});
|
});
|
||||||
|
|
||||||
// j is the number of non-false, sz - j the number of false.
|
// j is the number of non-false, sz - j the number of false.
|
||||||
|
@ -86,7 +86,7 @@ namespace sat {
|
||||||
//
|
//
|
||||||
|
|
||||||
for (unsigned i = bound; i < sz; ++i) {
|
for (unsigned i = bound; i < sz; ++i) {
|
||||||
if (s().lvl(alit) < s().lvl(c[i])) {
|
if (lvl(alit) < lvl(c[i])) {
|
||||||
c.swap(i, j);
|
c.swap(i, j);
|
||||||
alit = c[j];
|
alit = c[j];
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ namespace sat {
|
||||||
}
|
}
|
||||||
|
|
||||||
void card_extension::assign(card& c, literal lit) {
|
void card_extension::assign(card& c, literal lit) {
|
||||||
if (s().value(lit) == l_true) {
|
if (value(lit) == l_true) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_stats.m_num_propagations++;
|
m_stats.m_num_propagations++;
|
||||||
|
@ -155,19 +155,20 @@ namespace sat {
|
||||||
|
|
||||||
void card_extension::set_conflict(card& c, literal lit) {
|
void card_extension::set_conflict(card& c, literal lit) {
|
||||||
SASSERT(validate_conflict(c));
|
SASSERT(validate_conflict(c));
|
||||||
literal_vector& lits = get_literals();
|
|
||||||
SASSERT(s().value(lit) == l_false);
|
|
||||||
SASSERT(s().value(c.lit()) == l_true);
|
|
||||||
lits.push_back(~c.lit());
|
|
||||||
lits.push_back(lit);
|
|
||||||
unsigned sz = c.size();
|
|
||||||
for (unsigned i = c.k(); i < sz; ++i) {
|
|
||||||
SASSERT(s().value(c[i]) == l_false);
|
|
||||||
lits.push_back(c[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_stats.m_num_conflicts++;
|
m_stats.m_num_conflicts++;
|
||||||
if (!resolve_conflict(c, lits)) {
|
if (!resolve_conflict(c, lit)) {
|
||||||
|
|
||||||
|
literal_vector& lits = get_literals();
|
||||||
|
SASSERT(value(lit) == l_false);
|
||||||
|
SASSERT(value(c.lit()) == l_true);
|
||||||
|
lits.push_back(~c.lit());
|
||||||
|
lits.push_back(lit);
|
||||||
|
unsigned sz = c.size();
|
||||||
|
for (unsigned i = c.k(); i < sz; ++i) {
|
||||||
|
SASSERT(value(c[i]) == l_false);
|
||||||
|
lits.push_back(c[i]);
|
||||||
|
}
|
||||||
s().mk_clause_core(lits.size(), lits.c_ptr(), true);
|
s().mk_clause_core(lits.size(), lits.c_ptr(), true);
|
||||||
}
|
}
|
||||||
SASSERT(s().inconsistent());
|
SASSERT(s().inconsistent());
|
||||||
|
@ -231,16 +232,16 @@ namespace sat {
|
||||||
m_active_vars.reset();
|
m_active_vars.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool card_extension::resolve_conflict(card& c, literal_vector const& conflict_clause) {
|
bool card_extension::resolve_conflict(card& c, literal alit) {
|
||||||
|
|
||||||
bool_var v;
|
bool_var v;
|
||||||
m_conflict_lvl = 0;
|
m_conflict_lvl = 0;
|
||||||
for (unsigned i = 0; i < c.size(); ++i) {
|
for (unsigned i = 0; i < c.size(); ++i) {
|
||||||
literal lit = c[i];
|
literal lit = c[i];
|
||||||
SASSERT(s().value(lit) == l_false);
|
SASSERT(value(lit) == l_false);
|
||||||
m_conflict_lvl = std::max(m_conflict_lvl, s().lvl(lit));
|
m_conflict_lvl = std::max(m_conflict_lvl, lvl(lit));
|
||||||
}
|
}
|
||||||
if (m_conflict_lvl < s().lvl(c.lit()) || m_conflict_lvl == 0) {
|
if (m_conflict_lvl < lvl(c.lit()) || m_conflict_lvl == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,14 +252,14 @@ namespace sat {
|
||||||
literal_vector const& lits = s().m_trail;
|
literal_vector const& lits = s().m_trail;
|
||||||
unsigned idx = lits.size()-1;
|
unsigned idx = lits.size()-1;
|
||||||
justification js;
|
justification js;
|
||||||
literal consequent = ~conflict_clause[1];
|
literal consequent = ~alit;
|
||||||
process_card(c, 1);
|
process_card(c, 1);
|
||||||
literal alit;
|
|
||||||
|
DEBUG_CODE(active2pb(m_A););
|
||||||
|
|
||||||
while (m_num_marks > 0) {
|
while (m_num_marks > 0) {
|
||||||
|
SASSERT(value(consequent) == l_true);
|
||||||
v = consequent.var();
|
v = consequent.var();
|
||||||
|
|
||||||
int offset = get_abs_coeff(v);
|
int offset = get_abs_coeff(v);
|
||||||
|
|
||||||
if (offset == 0) {
|
if (offset == 0) {
|
||||||
|
@ -268,9 +269,11 @@ namespace sat {
|
||||||
goto bail_out;
|
goto bail_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SASSERT(validate_lemma());
|
||||||
SASSERT(offset > 0);
|
SASSERT(offset > 0);
|
||||||
|
|
||||||
js = s().m_justification[v];
|
js = s().m_justification[v];
|
||||||
|
DEBUG_CODE(justification2pb(js, consequent, offset, m_B););
|
||||||
|
|
||||||
int bound = 1;
|
int bound = 1;
|
||||||
switch(js.get_kind()) {
|
switch(js.get_kind()) {
|
||||||
|
@ -289,15 +292,13 @@ namespace sat {
|
||||||
inc_coeff(consequent, offset);
|
inc_coeff(consequent, offset);
|
||||||
clause & c = *(s().m_cls_allocator.get_clause(js.get_clause_offset()));
|
clause & c = *(s().m_cls_allocator.get_clause(js.get_clause_offset()));
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
if (consequent != null_literal) {
|
SASSERT(c[0] == consequent || c[1] == consequent);
|
||||||
SASSERT(c[0] == consequent || c[1] == consequent);
|
if (c[0] == consequent) {
|
||||||
if (c[0] == consequent) {
|
i = 1;
|
||||||
i = 1;
|
}
|
||||||
}
|
else {
|
||||||
else {
|
process_antecedent(~c[0], offset);
|
||||||
process_antecedent(~c[0], offset);
|
i = 2;
|
||||||
i = 2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
unsigned sz = c.size();
|
unsigned sz = c.size();
|
||||||
for (; i < sz; i++)
|
for (; i < sz; i++)
|
||||||
|
@ -316,6 +317,11 @@ namespace sat {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
m_bound += offset * bound;
|
m_bound += offset * bound;
|
||||||
|
|
||||||
|
DEBUG_CODE(
|
||||||
|
active2pb(m_C);
|
||||||
|
SASSERT(validate_resolvent());
|
||||||
|
m_A = m_C;);
|
||||||
|
|
||||||
// cut();
|
// cut();
|
||||||
|
|
||||||
|
@ -331,7 +337,7 @@ namespace sat {
|
||||||
--idx;
|
--idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
SASSERT(s().lvl(v) == m_conflict_lvl);
|
SASSERT(lvl(v) == m_conflict_lvl);
|
||||||
s().reset_mark(v);
|
s().reset_mark(v);
|
||||||
--idx;
|
--idx;
|
||||||
--m_num_marks;
|
--m_num_marks;
|
||||||
|
@ -390,24 +396,24 @@ namespace sat {
|
||||||
|
|
||||||
void card_extension::process_card(card& c, int offset) {
|
void card_extension::process_card(card& c, int offset) {
|
||||||
SASSERT(c.k() <= c.size());
|
SASSERT(c.k() <= c.size());
|
||||||
SASSERT(s().value(c.lit()) == l_true);
|
SASSERT(value(c.lit()) == l_true);
|
||||||
for (unsigned i = c.k(); i < c.size(); ++i) {
|
for (unsigned i = c.k(); i < c.size(); ++i) {
|
||||||
process_antecedent(c[i], offset);
|
process_antecedent(c[i], offset);
|
||||||
}
|
}
|
||||||
for (unsigned i = 0; i < c.k(); ++i) {
|
for (unsigned i = 0; i < c.k(); ++i) {
|
||||||
inc_coeff(c[i], offset);
|
inc_coeff(c[i], offset);
|
||||||
}
|
}
|
||||||
if (s().lvl(c.lit()) > 0) {
|
if (lvl(c.lit()) > 0) {
|
||||||
m_conflict.push_back(~c.lit());
|
m_conflict.push_back(~c.lit());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void card_extension::process_antecedent(literal l, int offset) {
|
void card_extension::process_antecedent(literal l, int offset) {
|
||||||
SASSERT(s().value(l) == l_false);
|
SASSERT(value(l) == l_false);
|
||||||
bool_var v = l.var();
|
bool_var v = l.var();
|
||||||
unsigned lvl = s().lvl(v);
|
unsigned level = lvl(v);
|
||||||
|
|
||||||
if (lvl > 0 && !s().is_marked(v) && lvl == m_conflict_lvl) {
|
if (level > 0 && !s().is_marked(v) && level == m_conflict_lvl) {
|
||||||
s().mark(v);
|
s().mark(v);
|
||||||
++m_num_marks;
|
++m_num_marks;
|
||||||
}
|
}
|
||||||
|
@ -418,12 +424,13 @@ namespace sat {
|
||||||
if (get_abs_coeff(p.var()) != 0) {
|
if (get_abs_coeff(p.var()) != 0) {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
unsigned lvl = 0;
|
unsigned level = 0;
|
||||||
for (unsigned i = 0; i < m_active_vars.size(); ++i) {
|
for (unsigned i = 0; i < m_active_vars.size(); ++i) {
|
||||||
bool_var v = m_active_vars[i];
|
bool_var v = m_active_vars[i];
|
||||||
literal lit(v, get_coeff(v) < 0);
|
literal lit(v, get_coeff(v) < 0);
|
||||||
if (s().value(lit) == l_false && s().lvl(lit) > lvl) {
|
if (value(lit) == l_false && lvl(lit) > level) {
|
||||||
p = lit;
|
p = lit;
|
||||||
|
level = lvl(lit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
|
@ -463,21 +470,24 @@ namespace sat {
|
||||||
}
|
}
|
||||||
SASSERT(found););
|
SASSERT(found););
|
||||||
|
|
||||||
|
r.push_back(c.lit());
|
||||||
|
SASSERT(value(c.lit()) == l_true);
|
||||||
for (unsigned i = c.k(); i < c.size(); ++i) {
|
for (unsigned i = c.k(); i < c.size(); ++i) {
|
||||||
SASSERT(s().value(c[i]) == l_false);
|
SASSERT(value(c[i]) == l_false);
|
||||||
r.push_back(c[i]);
|
r.push_back(~c[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
lbool card_extension::add_assign(card& c, literal alit) {
|
lbool card_extension::add_assign(card& c, literal alit) {
|
||||||
// literal is assigned to false.
|
// literal is assigned to false.
|
||||||
unsigned sz = c.size();
|
unsigned sz = c.size();
|
||||||
unsigned bound = c.k();
|
unsigned bound = c.k();
|
||||||
TRACE("pb", tout << "assign: " << c.lit() << " " << ~alit << " " << bound << "\n";);
|
TRACE("sat", tout << "assign: " << c.lit() << " " << ~alit << " " << bound << "\n";);
|
||||||
|
|
||||||
SASSERT(0 < bound && bound < sz);
|
SASSERT(0 < bound && bound < sz);
|
||||||
SASSERT(s().value(alit) == l_false);
|
SASSERT(value(alit) == l_false);
|
||||||
SASSERT(s().value(c.lit()) == l_true);
|
SASSERT(value(c.lit()) == l_true);
|
||||||
unsigned index = 0;
|
unsigned index = 0;
|
||||||
for (index = 0; index <= bound; ++index) {
|
for (index = 0; index <= bound; ++index) {
|
||||||
if (c[index] == alit) {
|
if (c[index] == alit) {
|
||||||
|
@ -494,7 +504,7 @@ namespace sat {
|
||||||
// find a literal to swap with:
|
// find a literal to swap with:
|
||||||
for (unsigned i = bound + 1; i < sz; ++i) {
|
for (unsigned i = bound + 1; i < sz; ++i) {
|
||||||
literal lit2 = c[i];
|
literal lit2 = c[i];
|
||||||
if (s().value(lit2) != l_false) {
|
if (value(lit2) != l_false) {
|
||||||
c.swap(index, i);
|
c.swap(index, i);
|
||||||
watch_literal(c, lit2);
|
watch_literal(c, lit2);
|
||||||
return l_undef;
|
return l_undef;
|
||||||
|
@ -502,13 +512,13 @@ namespace sat {
|
||||||
}
|
}
|
||||||
|
|
||||||
// conflict
|
// conflict
|
||||||
if (bound != index && s().value(c[bound]) == l_false) {
|
if (bound != index && value(c[bound]) == l_false) {
|
||||||
TRACE("sat", tout << "conflict " << c[bound] << " " << alit << "\n";);
|
TRACE("sat", tout << "conflict " << c[bound] << " " << alit << "\n";);
|
||||||
set_conflict(c, alit);
|
set_conflict(c, alit);
|
||||||
return l_false;
|
return l_false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("pb", tout << "no swap " << index << " " << alit << "\n";);
|
TRACE("sat", tout << "no swap " << index << " " << alit << "\n";);
|
||||||
// there are no literals to swap with,
|
// there are no literals to swap with,
|
||||||
// prepare for unit propagation by swapping the false literal into
|
// prepare for unit propagation by swapping the false literal into
|
||||||
// position bound. Then literals in positions 0..bound-1 have to be
|
// position bound. Then literals in positions 0..bound-1 have to be
|
||||||
|
@ -532,7 +542,7 @@ namespace sat {
|
||||||
ptr_vector<card>::iterator it = cards->begin(), it2 = it, end = cards->end();
|
ptr_vector<card>::iterator it = cards->begin(), it2 = it, end = cards->end();
|
||||||
for (; it != end; ++it) {
|
for (; it != end; ++it) {
|
||||||
card& c = *(*it);
|
card& c = *(*it);
|
||||||
if (s().value(c.lit()) != l_true) {
|
if (value(c.lit()) != l_true) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
switch (add_assign(c, l)) {
|
switch (add_assign(c, l)) {
|
||||||
|
@ -604,9 +614,9 @@ namespace sat {
|
||||||
out << c.lit();
|
out << c.lit();
|
||||||
if (c.lit() != null_literal) {
|
if (c.lit() != null_literal) {
|
||||||
if (values) {
|
if (values) {
|
||||||
out << "@(" << s().value(c.lit());
|
out << "@(" << value(c.lit());
|
||||||
if (s().value(c.lit()) != l_undef) {
|
if (value(c.lit()) != l_undef) {
|
||||||
out << ":" << s().lvl(c.lit());
|
out << ":" << lvl(c.lit());
|
||||||
}
|
}
|
||||||
out << ")";
|
out << ")";
|
||||||
}
|
}
|
||||||
|
@ -619,9 +629,9 @@ namespace sat {
|
||||||
literal l = c[i];
|
literal l = c[i];
|
||||||
out << l;
|
out << l;
|
||||||
if (values) {
|
if (values) {
|
||||||
out << "@(" << s().value(l);
|
out << "@(" << value(l);
|
||||||
if (s().value(l) != l_undef) {
|
if (value(l) != l_undef) {
|
||||||
out << ":" << s().lvl(l);
|
out << ":" << lvl(l);
|
||||||
}
|
}
|
||||||
out << ") ";
|
out << ") ";
|
||||||
}
|
}
|
||||||
|
@ -651,35 +661,142 @@ namespace sat {
|
||||||
bool card_extension::validate_conflict(card& c) {
|
bool card_extension::validate_conflict(card& c) {
|
||||||
if (!validate_unit_propagation(c)) return false;
|
if (!validate_unit_propagation(c)) return false;
|
||||||
for (unsigned i = 0; i < c.k(); ++i) {
|
for (unsigned i = 0; i < c.k(); ++i) {
|
||||||
if (s().value(c[i]) == l_false) return true;
|
if (value(c[i]) == l_false) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool card_extension::validate_unit_propagation(card const& c) {
|
bool card_extension::validate_unit_propagation(card const& c) {
|
||||||
|
if (value(c.lit()) != l_true) return false;
|
||||||
for (unsigned i = c.k(); i < c.size(); ++i) {
|
for (unsigned i = c.k(); i < c.size(); ++i) {
|
||||||
if (s().value(c[i]) != l_false) return false;
|
if (value(c[i]) != l_false) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool card_extension::validate_lemma() {
|
bool card_extension::validate_lemma() {
|
||||||
int value = -m_bound;
|
int val = -m_bound;
|
||||||
normalize_active_coeffs();
|
normalize_active_coeffs();
|
||||||
for (unsigned i = 0; i < m_active_vars.size(); ++i) {
|
for (unsigned i = 0; i < m_active_vars.size(); ++i) {
|
||||||
bool_var v = m_active_vars[i];
|
bool_var v = m_active_vars[i];
|
||||||
int coeff = get_coeff(v);
|
int coeff = get_coeff(v);
|
||||||
|
literal lit(v, false);
|
||||||
SASSERT(coeff != 0);
|
SASSERT(coeff != 0);
|
||||||
if (coeff < 0 && s().value(v) != l_true) {
|
if (coeff < 0 && value(lit) != l_true) {
|
||||||
value -= coeff;
|
val -= coeff;
|
||||||
}
|
}
|
||||||
else if (coeff > 0 && s().value(v) != l_false) {
|
else if (coeff > 0 && value(lit) != l_false) {
|
||||||
value += coeff;
|
val += coeff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return value < 0;
|
return val < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool card_extension::validate_assign(literal_vector const& lits, literal lit) { return true; }
|
void card_extension::active2pb(ineq& p) {
|
||||||
bool card_extension::validate_conflict(literal_vector const& lits) { return true; }
|
normalize_active_coeffs();
|
||||||
|
p.reset(m_bound);
|
||||||
|
for (unsigned i = 0; i < m_active_vars.size(); ++i) {
|
||||||
|
bool_var v = m_active_vars[i];
|
||||||
|
literal lit(v, get_coeff(v) < 0);
|
||||||
|
p.m_lits.push_back(lit);
|
||||||
|
p.m_coeffs.push_back(get_abs_coeff(v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void card_extension::justification2pb(justification const& js, literal lit, unsigned offset, ineq& p) {
|
||||||
|
switch (js.get_kind()) {
|
||||||
|
case justification::NONE:
|
||||||
|
p.reset(0);
|
||||||
|
break;
|
||||||
|
case justification::BINARY:
|
||||||
|
p.reset(offset);
|
||||||
|
p.push(lit, offset);
|
||||||
|
p.push(~js.get_literal(), offset);
|
||||||
|
break;
|
||||||
|
case justification::TERNARY:
|
||||||
|
p.reset(offset);
|
||||||
|
p.push(lit, offset);
|
||||||
|
p.push(~(js.get_literal1()), offset);
|
||||||
|
p.push(~(js.get_literal2()), offset);
|
||||||
|
break;
|
||||||
|
case justification::CLAUSE: {
|
||||||
|
p.reset(offset);
|
||||||
|
clause & c = *(s().m_cls_allocator.get_clause(js.get_clause_offset()));
|
||||||
|
unsigned sz = c.size();
|
||||||
|
for (unsigned i = 0; i < sz; i++)
|
||||||
|
p.push(~c[i], offset);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case justification::EXT_JUSTIFICATION: {
|
||||||
|
unsigned index = js.get_ext_justification_idx();
|
||||||
|
card& c = *m_constraints[index];
|
||||||
|
p.reset(offset*c.k());
|
||||||
|
for (unsigned i = 0; i < c.size(); ++i) {
|
||||||
|
p.push(c[i], offset);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// validate that m_A & m_B implies m_C
|
||||||
|
|
||||||
|
bool card_extension::validate_resolvent() {
|
||||||
|
u_map<unsigned> coeffs;
|
||||||
|
unsigned k = m_A.m_k + m_B.m_k;
|
||||||
|
for (unsigned i = 0; i < m_A.m_lits.size(); ++i) {
|
||||||
|
unsigned coeff = m_A.m_coeffs[i];
|
||||||
|
SASSERT(!coeffs.contains(m_A.m_lits[i].index()));
|
||||||
|
coeffs.insert(m_A.m_lits[i].index(), coeff);
|
||||||
|
}
|
||||||
|
for (unsigned i = 0; i < m_B.m_lits.size(); ++i) {
|
||||||
|
unsigned coeff1 = m_B.m_coeffs[i], coeff2;
|
||||||
|
literal lit = m_B.m_lits[i];
|
||||||
|
if (coeffs.find((~lit).index(), coeff2)) {
|
||||||
|
if (coeff1 == coeff2) {
|
||||||
|
coeffs.remove((~lit).index());
|
||||||
|
k += coeff1;
|
||||||
|
}
|
||||||
|
else if (coeff1 < coeff2) {
|
||||||
|
coeffs.insert((~lit).index(), coeff2 - coeff1);
|
||||||
|
k += coeff1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SASSERT(coeff2 < coeff1);
|
||||||
|
coeffs.remove((~lit).index());
|
||||||
|
coeffs.insert(lit.index(), coeff1 - coeff2);
|
||||||
|
k += coeff2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (coeffs.find(lit.index(), coeff2)) {
|
||||||
|
coeffs.insert(lit.index(), coeff1 + coeff2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
coeffs.insert(lit.index(), coeff1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// C is above the sum of A and B
|
||||||
|
for (unsigned i = 0; i < m_C.m_lits.size(); ++i) {
|
||||||
|
literal lit = m_C.m_lits[i];
|
||||||
|
unsigned coeff;
|
||||||
|
if (coeffs.find(lit.index(), coeff)) {
|
||||||
|
SASSERT(coeff <= m_C.m_coeffs[i]);
|
||||||
|
coeffs.remove(lit.index());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SASSERT(coeffs.empty());
|
||||||
|
SASSERT(m_C.m_k <= k);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool card_extension::validate_conflict(literal_vector const& lits) {
|
||||||
|
for (unsigned i = 0; i < lits.size(); ++i) {
|
||||||
|
if (value(lits[i]) != l_false) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,7 +23,7 @@ Revision History:
|
||||||
#include"sat_solver.h"
|
#include"sat_solver.h"
|
||||||
|
|
||||||
namespace sat {
|
namespace sat {
|
||||||
|
|
||||||
class card_extension : public extension {
|
class card_extension : public extension {
|
||||||
struct stats {
|
struct stats {
|
||||||
unsigned m_num_propagations;
|
unsigned m_num_propagations;
|
||||||
|
@ -31,7 +31,7 @@ namespace sat {
|
||||||
stats() { reset(); }
|
stats() { reset(); }
|
||||||
void reset() { memset(this, 0, sizeof(*this)); }
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class card {
|
class card {
|
||||||
unsigned m_index;
|
unsigned m_index;
|
||||||
literal m_lit;
|
literal m_lit;
|
||||||
|
@ -49,6 +49,14 @@ namespace sat {
|
||||||
void negate();
|
void negate();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ineq {
|
||||||
|
literal_vector m_lits;
|
||||||
|
unsigned_vector m_coeffs;
|
||||||
|
unsigned m_k;
|
||||||
|
void reset(unsigned k) { m_lits.reset(); m_coeffs.reset(); m_k = k; }
|
||||||
|
void push(literal l, unsigned c) { m_lits.push_back(l); m_coeffs.push_back(c); }
|
||||||
|
};
|
||||||
|
|
||||||
typedef ptr_vector<card> watch;
|
typedef ptr_vector<card> watch;
|
||||||
struct var_info {
|
struct var_info {
|
||||||
watch* m_lit_watch[2];
|
watch* m_lit_watch[2];
|
||||||
|
@ -95,6 +103,10 @@ namespace sat {
|
||||||
void clear_watch(card& c);
|
void clear_watch(card& c);
|
||||||
void reset_coeffs();
|
void reset_coeffs();
|
||||||
|
|
||||||
|
inline lbool value(literal lit) const { return m_solver->value(lit); }
|
||||||
|
inline unsigned lvl(literal lit) const { return m_solver->lvl(lit); }
|
||||||
|
inline unsigned lvl(bool_var v) const { return m_solver->lvl(v); }
|
||||||
|
|
||||||
void unwatch_literal(literal w, card* c);
|
void unwatch_literal(literal w, card* c);
|
||||||
void remove(ptr_vector<card>& cards, card* c);
|
void remove(ptr_vector<card>& cards, card* c);
|
||||||
|
|
||||||
|
@ -105,7 +117,7 @@ namespace sat {
|
||||||
|
|
||||||
literal_vector& get_literals() { m_literals.reset(); return m_literals; }
|
literal_vector& get_literals() { m_literals.reset(); return m_literals; }
|
||||||
literal get_asserting_literal(literal conseq);
|
literal get_asserting_literal(literal conseq);
|
||||||
bool resolve_conflict(card& c, literal_vector const& conflict_clause);
|
bool resolve_conflict(card& c, literal alit);
|
||||||
void process_antecedent(literal l, int offset);
|
void process_antecedent(literal l, int offset);
|
||||||
void process_card(card& c, int offset);
|
void process_card(card& c, int offset);
|
||||||
void cut();
|
void cut();
|
||||||
|
@ -117,6 +129,11 @@ namespace sat {
|
||||||
bool validate_unit_propagation(card const& c);
|
bool validate_unit_propagation(card const& c);
|
||||||
bool validate_conflict(literal_vector const& lits);
|
bool validate_conflict(literal_vector const& lits);
|
||||||
|
|
||||||
|
ineq m_A, m_B, m_C;
|
||||||
|
void active2pb(ineq& p);
|
||||||
|
void justification2pb(justification const& j, literal lit, unsigned offset, ineq& p);
|
||||||
|
bool validate_resolvent();
|
||||||
|
|
||||||
void display(std::ostream& out, card& c, bool values) const;
|
void display(std::ostream& out, card& c, bool values) const;
|
||||||
void display_watch(std::ostream& out, bool_var v, bool sign) const;
|
void display_watch(std::ostream& out, bool_var v, bool sign) const;
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue