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:
parent
40027df32f
commit
481e20bc20
6 changed files with 166 additions and 99 deletions
|
@ -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++)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue