mirror of
https://github.com/Z3Prover/z3
synced 2025-06-28 00:48:45 +00:00
fixplex
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
60dbfed69e
commit
6ac7c2b942
3 changed files with 105 additions and 122 deletions
|
@ -64,8 +64,6 @@ namespace polysat {
|
||||||
var_t v = UINT_MAX;
|
var_t v = UINT_MAX;
|
||||||
var_t w = UINT_MAX;
|
var_t w = UINT_MAX;
|
||||||
bool strict = false;
|
bool strict = false;
|
||||||
bool is_active = true;
|
|
||||||
bool is_touched = false;
|
|
||||||
u_dependency* dep = nullptr;
|
u_dependency* dep = nullptr;
|
||||||
ineq(var_t v, var_t w, u_dependency* dep, bool s) :
|
ineq(var_t v, var_t w, u_dependency* dep, bool s) :
|
||||||
v(v), w(w), strict(s), dep(dep) {}
|
v(v), w(w), strict(s), dep(dep) {}
|
||||||
|
@ -174,13 +172,14 @@ namespace polysat {
|
||||||
mutable matrix M;
|
mutable matrix M;
|
||||||
unsigned m_max_iterations = UINT_MAX;
|
unsigned m_max_iterations = UINT_MAX;
|
||||||
unsigned m_num_non_integral = 0;
|
unsigned m_num_non_integral = 0;
|
||||||
|
uint_set m_non_integral;
|
||||||
var_heap m_to_patch;
|
var_heap m_to_patch;
|
||||||
vector<var_info> m_vars;
|
vector<var_info> m_vars;
|
||||||
vector<row_info> m_rows;
|
vector<row_info> m_rows;
|
||||||
vector<var_eq> m_var_eqs;
|
vector<var_eq> m_var_eqs;
|
||||||
bool m_bland = false ;
|
bool m_bland = false ;
|
||||||
unsigned m_blands_rule_threshold = 1000;
|
unsigned m_blands_rule_threshold = 1000;
|
||||||
var_t m_last_pivot_var = null_var;
|
unsigned m_num_repeated = 0;
|
||||||
random_gen m_random;
|
random_gen m_random;
|
||||||
uint_set m_left_basis;
|
uint_set m_left_basis;
|
||||||
unsigned_vector m_unsat_core;
|
unsigned_vector m_unsat_core;
|
||||||
|
@ -195,10 +194,9 @@ namespace polysat {
|
||||||
|
|
||||||
// inequalities
|
// inequalities
|
||||||
svector<ineq> m_ineqs;
|
svector<ineq> m_ineqs;
|
||||||
unsigned_vector m_ineqs_to_check;
|
uint_set m_ineqs_to_propagate;
|
||||||
bool_vector m_var_is_touched;
|
uint_set m_touched_vars;
|
||||||
vector<unsigned_vector> m_var2ineqs;
|
vector<unsigned_vector> m_var2ineqs;
|
||||||
svector<var_t> m_vars_to_untouch;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
fixplex(params_ref const& p, reslimit& lim):
|
fixplex(params_ref const& p, reslimit& lim):
|
||||||
|
@ -239,7 +237,6 @@ namespace polysat {
|
||||||
void set_max_iterations(unsigned n) { m_max_iterations = n; }
|
void set_max_iterations(unsigned n) { m_max_iterations = n; }
|
||||||
unsigned get_num_vars() const { return m_vars.size(); }
|
unsigned get_num_vars() const { return m_vars.size(); }
|
||||||
void reset();
|
void reset();
|
||||||
lbool propagate_bounds();
|
|
||||||
|
|
||||||
svector<std::pair<unsigned, ineq>> stack;
|
svector<std::pair<unsigned, ineq>> stack;
|
||||||
uint_set on_stack;
|
uint_set on_stack;
|
||||||
|
@ -260,6 +257,10 @@ namespace polysat {
|
||||||
void update_value_core(var_t v, numeral const& delta);
|
void update_value_core(var_t v, numeral const& delta);
|
||||||
void ensure_var(var_t v);
|
void ensure_var(var_t v);
|
||||||
|
|
||||||
|
bool patch();
|
||||||
|
bool propagate();
|
||||||
|
bool is_satisfied();
|
||||||
|
|
||||||
var_t select_smallest_var() { return m_to_patch.empty()?null_var:m_to_patch.erase_min(); }
|
var_t select_smallest_var() { return m_to_patch.empty()?null_var:m_to_patch.erase_min(); }
|
||||||
lbool make_var_feasible(var_t x_i);
|
lbool make_var_feasible(var_t x_i);
|
||||||
bool is_infeasible_row(var_t x);
|
bool is_infeasible_row(var_t x);
|
||||||
|
@ -306,7 +307,7 @@ namespace polysat {
|
||||||
int get_num_non_free_dep_vars(var_t x_j, int best_so_far);
|
int get_num_non_free_dep_vars(var_t x_j, int best_so_far);
|
||||||
void add_patch(var_t v);
|
void add_patch(var_t v);
|
||||||
var_t select_var_to_fix();
|
var_t select_var_to_fix();
|
||||||
void check_blands_rule(var_t v, unsigned& num_repeated);
|
void check_blands_rule(var_t v);
|
||||||
pivot_strategy_t pivot_strategy() { return m_bland ? S_BLAND : S_DEFAULT; }
|
pivot_strategy_t pivot_strategy() { return m_bland ? S_BLAND : S_DEFAULT; }
|
||||||
var_t select_error_var(bool least);
|
var_t select_error_var(bool least);
|
||||||
void set_infeasible_base(var_t v);
|
void set_infeasible_base(var_t v);
|
||||||
|
@ -317,9 +318,7 @@ namespace polysat {
|
||||||
// facilities for handling inequalities
|
// facilities for handling inequalities
|
||||||
void add_ineq(var_t v, var_t w, unsigned dep, bool strict);
|
void add_ineq(var_t v, var_t w, unsigned dep, bool strict);
|
||||||
void touch_var(var_t x);
|
void touch_var(var_t x);
|
||||||
bool ineqs_are_violated();
|
|
||||||
bool ineqs_are_satisfied();
|
|
||||||
void reset_ineqs_to_check();
|
|
||||||
|
|
||||||
bool is_solved(row const& r) const;
|
bool is_solved(row const& r) const;
|
||||||
bool is_solved(var_t v) const { SASSERT(is_base(v)); return is_solved(base2row(v)); }
|
bool is_solved(var_t v) const { SASSERT(is_base(v)); return is_solved(base2row(v)); }
|
||||||
|
|
|
@ -99,19 +99,19 @@ namespace polysat {
|
||||||
m_deps.pop_scope(n);
|
m_deps.pop_scope(n);
|
||||||
while (n > 0) {
|
while (n > 0) {
|
||||||
switch (m_trail.back()) {
|
switch (m_trail.back()) {
|
||||||
case trail_i::inc_level_i:
|
case trail_i::inc_level_i:
|
||||||
--n;
|
--n;
|
||||||
break;
|
break;
|
||||||
case trail_i::set_bound_i:
|
case trail_i::set_bound_i:
|
||||||
restore_bound();
|
restore_bound();
|
||||||
break;
|
break;
|
||||||
case trail_i::add_row_i:
|
case trail_i::add_row_i:
|
||||||
del_row(m_row_trail.back());
|
del_row(m_row_trail.back());
|
||||||
m_row_trail.pop_back();
|
m_row_trail.pop_back();
|
||||||
break;
|
break;
|
||||||
case trail_i::add_ineq_i:
|
case trail_i::add_ineq_i:
|
||||||
restore_ineq();
|
restore_ineq();
|
||||||
break;
|
break;
|
||||||
case trail_i::set_inconsistent_i:
|
case trail_i::set_inconsistent_i:
|
||||||
SASSERT(m_inconsistent);
|
SASSERT(m_inconsistent);
|
||||||
m_inconsistent = false;
|
m_inconsistent = false;
|
||||||
|
@ -147,45 +147,48 @@ namespace polysat {
|
||||||
|
|
||||||
template<typename Ext>
|
template<typename Ext>
|
||||||
lbool fixplex<Ext>::make_feasible() {
|
lbool fixplex<Ext>::make_feasible() {
|
||||||
if (m_inconsistent)
|
|
||||||
return l_false;
|
|
||||||
++m_stats.m_num_checks;
|
++m_stats.m_num_checks;
|
||||||
m_left_basis.reset();
|
m_left_basis.reset();
|
||||||
m_last_pivot_var = null_var;
|
m_num_repeated = 0;
|
||||||
unsigned num_iterations = 0;
|
|
||||||
unsigned num_repeated = 0;
|
|
||||||
var_t v = null_var;
|
|
||||||
m_bland = false;
|
m_bland = false;
|
||||||
|
unsigned num_iterations = 0;
|
||||||
SASSERT(well_formed());
|
SASSERT(well_formed());
|
||||||
while ((v = select_var_to_fix()) != null_var) {
|
while (m_limit.inc() && num_iterations < m_max_iterations) {
|
||||||
TRACE("polysat", display(tout << "v" << v << "\n"););
|
if (inconsistent())
|
||||||
if (!m_limit.inc() || num_iterations > m_max_iterations)
|
|
||||||
return l_undef;
|
|
||||||
check_blands_rule(v, num_repeated);
|
|
||||||
switch (make_var_feasible(v)) {
|
|
||||||
case l_true:
|
|
||||||
++num_iterations;
|
|
||||||
break;
|
|
||||||
case l_false:
|
|
||||||
m_to_patch.insert(v);
|
|
||||||
set_infeasible_base(v);
|
|
||||||
++m_stats.m_num_infeasible;
|
|
||||||
return l_false;
|
return l_false;
|
||||||
case l_undef:
|
if (!propagate())
|
||||||
m_to_patch.insert(v);
|
return l_false;
|
||||||
if (ineqs_are_violated())
|
if (is_satisfied())
|
||||||
return l_false;
|
return l_true;
|
||||||
|
if (!patch())
|
||||||
return l_undef;
|
return l_undef;
|
||||||
}
|
++num_iterations;
|
||||||
|
SASSERT(well_formed());
|
||||||
}
|
}
|
||||||
SASSERT(well_formed());
|
|
||||||
if (ineqs_are_violated())
|
|
||||||
return l_false;
|
|
||||||
if (ineqs_are_satisfied() && m_num_non_integral == 0)
|
|
||||||
return l_true;
|
|
||||||
return l_undef;
|
return l_undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Ext>
|
||||||
|
bool fixplex<Ext>::patch() {
|
||||||
|
var_t v = select_var_to_fix();
|
||||||
|
if (v == null_var)
|
||||||
|
return false;
|
||||||
|
check_blands_rule(v);
|
||||||
|
switch (make_var_feasible(v)) {
|
||||||
|
case l_true:
|
||||||
|
return true;
|
||||||
|
case l_false:
|
||||||
|
m_to_patch.insert(v);
|
||||||
|
set_infeasible_base(v);
|
||||||
|
return true;
|
||||||
|
case l_undef:
|
||||||
|
m_to_patch.insert(v);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
UNREACHABLE();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Ext>
|
template<typename Ext>
|
||||||
void fixplex<Ext>::add_row(var_t base_var, unsigned num_vars, var_t const* vars, rational const* coeffs) {
|
void fixplex<Ext>::add_row(var_t base_var, unsigned num_vars, var_t const* vars, rational const* coeffs) {
|
||||||
vector<numeral> _coeffs;
|
vector<numeral> _coeffs;
|
||||||
|
@ -277,6 +280,7 @@ namespace polysat {
|
||||||
m_vars[var].m_is_base = false;
|
m_vars[var].m_is_base = false;
|
||||||
m_vars[var].set_free();
|
m_vars[var].set_free();
|
||||||
m_rows[r.id()].m_base = null_var;
|
m_rows[r.id()].m_base = null_var;
|
||||||
|
m_non_integral.remove(r.id());
|
||||||
M.del(r);
|
M.del(r);
|
||||||
SASSERT(M.col_begin(var) == M.col_end(var));
|
SASSERT(M.col_begin(var) == M.col_end(var));
|
||||||
SASSERT(well_formed());
|
SASSERT(well_formed());
|
||||||
|
@ -414,8 +418,6 @@ namespace polysat {
|
||||||
numeral const& b = r.coeff();
|
numeral const& b = r.coeff();
|
||||||
if (x == y)
|
if (x == y)
|
||||||
continue;
|
continue;
|
||||||
if (y == m_last_pivot_var)
|
|
||||||
continue;
|
|
||||||
if (!has_minimal_trailing_zeros(y, b))
|
if (!has_minimal_trailing_zeros(y, b))
|
||||||
continue;
|
continue;
|
||||||
numeral new_y_value = solve_for(row_value - b * value(y), b);
|
numeral new_y_value = solve_for(row_value - b * value(y), b);
|
||||||
|
@ -478,7 +480,7 @@ namespace polysat {
|
||||||
row r = base2row(x);
|
row r = base2row(x);
|
||||||
for (auto const& c : M.col_entries(r)) {
|
for (auto const& c : M.col_entries(r)) {
|
||||||
var_t y = c.var();
|
var_t y = c.var();
|
||||||
if (x == y || y >= result || y == m_last_pivot_var)
|
if (x == y || y >= result)
|
||||||
continue;
|
continue;
|
||||||
numeral const& b = c.coeff();
|
numeral const& b = c.coeff();
|
||||||
if (can_improve(y, b)) {
|
if (can_improve(y, b)) {
|
||||||
|
@ -615,7 +617,8 @@ namespace polysat {
|
||||||
m_var2ineqs.reserve(std::max(v, w) + 1);
|
m_var2ineqs.reserve(std::max(v, w) + 1);
|
||||||
m_var2ineqs[v].push_back(idx);
|
m_var2ineqs[v].push_back(idx);
|
||||||
m_var2ineqs[w].push_back(idx);
|
m_var2ineqs[w].push_back(idx);
|
||||||
m_ineqs_to_check.push_back(idx);
|
touch_var(v);
|
||||||
|
m_ineqs_to_propagate.insert(idx);
|
||||||
m_trail.push_back(trail_i::add_ineq_i);
|
m_trail.push_back(trail_i::add_ineq_i);
|
||||||
m_ineqs.push_back(ineq(v, w, mk_leaf(dep), strict));
|
m_ineqs.push_back(ineq(v, w, mk_leaf(dep), strict));
|
||||||
}
|
}
|
||||||
|
@ -630,49 +633,32 @@ namespace polysat {
|
||||||
|
|
||||||
template<typename Ext>
|
template<typename Ext>
|
||||||
void fixplex<Ext>::touch_var(var_t v) {
|
void fixplex<Ext>::touch_var(var_t v) {
|
||||||
if (v >= m_var2ineqs.size())
|
m_touched_vars.insert(v);
|
||||||
return;
|
|
||||||
if (m_var_is_touched.get(v, false))
|
|
||||||
return;
|
|
||||||
m_var_is_touched.setx(v, true, false);
|
|
||||||
for (auto idx : m_var2ineqs[v]) {
|
|
||||||
if (!m_ineqs[idx].is_active) {
|
|
||||||
m_ineqs[idx].is_active = true;
|
|
||||||
m_ineqs_to_check.push_back(idx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Ext>
|
|
||||||
void fixplex<Ext>::reset_ineqs_to_check() {
|
|
||||||
for (auto idx : m_ineqs_to_check) {
|
|
||||||
if (idx >= m_ineqs.size())
|
|
||||||
continue;
|
|
||||||
auto& ineq = m_ineqs[idx];
|
|
||||||
m_var_is_touched.setx(ineq.v, false, false);
|
|
||||||
m_var_is_touched.setx(ineq.w, false, false);
|
|
||||||
ineq.is_active = false;
|
|
||||||
}
|
|
||||||
m_ineqs_to_check.reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the current assignment satisfies the inequalities
|
* Check if the current assignment satisfies the inequalities
|
||||||
*/
|
*/
|
||||||
template<typename Ext>
|
template<typename Ext>
|
||||||
bool fixplex<Ext>::ineqs_are_satisfied() {
|
bool fixplex<Ext>::is_satisfied() {
|
||||||
for (auto idx : m_ineqs_to_check) {
|
if (!m_to_patch.empty())
|
||||||
if (idx >= m_ineqs.size())
|
return false;
|
||||||
continue;
|
if (!m_non_integral.empty())
|
||||||
auto& ineq = m_ineqs[idx];
|
return false;
|
||||||
var_t v = ineq.v;
|
for (auto var : m_touched_vars) {
|
||||||
var_t w = ineq.w;
|
for (auto idx : m_var2ineqs[var]) {
|
||||||
if (ineq.strict && value(v) >= value(w))
|
if (idx >= m_ineqs.size())
|
||||||
return false;
|
continue;
|
||||||
if (!ineq.strict && value(v) > value(w))
|
auto& ineq = m_ineqs[idx];
|
||||||
return false;
|
var_t v = ineq.v;
|
||||||
|
var_t w = ineq.w;
|
||||||
|
if (ineq.strict && value(v) >= value(w))
|
||||||
|
return false;
|
||||||
|
if (!ineq.strict && value(v) > value(w))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
reset_ineqs_to_check();
|
m_touched_vars.reset();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -680,16 +666,16 @@ namespace polysat {
|
||||||
* Propagate bounds and check if the current inequalities are satisfied
|
* Propagate bounds and check if the current inequalities are satisfied
|
||||||
*/
|
*/
|
||||||
template<typename Ext>
|
template<typename Ext>
|
||||||
bool fixplex<Ext>::ineqs_are_violated() {
|
bool fixplex<Ext>::propagate() {
|
||||||
lbool r;
|
lbool r;
|
||||||
for (unsigned i = 0; i < m_ineqs_to_check.size(); ++i) {
|
for (unsigned idx : m_ineqs_to_propagate) {
|
||||||
unsigned idx = m_ineqs_to_check[i];
|
|
||||||
if (idx >= m_ineqs.size())
|
if (idx >= m_ineqs.size())
|
||||||
continue;
|
continue;
|
||||||
if (r = propagate_ineqs(m_ineqs[idx]), r == l_false)
|
if (r = propagate_ineqs(m_ineqs[idx]), r == l_false)
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
m_ineqs_to_propagate.reset();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -799,7 +785,7 @@ namespace polysat {
|
||||||
z = base(r)
|
z = base(r)
|
||||||
d = base_coeff(r)
|
d = base_coeff(r)
|
||||||
b1 = (b >> tz(b))
|
b1 = (b >> tz(b))
|
||||||
c1 = (c >> (tz(c) - tz(b)))
|
c1 = (c >> tz(b))
|
||||||
r <- b1 * r - c1 * r_x
|
r <- b1 * r - c1 * r_x
|
||||||
value(r) := b1 * value(r) - b1 * old_value(y) - c1 * value(r_x)
|
value(r) := b1 * value(r) - b1 * old_value(y) - c1 * value(r_x)
|
||||||
value(z) := - value(r) / d
|
value(z) := - value(r) / d
|
||||||
|
@ -808,7 +794,6 @@ namespace polysat {
|
||||||
template<typename Ext>
|
template<typename Ext>
|
||||||
void fixplex<Ext>::pivot(var_t x, var_t y, numeral const& b, numeral const& new_value) {
|
void fixplex<Ext>::pivot(var_t x, var_t y, numeral const& b, numeral const& new_value) {
|
||||||
++m_stats.m_num_pivots;
|
++m_stats.m_num_pivots;
|
||||||
m_last_pivot_var = x;
|
|
||||||
SASSERT(is_base(x));
|
SASSERT(is_base(x));
|
||||||
SASSERT(!is_base(y));
|
SASSERT(!is_base(y));
|
||||||
var_info& xI = m_vars[x];
|
var_info& xI = m_vars[x];
|
||||||
|
@ -909,7 +894,7 @@ namespace polysat {
|
||||||
m_inconsistent = true;
|
m_inconsistent = true;
|
||||||
m_trail.push_back(trail_i::set_inconsistent_i);
|
m_trail.push_back(trail_i::set_inconsistent_i);
|
||||||
m_deps.linearize(todo, m_unsat_core);
|
m_deps.linearize(todo, m_unsat_core);
|
||||||
|
++m_stats.m_num_infeasible;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -975,15 +960,15 @@ namespace polysat {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ext>
|
template<typename Ext>
|
||||||
void fixplex<Ext>::check_blands_rule(var_t v, unsigned& num_repeated) {
|
void fixplex<Ext>::check_blands_rule(var_t v) {
|
||||||
if (m_bland)
|
if (m_bland)
|
||||||
return;
|
return;
|
||||||
if (!m_left_basis.contains(v))
|
if (!m_left_basis.contains(v))
|
||||||
m_left_basis.insert(v);
|
m_left_basis.insert(v);
|
||||||
else {
|
else {
|
||||||
++num_repeated;
|
++m_num_repeated;
|
||||||
m_bland = num_repeated > m_blands_rule_threshold;
|
m_bland = m_num_repeated > m_blands_rule_threshold;
|
||||||
CTRACE("polysat", m_bland, tout << "using blands rule, " << num_repeated << "\n";);
|
CTRACE("polysat", m_bland, tout << "using blands rule, " << m_num_repeated << "\n";);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1038,12 +1023,11 @@ namespace polysat {
|
||||||
row r = base2row(x);
|
row r = base2row(x);
|
||||||
m_vars[x].m_value = solve_for(row2value(r), row2base_coeff(r));
|
m_vars[x].m_value = solve_for(row2value(r), row2base_coeff(r));
|
||||||
touch_var(x);
|
touch_var(x);
|
||||||
bool was_integral = row_is_integral(r);
|
|
||||||
m_rows[r.id()].m_integral = is_solved(r);
|
m_rows[r.id()].m_integral = is_solved(r);
|
||||||
if (was_integral && !row_is_integral(r))
|
if (row_is_integral(r))
|
||||||
++m_num_non_integral;
|
m_non_integral.remove(r.id());
|
||||||
else if (!was_integral && row_is_integral(r))
|
else
|
||||||
--m_num_non_integral;
|
m_non_integral.insert(r.id());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1152,6 +1136,7 @@ namespace polysat {
|
||||||
m_var_eqs.push_back(var_eq(x, y, r1, r2));
|
m_var_eqs.push_back(var_eq(x, y, r1, r2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
template<typename Ext>
|
template<typename Ext>
|
||||||
lbool fixplex<Ext>::propagate_bounds() {
|
lbool fixplex<Ext>::propagate_bounds() {
|
||||||
lbool r = l_true;
|
lbool r = l_true;
|
||||||
|
@ -1163,6 +1148,7 @@ namespace polysat {
|
||||||
return r;
|
return r;
|
||||||
return l_true;
|
return l_true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// DFS search propagating inequalities
|
// DFS search propagating inequalities
|
||||||
|
@ -1185,12 +1171,9 @@ namespace polysat {
|
||||||
// std::cout << "propagate " << i0 << "\n";
|
// std::cout << "propagate " << i0 << "\n";
|
||||||
if (!propagate_ineq(i0))
|
if (!propagate_ineq(i0))
|
||||||
return l_false;
|
return l_false;
|
||||||
if (old_lo == m_vars[i0.w].lo && i0.is_touched)
|
|
||||||
return l_true;
|
|
||||||
on_stack.reset();
|
on_stack.reset();
|
||||||
stack.reset();
|
stack.reset();
|
||||||
stack.push_back(std::make_pair(0, i0));
|
stack.push_back(std::make_pair(0, i0));
|
||||||
i0.is_touched = true;
|
|
||||||
on_stack.insert(i0.v);
|
on_stack.insert(i0.v);
|
||||||
while (!stack.empty()) {
|
while (!stack.empty()) {
|
||||||
if (!m_limit.inc())
|
if (!m_limit.inc())
|
||||||
|
@ -1209,8 +1192,7 @@ namespace polysat {
|
||||||
return l_false;
|
return l_false;
|
||||||
|
|
||||||
bool is_onstack = on_stack.contains(i_out.w);
|
bool is_onstack = on_stack.contains(i_out.w);
|
||||||
if ((old_lo != m_vars[i_out.w].lo || !i_out.is_touched) && !is_onstack) {
|
if ((old_lo != m_vars[i_out.w].lo) && !is_onstack) {
|
||||||
i_out.is_touched = true;
|
|
||||||
on_stack.insert(i_out.w);
|
on_stack.insert(i_out.w);
|
||||||
stack.back().first = ineq_out + 1;
|
stack.back().first = ineq_out + 1;
|
||||||
stack.push_back(std::make_pair(0, i_out));
|
stack.push_back(std::make_pair(0, i_out));
|
||||||
|
@ -1528,6 +1510,7 @@ namespace polysat {
|
||||||
m_deps.linearize(a, m_unsat_core);
|
m_deps.linearize(a, m_unsat_core);
|
||||||
SASSERT(!m_inconsistent);
|
SASSERT(!m_inconsistent);
|
||||||
m_inconsistent = true;
|
m_inconsistent = true;
|
||||||
|
++m_stats.m_num_infeasible;
|
||||||
m_trail.push_back(trail_i::set_inconsistent_i);
|
m_trail.push_back(trail_i::set_inconsistent_i);
|
||||||
TRACE("polysat", tout << "core: " << m_unsat_core << "\n";);
|
TRACE("polysat", tout << "core: " << m_unsat_core << "\n";);
|
||||||
}
|
}
|
||||||
|
@ -1657,7 +1640,7 @@ return d;
|
||||||
st.update("fixplex num pivots", m_stats.m_num_pivots);
|
st.update("fixplex num pivots", m_stats.m_num_pivots);
|
||||||
st.update("fixplex num infeasible", m_stats.m_num_infeasible);
|
st.update("fixplex num infeasible", m_stats.m_num_infeasible);
|
||||||
st.update("fixplex num checks", m_stats.m_num_checks);
|
st.update("fixplex num checks", m_stats.m_num_checks);
|
||||||
st.update("fixplex num non-integral", m_num_non_integral);
|
st.update("fixplex num non-integral", m_non_integral.num_elems());
|
||||||
st.update("fixplex num approximated row additions", m_stats.m_num_approx);
|
st.update("fixplex num approximated row additions", m_stats.m_num_approx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,21 +71,18 @@ namespace polysat {
|
||||||
fp.set_bounds(x, 3, 4, 1);
|
fp.set_bounds(x, 3, 4, 1);
|
||||||
fp.set_bounds(y, 3, 6, 2);
|
fp.set_bounds(y, 3, 6, 2);
|
||||||
fp.run();
|
fp.run();
|
||||||
fp.propagate_bounds();
|
|
||||||
fp.reset();
|
fp.reset();
|
||||||
coeffs[2] = 0ull - 1;
|
coeffs[2] = 0ull - 1;
|
||||||
fp.add_row(x, 3, ys, coeffs);
|
fp.add_row(x, 3, ys, coeffs);
|
||||||
fp.set_bounds(x, 3, 4, 1);
|
fp.set_bounds(x, 3, 4, 1);
|
||||||
fp.set_bounds(y, 3, 6, 2);
|
fp.set_bounds(y, 3, 6, 2);
|
||||||
fp.run();
|
fp.run();
|
||||||
fp.propagate_bounds();
|
|
||||||
fp.reset();
|
fp.reset();
|
||||||
fp.add_row(x, 3, ys, coeffs);
|
fp.add_row(x, 3, ys, coeffs);
|
||||||
fp.set_bounds(x, 3, 4, 1);
|
fp.set_bounds(x, 3, 4, 1);
|
||||||
fp.set_bounds(y, 3, 6, 2);
|
fp.set_bounds(y, 3, 6, 2);
|
||||||
fp.set_bounds(z, 1, 8, 3);
|
fp.set_bounds(z, 1, 8, 3);
|
||||||
fp.run();
|
fp.run();
|
||||||
fp.propagate_bounds();
|
|
||||||
fp.reset();
|
fp.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,31 +369,35 @@ namespace polysat {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void save_scenario(
|
static void save_scenario(
|
||||||
|
unsigned id,
|
||||||
vector<svector<std::pair<unsigned, uint64_t>>> const& rows,
|
vector<svector<std::pair<unsigned, uint64_t>>> const& rows,
|
||||||
svector<ineq> const& ineqs,
|
svector<ineq> const& ineqs,
|
||||||
vector<mod_interval<uint64_t>> const& bounds) {
|
vector<mod_interval<uint64_t>> const& bounds) {
|
||||||
std::cout << "static void scenario() {";
|
std::cout << "static void scenario" << id << "() {\n";
|
||||||
std::cout << " vector<svector<std::pair<unsigned, uint64_t>>> rows\n;";
|
std::cout << " vector<svector<std::pair<unsigned, uint64_t>>> rows;\n";
|
||||||
std::cout << " svector<ineq> ineqs\n;";
|
std::cout << " svector<ineq> ineqs;\n";
|
||||||
std::cout << " vector<mod_interval<uint64_t>> bounds\n";
|
std::cout << " vector<mod_interval<uint64_t>> bounds;\n";
|
||||||
for (auto row : rows) {
|
for (auto const& row : rows) {
|
||||||
std::cout << " rows.push_back(svector<std::pair<unsigned, uint64_t>>());\n";
|
std::cout << " rows.push_back(svector<std::pair<unsigned, uint64_t>>());\n";
|
||||||
for (auto col : row)
|
for (auto col : row)
|
||||||
std::cout << " rows.back().push_back(std::make_pair(" << col.first << ", " << col.second << ");\n";
|
std::cout << " rows.back().push_back(std::make_pair(" << col.first << ", " << col.second << ");\n";
|
||||||
}
|
}
|
||||||
for (auto ineq : ineqs)
|
for (auto const& ineq : ineqs)
|
||||||
std::cout << " ineqs.push_back(ineq(" << ineq.v << ", " << ineq.w << " " << ineq.strict << ");\n";
|
std::cout << " ineqs.push_back(ineq(" << ineq.v << ", " << ineq.w << ", 0, " << (ineq.strict?"true":"false") << ");\n";
|
||||||
for (auto bound : bounds)
|
for (auto const& bound : bounds)
|
||||||
std::cout << " bounds.push_back(mod_interval<uint64_t>(" << bound.lo << ", " << bound.hi << ");\n";
|
std::cout << " bounds.push_back(mod_interval<uint64_t>(" << bound.lo << ", " << bound.hi << ");\n";
|
||||||
std::cout << " test_lp(rows, ineqs, bounds);\n}\n";
|
std::cout << " test_lp(rows, ineqs, bounds); \n }\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned num_test = 0;
|
||||||
|
|
||||||
static void test_lp(
|
static void test_lp(
|
||||||
vector<svector<std::pair<unsigned, uint64_t>>> const& rows,
|
vector<svector<std::pair<unsigned, uint64_t>>> const& rows,
|
||||||
svector<ineq> const& ineqs,
|
svector<ineq> const& ineqs,
|
||||||
vector<mod_interval<uint64_t>> const& bounds) {
|
vector<mod_interval<uint64_t>> const& bounds) {
|
||||||
|
|
||||||
|
// save_scenario(++num_test, rows, ineqs, bounds);
|
||||||
|
|
||||||
unsigned num_vars = 0;
|
unsigned num_vars = 0;
|
||||||
for (auto const& row : rows)
|
for (auto const& row : rows)
|
||||||
for (auto [v, c] : row)
|
for (auto [v, c] : row)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue