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:
parent
3c8c8f5d40
commit
7e7f88ae3d
4 changed files with 18 additions and 28 deletions
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue