mirror of
https://github.com/Z3Prover/z3
synced 2025-06-06 06:03:23 +00:00
find_on_layer: fixed bits refinement
This commit is contained in:
parent
6fa3af29c6
commit
91a47b262b
2 changed files with 40 additions and 7 deletions
|
@ -429,7 +429,7 @@ namespace polysat {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool FORWARD>
|
template <bool FORWARD>
|
||||||
bool viable::refine_viable(pvar v, rational const& val, fixed_bits_info const& fbi) {
|
bool viable::refine_viable(pvar v, rational const& val, fixed_bits_info const& fbi) {
|
||||||
return refine_bits<FORWARD>(v, val, fbi) && refine_equal_lin(v, val) && refine_disequal_lin(v, val);
|
return refine_bits<FORWARD>(v, val, fbi) && refine_equal_lin(v, val) && refine_disequal_lin(v, val);
|
||||||
}
|
}
|
||||||
|
@ -1461,7 +1461,7 @@ namespace polysat {
|
||||||
|
|
||||||
rational const& max_value = s.var2pdd(v).max_value();
|
rational const& max_value = s.var2pdd(v).max_value();
|
||||||
|
|
||||||
lbool result_lo = find_on_layer(widths.size() - 1, widths, overlaps, fbi, rational::zero(), max_value, lo);
|
lbool result_lo = find_on_layer(v, widths.size() - 1, widths, overlaps, fbi, rational::zero(), max_value, lo);
|
||||||
if (result_lo == l_false)
|
if (result_lo == l_false)
|
||||||
return l_false; // conflict
|
return l_false; // conflict
|
||||||
if (result_lo == l_undef)
|
if (result_lo == l_undef)
|
||||||
|
@ -1472,7 +1472,7 @@ namespace polysat {
|
||||||
return l_true;
|
return l_true;
|
||||||
}
|
}
|
||||||
|
|
||||||
lbool result_hi = find_on_layer(widths.size() - 1, widths, overlaps, fbi, lo + 1, max_value, hi);
|
lbool result_hi = find_on_layer(v, widths.size() - 1, widths, overlaps, fbi, lo + 1, max_value, hi);
|
||||||
if (result_hi == l_false)
|
if (result_hi == l_false)
|
||||||
hi = lo; // no other viable value
|
hi = lo; // no other viable value
|
||||||
if (result_hi == l_undef)
|
if (result_hi == l_undef)
|
||||||
|
@ -1506,11 +1506,12 @@ namespace polysat {
|
||||||
}
|
}
|
||||||
|
|
||||||
// find viable values in half-open interval [to_cover_lo;to_cover_hi[ w.r.t. unit intervals on the given layer
|
// find viable values in half-open interval [to_cover_lo;to_cover_hi[ w.r.t. unit intervals on the given layer
|
||||||
lbool viable::find_on_layer(unsigned w_idx, unsigned_vector const& widths, pvar_vector const& overlaps, fixed_bits_info const& fbi, rational const& to_cover_lo, rational const& to_cover_hi, rational& val) {
|
lbool viable::find_on_layer(pvar v, unsigned w_idx, unsigned_vector const& widths, pvar_vector const& overlaps, fixed_bits_info const& fbi, rational const& to_cover_lo, rational const& to_cover_hi, rational& val) {
|
||||||
|
|
||||||
unsigned const w = widths[w_idx];
|
unsigned const w = widths[w_idx];
|
||||||
rational const& mod_value = rational::power_of_two(w);
|
rational const& mod_value = rational::power_of_two(w);
|
||||||
|
|
||||||
|
LOG("layer " << w << " bits, to_cover: [" << to_cover_lo << "; " << to_cover_hi << "[");
|
||||||
SASSERT(0 <= to_cover_lo);
|
SASSERT(0 <= to_cover_lo);
|
||||||
SASSERT(0 <= to_cover_hi);
|
SASSERT(0 <= to_cover_hi);
|
||||||
SASSERT(to_cover_lo < mod_value);
|
SASSERT(to_cover_lo < mod_value);
|
||||||
|
@ -1543,6 +1544,7 @@ namespace polysat {
|
||||||
if (s.size(x) < w) // note that overlaps are sorted by variable size descending
|
if (s.size(x) < w) // note that overlaps are sorted by variable size descending
|
||||||
break;
|
break;
|
||||||
if (entry* e = m_units[x].get_entries(w)) {
|
if (entry* e = m_units[x].get_entries(w)) {
|
||||||
|
display_all(std::cerr << "units for width " << w << ":\n", 0, e, "\n");
|
||||||
entry_cursor ec;
|
entry_cursor ec;
|
||||||
ec.cur = e;
|
ec.cur = e;
|
||||||
// ec.first = nullptr;
|
// ec.first = nullptr;
|
||||||
|
@ -1554,6 +1556,9 @@ namespace polysat {
|
||||||
rational const to_cover_len = r_interval::len(to_cover_lo, to_cover_hi, mod_value);
|
rational const to_cover_len = r_interval::len(to_cover_lo, to_cover_hi, mod_value);
|
||||||
val = to_cover_lo;
|
val = to_cover_lo;
|
||||||
|
|
||||||
|
// TODO: for each e in refine_todo, intersect(v, e);
|
||||||
|
svector<std::pair<pvar, entry*>> refine_todo;
|
||||||
|
|
||||||
rational progress; // = 0
|
rational progress; // = 0
|
||||||
rational old_progress;
|
rational old_progress;
|
||||||
do {
|
do {
|
||||||
|
@ -1563,12 +1568,15 @@ namespace polysat {
|
||||||
for (entry_cursor& ec : ecs) {
|
for (entry_cursor& ec : ecs) {
|
||||||
// advance until current value 'val'
|
// advance until current value 'val'
|
||||||
auto const [e, e_contains_val] = find_value(val, ec.cur);
|
auto const [e, e_contains_val] = find_value(val, ec.cur);
|
||||||
|
// display_one(std::cerr << "found entry e: ", 0, e) << "\n";
|
||||||
|
// LOG("e_contains_val: " << e_contains_val << " val = " << val);
|
||||||
ec.cur = e;
|
ec.cur = e;
|
||||||
if (e_contains_val) {
|
if (e_contains_val) {
|
||||||
rational const& new_val = e->interval.hi_val();
|
rational const& new_val = e->interval.hi_val();
|
||||||
rational const dist = distance(val, new_val, mod_value);
|
rational const dist = distance(val, new_val, mod_value);
|
||||||
val = new_val;
|
val = new_val;
|
||||||
progress += dist;
|
progress += dist;
|
||||||
|
LOG("val: " << val << " progress: " << progress);
|
||||||
if (progress >= mod_value) {
|
if (progress >= mod_value) {
|
||||||
// covered the whole domain => conflict
|
// covered the whole domain => conflict
|
||||||
return l_false;
|
return l_false;
|
||||||
|
@ -1587,8 +1595,29 @@ namespace polysat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check (virtual) fixed-bits interval
|
// if we make no more progress by existing intervals, try interval from fixed bits
|
||||||
|
if (progress == old_progress) {
|
||||||
|
if (entry* e = refine_bits<true>(v, val, w, fbi)) {
|
||||||
|
refine_todo.push_back({v, e});
|
||||||
|
SASSERT(e->interval.currently_contains(val));
|
||||||
|
rational const& new_val = e->interval.hi_val();
|
||||||
|
LOG("by bits: " << val << " -> " << new_val);
|
||||||
|
rational const dist = distance(val, new_val, mod_value);
|
||||||
|
val = new_val;
|
||||||
|
progress += dist;
|
||||||
|
LOG("val: " << val << " progress: " << progress);
|
||||||
|
if (progress >= mod_value) {
|
||||||
|
// covered the whole domain => conflict
|
||||||
|
return l_false;
|
||||||
|
}
|
||||||
|
if (progress >= to_cover_len) {
|
||||||
|
// we covered the hole left at larger bit-width
|
||||||
|
return l_undef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG("old_progress: " << old_progress << " progress: " << progress);
|
||||||
} while (old_progress != progress);
|
} while (old_progress != progress);
|
||||||
|
|
||||||
// no more progress
|
// no more progress
|
||||||
|
@ -1624,12 +1653,16 @@ namespace polysat {
|
||||||
}
|
}
|
||||||
|
|
||||||
rational a;
|
rational a;
|
||||||
lbool result = find_on_layer(w_idx - 1, widths, overlaps, fbi, lower_cover_lo, lower_cover_hi, a);
|
lbool result = find_on_layer(v, w_idx - 1, widths, overlaps, fbi, lower_cover_lo, lower_cover_hi, a);
|
||||||
if (result == l_false)
|
if (result == l_false)
|
||||||
return l_false; // conflict
|
return l_false; // conflict
|
||||||
|
|
||||||
// replace lower bits of 'val' by 'a'
|
// replace lower bits of 'val' by 'a'
|
||||||
|
// LOG("old val: " << val);
|
||||||
val = val - lower_cover_lo + a;
|
val = val - lower_cover_lo + a;
|
||||||
|
// LOG("new val: " << val);
|
||||||
|
LOG("distance(val, cover_hi) = " << distance(val, to_cover_hi, mod_value));
|
||||||
|
LOG("distance(next_val, cover_hi) = " << distance(next_val, to_cover_hi, mod_value));
|
||||||
SASSERT(distance(val, to_cover_hi, mod_value) >= distance(next_val, to_cover_hi, mod_value));
|
SASSERT(distance(val, to_cover_hi, mod_value) >= distance(next_val, to_cover_hi, mod_value));
|
||||||
|
|
||||||
if (result == l_true)
|
if (result == l_true)
|
||||||
|
|
|
@ -205,7 +205,7 @@ namespace polysat {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
lbool find_viable2_new(pvar v, rational& out_lo, rational& out_hi);
|
lbool find_viable2_new(pvar v, rational& out_lo, rational& out_hi);
|
||||||
lbool find_on_layer(unsigned w_idx, unsigned_vector const& widths, pvar_vector const& overlaps, fixed_bits_info const& fbi, rational const& to_cover_lo, rational const& to_cover_hi, rational& out_val);
|
lbool find_on_layer(pvar v, unsigned w_idx, unsigned_vector const& widths, pvar_vector const& overlaps, fixed_bits_info const& fbi, rational const& to_cover_lo, rational const& to_cover_hi, rational& out_val);
|
||||||
|
|
||||||
std::pair<entry*, bool> find_value(rational const& val, entry* entries);
|
std::pair<entry*, bool> find_value(rational const& val, entry* entries);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue