3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-27 19:05:51 +00:00

compute with deps

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2021-08-05 10:03:42 -07:00
parent 40027df32f
commit 481e20bc20
6 changed files with 166 additions and 99 deletions

View file

@ -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++)
{

View file

@ -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;

View file

@ -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_config> dep_manager;
#endif
struct var_info : public mod_interval<numeral> {
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<stashed_bound> m_stashed_bounds;
u_dependency_manager m_deps;
svector<trail_i> m_trail;
svector<var_t> m_row_trail;
map<numeral, fix_entry, typename manager::hash, typename manager::eq> 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<numeral> 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);

View file

@ -72,6 +72,37 @@ namespace polysat {
reset();
}
template<typename Ext>
void fixplex<Ext>::push() {
m_trail.push_back(trail_i::inc_level_i);
m_deps.push_scope();
}
template<typename Ext>
void fixplex<Ext>::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<typename Ext>
void fixplex<Ext>::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<typename Ext>
@ -486,13 +519,7 @@ namespace polysat {
*/
template<typename Ext>
void fixplex<Ext>::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<typename Ext>
void fixplex<Ext>::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<typename Ext>
void fixplex<Ext>::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<typename Ext>
void fixplex<Ext>::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<typename Ext>
void fixplex<Ext>::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<typename Ext>
void fixplex<Ext>::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<typename Ext>
lbool fixplex<Ext>::conflict_bound(ineq const& i) {
NOT_IMPLEMENTED_YET();
lbool fixplex<Ext>::conflict(ineq const& i, u_dependency* a, u_dependency* b) {
return conflict(a, m_deps.mk_join(mk_leaf(i.dep), b));
}
template<typename Ext>
lbool fixplex<Ext>::conflict(u_dependency* a) {
m_unsat_core.reset();
m_deps.linearize(a, m_unsat_core);
return l_false;
}
template<typename Ext>
lbool fixplex<Ext>::new_bound(ineq const& i, var_t x, numeral const& l, numeral const& h) {
mod_interval<numeral> 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<Ext>::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<typename Ext>
lbool fixplex<Ext>::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;

View file

@ -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<generic_uint_ext<unsigned char>>, s.m_lim);
break;
case 16:
b = alloc(fixplex<generic_uint_ext<unsigned short>>, s.m_lim);
break;
case 32:
b = alloc(fixplex<generic_uint_ext<unsigned>>, 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));
}
};

View file

@ -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<fixplex_base> m_fix;
ptr_vector<fixplex_base> m_fix_ptr;
svector<trail_i> m_trail;
svector<std::pair<var_t, unsigned>> m_rows;
unsigned_vector m_var2ext;
@ -94,7 +94,7 @@ namespace polysat {
svector<mono_info> 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);