mirror of
https://github.com/Z3Prover/z3
synced 2026-03-05 05:00:23 +00:00
Add level to conflict
- reset conflict at correct level when popping user scopes - functions as flag when handling inconsistent input (e.g., opposite literals) - now all constraints in the conflict core should have bvalue == l_true
This commit is contained in:
parent
86d00b536a
commit
a4f0e3a228
5 changed files with 87 additions and 28 deletions
|
|
@ -140,10 +140,14 @@ namespace polysat {
|
|||
}
|
||||
|
||||
bool conflict::empty() const {
|
||||
return m_literals.empty()
|
||||
&& m_vars.empty()
|
||||
&& m_bail_vars.empty()
|
||||
&& m_lemmas.empty();
|
||||
bool const is_empty = (m_level == UINT_MAX);
|
||||
if (is_empty) {
|
||||
SASSERT(m_literals.empty());
|
||||
SASSERT(m_vars.empty());
|
||||
SASSERT(m_bail_vars.empty());
|
||||
SASSERT(m_lemmas.empty());
|
||||
}
|
||||
return is_empty;
|
||||
}
|
||||
|
||||
void conflict::reset() {
|
||||
|
|
@ -154,6 +158,7 @@ namespace polysat {
|
|||
m_var_occurrences.reset();
|
||||
m_lemmas.reset();
|
||||
m_kind = conflict_kind_t::ok;
|
||||
m_level = UINT_MAX;
|
||||
SASSERT(empty());
|
||||
}
|
||||
|
||||
|
|
@ -182,7 +187,6 @@ namespace polysat {
|
|||
return true;
|
||||
case conflict_kind_t::backtrack:
|
||||
return pvar_occurs_in_constraints(v) || m_relevant_vars.contains(v);
|
||||
// return m_relevant_vars.contains(v);
|
||||
case conflict_kind_t::backjump:
|
||||
UNREACHABLE(); // we don't follow the regular loop when backjumping
|
||||
return false;
|
||||
|
|
@ -195,8 +199,30 @@ namespace polysat {
|
|||
return contains(lit) || contains(~lit);
|
||||
}
|
||||
|
||||
void conflict::init_at_base_level() {
|
||||
SASSERT(empty());
|
||||
SASSERT(s.at_base_level());
|
||||
m_level = s.m_level;
|
||||
SASSERT(!empty());
|
||||
}
|
||||
|
||||
void conflict::init(signed_constraint c) {
|
||||
SASSERT(empty());
|
||||
m_level = s.m_level;
|
||||
/*
|
||||
// NOTE: c.is_always_false() may happen e.g. if we add an always false constraint in the input
|
||||
if (c.is_always_false()) {
|
||||
SASSERT(c.bvalue(s) == l_true);
|
||||
SASSERT(s.m_bvars.is_assumption(c.blit()));
|
||||
SASSERT(s.at_base_level());
|
||||
// TODO: this kind of constraint should be handled when it is being added to the solver.
|
||||
return;
|
||||
}
|
||||
if (c.bvalue(s) == l_false && s.at_base_level()) {
|
||||
// We have opposite literals in the input.
|
||||
return;
|
||||
}
|
||||
*/
|
||||
set_impl(c);
|
||||
logger().begin_conflict();
|
||||
}
|
||||
|
|
@ -238,6 +264,7 @@ namespace polysat {
|
|||
// return;
|
||||
// LOG("Conflict: " << cl);
|
||||
SASSERT(empty());
|
||||
m_level = s.m_level;
|
||||
for (auto lit : cl) {
|
||||
auto c = s.lit2cnstr(lit);
|
||||
SASSERT(c.bvalue(s) == l_false);
|
||||
|
|
@ -248,6 +275,8 @@ namespace polysat {
|
|||
}
|
||||
|
||||
void conflict::init(pvar v, bool by_viable_fallback) {
|
||||
SASSERT(empty());
|
||||
m_level = s.m_level;
|
||||
if (by_viable_fallback) {
|
||||
logger().begin_conflict(header_with_var("unsat core from viable fallback for v", v));
|
||||
// Conflict detected by viable fallback:
|
||||
|
|
@ -264,6 +293,7 @@ namespace polysat {
|
|||
// but each branch exclude the current assignment.
|
||||
// in those cases we will (additionally?) need an abstraction that is asserting to make sure viable is updated properly.
|
||||
}
|
||||
SASSERT(!empty());
|
||||
}
|
||||
|
||||
bool conflict::contains(sat::literal lit) const {
|
||||
|
|
@ -276,7 +306,8 @@ namespace polysat {
|
|||
return;
|
||||
if (c.is_always_true())
|
||||
return;
|
||||
LOG("Inserting: " << c);
|
||||
LOG("Inserting " << lit_pp(s, c));
|
||||
SASSERT(c.bvalue(s) == l_true);
|
||||
SASSERT(!c.is_always_false()); // if we added c, the core would be a tautology
|
||||
SASSERT(!c->vars().empty());
|
||||
m_literals.insert(c.blit().index());
|
||||
|
|
@ -424,9 +455,12 @@ namespace polysat {
|
|||
LOG("core: " << *this);
|
||||
clause_builder lemma(s);
|
||||
|
||||
// TODO: is this sound, doing it for each constraint separately?
|
||||
for (auto c : *this)
|
||||
#if 0
|
||||
if (m_literals.size() == 1) {
|
||||
auto c = *begin();
|
||||
minimize_vars(c);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (auto c : *this)
|
||||
lemma.push(~c);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue