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:
parent
a2df3cb828
commit
3d33d28f8c
3 changed files with 53 additions and 14 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue