3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-25 18:15:32 +00:00

fix backtracking from fi

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2021-09-15 09:28:59 +01:00
parent 3c8c8f5d40
commit 7e7f88ae3d
4 changed files with 18 additions and 28 deletions

View file

@ -240,20 +240,10 @@ namespace polysat {
return false; return false;
if (conflict_var() == v) { if (conflict_var() == v) {
clause_builder lemma(s());
forbidden_intervals fi; forbidden_intervals fi;
if (fi.perform(s(), v, cjust_v, lemma)) { if (fi.perform(s(), v, cjust_v, *this))
// TODO: pass core to FI instead of a clause_builder?
reset();
for (auto lit : lemma) {
auto c = cm().lookup(lit);
insert(~c);
}
set_bailout();
return true; return true;
} }
// TODO: add a dummy value for v?
}
m_vars.remove(v); m_vars.remove(v);

View file

@ -18,7 +18,6 @@ move "forbidden interval method from constraints
--*/ --*/
#include "math/polysat/forbidden_intervals.h" #include "math/polysat/forbidden_intervals.h"
#include "math/polysat/clause_builder.h"
#include "math/polysat/interval.h" #include "math/polysat/interval.h"
#include "math/polysat/log.h" #include "math/polysat/log.h"
@ -73,13 +72,15 @@ namespace polysat {
* We assume that neg_cond is a consequence of src that * We assume that neg_cond is a consequence of src that
* does not mention the variable v to be eliminated. * does not mention the variable v to be eliminated.
*/ */
void forbidden_intervals::full_interval_conflict(signed_constraint src, signed_constraint neg_cond, clause_builder& lemma) { void forbidden_intervals::full_interval_conflict(signed_constraint src, signed_constraint neg_cond, conflict_core& core) {
SASSERT(neg_cond); SASSERT(neg_cond);
lemma.push_new(neg_cond); core.reset();
lemma.push(~src); core.insert(~neg_cond);
core.insert(src);
core.set_bailout();
} }
bool forbidden_intervals::perform(solver& s, pvar v, vector<signed_constraint> const& just, clause_builder& lemma) { bool forbidden_intervals::perform(solver& s, pvar v, vector<signed_constraint> const& just, conflict_core& core) {
// Extract forbidden intervals from conflicting constraints // Extract forbidden intervals from conflicting constraints
vector<fi_record> records; vector<fi_record> records;
@ -97,7 +98,7 @@ namespace polysat {
if (interval.is_full()) { if (interval.is_full()) {
// We have a single interval covering the whole domain // We have a single interval covering the whole domain
// => the side conditions of that interval are enough to produce a conflict // => the side conditions of that interval are enough to produce a conflict
full_interval_conflict(c, neg_cond, lemma); full_interval_conflict(c, neg_cond, core);
return true; return true;
} }
else { else {
@ -131,9 +132,6 @@ namespace polysat {
LOG("seq: " << seq); LOG("seq: " << seq);
SASSERT(seq.size() >= 2); // otherwise has_full should have been true SASSERT(seq.size() >= 2); // otherwise has_full should have been true
// TODO lemma level depends on clauses used to derive it, not on levels of constraints
unsigned lemma_lvl = 0;
// Update the conflict state // Update the conflict state
// Idea: // Idea:
// - If the src constraints hold, and // - If the src constraints hold, and
@ -142,6 +140,7 @@ namespace polysat {
// then the forbidden intervals cover the whole domain and we have a conflict. // then the forbidden intervals cover the whole domain and we have a conflict.
// //
core.reset();
// Add side conditions and interval constraints // Add side conditions and interval constraints
for (unsigned seq_i = seq.size(); seq_i-- > 0; ) { for (unsigned seq_i = seq.size(); seq_i-- > 0; ) {
unsigned const i = seq[seq_i]; unsigned const i = seq[seq_i];
@ -158,15 +157,16 @@ namespace polysat {
// the level of a literal is when it was assigned. Lemmas could have unassigned literals. // the level of a literal is when it was assigned. Lemmas could have unassigned literals.
signed_constraint c = s.m_constraints.ult(lhs, rhs); signed_constraint c = s.m_constraints.ult(lhs, rhs);
LOG("constraint: " << c); LOG("constraint: " << c);
lemma.push_new(~c); core.insert(c);
// Side conditions // Side conditions
// TODO: check whether the condition is subsumed by c? maybe at the end do a "lemma reduction" step, to try and reduce branching? // TODO: check whether the condition is subsumed by c? maybe at the end do a "lemma reduction" step, to try and reduce branching?
signed_constraint& neg_cond = records[i].neg_cond; signed_constraint& neg_cond = records[i].neg_cond;
if (neg_cond) if (neg_cond)
lemma.push_new(std::move(neg_cond)); core.insert(~neg_cond);
lemma.push(~records[i].src); core.insert(records[i].src);
} }
core.set_bailout();
return true; return true;
} }

View file

@ -20,9 +20,9 @@ Author:
namespace polysat { namespace polysat {
class forbidden_intervals { class forbidden_intervals {
void full_interval_conflict(signed_constraint c, signed_constraint neg_cond, clause_builder& lemma); void full_interval_conflict(signed_constraint c, signed_constraint neg_cond, conflict_core& core);
bool get_interval(solver& s, signed_constraint const& c, pvar v, eval_interval& out_interval, signed_constraint& out_neg_cond); bool get_interval(solver& s, signed_constraint const& c, pvar v, eval_interval& out_interval, signed_constraint& out_neg_cond);
public: public:
bool perform(solver& s, pvar v, vector<signed_constraint> const& just, clause_builder& lemma); bool perform(solver& s, pvar v, vector<signed_constraint> const& just, conflict_core& core);
}; };
} }

View file

@ -467,7 +467,7 @@ namespace polysat {
if (item.is_assignment()) { if (item.is_assignment()) {
// Resolve over variable assignment // Resolve over variable assignment
pvar v = item.var(); pvar v = item.var();
if (!m_conflict.is_pmarked(v)) if (!m_conflict.is_pmarked(v) && !m_conflict.is_bailout())
continue; continue;
justification& j = m_justification[v]; justification& j = m_justification[v];
LOG("Justification: " << j); LOG("Justification: " << j);