mirror of
https://github.com/Z3Prover/z3
synced 2025-05-01 12:55:52 +00:00
Polysat: conflict resolution wip (#5529)
* conflict_core doesn't need gc() anymore * update comments, ensure_bvar for new constraints * Make sure constraints can only be created through constraint_manager * fix constraint::display if no boolean variable is assigned * Move clause into separate file * Add conflict_core binary resolution * conflict_core additions * reactivate conflict resolution outer loop * wip * seems commented includes break CI build
This commit is contained in:
parent
8b374c3745
commit
dc547510db
16 changed files with 423 additions and 335 deletions
|
@ -16,6 +16,7 @@ Author:
|
|||
#include "math/polysat/solver.h"
|
||||
#include "math/polysat/log.h"
|
||||
#include "math/polysat/log_helper.h"
|
||||
#include <algorithm>
|
||||
|
||||
namespace polysat {
|
||||
|
||||
|
@ -46,40 +47,71 @@ namespace polysat {
|
|||
m_needs_model = true;
|
||||
}
|
||||
|
||||
void conflict_core::set(pvar v, vector<signed_constraint> const& cjust_v) {
|
||||
LOG("Conflict for v" << v << ": " << cjust_v);
|
||||
void conflict_core::set(pvar v) {
|
||||
LOG("Conflict: v" << v);
|
||||
SASSERT(empty());
|
||||
NOT_IMPLEMENTED_YET();
|
||||
m_conflict_var = v;
|
||||
m_constraints.append(cjust_v);
|
||||
if (cjust_v.empty())
|
||||
m_constraints.push_back({});
|
||||
m_needs_model = true;
|
||||
}
|
||||
|
||||
void conflict_core::resolve(sat::bool_var var, clause const& cl) {
|
||||
// TODO: fix the implementation: should resolve the given clause with the current conflict core.
|
||||
#if 0
|
||||
DEBUG_CODE({
|
||||
bool this_has_pos = std::count(begin(), end(), sat::literal(var)) > 0;
|
||||
bool this_has_neg = std::count(begin(), end(), ~sat::literal(var)) > 0;
|
||||
bool other_has_pos = std::count(other.begin(), other.end(), sat::literal(var)) > 0;
|
||||
bool other_has_neg = std::count(other.begin(), other.end(), ~sat::literal(var)) > 0;
|
||||
SASSERT(!this_has_pos || !this_has_neg); // otherwise this is tautology
|
||||
SASSERT(!other_has_pos || !other_has_neg); // otherwise other is tautology
|
||||
SASSERT((this_has_pos && other_has_neg) || (this_has_neg && other_has_pos));
|
||||
});
|
||||
// The resolved var should not be one of the new constraints
|
||||
int j = 0;
|
||||
for (auto lit : m_literals)
|
||||
if (lit.var() != var)
|
||||
m_literals[j++] = lit;
|
||||
m_literals.shrink(j);
|
||||
for (sat::literal lit : other)
|
||||
if (lit.var() != var)
|
||||
m_literals.push_back(lit);
|
||||
return true;
|
||||
#endif
|
||||
void conflict_core::push(signed_constraint c) {
|
||||
SASSERT(!empty()); // should use set() to enter conflict state
|
||||
// Skip trivial constraints
|
||||
// (e.g., constant ones such as "4 > 1"... only true ones should appear, otherwise the lemma would be a tautology)
|
||||
if (c.is_always_true())
|
||||
return;
|
||||
SASSERT(!c.is_always_false());
|
||||
m_constraints.push_back(c);
|
||||
}
|
||||
|
||||
void conflict_core::resolve(constraint_manager const& m, sat::bool_var var, clause const& cl) {
|
||||
// Note: core: x, y, z; corresponds to clause ~x \/ ~y \/ ~z
|
||||
// clause: x \/ u \/ v
|
||||
// resolvent: ~y \/ ~z \/ u \/ v; as core: y, z, ~u, ~v
|
||||
|
||||
SASSERT(var != sat::null_bool_var);
|
||||
DEBUG_CODE({
|
||||
bool core_has_pos = std::count_if(begin(), end(), [var](auto c){ return c.blit() == sat::literal(var); }) > 0;
|
||||
bool core_has_neg = std::count_if(begin(), end(), [var](auto c){ return c.blit() == ~sat::literal(var); }) > 0;
|
||||
bool clause_has_pos = std::count(cl.begin(), cl.end(), sat::literal(var)) > 0;
|
||||
bool clause_has_neg = std::count(cl.begin(), cl.end(), ~sat::literal(var)) > 0;
|
||||
SASSERT(!core_has_pos || !core_has_neg); // otherwise core is tautology
|
||||
SASSERT(!clause_has_pos || !clause_has_neg); // otherwise clause is tautology
|
||||
SASSERT((core_has_pos && clause_has_pos) || (core_has_neg && clause_has_neg));
|
||||
});
|
||||
|
||||
int j = 0;
|
||||
for (auto c : m_constraints)
|
||||
if (c->bvar() == var)
|
||||
m_constraints[j++] = c;
|
||||
m_constraints.shrink(j);
|
||||
|
||||
for (sat::literal lit : cl)
|
||||
if (lit.var() != var)
|
||||
m_constraints.push_back(m.lookup(~lit));
|
||||
}
|
||||
|
||||
clause_ref conflict_core::build_lemma(solver& s, unsigned trail_idx) {
|
||||
sat::literal_vector literals;
|
||||
p_dependency_ref dep = s.mk_dep_ref(null_dependency);
|
||||
unsigned lvl = 0;
|
||||
|
||||
// TODO: another core reduction step?
|
||||
|
||||
for (auto c : m_constraints) {
|
||||
if (c->unit_clause()) {
|
||||
dep = s.m_dm.mk_join(dep, c->unit_dep());
|
||||
continue;
|
||||
}
|
||||
lvl = std::max(lvl, c->level());
|
||||
s.m_constraints.ensure_bvar(c.get());
|
||||
literals.push_back(~c.blit());
|
||||
}
|
||||
|
||||
if (m_needs_model) {
|
||||
// TODO: add equalities corresponding to model up to trail_idx
|
||||
}
|
||||
|
||||
return clause::from_literals(lvl, std::move(dep), std::move(literals));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue