mirror of
https://github.com/Z3Prover/z3
synced 2025-06-06 14:13:23 +00:00
outer loop, to continue search after recursive call
This commit is contained in:
parent
5d3a5a94e8
commit
590e9b0fb1
1 changed files with 105 additions and 104 deletions
|
@ -1619,132 +1619,133 @@ namespace polysat {
|
||||||
|
|
||||||
rational progress; // = 0
|
rational progress; // = 0
|
||||||
while (true) {
|
while (true) {
|
||||||
entry* e = nullptr;
|
while (true) {
|
||||||
|
entry* e = nullptr;
|
||||||
|
|
||||||
// try to make progress using any of the relevant interval lists
|
// try to make progress using any of the relevant interval lists
|
||||||
for (entry_cursor& ec : ecs) {
|
for (entry_cursor& ec : ecs) {
|
||||||
// advance until current value 'val'
|
// advance until current value 'val'
|
||||||
auto const [n, n_contains_val] = find_value(val, ec.cur);
|
auto const [n, n_contains_val] = find_value(val, ec.cur);
|
||||||
// display_one(std::cerr << "found entry n: ", 0, n) << "\n";
|
// display_one(std::cerr << "found entry n: ", 0, n) << "\n";
|
||||||
// LOG("n_contains_val: " << n_contains_val << " val = " << val);
|
// LOG("n_contains_val: " << n_contains_val << " val = " << val);
|
||||||
ec.cur = n;
|
ec.cur = n;
|
||||||
if (n_contains_val) {
|
if (n_contains_val) {
|
||||||
e = n;
|
e = n;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// when we cannot make progress by existing intervals any more, try interval from fixed bits
|
||||||
|
if (!e) {
|
||||||
|
e = refine_bits<true>(v, val, w, fbi);
|
||||||
|
if (e) {
|
||||||
|
refine_todo.push_back(e);
|
||||||
|
display_one(std::cerr << "found entry by bits: ", 0, e) << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no more progress on current layer
|
||||||
|
if (!e)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// when we cannot make progress by existing intervals any more, try interval from fixed bits
|
SASSERT(e->interval.currently_contains(val));
|
||||||
if (!e) {
|
rational const& new_val = e->interval.hi_val();
|
||||||
e = refine_bits<true>(v, val, w, fbi);
|
rational const dist = distance(val, new_val, mod_value);
|
||||||
if (e) {
|
SASSERT(dist > 0);
|
||||||
refine_todo.push_back(e);
|
val = new_val;
|
||||||
display_one(std::cerr << "found entry by bits: ", 0, e) << "\n";
|
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
|
||||||
|
// TODO: maybe we want to keep trying a bit longer to see if we can cover the whole domain. or maybe only if we enter this layer multiple times.
|
||||||
|
return l_undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
// (another way to compute 'progress')
|
||||||
|
SASSERT_EQ(progress, distance(to_cover_lo, val, mod_value));
|
||||||
}
|
}
|
||||||
|
|
||||||
// no more progress
|
// no more progress
|
||||||
if (!e)
|
// => 'val' is viable w.r.t. unit intervals until current layer
|
||||||
break;
|
|
||||||
|
|
||||||
SASSERT(e->interval.currently_contains(val));
|
if (!w_idx) {
|
||||||
rational const& new_val = e->interval.hi_val();
|
// we are at the lowest layer
|
||||||
rational const dist = distance(val, new_val, mod_value);
|
// => found viable value w.r.t. unit intervals and fixed bits
|
||||||
SASSERT(dist > 0);
|
return l_true;
|
||||||
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
|
|
||||||
// TODO: maybe we want to keep trying a bit longer to see if we can cover the whole domain. or maybe only if we enter this layer multiple times.
|
|
||||||
return l_undef;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// (another way to compute 'progress')
|
// find next covered value
|
||||||
SASSERT_EQ(progress, distance(to_cover_lo, val, mod_value));
|
rational next_val = to_cover_hi;
|
||||||
}
|
for (entry_cursor& ec : ecs) {
|
||||||
|
// each ec.cur is now the next interval after 'lo'
|
||||||
// no more progress
|
rational const& n = ec.cur->interval.lo_val();
|
||||||
// => 'val' is viable w.r.t. unit intervals until current layer
|
SASSERT(r_interval::contains(ec.cur->prev()->interval.hi_val(), n, val));
|
||||||
|
if (distance(val, n, mod_value) < distance(val, next_val, mod_value))
|
||||||
if (!w_idx) {
|
next_val = n;
|
||||||
// we are at the lowest layer
|
}
|
||||||
// => found viable value w.r.t. unit intervals and fixed bits
|
if (entry* e = refine_bits<false>(v, next_val, w, fbi)) {
|
||||||
return l_true;
|
refine_todo.push_back(e);
|
||||||
}
|
rational const& n = e->interval.lo_val();
|
||||||
|
SASSERT(distance(val, n, mod_value) < distance(val, next_val, mod_value));
|
||||||
// find next covered value
|
|
||||||
rational next_val = to_cover_hi;
|
|
||||||
for (entry_cursor& ec : ecs) {
|
|
||||||
// each ec.cur is now the next interval after 'lo'
|
|
||||||
rational const& n = ec.cur->interval.lo_val();
|
|
||||||
SASSERT(r_interval::contains(ec.cur->prev()->interval.hi_val(), n, val));
|
|
||||||
if (distance(val, n, mod_value) < distance(val, next_val, mod_value))
|
|
||||||
next_val = n;
|
next_val = n;
|
||||||
}
|
}
|
||||||
if (entry* e = refine_bits<false>(v, next_val, w, fbi)) {
|
SASSERT(!refine_bits<true>(v, val, w, fbi));
|
||||||
refine_todo.push_back(e);
|
SASSERT(val != next_val);
|
||||||
rational const& n = e->interval.lo_val();
|
|
||||||
SASSERT(distance(val, n, mod_value) < distance(val, next_val, mod_value));
|
|
||||||
next_val = n;
|
|
||||||
}
|
|
||||||
SASSERT(!refine_bits<true>(v, val, w, fbi));
|
|
||||||
SASSERT(val != next_val);
|
|
||||||
|
|
||||||
unsigned const lower_w = widths[w_idx - 1];
|
unsigned const lower_w = widths[w_idx - 1];
|
||||||
rational const lower_mod_value = rational::power_of_two(lower_w);
|
rational const lower_mod_value = rational::power_of_two(lower_w);
|
||||||
|
|
||||||
|
rational lower_cover_lo, lower_cover_hi;
|
||||||
|
if (distance(val, next_val, mod_value) >= lower_mod_value) {
|
||||||
|
// NOTE: in this case we do not get the first viable value, but the one with smallest value in the lower bits.
|
||||||
|
// this is because we start the search in the recursive case at 0.
|
||||||
|
// if this is a problem, adapt to lower_cover_lo = mod(val, lower_mod_value), lower_cover_hi = ...
|
||||||
|
lower_cover_lo = 0;
|
||||||
|
lower_cover_hi = lower_mod_value;
|
||||||
|
rational a;
|
||||||
|
lbool result = find_on_layer(v, w_idx - 1, widths, overlaps, fbi, lower_cover_lo, lower_cover_hi, a, refine_todo);
|
||||||
|
VERIFY(result != l_undef);
|
||||||
|
if (result == l_false)
|
||||||
|
return l_false; // conflict
|
||||||
|
SASSERT(result == l_true);
|
||||||
|
// replace lower bits of 'val' by 'a'
|
||||||
|
rational const val_lower = mod(val, lower_mod_value);
|
||||||
|
val = val - val_lower + a;
|
||||||
|
if (a < val_lower)
|
||||||
|
a += lower_mod_value;
|
||||||
|
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));
|
||||||
|
return l_true;
|
||||||
|
}
|
||||||
|
|
||||||
|
lower_cover_lo = mod(val, lower_mod_value);
|
||||||
|
lower_cover_hi = mod(next_val, lower_mod_value);
|
||||||
|
|
||||||
rational lower_cover_lo, lower_cover_hi;
|
|
||||||
if (distance(val, next_val, mod_value) >= lower_mod_value) {
|
|
||||||
// NOTE: in this case we do not get the first viable value, but the one with smallest value in the lower bits.
|
|
||||||
// this is because we start the search in the recursive case at 0.
|
|
||||||
// if this is a problem, adapt to lower_cover_lo = mod(val, lower_mod_value), lower_cover_hi = ...
|
|
||||||
lower_cover_lo = 0;
|
|
||||||
lower_cover_hi = lower_mod_value;
|
|
||||||
rational a;
|
rational a;
|
||||||
lbool result = find_on_layer(v, w_idx - 1, widths, overlaps, fbi, lower_cover_lo, lower_cover_hi, a, refine_todo);
|
lbool result = find_on_layer(v, w_idx - 1, widths, overlaps, fbi, lower_cover_lo, lower_cover_hi, a, refine_todo);
|
||||||
VERIFY(result != l_undef);
|
|
||||||
if (result == l_false)
|
if (result == l_false)
|
||||||
return l_false; // conflict
|
return l_false; // conflict
|
||||||
SASSERT(result == l_true);
|
|
||||||
// replace lower bits of 'val' by 'a'
|
// replace lower bits of 'val' by 'a'
|
||||||
rational const val_lower = mod(val, lower_mod_value);
|
rational const dist = distance(lower_cover_lo, a, lower_mod_value);
|
||||||
val = val - val_lower + a;
|
val += dist;
|
||||||
if (a < val_lower)
|
progress += dist;
|
||||||
a += lower_mod_value;
|
|
||||||
LOG("distance(val, cover_hi) = " << distance(val, to_cover_hi, mod_value));
|
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));
|
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));
|
||||||
return l_true;
|
|
||||||
|
if (result == l_true)
|
||||||
|
return l_true; // done
|
||||||
|
|
||||||
|
SASSERT(result == l_undef);
|
||||||
|
// TODO: continue with intervals at current level
|
||||||
}
|
}
|
||||||
|
|
||||||
lower_cover_lo = mod(val, lower_mod_value);
|
|
||||||
lower_cover_hi = mod(next_val, lower_mod_value);
|
|
||||||
|
|
||||||
rational a;
|
|
||||||
lbool result = find_on_layer(v, w_idx - 1, widths, overlaps, fbi, lower_cover_lo, lower_cover_hi, a, refine_todo);
|
|
||||||
if (result == l_false)
|
|
||||||
return l_false; // conflict
|
|
||||||
|
|
||||||
// replace lower bits of 'val' by 'a'
|
|
||||||
rational const dist = distance(lower_cover_lo, a, lower_mod_value);
|
|
||||||
val += dist;
|
|
||||||
progress += dist;
|
|
||||||
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));
|
|
||||||
|
|
||||||
if (result == l_true)
|
|
||||||
return l_true; // done
|
|
||||||
|
|
||||||
SASSERT(result == l_undef);
|
|
||||||
// TODO: continue with intervals at current level
|
|
||||||
|
|
||||||
NOT_IMPLEMENTED_YET();
|
NOT_IMPLEMENTED_YET();
|
||||||
return l_undef;
|
return l_undef;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue