3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-27 00:18:45 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2021-09-12 18:14:25 +02:00
commit e365ad0e9e
8 changed files with 39 additions and 42 deletions

View file

@ -138,14 +138,6 @@ namespace polysat {
m_constraints.shrink(j); m_constraints.shrink(j);
} }
void conflict_core::keep(signed_constraint c) {
SASSERT(!c->has_bvar());
cm().ensure_bvar(c.get());
LOG("new constraint: " << c);
// Insert the temporary constraint from saturation into \Gamma.
handle_saturation_premises(c);
}
void conflict_core::resolve(constraint_manager const& m, sat::bool_var var, clause const& cl) { 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 // Note: core: x, y, z; corresponds to clause ~x \/ ~y \/ ~z
// clause: x \/ u \/ v // clause: x \/ u \/ v
@ -177,7 +169,9 @@ namespace polysat {
} }
/** If the constraint c is a temporary constraint derived by core saturation, insert it (and recursively, its premises) into \Gamma */ /** If the constraint c is a temporary constraint derived by core saturation, insert it (and recursively, its premises) into \Gamma */
void conflict_core::handle_saturation_premises(signed_constraint c) { void conflict_core::keep(signed_constraint c) {
cm().ensure_bvar(c.get());
LOG_H3("keeping: " << c);
// NOTE: maybe we should skip intermediate steps and just collect the leaf premises for c? // NOTE: maybe we should skip intermediate steps and just collect the leaf premises for c?
auto it = m_saturation_premises.find_iterator(c); auto it = m_saturation_premises.find_iterator(c);
if (it == m_saturation_premises.end()) if (it == m_saturation_premises.end())
@ -186,9 +180,7 @@ namespace polysat {
auto& premises = it->m_value; auto& premises = it->m_value;
clause_builder c_lemma(s()); clause_builder c_lemma(s());
for (auto premise : premises) { for (auto premise : premises) {
cm().ensure_bvar(premise.get()); keep(premise);
// keep(premise);
handle_saturation_premises(premise);
SASSERT(premise->has_bvar()); SASSERT(premise->has_bvar());
c_lemma.push(~premise.blit()); c_lemma.push(~premise.blit());
active_level = std::max(active_level, s().m_bvars.level(premise.blit())); active_level = std::max(active_level, s().m_bvars.level(premise.blit()));
@ -246,8 +238,8 @@ namespace polysat {
for (unsigned v : m_vars) { for (unsigned v : m_vars) {
if (!is_pmarked(v)) if (!is_pmarked(v))
continue; continue;
// SASSERT(!s().is_assigned()); // TODO: why does this trigger???? // SASSERT(!s().is_assigned(v)); // TODO: why does this trigger????
if (!s().is_assigned()) if (!s().is_assigned(v))
continue; continue;
if (s().m_justification[v].level() > model_level) if (s().m_justification[v].level() > model_level)
continue; continue;

View file

@ -61,7 +61,6 @@ namespace polysat {
// ptr_addr_map<constraint, vector<signed_constraint>> m_saturation_premises; // ptr_addr_map<constraint, vector<signed_constraint>> m_saturation_premises;
map<signed_constraint, vector<signed_constraint>, obj_hash<signed_constraint>, default_eq<signed_constraint>> m_saturation_premises; map<signed_constraint, vector<signed_constraint>, obj_hash<signed_constraint>, default_eq<signed_constraint>> m_saturation_premises;
void handle_saturation_premises(signed_constraint c);
public: public:
conflict_core(solver& s); conflict_core(solver& s);
~conflict_core(); ~conflict_core();

View file

@ -17,8 +17,6 @@ Author:
namespace polysat { namespace polysat {
constraint_manager& explainer::cm() { return s().m_constraints; }
signed_constraint ex_polynomial_superposition::resolve1(pvar v, signed_constraint c1, signed_constraint c2) { signed_constraint ex_polynomial_superposition::resolve1(pvar v, signed_constraint c1, signed_constraint c2) {
// c1 is true, c2 is false // c1 is true, c2 is false
SASSERT(c1.is_currently_true(s())); SASSERT(c1.is_currently_true(s()));
@ -35,7 +33,7 @@ namespace polysat {
// (this condition might be too strict, but we use it for now to prevent looping) // (this condition might be too strict, but we use it for now to prevent looping)
if (b.degree(v) <= r.degree(v)) if (b.degree(v) <= r.degree(v))
return {}; return {};
signed_constraint c = cm().eq(r); signed_constraint c = s().eq(r);
LOG("resolved: " << c << " currently false? " << c.is_currently_false(s())); LOG("resolved: " << c << " currently false? " << c.is_currently_false(s()));
if (!c.is_currently_false(s())) if (!c.is_currently_false(s()))
return {}; return {};

View file

@ -20,7 +20,6 @@ Author:
namespace polysat { namespace polysat {
class solver; class solver;
class constraint_manager;
class explainer { class explainer {
friend class conflict_core; friend class conflict_core;
@ -28,7 +27,6 @@ namespace polysat {
void set_solver(solver& s) { m_solver = &s; } void set_solver(solver& s) { m_solver = &s; }
protected: protected:
solver& s() { return *m_solver; } solver& s() { return *m_solver; }
constraint_manager& cm();
public: public:
virtual ~explainer() {} virtual ~explainer() {}
virtual bool try_explain(pvar v, /* vector<signed_constraint> const& cjust_v, */ conflict_core& core) = 0; virtual bool try_explain(pvar v, /* vector<signed_constraint> const& cjust_v, */ conflict_core& core) = 0;

View file

@ -75,13 +75,14 @@ namespace polysat {
inline std::ostream& operator<<(std::ostream& out, search_state const& s) { return s.display(out); } inline std::ostream& operator<<(std::ostream& out, search_state const& s) { return s.display(out); }
// Go backwards over the search_state // Go backwards over the search_state.
// If new entries are added during processing an item, they will be queued for processing next after the current item.
class search_iterator { class search_iterator {
search_state* m_search; search_state* m_search;
unsigned current; unsigned current;
unsigned first; unsigned first; // highest index + 1
struct idx_range { struct idx_range {
unsigned current; unsigned current;
@ -89,22 +90,41 @@ namespace polysat {
}; };
vector<idx_range> m_index_stack; vector<idx_range> m_index_stack;
public: void init() {
search_iterator(search_state& search):
m_search(&search) {
first = m_search->size(); first = m_search->size();
current = first; // we start one before the beginning, then it also works for empty m_search current = first - 1;
} }
search_item const& operator*() const { void try_push_block() {
return (*m_search)[current]; if (first != m_search->size()) {
m_index_stack.push_back({current, first});
init();
}
}
void pop_block() {
current = m_index_stack.back().current;
first = m_index_stack.back().first;
m_index_stack.pop_back();
} }
unsigned last() { unsigned last() {
return m_index_stack.empty() ? 0 : m_index_stack.back().first; return m_index_stack.empty() ? 0 : m_index_stack.back().first;
} }
public:
search_iterator(search_state& search):
m_search(&search) {
init();
current++; // we start one before the beginning, then it also works for empty m_search
}
search_item const& operator*() const {
return (*m_search)[current];
}
bool next() { bool next() {
try_push_block();
if (current > last()) { if (current > last()) {
--current; --current;
return true; return true;
@ -113,21 +133,10 @@ namespace polysat {
SASSERT(current == last()); SASSERT(current == last());
if (m_index_stack.empty()) if (m_index_stack.empty())
return false; return false;
current = m_index_stack.back().current; pop_block();
first = m_index_stack.back().first;
m_index_stack.pop_back();
return true; return true;
} }
} }
// to be called after all saturations for a step are done
void push_block() {
if (first != m_search->size()) {
m_index_stack.push_back({current, first});
first = m_search->size();
current = first - 1;
}
}
}; };
} }

View file

@ -456,6 +456,7 @@ namespace polysat {
while (search_it.next()) { while (search_it.next()) {
LOG("Conflict: " << m_conflict); LOG("Conflict: " << m_conflict);
auto const& item = *search_it; auto const& item = *search_it;
LOG_H2("Working on " << item);
if (item.is_assignment()) { if (item.is_assignment()) {
// Resolve over variable assignment // Resolve over variable assignment
pvar v = item.var(); pvar v = item.var();
@ -477,7 +478,6 @@ namespace polysat {
// Resolve over boolean literal // Resolve over boolean literal
SASSERT(item.is_boolean()); SASSERT(item.is_boolean());
sat::literal const lit = item.lit(); sat::literal const lit = item.lit();
LOG_H2("Working on blit " << lit);
sat::bool_var const var = lit.var(); sat::bool_var const var = lit.var();
if (!m_conflict.is_bmarked(var)) if (!m_conflict.is_bmarked(var))
continue; continue;

View file

@ -62,6 +62,7 @@ namespace polysat {
friend class viable; friend class viable;
friend class assignment_pp; friend class assignment_pp;
friend class assignments_pp; friend class assignments_pp;
friend class ex_polynomial_superposition;
friend class inf_saturate; friend class inf_saturate;
friend class constraint_manager; friend class constraint_manager;

View file

@ -44,7 +44,7 @@ namespace polysat {
inequality as_inequality(bool is_positive) const override; inequality as_inequality(bool is_positive) const override;
unsigned hash() const override; unsigned hash() const override;
bool operator==(constraint const& other) const override; bool operator==(constraint const& other) const override;
bool is_eq() const { return m_rhs.is_zero(); } bool is_eq() const override { return m_rhs.is_zero(); }
pdd const& p() const { SASSERT(is_eq()); return m_lhs; } pdd const& p() const { SASSERT(is_eq()); return m_lhs; }
}; };