diff --git a/src/math/bigfix/Hacl_Bignum.c b/src/math/bigfix/Hacl_Bignum.c index 54a282839..9dab783f8 100644 --- a/src/math/bigfix/Hacl_Bignum.c +++ b/src/math/bigfix/Hacl_Bignum.c @@ -317,6 +317,7 @@ static inline void bn_sqr_u32(uint32_t aLen, uint32_t *a, uint32_t *res) res[i0 + i0] = r; } uint32_t c0 = Hacl_Bignum_Addition_bn_add_eq_len_u32(resLen, res, res, res); + (void)c0; KRML_CHECK_SIZE(sizeof (uint32_t), resLen); uint32_t *tmp = alloca(resLen * sizeof (uint32_t)); memset(tmp, 0U, resLen * sizeof (uint32_t)); @@ -329,6 +330,7 @@ static inline void bn_sqr_u32(uint32_t aLen, uint32_t *a, uint32_t *res) tmp[(uint32_t)2U * i + (uint32_t)1U] = hi; } uint32_t c1 = Hacl_Bignum_Addition_bn_add_eq_len_u32(resLen, res, tmp, res); + (void)c1; } static inline void bn_sqr_u64(uint32_t aLen, uint64_t *a, uint64_t *res) @@ -366,6 +368,7 @@ static inline void bn_sqr_u64(uint32_t aLen, uint64_t *a, uint64_t *res) res[i0 + i0] = r; } uint64_t c0 = Hacl_Bignum_Addition_bn_add_eq_len_u64(resLen, res, res, res); + (void)c0; KRML_CHECK_SIZE(sizeof (uint64_t), resLen); uint64_t *tmp = alloca(resLen * sizeof (uint64_t)); memset(tmp, 0U, resLen * sizeof (uint64_t)); @@ -378,6 +381,7 @@ static inline void bn_sqr_u64(uint32_t aLen, uint64_t *a, uint64_t *res) tmp[(uint32_t)2U * i + (uint32_t)1U] = hi; } uint64_t c1 = Hacl_Bignum_Addition_bn_add_eq_len_u64(resLen, res, tmp, res); + (void)c1; } void @@ -720,6 +724,7 @@ Hacl_Bignum_Karatsuba_bn_karatsuba_sqr_uint64( uint64_t *tmp_ = tmp + aLen; uint64_t c0 = Hacl_Bignum_Addition_bn_sub_eq_len_u64(len2, a0, a1, tmp_); uint64_t c1 = Hacl_Bignum_Addition_bn_sub_eq_len_u64(len2, a1, a0, t0); + (void)c1; for (uint32_t i = (uint32_t)0U; i < len2; i++) { uint64_t *os = t0; @@ -727,6 +732,7 @@ Hacl_Bignum_Karatsuba_bn_karatsuba_sqr_uint64( os[i] = x; } uint64_t c00 = c0; + (void)c00; uint64_t *t23 = tmp + aLen; uint64_t *tmp1 = tmp + aLen + aLen; Hacl_Bignum_Karatsuba_bn_karatsuba_sqr_uint64(len2, t0, tmp1, t23); @@ -1428,6 +1434,7 @@ bn_almost_mont_reduction_u32( uint32_t *tmp = alloca(len * sizeof (uint32_t)); memset(tmp, 0U, len * sizeof (uint32_t)); uint32_t c1 = Hacl_Bignum_Addition_bn_sub_eq_len_u32(len, res, n, tmp); + (void)c1; uint32_t m = (uint32_t)0U - c00; for (uint32_t i = (uint32_t)0U; i < len; i++) { @@ -1524,6 +1531,7 @@ bn_almost_mont_reduction_u64( uint64_t *tmp = alloca(len * sizeof (uint64_t)); memset(tmp, 0U, len * sizeof (uint64_t)); uint64_t c1 = Hacl_Bignum_Addition_bn_sub_eq_len_u64(len, res, n, tmp); + (void)c1; uint64_t m = (uint64_t)0U - c00; for (uint32_t i = (uint32_t)0U; i < len; i++) { diff --git a/src/math/bigfix/Hacl_Bignum256.c b/src/math/bigfix/Hacl_Bignum256.c index 6894f8bd8..7eee57ccd 100644 --- a/src/math/bigfix/Hacl_Bignum256.c +++ b/src/math/bigfix/Hacl_Bignum256.c @@ -513,6 +513,7 @@ static inline void amont_sqr(uint64_t *n, uint64_t nInv_u64, uint64_t *aM, uint6 tmp[(uint32_t)2U * i + (uint32_t)1U] = hi; } uint64_t c1 = Hacl_Bignum_Addition_bn_add_eq_len_u64(resLen, c, tmp, c); + (void)c1; areduction(n, nInv_u64, c, resM); } @@ -559,6 +560,7 @@ bn_slow_precomp(uint64_t *n, uint64_t mu, uint64_t *r2, uint64_t *a, uint64_t *r uint64_t c00 = c0; uint64_t tmp[4U] = { 0U }; uint64_t c1 = Hacl_Bignum256_sub(a_mod, n, tmp); + (void)c1; uint64_t m = (uint64_t)0U - c00; for (uint32_t i = (uint32_t)0U; i < (uint32_t)4U; i++) { @@ -1132,6 +1134,7 @@ bool Hacl_Bignum256_mod_inv_prime_vartime(uint64_t *n, uint64_t *a, uint64_t *re uint64_t n2[4U] = { 0U }; uint64_t c0 = Lib_IntTypes_Intrinsics_sub_borrow_u64((uint64_t)0U, n[0U], (uint64_t)2U, n2); uint64_t c1; + (void)c1; if ((uint32_t)1U < (uint32_t)4U) { uint32_t rLen = (uint32_t)3U; @@ -1334,6 +1337,7 @@ Hacl_Bignum256_mod_inv_prime_vartime_precomp( uint64_t n2[4U] = { 0U }; uint64_t c0 = Lib_IntTypes_Intrinsics_sub_borrow_u64((uint64_t)0U, k1.n[0U], (uint64_t)2U, n2); uint64_t c1; + (void)c1; if ((uint32_t)1U < (uint32_t)4U) { uint32_t rLen = (uint32_t)3U; diff --git a/src/math/polysat/fixplex.h b/src/math/polysat/fixplex.h index a2c5450bf..f6af50ccd 100644 --- a/src/math/polysat/fixplex.h +++ b/src/math/polysat/fixplex.h @@ -30,6 +30,8 @@ Author: #include "util/ref.h" inline rational to_rational(uint64_t n) { return rational(n, rational::ui64()); } +inline unsigned trailing_zeros(unsigned short n) { return trailing_zeros((uint32_t)n); } +inline unsigned trailing_zeros(unsigned char n) { return trailing_zeros((uint32_t)n); } namespace polysat { @@ -40,6 +42,8 @@ namespace polysat { virtual lbool make_feasible() = 0; virtual void add_row(var_t base, unsigned num_vars, var_t const* vars, rational const* coeffs) = 0; virtual void del_row(var_t base_var) = 0; + virtual void push() = 0; + virtual void pop(unsigned n) = 0; virtual std::ostream& display(std::ostream& out) const = 0; virtual void collect_statistics(::statistics & st) const = 0; virtual void set_bounds(var_t v, rational const& lo, rational const& hi, unsigned dep) = 0; @@ -50,6 +54,7 @@ namespace polysat { virtual void add_lt(var_t v, var_t w, unsigned dep) = 0; virtual void restore_ineq() = 0; virtual unsigned_vector const& get_unsat_core() const = 0; + }; @@ -95,14 +100,6 @@ namespace polysat { S_DEFAULT }; -#if 0 - struct dep_config { - static const bool ref_count = true; - typedef unsigned value; - }; - typedef dependency_manager dep_manager; -#endif - struct var_info : public mod_interval { unsigned m_base2row:29; unsigned m_is_base:1; @@ -156,6 +153,13 @@ namespace polysat { v(v), w(w), strict(s), dep(dep) {} }; + enum trail_i { + inc_level_i, + set_bound_i, + add_ineq_i, + add_row_i + }; + static const var_t null_var = UINT_MAX; reslimit& m_limit; mutable manager m; @@ -175,6 +179,8 @@ namespace polysat { stats m_stats; vector m_stashed_bounds; u_dependency_manager m_deps; + svector m_trail; + svector m_row_trail; map m_value2fixed_var; // inequalities @@ -192,6 +198,9 @@ namespace polysat { ~fixplex() override; + void push() override; + void pop(unsigned n) override; + lbool make_feasible() override; void add_row(var_t base, unsigned num_vars, var_t const* vars, rational const* coeffs) override; std::ostream& display(std::ostream& out) const override; @@ -206,6 +215,7 @@ namespace polysat { virtual void restore_ineq() override; void set_bounds(var_t v, numeral const& lo, numeral const& hi, unsigned dep); + void update_bounds(var_t v, numeral const& l, numeral const& h, u_dependency* dep); void unset_bounds(var_t v) { m_vars[v].set_free(); } @@ -244,8 +254,11 @@ namespace polysat { lbool propagate_bounds(row const& r); lbool propagate_bounds(ineq const& i); lbool new_bound(row const& r, var_t x, mod_interval const& range); - lbool new_bound(ineq const& i, var_t x, numeral const& lo, numeral const& hi); - lbool conflict_bound(ineq const& i); + lbool new_bound(ineq const& i, var_t x, numeral const& lo, numeral const& hi, u_dependency* a = nullptr, u_dependency* b = nullptr); + lbool conflict(ineq const& i, u_dependency* a = nullptr, u_dependency* b = nullptr); + lbool conflict(u_dependency* a); + lbool conflict(u_dependency* a, u_dependency* b) { return conflict(m_deps.mk_join(a, b)); } + u_dependency* row2dep(row const& r); void pivot(var_t x_i, var_t x_j, numeral const& b, numeral const& value); numeral value2delta(var_t v, numeral const& new_value) const; numeral value2error(var_t v, numeral const& new_value) const; @@ -279,6 +292,8 @@ namespace polysat { void set_infeasible_base(var_t v); void set_infeasible_bounds(var_t v); + u_dependency* mk_leaf(unsigned dep) { return UINT_MAX == dep ? nullptr : m_deps.mk_leaf(dep); } + // facilities for handling inequalities void add_ineq(var_t v, var_t w, unsigned dep, bool strict); void touch_var(var_t x); diff --git a/src/math/polysat/fixplex_def.h b/src/math/polysat/fixplex_def.h index e335bc204..722621189 100644 --- a/src/math/polysat/fixplex_def.h +++ b/src/math/polysat/fixplex_def.h @@ -72,6 +72,37 @@ namespace polysat { reset(); } + template + void fixplex::push() { + m_trail.push_back(trail_i::inc_level_i); + m_deps.push_scope(); + } + + template + void fixplex::pop(unsigned n) { + m_deps.pop_scope(n); + while (n > 0) { + switch (m_trail.back()) { + case trail_i::inc_level_i: + --n; + break; + case trail_i::set_bound_i: + restore_bound(); + break; + case trail_i::add_row_i: + del_row(m_row_trail.back()); + m_row_trail.pop_back(); + break; + case trail_i::add_ineq_i: + restore_ineq(); + break; + default: + UNREACHABLE(); + } + m_trail.pop_back(); + } + } + template void fixplex::ensure_var(var_t v) { while (v >= m_vars.size()) { @@ -173,6 +204,8 @@ namespace polysat { ++m_stats.m_num_approx; SASSERT(well_formed_row(r)); SASSERT(well_formed()); + m_trail.push_back(trail_i::add_row_i); + m_row_trail.push_back(base_var); } template @@ -486,13 +519,7 @@ namespace polysat { */ template void fixplex::set_bounds(var_t v, numeral const& l, numeral const& h, unsigned dep) { - auto lo0 = m_vars[v].lo; - auto hi0 = m_vars[v].hi; - m_vars[v] &= mod_interval(l, h); - if (lo0 != m_vars[v].lo) - m_vars[v].m_lo_dep = nullptr; // TODO set_atom(dep); - if (hi0 != m_vars[v].hi) - m_vars[v].m_hi_dep = nullptr; // TODO .set_atom(dep); + update_bounds(v, l, h, mk_leaf(dep)); if (in_bounds(v)) return; if (is_base(v)) @@ -501,18 +528,29 @@ namespace polysat { update_value(v, value2delta(v, value(v))); } + template + void fixplex::update_bounds(var_t v, numeral const& l, numeral const& h, u_dependency* dep) { + auto lo0 = m_vars[v].lo; + auto hi0 = m_vars[v].hi; + m_stashed_bounds.push_back(stashed_bound(v, m_vars[v])); + m_trail.push_back(trail_i::set_bound_i); + m_vars[v] &= mod_interval(l, h); + if (lo0 != m_vars[v].lo) + m_vars[v].m_lo_dep = dep; + if (hi0 != m_vars[v].hi) + m_vars[v].m_hi_dep = dep; + } + template void fixplex::set_bounds(var_t v, rational const& _lo, rational const& _hi, unsigned dep) { numeral lo = m.from_rational(_lo); numeral hi = m.from_rational(_hi); - m_stashed_bounds.push_back(stashed_bound(v, m_vars[v])); set_bounds(v, lo, hi, dep); } template void fixplex::set_value(var_t v, rational const& _val, unsigned dep) { numeral val = m.from_rational(_val); - m_stashed_bounds.push_back(stashed_bound(v, m_vars[v])); set_bounds(v, val, val + 1, dep); } @@ -524,24 +562,21 @@ namespace polysat { template void fixplex::restore_bound() { auto& b = m_stashed_bounds.back(); - auto* lo = m_vars[b.m_var].m_lo_dep; - auto* hi = m_vars[b.m_var].m_hi_dep; m_vars[b.m_var].lo = b.lo; m_vars[b.m_var].hi = b.hi; m_vars[b.m_var].m_lo_dep = b.m_lo_dep; m_vars[b.m_var].m_hi_dep = b.m_hi_dep; -// m_deps.dec_ref(lo); -// m_deps.dec_ref(hi); m_stashed_bounds.pop_back(); } template void fixplex::add_ineq(var_t v, var_t w, unsigned dep, bool strict) { - unsigned idx = m_ineqs.size(); + unsigned idx = m_ineqs.size(); m_var2ineqs.reserve(std::max(v, w) + 1); m_var2ineqs[v].push_back(idx); m_var2ineqs[w].push_back(idx); m_ineqs_to_check.push_back(idx); + m_trail.push_back(trail_i::add_ineq_i); m_ineqs.push_back(ineq(v, w, dep, strict)); } @@ -1126,50 +1161,64 @@ namespace polysat { var_t v = i.v, w = i.w; bool s = i.strict; if (s && lo(v) + 1 == 0) - return conflict_bound(i); + return conflict(i, m_vars[v].m_lo_dep); else if (s && hi(w) == 0) - return conflict_bound(i); + return conflict(i, m_vars[v].m_hi_dep); else if (s && lo(v) >= hi(w)) - return conflict_bound(i); + return conflict(i, m_vars[v].m_lo_dep, m_vars[w].m_hi_dep); else if (!s && lo(v) > hi(w)) - return conflict_bound(i); + return conflict(i, m_vars[v].m_lo_dep, m_vars[w].m_hi_dep); else if (s && hi(v) >= hi(w)) { SASSERT(lo(v) < hi(w)); SASSERT(hi(w) != 0); - return new_bound(i, v, lo(v), hi(w) - 1); + return new_bound(i, v, lo(v), hi(w) - 1, m_vars[v].m_hi_dep, m_vars[w].m_hi_dep); } else if (s && lo(v) >= lo(w)) { SASSERT(lo(v) + 1 != 0); SASSERT(hi(w) > lo(v)); - return new_bound(i, w, lo(v) + 1, hi(w)); + return new_bound(i, w, lo(v) + 1, hi(w), m_vars[v].m_lo_dep, m_vars[w].m_lo_dep); } else if (!s && hi(v) > hi(w)) { SASSERT(lo(v) <= hi(w)); - return new_bound(i, v, lo(v), hi(w)); + return new_bound(i, v, lo(v), hi(w), m_vars[v].m_hi_dep, m_vars[w].m_hi_dep); } else if (!s && lo(v) > lo(w)) { SASSERT(lo(v) <= hi(w)); - return new_bound(i, w, lo(v), hi(w)); + return new_bound(i, w, lo(v), hi(w), m_vars[v].m_lo_dep, m_vars[w].m_lo_dep); } return l_true; } template - lbool fixplex::conflict_bound(ineq const& i) { - NOT_IMPLEMENTED_YET(); + lbool fixplex::conflict(ineq const& i, u_dependency* a, u_dependency* b) { + return conflict(a, m_deps.mk_join(mk_leaf(i.dep), b)); + } + + template + lbool fixplex::conflict(u_dependency* a) { + m_unsat_core.reset(); + m_deps.linearize(a, m_unsat_core); return l_false; } template - lbool fixplex::new_bound(ineq const& i, var_t x, numeral const& l, numeral const& h) { - mod_interval r(l, h); - bool was_fixed = lo(x) + 1 == hi(x); - m_vars[x] &= r; - if (m_vars[x].is_empty()) { - // TODO - IF_VERBOSE(0, verbose_stream() << "infeasible\n"); - return l_false; + u_dependency* fixplex::row2dep(row const& r) { + u_dependency* d = nullptr; + for (auto const& e : M.row_entries(r)) { + var_t v = e.var(); + d = m_deps.mk_join(m_vars[v].m_lo_dep, d); + d = m_deps.mk_join(m_vars[v].m_hi_dep, d); } + return d; + } + + template + lbool fixplex::new_bound(ineq const& i, var_t x, numeral const& l, numeral const& h, u_dependency* a, u_dependency* b) { + bool was_fixed = lo(x) + 1 == hi(x); + u_dependency* dep = m_deps.mk_join(mk_leaf(i.dep), m_deps.mk_join(a, b)); + update_bounds(x, l, h, dep); + if (m_vars[x].is_empty()) + return conflict(m_vars[x].m_lo_dep, m_vars[x].m_hi_dep); else if (!was_fixed && lo(x) + 1 == hi(x)) { // TBD: track based on inequality not row // fixed_var_eh(r, x); @@ -1182,12 +1231,10 @@ namespace polysat { if (range.is_free()) return l_true; bool was_fixed = lo(x) + 1 == hi(x); - m_vars[x] &= range; + update_bounds(x, range.lo, range.hi, row2dep(r)); IF_VERBOSE(0, verbose_stream() << "new-bound v" << x << " " << m_vars[x] << "\n"); - if (m_vars[x].is_empty()) { - IF_VERBOSE(0, verbose_stream() << "infeasible\n"); - return l_false; - } + if (m_vars[x].is_empty()) + return conflict(m_vars[x].m_lo_dep, m_vars[x].m_hi_dep); else if (!was_fixed && lo(x) + 1 == hi(x)) fixed_var_eh(r, x); return l_true; diff --git a/src/math/polysat/linear_solver.cpp b/src/math/polysat/linear_solver.cpp index 699a28d31..535d9c670 100644 --- a/src/math/polysat/linear_solver.cpp +++ b/src/math/polysat/linear_solver.cpp @@ -22,9 +22,13 @@ namespace polysat { void linear_solver::push() { m_trail.push_back(trail_i::inc_level_i); + for (auto* f : m_fix_ptr) + f->push(); } void linear_solver::pop(unsigned n) { + for (auto* f : m_fix_ptr) + f->pop(n); while (n > 0) { switch (m_trail.back()) { case trail_i::inc_level_i: @@ -43,24 +47,6 @@ namespace polysat { m_monomials.pop_back(); break; } - case trail_i::set_bound_i: { - auto [v, sz] = m_rows.back(); - sz2fixplex(sz).restore_bound(); - m_rows.pop_back(); - break; - } - case trail_i::add_row_i: { - auto [v, sz] = m_rows.back(); - sz2fixplex(sz).del_row(v); - m_rows.pop_back(); - break; - } - case trail_i::add_ineq_i: { - auto [v, sz] = m_rows.back(); - sz2fixplex(sz).restore_ineq(); - m_rows.pop_back(); - break; - } case trail_i::set_active_i: m_active.pop_back(); break; @@ -73,10 +59,16 @@ namespace polysat { m_unsat_f = nullptr; } - fixplex_base& linear_solver::sz2fixplex(unsigned sz) { + fixplex_base* linear_solver::sz2fixplex(unsigned sz) { fixplex_base* b = m_fix.get(sz, nullptr); if (!b) { switch (sz) { + case 8: + b = alloc(fixplex>, s.m_lim); + break; + case 16: + b = alloc(fixplex>, s.m_lim); + break; case 32: b = alloc(fixplex>, s.m_lim); break; @@ -93,9 +85,11 @@ namespace polysat { NOT_IMPLEMENTED_YET(); break; } + if (b) + m_fix_ptr.push_back(b); m_fix.set(sz, b); } - return *b; + return b; } @@ -107,9 +101,9 @@ namespace polysat { var_t v = fresh_var(sz); m_vars.push_back(v); m_coeffs.push_back(rational::power_of_two(sz) - 1); - sz2fixplex(sz).add_row(v, m_vars.size(), m_vars.data(), m_coeffs.data()); - m_rows.push_back(std::make_pair(v, sz)); - m_trail.push_back(trail_i::add_row_i); + auto* f = sz2fixplex(sz); + if (f) + f->add_row(v, m_vars.size(), m_vars.data(), m_coeffs.data()); return v; } @@ -135,15 +129,15 @@ namespace polysat { unsigned c_dep = constraint_idx2dep(m_active.size() - 1); var_t v = m_bool_var2row[c.bvar()].first; unsigned sz = c.p().power_of_2(); - auto& fp = sz2fixplex(sz); - m_trail.push_back(trail_i::set_bound_i); - m_rows.push_back(std::make_pair(v, sz)); + auto* fp = sz2fixplex(sz); + if (!fp) + return; rational z(0), o(1); SASSERT(!c.is_undef()); if (is_positive) - fp.set_bounds(v, z, z, c_dep); + fp->set_bounds(v, z, z, c_dep); else - fp.set_bounds(v, o, z, c_dep); + fp->set_bounds(v, o, z, c_dep); } // @@ -162,44 +156,40 @@ namespace polysat { void linear_solver::assert_le(bool is_positive, ule_constraint& c) { auto [v, w] = m_bool_var2row[c.bvar()]; unsigned sz = c.lhs().power_of_2(); - auto& fp = sz2fixplex(sz); + auto* fp = sz2fixplex(sz); + if (!fp) + return; unsigned c_dep = constraint_idx2dep(m_active.size() - 1); rational z(0); if (c.rhs().is_val()) { bool is_max_value = false; if (is_positive) // v <= rhs - fp.set_bounds(v, z, c.rhs().val(), c_dep); + fp->set_bounds(v, z, c.rhs().val(), c_dep); else if (is_max_value) throw default_exception("conflict not implemented"); else // rhs < v - fp.set_bounds(v, c.rhs().val() + 1, z, c_dep); - m_trail.push_back(trail_i::set_bound_i); - m_rows.push_back(std::make_pair(v, sz)); + fp->set_bounds(v, c.rhs().val() + 1, z, c_dep); return; } if (c.lhs().is_val()) { if (is_positive) // w >= lhs - fp.set_bounds(w, c.lhs().val(), z, c_dep); + fp->set_bounds(w, c.lhs().val(), z, c_dep); else if (c.lhs().val() == 0) throw default_exception("conflict not implemented"); else // w < lhs - fp.set_bounds(w, z, c.lhs().val() - 1, c_dep); - m_trail.push_back(trail_i::set_bound_i); - m_rows.push_back(std::make_pair(w, sz)); + fp->set_bounds(w, z, c.lhs().val() - 1, c_dep); return; } if (is_positive) - fp.add_le(v, w, c_dep); + fp->add_le(v, w, c_dep); else - fp.add_lt(w, v, c_dep); - m_trail.push_back(trail_i::add_ineq_i); - m_rows.push_back(std::make_pair(v, sz)); + fp->add_lt(w, v, c_dep); } @@ -273,20 +263,20 @@ namespace polysat { void linear_solver::set_value(pvar v, rational const& value, unsigned dep) { unsigned sz = s.size(v); - auto& fp = sz2fixplex(sz); + auto* fp = sz2fixplex(sz); + if (!fp) + return; var_t w = pvar2var(sz, v); - m_trail.push_back(trail_i::set_bound_i); - m_rows.push_back(std::make_pair(w, sz)); - fp.set_value(w, value, external_dep2dep(dep)); + fp->set_value(w, value, external_dep2dep(dep)); } void linear_solver::set_bound(pvar v, rational const& lo, rational const& hi, unsigned dep) { unsigned sz = s.size(v); - auto& fp = sz2fixplex(sz); + auto* fp = sz2fixplex(sz); + if (!fp) + return; var_t w = pvar2var(sz, v); - m_trail.push_back(trail_i::set_bound_i); - m_rows.push_back(std::make_pair(w, sz)); - fp.set_bounds(w, lo, hi, external_dep2dep(dep)); + fp->set_bounds(w, lo, hi, external_dep2dep(dep)); } /** @@ -325,7 +315,10 @@ namespace polysat { // current value assigned to (linear) variable according to tableau. rational linear_solver::value(pvar v) { unsigned sz = s.size(v); - return sz2fixplex(sz).get_value(pvar2var(sz, v)); + auto* fp = sz2fixplex(sz); + if (!fp) + return rational::zero(); + return fp->get_value(pvar2var(sz, v)); } }; diff --git a/src/math/polysat/linear_solver.h b/src/math/polysat/linear_solver.h index 8472a0721..88602a4e3 100644 --- a/src/math/polysat/linear_solver.h +++ b/src/math/polysat/linear_solver.h @@ -41,7 +41,6 @@ namespace polysat { inc_level_i, add_var_i, add_mono_i, - set_bound_i, add_ineq_i, add_row_i, set_active_i @@ -78,6 +77,7 @@ namespace polysat { solver& s; scoped_ptr_vector m_fix; + ptr_vector m_fix_ptr; svector m_trail; svector> m_rows; unsigned_vector m_var2ext; @@ -94,7 +94,7 @@ namespace polysat { svector m_monomials; fixplex_base* m_unsat_f = nullptr; - fixplex_base& sz2fixplex(unsigned sz); + fixplex_base* sz2fixplex(unsigned sz); void linearize(pdd const& p); var_t fresh_var(unsigned sz);