3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-06 01:24:08 +00:00

fixes to bv-sls

This commit is contained in:
Nikolaj Bjorner 2024-04-07 14:24:13 -07:00
parent d7c0e17f96
commit bab7ca2b70
8 changed files with 279 additions and 286 deletions

View file

@ -124,6 +124,7 @@ namespace bv {
};
m_eval.init_eval(m_terms.assertions(), eval);
init_repair();
// m_engine_init = false;
}
std::pair<bool, app*> sls::next_to_repair() {
@ -161,17 +162,18 @@ namespace bv {
lbool sls::search1() {
// init and init_eval were invoked
unsigned n = 0;
for (; n++ < m_config.m_max_repairs && m.inc(); ) {
for (; n < m_config.m_max_repairs && m.inc(); ) {
auto [down, e] = next_to_repair();
if (!e)
return l_true;
trace_repair(down, e);
IF_VERBOSE(20, trace_repair(down, e));
++m_stats.m_moves;
if (down)
if (down) {
try_repair_down(e);
++n;
}
else
try_repair_up(e);
}
@ -181,12 +183,13 @@ namespace bv {
lbool sls::search2() {
lbool res = l_undef;
if (m_stats.m_restarts == 0)
res = m_engine();
res = m_engine(),
m_engine_init = true;
else if (m_stats.m_restarts % 1000 == 0)
res = m_engine.search_loop();
res = m_engine.search_loop(),
m_engine_init = true;
if (res != l_undef)
m_engine_model = true;
m_engine_init = true;
return res;
}
@ -203,7 +206,7 @@ namespace bv {
if (res != l_undef)
break;
trace();
// res = search2();
//res = search2();
if (res != l_undef)
break;
reinit_eval();
@ -223,6 +226,7 @@ namespace bv {
VERIFY(m_eval.wval(e).commit_eval());
}
IF_VERBOSE(3, verbose_stream() << "done\n");
for (auto p : m_terms.parents(e))
m_repair_up.insert(p->get_id());
@ -256,6 +260,7 @@ namespace bv {
}
}
}
IF_VERBOSE(3, verbose_stream() << "init-repair " << mk_bounded_pp(e, m) << "\n");
// repair was not successful, so reset the state to find a different way to repair
init_repair();
}
@ -265,7 +270,7 @@ namespace bv {
if (m_terms.is_assertion(e))
m_repair_roots.insert(e->get_id());
else if (!m_eval.repair_up(e)) {
//m_repair_roots.insert(e->get_id());
IF_VERBOSE(2, verbose_stream() << "repair-up "; trace_repair(true, e));
init_repair();
}
else {
@ -366,14 +371,14 @@ namespace bv {
m_engine.updt_params(q);
}
void sls::trace_repair(bool down, expr* e) {
IF_VERBOSE(20,
std::ostream& sls::trace_repair(bool down, expr* e) {
verbose_stream() << (down ? "d #" : "u #")
<< e->get_id() << ": "
<< mk_bounded_pp(e, m, 1) << " ";
if (bv.is_bv(e)) verbose_stream() << m_eval.wval(e) << " " << (m_eval.is_fixed0(e) ? "fixed " : " ");
if (m.is_bool(e)) verbose_stream() << m_eval.bval0(e) << " ";
verbose_stream() << "\n");
verbose_stream() << "\n";
return verbose_stream();
}
void sls::trace() {

View file

@ -68,7 +68,7 @@ namespace bv {
void reinit_eval();
void init_repair();
void trace();
void trace_repair(bool down, expr* e);
std::ostream& trace_repair(bool down, expr* e);
indexed_uint_set m_to_repair;
void init_repair_candidates();

View file

@ -1351,55 +1351,18 @@ namespace bv {
return false;
}
bool sls_eval::try_repair_ashr(bvect const& e, bvval & a, bvval& b, unsigned i) {
if (true) {
bool sls_eval::try_repair_ashr(bvect const& e, bvval & a, bvval& b, unsigned i) {
if (i == 0)
return try_repair_ashr0(e, a, b);
else
return try_repair_ashr1(e, a, b);
}
if (i == 0) {
unsigned sh = b.to_nat(b.bw);
if (sh == 0)
return a.try_set(e);
else if (sh >= b.bw) {
if (e.get(a.bw - 1))
return a.try_set_bit(a.bw - 1, true);
else
return a.try_set_bit(a.bw - 1, false);
}
else {
// e = a >> sh
// a[bw-1:sh] = e[bw-sh-1:0]
// a[sh-1:0] = a[sh-1:0]
// ignore sign
for (unsigned i = sh; i < a.bw; ++i)
m_tmp.set(i, e.get(i - sh));
for (unsigned i = 0; i < sh; ++i)
m_tmp.set(i, a.get_bit(i));
a.clear_overflow_bits(m_tmp);
return a.try_set(m_tmp);
}
}
else {
// NB. blind sub-range of possible values for b
SASSERT(i == 1);
unsigned sh = m_rand(a.bw + 1);
b.set(m_tmp, sh);
return b.try_set(m_tmp);
}
}
bool sls_eval::try_repair_lshr(bvect const& e, bvval& a, bvval& b, unsigned i) {
#if 0
return try_repair_ashr(e, a, b, i);
#else
if (i == 0)
return try_repair_lshr0(e, a, b);
else
return try_repair_lshr1(e, a, b);
#endif
}
/**
@ -1427,22 +1390,25 @@ namespace bv {
return true;
}
unsigned sh = b.to_nat(b.bw);
if (sh == 0 && a.try_set(e))
return true;
else if (sh >= b.bw)
return true;
else if (sh < b.bw && m_rand(20) != 0) {
// e = a >> sh
// a[bw-1:sh] = e[bw-sh-1:0]
// a[sh-1:0] = a[sh-1:0]
for (unsigned i = sh; i < a.bw; ++i)
t.set(i, e.get(i - sh));
for (unsigned i = 0; i < sh; ++i)
t.set(i, a.get_bit(i));
a.clear_overflow_bits(t);
if (a.try_set(t))
if (m_rand(20) != 0) {
if (sh == 0 && a.try_set(e))
return true;
else if (sh >= b.bw)
return true;
else if (sh < b.bw && m_rand(20) != 0) {
// e = a >> sh
// a[bw-1:sh] = e[bw-sh-1:0]
// a[sh-1:0] = a[sh-1:0]
for (unsigned i = sh; i < a.bw; ++i)
t.set(i, e.get(i - sh));
for (unsigned i = 0; i < sh; ++i)
t.set(i, a.get_bit(i));
a.clear_overflow_bits(t);
if (a.try_set(t))
return true;
}
}
//bool r = try_repair_ashr(e, a, const_cast<bvval&>(b), 0);

View file

@ -53,7 +53,7 @@ namespace bv {
// s <=s t <=> s + K <= t + K, K = 2^{bw-1}
void sls_fixed::init_range(app* e, bool sign) {
bool sls_fixed::init_range(app* e, bool sign) {
expr* s, * t, * x, * y;
rational a, b;
unsigned idx;
@ -64,63 +64,116 @@ namespace bv {
if (bv.is_ule(e, s, t)) {
get_offset(s, x, a);
get_offset(t, y, b);
init_range(x, a, y, b, sign);
return init_range(x, a, y, b, sign);
}
else if (bv.is_ult(e, s, t)) {
get_offset(s, x, a);
get_offset(t, y, b);
init_range(y, b, x, a, !sign);
return init_range(y, b, x, a, !sign);
}
else if (bv.is_uge(e, s, t)) {
get_offset(s, x, a);
get_offset(t, y, b);
init_range(y, b, x, a, sign);
return init_range(y, b, x, a, sign);
}
else if (bv.is_ugt(e, s, t)) {
get_offset(s, x, a);
get_offset(t, y, b);
init_range(x, a, y, b, !sign);
return init_range(x, a, y, b, !sign);
}
else if (bv.is_sle(e, s, t)) {
get_offset(s, x, a);
get_offset(t, y, b);
init_range(x, a + N(s), y, b + N(s), sign);
return init_range(x, a + N(s), y, b + N(s), sign);
}
else if (bv.is_slt(e, s, t)) {
get_offset(s, x, a);
get_offset(t, y, b);
init_range(y, b + N(s), x, a + N(s), !sign);
return init_range(y, b + N(s), x, a + N(s), !sign);
}
else if (bv.is_sge(e, s, t)) {
get_offset(s, x, a);
get_offset(t, y, b);
init_range(y, b + N(s), x, a + N(s), sign);
return init_range(y, b + N(s), x, a + N(s), sign);
}
else if (bv.is_sgt(e, s, t)) {
get_offset(s, x, a);
get_offset(t, y, b);
init_range(x, a + N(s), y, b + N(s), !sign);
return init_range(x, a + N(s), y, b + N(s), !sign);
}
else if (!sign && m.is_eq(e, s, t)) {
else if (m.is_eq(e, s, t)) {
if (bv.is_numeral(s, a))
// t - a <= 0
init_range(t, -a, nullptr, rational(0), false);
init_eq(t, a, sign);
else if (bv.is_numeral(t, a))
init_range(s, -a, nullptr, rational(0), false);
}
else if (sign && m.is_eq(e, s, t)) {
if (bv.is_numeral(s, a))
// 1 <= t - a
init_range(nullptr, rational(1), t, -a, false);
else if (bv.is_numeral(t, a))
init_range(nullptr, rational(1), s, -a, false);
init_eq(s, a, sign);
else
return false;
return true;
}
else if (bv.is_bit2bool(e, s, idx)) {
auto& val = wval(s);
val.try_set_bit(idx, !sign);
val.fixed.set(idx, true);
val.tighten_range();
return true;
}
return false;
}
bool sls_fixed::init_eq(expr* t, rational const& a, bool sign) {
unsigned lo, hi;
rational b(0);
// verbose_stream() << mk_bounded_pp(t, m) << " == " << a << "\n";
expr* s = nullptr;
if (sign)
// 1 <= t - a
init_range(nullptr, rational(1), t, -a, false);
else
// t - a <= 0
init_range(t, -a, nullptr, rational::zero(), false);
if (!sign && bv.is_bv_not(t, s)) {
for (unsigned i = 0; i < bv.get_bv_size(s); ++i)
if (!a.get_bit(i))
b += rational::power_of_two(i);
init_eq(s, b, false);
return true;
}
if (!sign && bv.is_concat(t) && to_app(t)->get_num_args() == 2) {
auto x = to_app(t)->get_arg(0);
auto y = to_app(t)->get_arg(1);
auto sz = bv.get_bv_size(y);
auto k = rational::power_of_two(sz);
init_eq(y, mod(a, k), false);
init_eq(x, div(a + k - 1, k), false);
return true;
}
if (bv.is_extract(t, lo, hi, s)) {
if (hi == lo) {
sign = sign ? a == 1 : a == 0;
auto& val = wval(s);
if (val.try_set_bit(lo, !sign))
val.fixed.set(lo, true);
val.tighten_range();
}
else if (!sign) {
auto& val = wval(s);
for (unsigned i = lo; i <= hi; ++i)
if (val.try_set_bit(i, a.get_bit(i - lo)))
val.fixed.set(i, true);
val.tighten_range();
// verbose_stream() << lo << " " << hi << " " << val << " := " << a << "\n";
}
if (!sign && hi + 1 == bv.get_bv_size(s)) {
// s < 2^lo * (a + 1)
rational b = rational::power_of_two(lo) * (a + 1) - 1;
rational offset;
get_offset(s, t, offset);
// t + offset <= b
init_range(t, offset, nullptr, b, false);
}
}
return true;
}
//
@ -132,51 +185,66 @@ namespace bv {
// a < x + b <=> ! (x + b <= a) <=> x not in [-a, b - a [ <=> x in [b - a, -a [ a != -1
// x + a < x + b <=> ! (x + b <= x + a) <=> x in [-a, -b [ a != b
//
void sls_fixed::init_range(expr* x, rational const& a, expr* y, rational const& b, bool sign) {
bool sls_fixed::init_range(expr* x, rational const& a, expr* y, rational const& b, bool sign) {
if (!x && !y)
return;
if (!x) {
// a <= y + b
if (a == 0)
return;
auto& v = wval(y);
if (!sign)
v.add_range(a - b, -b);
else
v.add_range(-b, a - b);
}
else if (!y) {
return false;
if (!x)
return add_range(y, a - b, -b, sign);
else if (!y)
return add_range(x, -a, b - a + 1, sign);
else if (x == y)
return add_range(x, -a, -b, sign);
return false;
}
if (mod(b + 1, rational::power_of_two(bv.get_bv_size(x))) == 0)
return;
auto& v = wval(x);
if (!sign)
v.add_range(-a, b - a + 1);
else
v.add_range(b - a + 1, -a);
}
else if (x == y) {
if (a == b)
return;
auto& v = wval(x);
if (!sign)
v.add_range(-a, -b);
else
v.add_range(-b, -a);
bool sls_fixed::add_range(expr* e, rational lo, rational hi, bool sign) {
auto& v = wval(e);
lo = mod(lo, rational::power_of_two(bv.get_bv_size(e)));
hi = mod(hi, rational::power_of_two(bv.get_bv_size(e)));
if (lo == hi)
return false;
if (sign)
std::swap(lo, hi);
v.add_range(lo, hi);
if (v.lo() == 0 && bv.is_concat(e) && to_app(e)->get_num_args() == 2) {
auto x = to_app(e)->get_arg(0);
auto y = to_app(e)->get_arg(1);
auto sz = bv.get_bv_size(y);
auto k = rational::power_of_two(sz);
lo = v.lo();
hi = v.hi();
if (hi <= k) {
add_range(y, lo, hi, false);
init_eq(x, lo, false);
}
else {
hi = div(hi + k - 1, k);
add_range(x, lo, hi, false);
}
}
return true;
}
void sls_fixed::get_offset(expr* e, expr*& x, rational& offset) {
expr* s, * t;
x = e;
offset = 0;
if (bv.is_bv_add(e, s, t)) {
if (bv.is_numeral(s, offset))
rational n;
while (true) {
if (bv.is_bv_add(x, s, t) && bv.is_numeral(s, n)) {
x = t;
else if (bv.is_numeral(t, offset))
offset += n;
continue;
}
if (bv.is_bv_add(x, s, t) && bv.is_numeral(t, n)) {
x = s;
offset += n;
continue;
}
break;
}
else if (bv.is_numeral(e, offset))
if (bv.is_numeral(e, n))
offset += n,
x = nullptr;
}
@ -264,11 +332,6 @@ namespace bv {
case OP_BADD: {
auto& a = wval(e->get_arg(0));
auto& b = wval(e->get_arg(1));
rational r;
if (bv.is_numeral(e->get_arg(0), r) && b.has_range())
v.add_range(r + b.lo(), r + b.hi());
else if (bv.is_numeral(e->get_arg(1), r) && a.has_range())
v.add_range(r + a.lo(), r + a.hi());
bool pfixed = true;
for (unsigned i = 0; i < v.bw; ++i) {
if (pfixed && a.fixed.get(i) && b.fixed.get(i))
@ -283,7 +346,6 @@ namespace bv {
v.fixed.set(i, false);
}
}
break;
}
case OP_BMUL: {

View file

@ -30,9 +30,11 @@ namespace bv {
bv_util& bv;
void init_ranges(expr_ref_vector const& es);
void init_range(app* e, bool sign);
void init_range(expr* x, rational const& a, expr* y, rational const& b, bool sign);
bool init_range(app* e, bool sign);
bool init_range(expr* x, rational const& a, expr* y, rational const& b, bool sign);
void get_offset(expr* e, expr*& x, rational& offset);
bool init_eq(expr* e, rational const& v, bool sign);
bool add_range(expr* e, rational lo, rational hi, bool sign);
void init_fixed_basic(app* e);
void init_fixed_bv(app* e);

View file

@ -204,139 +204,69 @@ namespace bv {
//
// largest dst <= src and dst is feasible
// set dst := src & (~fixed | bits)
//
// increment dst if dst < src by setting bits below msb(src & ~dst) to 1
//
// if dst < lo < hi:
// return false
// if lo < hi <= dst:
// set dst := hi - 1
// if hi <= dst < lo
// set dst := hi - 1
//
//
bool sls_valuation::get_at_most(bvect const& src, bvect& dst) const {
SASSERT(!has_overflow(src));
for (unsigned i = 0; i < nw; ++i)
dst[i] = src[i] & (~fixed[i] | m_bits[i]);
//
// If dst < src, then find the most significant
// bit where src[idx] = 1, dst[idx] = 0
// set dst[j] = bits_j | ~fixed_j for j < idx
//
for (unsigned i = nw; i-- > 0; ) {
if (0 != (~dst[i] & src[i])) {
auto idx = log2(~dst[i] & src[i]);
auto mask = (1 << idx) - 1;
dst[i] = (~fixed[i] & mask) | dst[i];
for (unsigned j = i; j-- > 0; )
dst[j] = (~fixed[j] | m_bits[j]);
break;
}
}
SASSERT(!has_overflow(dst));
return round_down(dst);
src.copy_to(nw, dst);
sup_feasible(dst);
if (in_range(dst)) {
SASSERT(can_set(dst));
return true;
}
if (dst < m_lo && m_lo < m_hi) // dst < lo < hi
return false;
if (is_zero(m_hi))
return false;
m_hi.copy_to(nw, dst); // hi <= dst < lo or lo < hi <= dst
sub1(dst);
SASSERT(can_set(dst));
return true;
}
//
// smallest dst >= src and dst is feasible with respect to this.
// set dst := (src & ~fixed) | (fixed & bits)
//
// decrement dst if dst > src by setting bits below msb to 0 unless fixed
//
// if lo < hi <= dst
// return false
// if dst < lo < hi:
// set dst := lo
// if hi <= dst < lo
// set dst := lo
//
bool sls_valuation::get_at_least(bvect const& src, bvect& dst) const {
SASSERT(!has_overflow(src));
for (unsigned i = 0; i < nw; ++i)
dst[i] = (~fixed[i] & src[i]) | (fixed[i] & m_bits[i]);
src.copy_to(nw, dst);
dst.set_bw(bw);
inf_feasible(dst);
if (in_range(dst)) {
SASSERT(can_set(dst));
return true;
}
//
// If dst > src, then find the most significant
// bit where src[idx] = 0, dst[idx] = 1
// set dst[j] = dst[j] & fixed_j for j < idx
//
for (unsigned i = nw; i-- > 0; ) {
if (0 != (dst[i] & ~src[i])) {
auto idx = log2(dst[i] & ~src[i]);
auto mask = (1 << idx);
dst[i] = dst[i] & (fixed[i] | mask);
for (unsigned j = i; j-- > 0; )
dst[j] = dst[j] & fixed[j];
break;
}
}
SASSERT(!has_overflow(dst));
return round_up(dst);
}
bool sls_valuation::round_up(bvect& dst) const {
if (m_lo < m_hi) {
if (m_hi <= dst)
return false;
if (m_lo > dst)
set(dst, m_lo);
}
else if (m_hi <= dst && m_lo > dst)
set(dst, m_lo);
SASSERT(!has_overflow(dst));
return true;
}
bool sls_valuation::round_down(bvect& dst) const {
if (m_lo < m_hi) {
if (m_lo > dst)
return false;
if (m_hi <= dst) {
set(dst, m_hi);
sub1(dst);
}
}
else if (m_hi <= dst && m_lo > dst) {
set(dst, m_hi);
sub1(dst);
}
SASSERT(well_formed());
if (dst > m_lo)
return false;
m_lo.copy_to(nw, dst);
SASSERT(can_set(dst));
return true;
}
bool sls_valuation::set_random_at_most(bvect const& src, bvect& tmp, random_gen& r) {
if (!get_at_most(src, tmp))
return false;
if (is_zero(tmp) || (0 == r() % 2))
if (is_zero(tmp) || (0 != r(10)))
return try_set(tmp);
set_random_below(tmp, r);
// random value below tmp
if (m_lo == m_hi || is_zero(m_lo) || m_lo <= tmp)
return try_set(tmp);
// for simplicity, bail out if we were not lucky
return get_at_most(src, tmp) && try_set(tmp);
set_random_below(tmp, r);
return (can_set(tmp) || get_at_most(src, tmp)) && try_set(tmp);
}
bool sls_valuation::set_random_at_least(bvect const& src, bvect& tmp, random_gen& r) {
if (!get_at_least(src, tmp))
return false;
if (is_ones(tmp) || (0 == r() % 2))
if (is_ones(tmp) || (0 != r(10)))
return try_set(tmp);
// random value at least tmp
set_random_above(tmp, r);
if (m_lo == m_hi || is_zero(m_hi) || m_hi > tmp)
return try_set(tmp);
// for simplicity, bail out if we were not lucky
return get_at_least(src, tmp) && try_set(tmp);
return (can_set(tmp) || get_at_least(src, tmp)) && try_set(tmp);
}
bool sls_valuation::set_random_in_range(bvect const& lo, bvect const& hi, bvect& tmp, random_gen& r) {
@ -533,7 +463,7 @@ namespace bv {
//
// new_bits != bits => ~fixed
// 0 = (new_bits ^ bits) & fixed
// 0 = (new_bits ^ bits) & fixedf
// also check that new_bits are in range
//
bool sls_valuation::can_set(bvect const& new_bits) const {
@ -559,14 +489,16 @@ namespace bv {
}
void sls_valuation::add_range(rational l, rational h) {
//return;
return;
//verbose_stream() << *this << " " << l << " " << h << " --> \n";
l = mod(l, rational::power_of_two(bw));
h = mod(h, rational::power_of_two(bw));
if (h == l)
return;
// verbose_stream() << *this << " " << l << " " << h << " --> ";
if (m_lo == m_hi) {
set_value(m_lo, l);
set_value(m_hi, h);
@ -591,19 +523,25 @@ namespace bv {
set_value(m_lo, l);
set_value(m_hi, h);
}
else if (old_lo + 1 == l) {
else if (old_lo + 1 == l)
set_value(m_lo, l);
else if (old_hi == h + 1)
set_value(m_hi, h);
else if (old_hi == h && old_lo < l)
set_value(m_lo, l);
}
else if (old_hi == h + 1) {
else if (old_lo == l && h < old_hi)
set_value(m_hi, h);
}
}
}
SASSERT(!has_overflow(m_lo));
SASSERT(!has_overflow(m_hi));
//verbose_stream() << *this << " --> ";
tighten_range();
//verbose_stream() << *this << "\n";
SASSERT(well_formed());
}
@ -621,59 +559,76 @@ namespace bv {
// lo + 1 = hi -> set bits = lo
// lo < hi, set most significant bits based on hi
//
unsigned sls_valuation::diff_index(bvect const& a) const {
unsigned index = 0;
for (unsigned i = nw; i-- > 0; ) {
auto diff = fixed[i] & (m_bits[i] ^ a[i]);
if (diff != 0 && index == 0)
index = 1 + i * 8 * sizeof(digit_t) + log2(diff);
}
return index;
}
void sls_valuation::inf_feasible(bvect& a) const {
unsigned lo_index = diff_index(a);
if (lo_index != 0) {
lo_index--;
SASSERT(a.get(lo_index) != m_bits.get(lo_index));
SASSERT(fixed.get(lo_index));
for (unsigned i = 0; i <= lo_index; ++i) {
if (!fixed.get(i))
a.set(i, false);
else if (fixed.get(i))
a.set(i, m_bits.get(i));
}
if (!a.get(lo_index)) {
for (unsigned i = lo_index + 1; i < bw; ++i)
if (!fixed.get(i) && !a.get(i)) {
a.set(i, true);
break;
}
}
}
}
void sls_valuation::sup_feasible(bvect& a) const {
unsigned hi_index = diff_index(a);
if (hi_index != 0) {
hi_index--;
SASSERT(a.get(hi_index) != m_bits.get(hi_index));
SASSERT(fixed.get(hi_index));
for (unsigned i = 0; i <= hi_index; ++i) {
if (!fixed.get(i))
a.set(i, true);
else if (fixed.get(i))
a.set(i, m_bits.get(i));
}
if (a.get(hi_index)) {
for (unsigned i = hi_index + 1; i < bw; ++i)
if (!fixed.get(i) && a.get(i)) {
a.set(i, false);
break;
}
}
}
}
void sls_valuation::tighten_range() {
if (m_lo == m_hi)
return;
inf_feasible(m_lo);
bvect hi1(nw);
hi1.set_bw(bw);
m_hi.copy_to(nw, hi1);
sub1(hi1);
unsigned lo_index = 0, hi_index = 0;
for (unsigned i = nw; i-- > 0; ) {
auto lo_diff = (fixed[i] & (m_bits[i] ^ m_lo[i]));
if (lo_diff != 0 && lo_index == 0)
lo_index = 1 + i * 8 * sizeof(digit_t) + log2(lo_diff);
auto hi_diff = (fixed[i] & (m_bits[i] ^ hi1[i]));
if (hi_diff != 0 && hi_index == 0)
hi_index = 1 + i * 8 * sizeof(digit_t) + log2(hi_diff);
}
if (lo_index != 0) {
lo_index--;
SASSERT(m_lo.get(lo_index) != m_bits.get(lo_index));
SASSERT(fixed.get(lo_index));
for (unsigned i = 0; i <= lo_index; ++i) {
if (!fixed.get(i))
m_lo.set(i, false);
else if (fixed.get(i))
m_lo.set(i, m_bits.get(i));
}
for (unsigned i = lo_index + 1; i < bw; ++i)
if (!fixed.get(i) && !m_lo.get(i)) {
m_lo.set(i, true);
break;
}
}
if (hi_index != 0) {
hi_index--;
SASSERT(hi1.get(hi_index) != m_bits.get(hi_index));
SASSERT(fixed.get(hi_index));
for (unsigned i = 0; i <= hi_index; ++i) {
if (!fixed.get(i))
hi1.set(i, true);
else if (fixed.get(i))
hi1.set(i, m_bits.get(i));
}
for (unsigned i = hi_index + 1; i < bw; ++i)
if (!fixed.get(i) && hi1.get(i)) {
hi1.set(i, false);
break;
}
add1(hi1);
hi1.copy_to(nw, m_hi);
}
sup_feasible(hi1);
add1(hi1);
hi1.copy_to(nw, m_hi);
if (has_range() && !in_range(m_bits))
m_bits = m_lo;

View file

@ -113,8 +113,6 @@ namespace bv {
unsigned m_signed_prefix = 0;
unsigned mask;
bool round_up(bvect& dst) const;
bool round_down(bvect& dst) const;
void repair_sign_bits(bvect& dst) const;
@ -141,9 +139,11 @@ namespace bv {
SASSERT(in_range(m_bits));
if (fixed.get(i) && get_bit(i) != b)
return false;
m_bits.set(i, b);
eval.set(i, b);
if (in_range(m_bits))
return true;
m_bits.set(i, !b);
eval.set(i, !b);
return false;
}
@ -155,6 +155,9 @@ namespace bv {
rational lo() const { return m_lo.get_value(nw); }
rational hi() const { return m_hi.get_value(nw); }
unsigned diff_index(bvect const& a) const;
void inf_feasible(bvect& a) const;
void sup_feasible(bvect& a) const;
void get(bvect& dst) const;
void add_range(rational lo, rational hi);

View file

@ -175,8 +175,8 @@ public:
m_st.reset();
m_sls->collect_statistics(m_st);
report_tactic_progress("Number of flips:", m_sls->get_num_moves());
IF_VERBOSE(20, verbose_stream() << res << "\n");
IF_VERBOSE(20, m_sls->display(verbose_stream()));
IF_VERBOSE(10, verbose_stream() << res << "\n");
IF_VERBOSE(10, m_sls->display(verbose_stream()));
if (res == l_true) {
if (g->models_enabled()) {