3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-24 17:45:32 +00:00

migrating to general form

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2021-04-13 11:21:41 -07:00
parent 6402a80f10
commit 7025d85da3
2 changed files with 46 additions and 100 deletions

View file

@ -84,9 +84,6 @@ namespace polysat {
m_lim(lim),
m_bdd(1000),
m_dm(m_value_manager, m_alloc),
m_vdeps(m_dm),
m_conflict_dep(nullptr, m_dm),
m_stash_dep(nullptr, m_dm),
m_free_vars(m_activity) {
}
@ -108,7 +105,6 @@ namespace polysat {
m_value.push_back(rational::zero());
m_justification.push_back(justification::unassigned());
m_viable.push_back(m_bdd.mk_true());
m_vdeps.push_back(m_dm.mk_empty());
m_cjust.push_back(constraints());
m_watch.push_back(ptr_vector<constraint>());
m_activity.push_back(0);
@ -123,7 +119,6 @@ namespace polysat {
pvar v = m_viable.size() - 1;
m_free_vars.del_var_eh(v);
m_viable.pop_back();
m_vdeps.pop_back();
m_cjust.pop_back();
m_value.pop_back();
m_justification.pop_back();
@ -166,18 +161,6 @@ namespace polysat {
// save for later
}
void solver::assign(pvar v, unsigned index, bool value, unsigned dep) {
m_viable[v] &= value ? m_bdd.mk_var(index) : m_bdd.mk_nvar(index);
add_viable_dep(v, mk_dep(dep));
if (m_viable[v].is_false()) {
// TBD: set conflict
}
}
void solver::add_viable_dep(pvar v, p_dependency* dep) {
if (dep)
m_vdeps[v] = m_dm.mk_join(m_vdeps.get(v), dep);
}
bool solver::can_propagate() {
return m_qhead < m_search.size() && !is_conflict();
@ -230,7 +213,6 @@ namespace polysat {
}
}
auto p = c.p().subst_val(m_search);
if (p.is_zero())
return false;
@ -314,7 +296,6 @@ namespace polysat {
m_justification[v] = justification::unassigned();
m_free_vars.unassign_var_eh(v);
m_cjust[v].reset();
m_vdeps[v] = nullptr;
m_viable[v] = m_bdd.mk_true(); // TBD does not work with external bit-assignments
}
@ -380,13 +361,11 @@ namespace polysat {
void solver::set_conflict(constraint& c) {
SASSERT(m_conflict_cs.empty());
m_conflict_cs.push_back(&c);
m_conflict_dep = nullptr;
}
void solver::set_conflict(pvar v) {
SASSERT(m_conflict_cs.empty());
m_conflict_cs.append(m_cjust[v]);
m_conflict_dep = m_vdeps.get(v);
if (m_cjust[v].empty())
m_conflict_cs.push_back(nullptr);
}
@ -413,7 +392,21 @@ namespace polysat {
*/
void solver::resolve_conflict() {
vector<pdd> ps = init_conflict();
if (m_conflict_cs.size() == 1 && !m_conflict_cs[0]) {
report_unsat();
return;
}
if (m_conflict_cs.size() > 1) {
revert_decision(m_search.size()-1);
return;
}
constraint* c = m_conflict_cs[0];
scoped_ptr<constraint> lemma;
reset_marks();
for (auto v : c->vars())
set_mark(v);
for (unsigned i = m_search.size(); i-- > 0; ) {
pvar v = m_search[i].first;
@ -425,12 +418,18 @@ namespace polysat {
return;
}
if (j.is_decision()) {
if (ps.size() == 1)
learn_lemma(v, ps[0]);
learn_lemma(v, lemma.detach());
revert_decision(i);
return;
}
pdd r = resolve(v, ps);
constraint* new_lemma = resolve(v, lemma.get());
if (!new_lemma) {
backtrack(i);
return;
}
lemma = new_lemma;
// TBD: this assumes lemma is an equality.
pdd r = lemma->p();
pdd rval = r.subst_val(m_search);
if (r.is_val() && rval.is_never_zero()) {
report_unsat();
@ -442,32 +441,13 @@ namespace polysat {
}
SASSERT(j.is_propagation());
reset_marks();
for (auto w : r.free_vars())
for (auto w : lemma->vars())
set_mark(w);
ps.shrink(1);
ps[0] = r;
c = lemma.get();
}
report_unsat();
}
vector<pdd> solver::init_conflict() {
SASSERT(!m_conflict_cs.empty());
m_conflict_level = 0;
vector<pdd> ps;
reset_marks();
for (auto* c : m_conflict_cs) {
if (!c)
continue;
for (auto v : c->vars())
set_mark(v);
ps.push_back(c->p());
m_conflict_level = std::max(m_conflict_level, c->level());
m_conflict_dep = m_dm.mk_join(m_conflict_dep, c->dep());
}
m_conflict_cs.reset();
return ps;
}
void solver::backtrack(unsigned i) {
do {
auto v = m_search[i].first;
@ -491,11 +471,12 @@ namespace polysat {
void solver::unsat_core(unsigned_vector& deps) {
deps.reset();
p_dependency_ref conflict_dep(m_dm);
for (auto* c : m_conflict_cs) {
if (c)
m_conflict_dep = m_dm.mk_join(c->dep(), m_conflict_dep);
conflict_dep = m_dm.mk_join(c->dep(), conflict_dep);
}
m_dm.linearize(m_conflict_dep, deps);
m_dm.linearize(conflict_dep, deps);
}
@ -506,9 +487,10 @@ namespace polysat {
* We add 'p == 0' as a lemma. The lemma depends on the dependencies used
* to derive p, and the level of the lemma is the maximal level of the dependencies.
*/
void solver::learn_lemma(pvar v, pdd const& p) {
void solver::learn_lemma(pvar v, constraint* c) {
if (!c)
return;
SASSERT(m_conflict_level <= m_justification[v].level());
constraint* c = constraint::eq(m_conflict_level, p, m_conflict_dep);
m_cjust[v].push_back(c);
add_lemma(c);
}
@ -523,18 +505,13 @@ namespace polysat {
backjump(m_justification[v].level()-1);
unstash_deps(v);
add_non_viable(v, m_value[v]);
add_viable_dep(v, m_conflict_dep);
decide(v);
}
void solver::stash_deps(pvar v) {
m_stash_dep = m_vdeps.get(v);
std::swap(m_stash_just, m_cjust[v]);
}
void solver::unstash_deps(pvar v) {
m_vdeps[v] = m_stash_dep;
std::swap(m_stash_just, m_cjust[v]);
}
void solver::backjump(unsigned new_level) {
@ -542,40 +519,12 @@ namespace polysat {
if (num_levels > 0)
pop_levels(num_levels);
}
/**
* resolve polynomials associated with unit propagating on v
* producing polynomial that isolates v to lowest degree
* and lowest power of 2.
*/
pdd solver::isolate(pvar v, vector<pdd> const& ps) {
pdd p = ps[0];
for (unsigned i = ps.size(); i-- > 1; ) {
// TBD reduce with respect to v
}
return p;
}
/**
* Return residue of superposing p and q with respect to v.
*/
pdd solver::resolve(pvar v, vector<pdd> const& ps) {
auto const& cs = m_cjust[v];
pdd r = isolate(v, ps);
auto degree = r.degree(v);
m_conflict_dep = m_dm.mk_join(m_conflict_dep, m_vdeps.get(v));
while (degree > 0) {
for (auto * c : cs) {
if (degree >= c->p().degree(v)) {
// TODO binary resolve, update r using result
// add parity condition to presere falsification
degree = r.degree(v);
m_conflict_level = std::max(m_conflict_level, c->level());
m_conflict_dep = m_dm.mk_join(m_conflict_dep.get(), c->dep());
}
}
}
return r;
constraint* solver::resolve(pvar v, constraint* c) {
return nullptr;
}
void solver::add_lemma(constraint* c) {

View file

@ -57,12 +57,12 @@ namespace polysat {
enum ckind_t { eq_t, ule_t, sle_t };
class constraint {
unsigned m_level;
ckind_t m_kind;
pdd m_poly;
pdd m_other;
unsigned m_level;
ckind_t m_kind;
pdd m_poly;
pdd m_other;
p_dependency_ref m_dep;
unsigned_vector m_vars;
unsigned_vector m_vars;
constraint(unsigned lvl, pdd const& p, pdd const& q, p_dependency_ref& dep, ckind_t k):
m_level(lvl), m_kind(k), m_poly(p), m_other(q), m_dep(dep) {
m_vars.append(p.free_vars());
@ -77,6 +77,9 @@ namespace polysat {
static constraint* ule(unsigned lvl, pdd const& p, pdd const& q, p_dependency_ref& d) {
return alloc(constraint, lvl, p, q, d, ckind_t::ule_t);
}
bool is_eq() const { return m_kind == ckind_t::eq_t; }
bool is_ule() const { return m_kind == ckind_t::ule_t; }
bool is_sle() const { return m_kind == ckind_t::sle_t; }
ckind_t kind() const { return m_kind; }
pdd const & p() const { return m_poly; }
pdd const & lhs() const { return m_poly; }
@ -125,9 +128,7 @@ namespace polysat {
dep_value_manager m_value_manager;
small_object_allocator m_alloc;
poly_dep_manager m_dm;
p_dependency_ref m_conflict_dep;
ptr_vector<constraint> m_conflict_cs;
p_dependency_ref m_stash_dep;
constraints m_conflict_cs;
constraints m_stash_just;
var_queue m_free_vars;
@ -137,7 +138,6 @@ namespace polysat {
// Per variable information
vector<bdd> m_viable; // set of viable values.
p_dependency_refv m_vdeps; // dependencies for viable values
vector<rational> m_value; // assigned value
vector<justification> m_justification; // justification for variable assignment
vector<constraints> m_cjust; // constraints justifying variable range.
@ -221,8 +221,7 @@ namespace polysat {
unsigned m_conflict_level { 0 };
pdd isolate(pvar v, vector<pdd> const& ps);
pdd resolve(pvar v, vector<pdd> const& ps);
constraint* resolve(pvar v, constraint* c);
bool can_decide() const { return !m_free_vars.empty(); }
void decide();
@ -237,12 +236,11 @@ namespace polysat {
bool at_base_level() const;
unsigned base_level() const;
vector<pdd> init_conflict();
void resolve_conflict();
void backtrack(unsigned i);
void report_unsat();
void revert_decision(unsigned i);
void learn_lemma(pvar v, pdd const& p);
void learn_lemma(pvar v, constraint* c);
void backjump(unsigned new_level);
void undo_var(pvar v);
void add_lemma(constraint* c);
@ -295,7 +293,6 @@ namespace polysat {
void add_sle(pdd const& p, pdd const& q, unsigned dep = null_dependency);
void add_slt(pdd const& p, pdd const& q, unsigned dep = null_dependency);
void assign(pvar v, unsigned index, bool value, unsigned dep);
/**
* main state transitions.