3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-03-06 21:34:53 +00:00

revive polynomial superposition (wip)

This commit is contained in:
Jakob Rath 2022-10-07 10:34:07 +02:00
parent 155b746e03
commit dcd6c01a90
5 changed files with 105 additions and 56 deletions

View file

@ -61,13 +61,17 @@ namespace polysat {
class conflict_resolver {
inf_saturate m_saturate;
ex_polynomial_superposition m_poly_sup;
public:
conflict_resolver(solver& s)
: m_saturate(s)
, m_poly_sup(s)
{}
bool try_resolve_value(pvar v, conflict& core) {
if (m_poly_sup.perform(v, core))
return true;
if (m_saturate.perform(v, core))
return true;
return false;
@ -212,7 +216,8 @@ namespace polysat {
}
void conflict::set(signed_constraint c) {
reset();
SASSERT(!empty());
remove_all();
set_impl(c);
}
@ -223,7 +228,8 @@ namespace polysat {
// - opposite input literals are handled separately
// - other boolean conflicts will discover violated clause during boolean propagation
VERIFY(false); // fail here to force check when we encounter this case
} else {
}
else {
// conflict due to assignment
SASSERT(c.bvalue(s) == l_true);
SASSERT(c.is_currently_false(s));
@ -265,13 +271,11 @@ namespace polysat {
}
SASSERT(!m_vars.contains(v));
// TODO: apply conflict resolution plugins here too?
} else {
}
else {
logger().begin_conflict(header_with_var("forbidden interval lemma for v", v));
set_backtrack();
VERIFY(s.m_viable.resolve(v, *this));
// TODO: in general the forbidden interval lemma is not asserting.
// 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());
}
@ -317,6 +321,33 @@ namespace polysat {
m_vars.insert(v);
}
void conflict::bool_propagate(signed_constraint c, signed_constraint const* premises, unsigned premises_len) {
if (c.is_always_false()) {
VERIFY(false); // TODO: this case can probably happen, but needs special attention
}
// Build lemma: premises ==> c
clause_builder cb(s);
for (unsigned i = 0; i < premises_len; ++i) {
SASSERT_EQ(premises[i].bvalue(s), l_true);
cb.push(~premises[i]);
}
SASSERT_EQ(c.bvalue(s), l_undef);
cb.push_new(c);
clause_ref lemma = cb.build();
SASSERT(lemma);
lemma->set_redundant(true);
set_side_lemma(c, lemma);
// TODO: we must "simulate" the propagation but don't want to put the literal onto the search stack.
s.assign_propagate(c.blit(), *lemma);
// s.m_search.pop(); // doesn't work... breaks m_trail and backjumping
SASSERT_EQ(c.bvalue(s), l_true);
// insert(c);
}
void conflict::bool_propagate(signed_constraint c, std::initializer_list<signed_constraint> premises) {
bool_propagate(c, std::data(premises), premises.size());
}
void conflict::remove(signed_constraint c) {
SASSERT(contains(c));
m_literals.remove(c.blit().index());
@ -324,6 +355,16 @@ namespace polysat {
m_var_occurrences[v]--;
}
void conflict::remove_all() {
SASSERT(!empty());
m_literals.reset();
m_vars.reset();
m_bail_vars.reset();
m_relevant_vars.reset();
m_var_occurrences.reset();
m_kind = conflict_kind_t::ok;
}
void conflict::insert(signed_constraint c, clause_ref lemma) {
unsigned const idx = c.blit().to_uint();
SASSERT(!contains(c)); // not required, but this case should be checked