3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 09:05:31 +00:00

check for viable assignment

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2024-01-11 13:02:40 -08:00
parent a2df3cb828
commit 3d33d28f8c
3 changed files with 53 additions and 14 deletions

View file

@ -363,6 +363,12 @@ namespace polysat {
void core::propagate_assignment(pvar v, rational const& value, dependency dep) {
TRACE("bv", tout << "propagate assignment v" << v << " := " << value << "\n");
SASSERT(!is_assigned(v));
if (!m_viable.assign(v, value)) {
auto deps = m_viable.explain();
deps.push_back(dep);
s.set_conflict(deps, "non-viable assignment");
return;
}
m_values[v] = value;
m_justification[v] = dep;
m_assignment.push(v , value);

View file

@ -83,21 +83,42 @@ namespace polysat {
return e;
}
bool viable::assign(pvar v, rational const& value) {
m_var = v;
m_explain_kind = explain_t::none;
m_num_bits = c.size(v);
m_fixed_bits.init(v);
init_overlaps(v);
check_fixed_bits(v, value);
check_disequal_lin(v, value);
check_equal_lin(v, value);
for (auto const& [w, offset] : m_overlaps) {
for (auto& layer : m_units[w].get_layers()) {
entry* e = find_overlap(w, layer, value);
if (!e)
continue;
m_explain.push_back({ e, value });
m_explain_kind = explain_t::assignment;
return false;
}
}
return true;
}
find_t viable::find_viable(pvar v, rational& lo) {
m_explain.reset();
m_var = v;
m_num_bits = c.size(v);
m_fixed_bits.init(v);
init_overlaps(v);
m_conflict = false;
m_propagation = false;
m_explain_kind = explain_t::none;
for (unsigned rounds = 0; rounds < 10; ) {
auto n = find_overlap(lo);
if (m_conflict)
if (m_explain_kind == explain_t::conflict)
return find_t::empty;
if (n)
@ -111,7 +132,7 @@ namespace polysat {
if (!check_equal_lin(v, lo))
continue;
if (is_propagation(lo)) {
m_propagation = true;
m_explain_kind = explain_t::propagation;
return find_t::singleton;
}
return find_t::multiple;
@ -146,7 +167,7 @@ namespace polysat {
update_value_to_high(val, e);
m_explain.push_back({ e, val });
if (is_conflict()) {
m_conflict = true;
m_explain_kind = explain_t::conflict;
return nullptr;
}
}
@ -154,7 +175,7 @@ namespace polysat {
return last;
}
viable::entry* viable::find_overlap(pvar w, layer& l, rational& val) {
viable::entry* viable::find_overlap(pvar w, layer& l, rational const& val) {
if (!l.entries)
return nullptr;
unsigned v_width = m_num_bits;
@ -539,7 +560,7 @@ namespace polysat {
return result;
}
SASSERT(m_conflict || m_propagation);
SASSERT(m_explain_kind != explain_t::none);
for (unsigned i = m_explain.size() - 1; i-- > 0; ) {
auto e = m_explain[i];
@ -549,7 +570,7 @@ namespace polysat {
if (e.e == last.e)
break;
}
if (m_propagation) {
if (m_explain_kind == explain_t::propagation) {
// assume first and last have same bit-width
auto first = m_explain[0];
SASSERT(first.e->bit_width == last.e->bit_width);
@ -558,6 +579,11 @@ namespace polysat {
auto sc = cs.eq(last.e->interval.hi() + 1, first.e->interval.lo());
result.push_back(c.propagate(sc, c.explain_weak_eval(sc)));
}
if (m_explain_kind == explain_t::assignment) {
// there is just one entry
SASSERT(m_explain.size() == 1);
explain_entry(last.e);
}
unmark();
return result;
}

View file

@ -115,19 +115,16 @@ namespace polysat {
bool intersect(pvar v, entry* e);
lbool find_viable(pvar v, rational& val1, rational& val2);
// find the first non-fixed entry that overlaps with val, if any.
entry* find_overlap(rational& val);
entry* find_overlap(pvar w, rational& val);
entry* find_overlap(pvar w, layer& l, rational& val);
entry* find_overlap(pvar w, layer& l, rational const& val);
void update_value_to_high(rational& val, entry* e);
bool is_conflict();
void explain_overlap(explanation const& e, explanation const& after, dependency_vector& deps);
lbool next_viable_layer(pvar w, layer& l, rational& val);
viable::entry* find_overlap(rational const& val, entry* entries);
bool check_disequal_lin(pvar v, rational const& val);
@ -138,9 +135,14 @@ namespace polysat {
bool is_propagation(rational const& val);
enum class explain_t {
conflict,
propagation,
assignment,
none
};
pvar m_var = null_var;
bool m_conflict = false;
bool m_propagation = false;
explain_t m_explain_kind = explain_t::none;
unsigned m_num_bits = 0;
fixed_bits m_fixed_bits;
offset_slices m_overlaps;
@ -173,6 +175,11 @@ namespace polysat {
*/
void ensure_var(pvar v);
/*
* Check if assignment is viable.
*/
bool assign(pvar v, rational const& value);
std::ostream& display(std::ostream& out) const;