mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 01:25:31 +00:00
na
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
commit
dcdbbfb925
144 changed files with 1528 additions and 517 deletions
|
@ -324,6 +324,7 @@ static void set_upper(impq & u, bool & inf_u, impq const & v) {
|
|||
}
|
||||
}
|
||||
|
||||
// this function assumes that all basic columns dependend on j are feasible
|
||||
bool int_solver::get_freedom_interval_for_column(unsigned j, bool & inf_l, impq & l, bool & inf_u, impq & u, mpq & m) {
|
||||
if (lrac.m_r_heading[j] >= 0) // the basic var
|
||||
return false;
|
||||
|
@ -336,62 +337,52 @@ bool int_solver::get_freedom_interval_for_column(unsigned j, bool & inf_l, impq
|
|||
l = u = zero_of_type<impq>();
|
||||
m = mpq(1);
|
||||
|
||||
if (has_lower(j)) {
|
||||
if (has_lower(j))
|
||||
set_lower(l, inf_l, lower_bound(j) - xj);
|
||||
}
|
||||
if (has_upper(j)) {
|
||||
|
||||
if (has_upper(j))
|
||||
set_upper(u, inf_u, upper_bound(j) - xj);
|
||||
}
|
||||
|
||||
|
||||
unsigned row_index;
|
||||
lp_assert(settings().use_tableau());
|
||||
const auto & A = lra.A_r();
|
||||
unsigned rounds = 0;
|
||||
for (auto c : A.column(j)) {
|
||||
row_index = c.var();
|
||||
const mpq & a = c.coeff();
|
||||
unsigned i = lrac.m_r_basis[row_index];
|
||||
TRACE("random_update", tout << "i = " << i << ", a = " << a << "\n";);
|
||||
if (column_is_int(i) && !a.is_int())
|
||||
m = lcm(m, denominator(a));
|
||||
}
|
||||
TRACE("random_update", tout << "m = " << m << "\n";);
|
||||
|
||||
auto delta = [](mpq const& x, impq const& y, impq const& z) {
|
||||
if (x.is_one())
|
||||
return y - z;
|
||||
if (x.is_minus_one())
|
||||
return z - y;
|
||||
return (y - z) / x;
|
||||
};
|
||||
|
||||
for (auto c : A.column(j)) {
|
||||
if (!inf_l && !inf_u && l >= u) break;
|
||||
row_index = c.var();
|
||||
unsigned row_index = c.var();
|
||||
const mpq & a = c.coeff();
|
||||
unsigned i = lrac.m_r_basis[row_index];
|
||||
impq const & xi = get_value(i);
|
||||
lp_assert(lrac.m_r_solver.column_is_feasible(i));
|
||||
if (column_is_int(i) && !a.is_int())
|
||||
m = lcm(m, denominator(a));
|
||||
|
||||
#define SET_BOUND(_fn_, a, b, x, y, z) \
|
||||
if (x.is_one()) \
|
||||
_fn_(a, b, y - z); \
|
||||
else if (x.is_minus_one()) \
|
||||
_fn_(a, b, z - y); \
|
||||
else if (z == y) \
|
||||
_fn_(a, b, zero_of_type<impq>()); \
|
||||
else \
|
||||
{ _fn_(a, b, (y - z)/x); } \
|
||||
|
||||
if (!inf_l && !inf_u) {
|
||||
if (l == u)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (a.is_neg()) {
|
||||
if (has_lower(i)) {
|
||||
SET_BOUND(set_lower, l, inf_l, a, xi, lrac.m_r_lower_bounds()[i]);
|
||||
}
|
||||
if (has_upper(i)) {
|
||||
SET_BOUND(set_upper, u, inf_u, a, xi, lrac.m_r_upper_bounds()[i]);
|
||||
}
|
||||
if (has_lower(i))
|
||||
set_lower(l, inf_l, delta(a, xi, lrac.m_r_lower_bounds()[i]));
|
||||
if (has_upper(i))
|
||||
set_upper(u, inf_u, delta(a, xi, lrac.m_r_upper_bounds()[i]));
|
||||
}
|
||||
else {
|
||||
if (has_upper(i)) {
|
||||
SET_BOUND(set_lower, l, inf_l, a, xi, lrac.m_r_upper_bounds()[i]);
|
||||
}
|
||||
if (has_lower(i)) {
|
||||
SET_BOUND(set_upper, u, inf_u, a, xi, lrac.m_r_lower_bounds()[i]);
|
||||
}
|
||||
if (has_upper(i))
|
||||
set_lower(l, inf_l, delta(a, xi, lrac.m_r_upper_bounds()[i]));
|
||||
if (has_lower(i))
|
||||
set_upper(u, inf_u, delta(a, xi, lrac.m_r_lower_bounds()[i]));
|
||||
}
|
||||
++rounds;
|
||||
}
|
||||
|
||||
l += xj;
|
||||
|
@ -545,7 +536,7 @@ for (const auto &c : row)
|
|||
}
|
||||
std::ostream& int_solver::display_row_info(std::ostream & out, unsigned row_index) const {
|
||||
auto & rslv = lrac.m_r_solver;
|
||||
auto row = rslv.m_A.m_rows[row_index];
|
||||
auto const& row = rslv.m_A.m_rows[row_index];
|
||||
return display_row(out, row);
|
||||
}
|
||||
|
||||
|
|
|
@ -179,11 +179,17 @@ void lar_core_solver::solve() {
|
|||
}
|
||||
lp_assert(!settings().use_tableau() || r_basis_is_OK());
|
||||
}
|
||||
if (m_r_solver.get_status() == lp_status::INFEASIBLE) {
|
||||
switch (m_r_solver.get_status())
|
||||
{
|
||||
case lp_status::INFEASIBLE:
|
||||
fill_not_improvable_zero_sum();
|
||||
}
|
||||
else if (m_r_solver.get_status() != lp_status::UNBOUNDED) {
|
||||
break;
|
||||
case lp_status::CANCELLED:
|
||||
case lp_status::UNBOUNDED: // do nothing in these cases
|
||||
break;
|
||||
default: // adjust the status to optimal
|
||||
m_r_solver.set_status(lp_status::OPTIMAL);
|
||||
break;
|
||||
}
|
||||
lp_assert(r_basis_is_OK());
|
||||
lp_assert(m_r_solver.non_basic_columns_are_set_correctly());
|
||||
|
|
|
@ -798,6 +798,18 @@ namespace lp {
|
|||
}
|
||||
|
||||
|
||||
// this function just looks at the status
|
||||
bool lar_solver::is_feasible() const {
|
||||
switch (this->get_status()) {
|
||||
case lp_status::OPTIMAL:
|
||||
case lp_status::FEASIBLE:
|
||||
case lp_status::UNBOUNDED:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
numeric_pair<mpq> lar_solver::get_basic_var_value_from_row(unsigned i) {
|
||||
numeric_pair<mpq> r = zero_of_type<numeric_pair<mpq>>();
|
||||
|
||||
|
|
|
@ -296,6 +296,8 @@ class lar_solver : public column_namer {
|
|||
mutable mpq m_delta;
|
||||
|
||||
public:
|
||||
// this function just looks at the status
|
||||
bool is_feasible() const;
|
||||
const map<mpq, unsigned, obj_hash<mpq>, default_eq<mpq>>& fixed_var_table_int() const {
|
||||
return m_fixed_var_table_int;
|
||||
}
|
||||
|
@ -555,6 +557,10 @@ public:
|
|||
return m_mpq_lar_core_solver.column_is_bounded(j);
|
||||
}
|
||||
|
||||
bool check_feasible() const {
|
||||
return m_mpq_lar_core_solver.m_r_solver.calc_current_x_is_feasible_include_non_basis();
|
||||
}
|
||||
|
||||
std::pair<constraint_index, constraint_index> add_equality(lpvar j, lpvar k);
|
||||
|
||||
inline void get_bound_constraint_witnesses_for_column(unsigned j, constraint_index & lc, constraint_index & uc) const {
|
||||
|
|
|
@ -116,28 +116,42 @@ class lp_bound_propagator {
|
|||
|
||||
|
||||
map<mpq, unsigned, obj_hash<mpq>, default_eq<mpq>> m_val2fixed_row;
|
||||
|
||||
bool is_fixed_row(unsigned r, unsigned & x) {
|
||||
x = UINT_MAX;
|
||||
const auto & row = lp().get_row(r);
|
||||
for (unsigned k = 0; k < row.size(); k++) {
|
||||
const auto& c = row[k];
|
||||
if (column_is_fixed(c.var()))
|
||||
continue;
|
||||
if (x != UINT_MAX)
|
||||
return false;
|
||||
x = c.var();
|
||||
}
|
||||
return x != UINT_MAX;
|
||||
}
|
||||
|
||||
void try_add_equation_with_internal_fixed_tables(unsigned r1, vertex const* v) {
|
||||
void try_add_equation_with_internal_fixed_tables(unsigned r1) {
|
||||
SASSERT(m_fixed_vertex);
|
||||
if (v != m_root)
|
||||
unsigned v1, v2;
|
||||
if (!is_fixed_row(r1, v1))
|
||||
return;
|
||||
unsigned v1 = v->column();
|
||||
unsigned r2 = UINT_MAX;
|
||||
if (!m_val2fixed_row.find(val(v1), r2) || r2 >= lp().row_count()) {
|
||||
m_val2fixed_row.insert(val(v1), r1);
|
||||
return;
|
||||
}
|
||||
unsigned v2, v3;
|
||||
int polarity;
|
||||
if (!is_tree_offset_row(r2, v2, v3, polarity) || !not_set(v3) ||
|
||||
is_int(v1) != is_int(v2) || val(v1) != val(v2)) {
|
||||
if (!is_fixed_row(r2, v2) || val(v1) != val(v2) || is_int(v1) != is_int(v2)) {
|
||||
m_val2fixed_row.insert(val(v1), r1);
|
||||
return;
|
||||
}
|
||||
if (v1 == v2)
|
||||
return;
|
||||
|
||||
explanation ex;
|
||||
explain_fixed_in_row(r1, ex);
|
||||
explain_fixed_in_row(r2, ex);
|
||||
TRACE("eq", print_row(tout, r1); print_row(tout, r2); tout << v1 << " == " << v2 << " = " << val(v1) << "\n");
|
||||
add_eq_on_columns(ex, v1, v2, true);
|
||||
}
|
||||
|
||||
|
@ -146,7 +160,7 @@ class lp_bound_propagator {
|
|||
unsigned v_j = v->column();
|
||||
unsigned j = null_lpvar;
|
||||
if (!lp().find_in_fixed_tables(val(v_j), is_int(v_j), j)) {
|
||||
// try_add_equation_with_internal_fixed_tables(row_index, v);
|
||||
try_add_equation_with_internal_fixed_tables(row_index);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -100,10 +100,7 @@ template <typename T, typename X> bool lp_dual_core_solver<T, X>::done() {
|
|||
if (this->get_status() == lp_status::OPTIMAL) {
|
||||
return true;
|
||||
}
|
||||
if (this->total_iterations() > this->m_settings.max_total_number_of_iterations) { // debug !!!!
|
||||
this->set_status(lp_status::ITERATIONS_EXHAUSTED);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false; // todo, need to be more cases
|
||||
}
|
||||
|
||||
|
@ -747,6 +744,6 @@ template <typename T, typename X> void lp_dual_core_solver<T, X>::solve() { // s
|
|||
one_iteration();
|
||||
} while (this->get_status() != lp_status::FLOATING_POINT_ERROR && this->get_status() != lp_status::DUAL_UNBOUNDED && this->get_status() != lp_status::OPTIMAL &&
|
||||
this->iters_with_no_cost_growing() <= this->m_settings.max_number_of_iterations_with_no_improvements
|
||||
&& this->total_iterations() <= this->m_settings.max_total_number_of_iterations);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,9 +31,6 @@ template <typename T, typename X> void lp_dual_simplex<T, X>::decide_on_status_a
|
|||
break;
|
||||
case lp_status::DUAL_UNBOUNDED:
|
||||
lp_unreachable();
|
||||
case lp_status::ITERATIONS_EXHAUSTED:
|
||||
this->m_status = lp_status::ITERATIONS_EXHAUSTED;
|
||||
break;
|
||||
case lp_status::TIME_EXHAUSTED:
|
||||
this->m_status = lp_status::TIME_EXHAUSTED;
|
||||
break;
|
||||
|
|
|
@ -956,8 +956,6 @@ template <typename T, typename X> unsigned lp_primal_core_solver<T, X>::solve()
|
|||
&&
|
||||
this->iters_with_no_cost_growing() <= this->m_settings.max_number_of_iterations_with_no_improvements
|
||||
&&
|
||||
this->total_iterations() <= this->m_settings.max_total_number_of_iterations
|
||||
&&
|
||||
!(this->current_x_is_feasible() && this->m_look_for_feasible_solution_only));
|
||||
|
||||
lp_assert(this->get_status() == lp_status::FLOATING_POINT_ERROR
|
||||
|
@ -1097,10 +1095,8 @@ template <typename T, typename X> bool lp_primal_core_solver<T, X>::done() {
|
|||
return true;
|
||||
}
|
||||
if (this->m_iters_with_no_cost_growing >= this->m_settings.max_number_of_iterations_with_no_improvements) {
|
||||
this->get_status() = lp_status::ITERATIONS_EXHAUSTED; return true;
|
||||
}
|
||||
if (this->total_iterations() >= this->m_settings.max_total_number_of_iterations) {
|
||||
this->get_status() = lp_status::ITERATIONS_EXHAUSTED; return true;
|
||||
this->set_status(lp_status::CANCELLED);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -182,9 +182,7 @@ unsigned lp_primal_core_solver<T, X>::solve_with_tableau() {
|
|||
if (this->m_settings.get_cancel_flag()
|
||||
||
|
||||
this->iters_with_no_cost_growing() > this->m_settings.max_number_of_iterations_with_no_improvements
|
||||
||
|
||||
this->total_iterations() > this->m_settings.max_total_number_of_iterations
|
||||
) {
|
||||
) {
|
||||
this->set_status(lp_status::CANCELLED);
|
||||
break; // from the loop
|
||||
}
|
||||
|
|
|
@ -71,7 +71,6 @@ enum class lp_status {
|
|||
FEASIBLE,
|
||||
FLOATING_POINT_ERROR,
|
||||
TIME_EXHAUSTED,
|
||||
ITERATIONS_EXHAUSTED,
|
||||
EMPTY,
|
||||
UNSTABLE,
|
||||
CANCELLED
|
||||
|
@ -210,7 +209,6 @@ public:
|
|||
double harris_feasibility_tolerance { 1e-7 }; // page 179 of Istvan Maros
|
||||
double ignore_epsilon_of_harris { 10e-5 };
|
||||
unsigned max_number_of_iterations_with_no_improvements { 2000000 };
|
||||
unsigned max_total_number_of_iterations { 20000000 };
|
||||
double time_limit; // the maximum time limit of the total run time in seconds
|
||||
// dual section
|
||||
double dual_feasibility_tolerance { 1e-7 }; // page 71 of the PhD thesis of Achim Koberstein
|
||||
|
|
|
@ -45,7 +45,6 @@ const char* lp_status_to_string(lp_status status) {
|
|||
case lp_status::FEASIBLE: return "FEASIBLE";
|
||||
case lp_status::FLOATING_POINT_ERROR: return "FLOATING_POINT_ERROR";
|
||||
case lp_status::TIME_EXHAUSTED: return "TIME_EXHAUSTED";
|
||||
case lp_status::ITERATIONS_EXHAUSTED: return "ITERATIONS_EXHAUSTED";
|
||||
case lp_status::EMPTY: return "EMPTY";
|
||||
case lp_status::UNSTABLE: return "UNSTABLE";
|
||||
default:
|
||||
|
@ -62,7 +61,6 @@ lp_status lp_status_from_string(std::string status) {
|
|||
if (status == "FEASIBLE") return lp_status::FEASIBLE;
|
||||
if (status == "FLOATING_POINT_ERROR") return lp_status::FLOATING_POINT_ERROR;
|
||||
if (status == "TIME_EXHAUSTED") return lp_status::TIME_EXHAUSTED;
|
||||
if (status == "ITERATIONS_EXHAUSTED") return lp_status::ITERATIONS_EXHAUSTED;
|
||||
if (status == "EMPTY") return lp_status::EMPTY;
|
||||
lp_unreachable();
|
||||
return lp_status::UNKNOWN; // it is unreachable
|
||||
|
|
|
@ -158,13 +158,7 @@ public:
|
|||
m_settings.time_limit = time_limit_in_seconds;
|
||||
}
|
||||
|
||||
void set_max_iterations_per_stage(unsigned max_iterations) {
|
||||
m_settings.max_total_number_of_iterations = max_iterations;
|
||||
}
|
||||
|
||||
unsigned get_max_iterations_per_stage() const {
|
||||
return m_settings.max_total_number_of_iterations;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool problem_is_empty();
|
||||
|
||||
|
|
|
@ -51,25 +51,23 @@ bool random_updater::shift_var(unsigned j) {
|
|||
|
||||
|
||||
void random_updater::update() {
|
||||
// VERIFY(m_lar_solver.check_feasible());
|
||||
auto columns = m_var_set.index(); // m_var_set is going to change during the loop
|
||||
for (auto j : columns) {
|
||||
if (!m_var_set.contains(j)) {
|
||||
TRACE("lar_solver_rand", tout << "skipped " << j << "\n";);
|
||||
continue;
|
||||
}
|
||||
if (!m_lar_solver.is_base(j)) {
|
||||
if (!m_lar_solver.is_base(j))
|
||||
shift_var(j);
|
||||
} else {
|
||||
else {
|
||||
unsigned row_index = m_lar_solver.r_heading()[j];
|
||||
for (auto & row_c : m_lar_solver.get_row(row_index)) {
|
||||
unsigned cj = row_c.var();
|
||||
if (!m_lar_solver.is_base(cj) &&
|
||||
!m_lar_solver.column_is_fixed(cj)
|
||||
&&
|
||||
shift_var(cj)
|
||||
) {
|
||||
break; // done with the basic var j
|
||||
}
|
||||
!m_lar_solver.column_is_fixed(cj) &&
|
||||
shift_var(cj))
|
||||
break; // done with the basic var j
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -220,6 +220,8 @@ public:
|
|||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
char const* name() const override { return "subpaving"; }
|
||||
|
||||
tactic * translate(ast_manager & m) override {
|
||||
return alloc(subpaving_tactic, m, m_params);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue