3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-15 13:28:47 +00:00

replace lp_assert(false) with UNREACHABLE

This commit is contained in:
Lev Nachmanson 2023-03-08 09:27:09 -08:00
parent 3efe91c3e3
commit 8b0aa22631
23 changed files with 654 additions and 891 deletions

View file

@ -139,7 +139,7 @@ template <typename T, typename X> void core_solver_pretty_printer<T, X>::adjust_
case column_type::free_column:
break;
default:
lp_assert(false);
UNREACHABLE();
break;
}
}

View file

@ -114,9 +114,6 @@ public:
}
}
void copy_column_to_indexed_vector(unsigned entering, indexed_vector<mpq> &w ) const {
lp_assert(false); // not implemented
}
general_matrix operator*(const general_matrix & m) const {
lp_assert(m.row_count() == column_count());
general_matrix ret(row_count(), m.column_count());
@ -172,23 +169,6 @@ public:
return r;
}
// bool create_upper_triangle(general_matrix& m, vector<mpq>& x) {
// for (unsigned i = 1; i < m.row_count(); i++) {
// lp_assert(false); // to be continued
// }
// }
// bool solve_A_x_equal_b(const general_matrix& m, vector<mpq>& x, const vector<mpq>& b) const {
// auto m_copy = m;
// // for square matrices
// lp_assert(row_count() == b.size());
// lp_assert(x.size() == column_count());
// lp_assert(row_count() == column_count());
// x = b;
// create_upper_triangle(copy_of_m, x);
// solve_on_triangle(copy_of_m, x);
// }
//
void transpose_rows(unsigned i, unsigned l) {
lp_assert(i != l);

View file

@ -44,7 +44,7 @@ inline std::string lconstraint_kind_string(lconstraint_kind t) {
case EQ: return std::string("=");
case NE: return std::string("!=");
}
lp_unreachable();
UNREACHABLE();
return std::string(); // it is unreachable
}

View file

@ -159,7 +159,7 @@ public:
case column_type::fixed:
return true;
default:
lp_assert(false);
UNREACHABLE();
}
return false;
}
@ -174,7 +174,7 @@ public:
case column_type::fixed:
return true;
default:
lp_assert(false);
UNREACHABLE();
}
return false;
}

View file

@ -466,7 +466,7 @@ namespace lp {
default:
lp_unreachable(); // wrong mode
UNREACHABLE(); // wrong mode
}
return false;
}
@ -802,7 +802,7 @@ namespace lp {
case GT: return left_side_val > constr.rhs();
case EQ: return left_side_val == constr.rhs();
default:
lp_unreachable();
UNREACHABLE();
}
return false; // it is unreachable
}
@ -857,7 +857,7 @@ namespace lp {
case EQ: lp_assert(rs != zero_of_type<mpq>());
break;
default:
lp_assert(false);
UNREACHABLE();
return false;
}
#endif
@ -1816,7 +1816,7 @@ namespace lp {
adjust_initial_state_for_tableau_rows();
break;
case simplex_strategy_enum::tableau_costs:
lp_assert(false); // not implemented
UNREACHABLE(); // not implemented
case simplex_strategy_enum::undecided:
adjust_initial_state_for_tableau_rows();
break;
@ -1905,7 +1905,7 @@ namespace lp {
}
default:
lp_unreachable();
UNREACHABLE();
}
if (m_mpq_lar_core_solver.m_r_upper_bounds[j] == m_mpq_lar_core_solver.m_r_lower_bounds[j]) {
m_mpq_lar_core_solver.m_column_types[j] = column_type::fixed;
@ -1959,7 +1959,7 @@ namespace lp {
}
default:
lp_unreachable();
UNREACHABLE();
}
}
@ -2009,7 +2009,7 @@ namespace lp {
}
default:
lp_unreachable();
UNREACHABLE();
}
}
void lar_solver::update_bound_with_no_ub_no_lb(var_index j, lconstraint_kind kind, const mpq& right_side, constraint_index ci) {
@ -2050,7 +2050,7 @@ namespace lp {
}
default:
lp_unreachable();
UNREACHABLE();
}
}

View file

@ -179,7 +179,7 @@ public:
return p.coeff().is_one();
}
}
lp_unreachable();
UNREACHABLE();
return false;
}

View file

@ -45,7 +45,7 @@ inline std::string lia_move_to_string(lia_move m) {
case lia_move::unsat:
return "unsat";
default:
lp_assert(false);
UNREACHABLE();
};
return "strange";
}

View file

@ -27,7 +27,6 @@ template bool lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::prin
template bool lp::lp_core_solver_base<lp::mpq, lp::mpq>::basis_heading_is_correct() const ;
template bool lp::lp_core_solver_base<lp::mpq, lp::mpq>::column_is_dual_feasible(unsigned int) const;
template bool lp::lp_core_solver_base<lp::mpq, lp::mpq>::print_statistics_with_iterations_and_nonzeroes_and_cost_and_check_that_the_time_is_over(char const*, std::ostream &);
template void lp::lp_core_solver_base<lp::mpq, lp::mpq>::set_non_basic_x_to_correct_bounds();
template void lp::lp_core_solver_base<lp::mpq, lp::mpq>::add_delta_to_entering(unsigned int, const lp::mpq&);
template void lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::init();
template void lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::init_basis_heading_and_non_basic_columns_vector();
@ -61,7 +60,6 @@ template bool lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::calc
template bool lp::lp_core_solver_base<lp::mpq, lp::mpq>::column_is_feasible(unsigned int) const;
// template void lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::print_linear_combination_of_column_indices(vector<std::pair<lp::mpq, unsigned int>, std::allocator<std::pair<lp::mpq, unsigned int> > > const&, std::ostream&) const;
template bool lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::column_is_feasible(unsigned int) const;
template bool lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::snap_non_basic_x_to_bound();
template bool lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq>>::pivot_column_tableau(unsigned int, unsigned int);
template bool lp::lp_core_solver_base<lp::mpq, lp::mpq>::pivot_column_tableau(unsigned int, unsigned int);
template void lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::transpose_rows_tableau(unsigned int, unsigned int);
@ -70,6 +68,5 @@ template bool lp::lp_core_solver_base<lp::mpq, lp::mpq>::inf_set_is_correct() co
template bool lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::infeasibility_costs_are_correct() const;
template bool lp::lp_core_solver_base<lp::mpq, lp::mpq >::infeasibility_costs_are_correct() const;
template bool lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::remove_from_basis(unsigned int);
template bool lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::remove_from_basis(unsigned int, lp::numeric_pair<lp::mpq> const&);

View file

@ -173,8 +173,6 @@ public:
void set_total_iterations(unsigned s) { m_total_iterations = s; }
void set_non_basic_x_to_correct_bounds();
bool at_bound(const X &x, const X & bound) const {
return !below_bound(x, bound) && !above_bound(x, bound);
}
@ -300,45 +298,6 @@ public:
std::string column_name(unsigned column) const;
bool snap_non_basic_x_to_bound() {
bool ret = false;
for (unsigned j : non_basis())
ret = snap_column_to_bound(j) || ret;
return ret;
}
bool snap_column_to_bound(unsigned j) {
switch (m_column_types[j]) {
case column_type::fixed:
if (x_is_at_bound(j))
break;
m_x[j] = m_lower_bounds[j];
return true;
case column_type::boxed:
if (x_is_at_bound(j))
break; // we should preserve x if possible
// snap randomly
if (m_settings.random_next() % 2 == 1)
m_x[j] = m_lower_bounds[j];
else
m_x[j] = m_upper_bounds[j];
return true;
case column_type::lower_bound:
if (x_is_at_lower_bound(j))
break;
m_x[j] = m_lower_bounds[j];
return true;
case column_type::upper_bound:
if (x_is_at_upper_bound(j))
break;
m_x[j] = m_upper_bounds[j];
return true;
default:
break;
}
return false;
}
bool make_column_feasible(unsigned j, numeric_pair<mpq> & delta) {
bool ret = false;
lp_assert(m_basis_heading[j] < 0);
@ -384,7 +343,6 @@ public:
}
bool remove_from_basis(unsigned j);
bool remove_from_basis(unsigned j, const impq&);
bool pivot_column_general(unsigned j, unsigned j_basic, indexed_vector<T> & w);
void init_basic_part_of_basis_heading() {
unsigned m = m_basis.size();
@ -456,31 +414,6 @@ public:
change_basis_unconditionally(leaving, entering);
}
bool non_basic_column_is_set_correctly(unsigned j) const {
if (j >= this->m_n())
return false;
switch (this->m_column_types[j]) {
case column_type::fixed:
case column_type::boxed:
if (!this->x_is_at_bound(j))
return false;
break;
case column_type::lower_bound:
if (!this->x_is_at_lower_bound(j))
return false;
break;
case column_type::upper_bound:
if (!this->x_is_at_upper_bound(j))
return false;
break;
case column_type::free_column:
break;
default:
lp_assert(false);
break;
}
return true;
}
bool non_basic_columns_are_set_correctly() const {
for (unsigned j : this->m_nbasis)
if (!column_is_feasible(j)) {
@ -540,13 +473,11 @@ public:
out << "[-oo, oo]";
break;
default:
lp_assert(false);
UNREACHABLE();
}
return out << "\n";
}
bool column_is_free(unsigned j) const { return this->m_column_types[j] == column_type::free_column; }
bool column_is_fixed(unsigned j) const { return this->m_column_types[j] == column_type::fixed; }
@ -579,16 +510,6 @@ public:
}
}
// only check for basic columns
bool calc_current_x_is_feasible() const {
unsigned i = this->m_m();
while (i--) {
if (!column_is_feasible(m_basis[i]))
return false;
}
return true;
}
void transpose_rows_tableau(unsigned i, unsigned ii);
void pivot_to_reduced_costs_tableau(unsigned i, unsigned j);

View file

@ -166,26 +166,6 @@ print_statistics_with_cost_and_check_that_the_time_is_over(X cost, std::ostream
return time_is_over();
}
template <typename T, typename X> void lp_core_solver_base<T, X>::
set_non_basic_x_to_correct_bounds() {
for (unsigned j : non_basis()) {
switch (m_column_types[j]) {
case column_type::boxed:
m_x[j] = m_d[j] < 0? m_upper_bounds[j]: m_lower_bounds[j];
break;
case column_type::lower_bound:
m_x[j] = m_lower_bounds[j];
lp_assert(column_is_dual_feasible(j));
break;
case column_type::upper_bound:
m_x[j] = m_upper_bounds[j];
lp_assert(column_is_dual_feasible(j));
break;
default:
break;
}
}
}
template <typename T, typename X> bool lp_core_solver_base<T, X>::
column_is_dual_feasible(unsigned j) const {
switch (m_column_types[j]) {
@ -201,9 +181,9 @@ column_is_dual_feasible(unsigned j) const {
case column_type::free_column:
return numeric_traits<X>::is_zero(m_d[j]);
default:
lp_unreachable();
UNREACHABLE();
}
lp_unreachable();
UNREACHABLE();
return false;
}
template <typename T, typename X> bool lp_core_solver_base<T, X>::
@ -257,7 +237,7 @@ template <typename T, typename X> bool lp_core_solver_base<T, X>::column_is_feas
return true;
break;
default:
lp_unreachable();
UNREACHABLE();
}
return false; // it is unreachable
}
@ -453,18 +433,6 @@ template <typename T, typename X> bool lp_core_solver_base<T, X>::remove_from_ba
return false;
}
template <typename T, typename X> bool lp_core_solver_base<T, X>::remove_from_basis(unsigned basic_j, const impq& val) {
indexed_vector<T> w(m_basis.size()); // the buffer
unsigned i = m_basis_heading[basic_j];
for (auto &c : m_A.m_rows[i]) {
if (c.var() == basic_j)
continue;
if (pivot_column_general(c.var(), basic_j, w))
return true;
}
return false;
}
template <typename T, typename X> bool
lp_core_solver_base<T, X>::infeasibility_costs_are_correct() const {
@ -513,7 +481,7 @@ lp_core_solver_base<T, X>::infeasibility_cost_is_correct_for_column(unsigned j)
case column_type::free_column:
return is_zero(this->m_costs[j]);
default:
lp_assert(false);
UNREACHABLE();
return true;
}
}

View file

@ -19,26 +19,27 @@ Revision History:
--*/
#pragma once
#include <list>
#include <limits>
#include <unordered_map>
#include <sstream>
#include <string>
#include "util/vector.h"
#include <set>
#include <math.h>
#include <cstdlib>
#include <algorithm>
#include "math/lp/static_matrix.h"
#include "math/lp/core_solver_pretty_printer.h"
#include "math/lp/lp_core_solver_base.h"
#include "math/lp/static_matrix.h"
#include "math/lp/u_set.h"
#include "util/vector.h"
#include <algorithm>
#include <cstdlib>
#include <limits>
#include <list>
#include <math.h>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
namespace lp {
// This core solver solves (Ax=b, lower_bound_values \leq x \leq upper_bound_values, maximize costs*x )
// The right side b is given implicitly by x and the basis
// This core solver solves (Ax=b, lower_bound_values \leq x \leq
// upper_bound_values, maximize costs*x ) The right side b is given implicitly
// by x and the basis
template <typename T, typename X>
class lp_primal_core_solver:public lp_core_solver_base<T, X> {
class lp_primal_core_solver : public lp_core_solver_base<T, X> {
public:
int m_sign_of_entering_delta;
vector<T> m_costs_backup;
@ -51,47 +52,42 @@ public:
std::list<unsigned> m_non_basis_list;
void sort_non_basis();
int choose_entering_column(unsigned number_of_benefitial_columns_to_go_over);
int choose_entering_column_tableau();
int choose_entering_column_presize(unsigned number_of_benefitial_columns_to_go_over);
bool needs_to_grow(unsigned bj) const {
lp_assert(!this->column_is_feasible(bj));
switch(this->m_column_types[bj]) {
switch (this->m_column_types[bj]) {
case column_type::free_column:
return false;
case column_type::fixed:
case column_type::lower_bound:
case column_type::boxed:
return this-> x_below_low_bound(bj);
return this->x_below_low_bound(bj);
default:
return false;
}
lp_assert(false); // unreachable
UNREACHABLE(); // unreachable
return false;
}
int inf_sign_of_column(unsigned bj) const {
lp_assert(!this->column_is_feasible(bj));
switch(this->m_column_types[bj]) {
switch (this->m_column_types[bj]) {
case column_type::free_column:
return 0;
case column_type::lower_bound:
return 1;
case column_type::fixed:
case column_type::boxed:
return this->x_above_upper_bound(bj)? -1: 1;
return this->x_above_upper_bound(bj) ? -1 : 1;
default:
return -1;
}
lp_assert(false); // unreachable
UNREACHABLE(); // unreachable
return 0;
}
bool monoid_can_decrease(const row_cell<T> & rc) const {
bool monoid_can_decrease(const row_cell<T> &rc) const {
unsigned j = rc.var();
lp_assert(this->column_is_feasible(j));
switch (this->m_column_types[j]) {
@ -120,11 +116,11 @@ public:
default:
return false;
}
lp_assert(false); // unreachable
UNREACHABLE(); // unreachable
return false;
}
bool monoid_can_increase(const row_cell<T> & rc) const {
bool monoid_can_increase(const row_cell<T> &rc) const {
unsigned j = rc.var();
lp_assert(this->column_is_feasible(j));
switch (this->m_column_types[j]) {
@ -153,13 +149,14 @@ public:
default:
return false;
}
lp_assert(false); // unreachable
UNREACHABLE(); // unreachable
return false;
}
unsigned get_number_of_basic_vars_that_might_become_inf(unsigned j) const { // consider looking at the signs here: todo
unsigned get_number_of_basic_vars_that_might_become_inf(
unsigned j) const { // consider looking at the signs here: todo
unsigned r = 0;
for (const auto & cc : this->m_A.m_columns[j]) {
for (const auto &cc : this->m_A.m_columns[j]) {
unsigned k = this->m_basis[cc.var()];
if (this->m_column_types[k] != column_type::free_column)
r++;
@ -167,12 +164,11 @@ public:
return r;
}
int find_beneficial_column_in_row_tableau_rows_bland_mode(int i, T & a_ent) {
int find_beneficial_column_in_row_tableau_rows_bland_mode(int i, T &a_ent) {
int j = -1;
unsigned bj = this->m_basis[i];
bool bj_needs_to_grow = needs_to_grow(bj);
for (const row_cell<T>& rc : this->m_A.m_rows[i]) {
for (const row_cell<T> &rc : this->m_A.m_rows[i]) {
if (rc.var() == bj)
continue;
if (bj_needs_to_grow) {
@ -182,7 +178,7 @@ public:
if (!monoid_can_increase(rc))
continue;
}
if (rc.var() < static_cast<unsigned>(j) ) {
if (rc.var() < static_cast<unsigned>(j)) {
j = rc.var();
a_ent = rc.coeff();
}
@ -194,10 +190,11 @@ public:
return j;
}
int find_beneficial_column_in_row_tableau_rows(int i, T & a_ent) {
int find_beneficial_column_in_row_tableau_rows(int i, T &a_ent) {
if (m_bland_mode_tableau)
return find_beneficial_column_in_row_tableau_rows_bland_mode(i, a_ent);
// a short row produces short infeasibility explanation and benefits at least one pivot operation
// a short row produces short infeasibility explanation and benefits at
// least one pivot operation
int choice = -1;
int nchoices = 0;
unsigned num_of_non_free_basics = 1000000;
@ -205,7 +202,7 @@ public:
unsigned bj = this->m_basis[i];
bool bj_needs_to_grow = needs_to_grow(bj);
for (unsigned k = 0; k < this->m_A.m_rows[i].size(); k++) {
const row_cell<T>& rc = this->m_A.m_rows[i][k];
const row_cell<T> &rc = this->m_A.m_rows[i][k];
unsigned j = rc.var();
if (j == bj)
continue;
@ -223,27 +220,28 @@ public:
choice = k;
nchoices = 1;
} else if (damage == num_of_non_free_basics &&
this->m_A.m_columns[j].size() <= len && (this->m_settings.random_next() % (++nchoices))) {
this->m_A.m_columns[j].size() <= len &&
(this->m_settings.random_next() % (++nchoices))) {
choice = k;
len = this->m_A.m_columns[j].size();
}
}
if (choice == -1) {
m_inf_row_index_for_tableau = i;
return -1;
}
const row_cell<T>& rc = this->m_A.m_rows[i][choice];
const row_cell<T> &rc = this->m_A.m_rows[i][choice];
a_ent = rc.coeff();
return rc.var();
}
bool try_jump_to_another_bound_on_entering(unsigned entering, const X & theta, X & t, bool & unlimited);
bool try_jump_to_another_bound_on_entering_unlimited(unsigned entering, X & t);
int find_leaving_and_t_tableau(unsigned entering, X & t);
bool try_jump_to_another_bound_on_entering(unsigned entering, const X &theta,
X &t, bool &unlimited);
bool try_jump_to_another_bound_on_entering_unlimited(unsigned entering, X &t);
int find_leaving_and_t_tableau(unsigned entering, X &t);
void limit_theta(const X & lim, X & theta, bool & unlimited) {
void limit_theta(const X &lim, X &theta, bool &unlimited) {
if (unlimited) {
theta = lim;
unlimited = false;
@ -252,31 +250,39 @@ public:
}
}
void limit_theta_on_basis_column_for_inf_case_m_neg_upper_bound(unsigned j, const T & m, X & theta, bool & unlimited) {
void limit_theta_on_basis_column_for_inf_case_m_neg_upper_bound(
unsigned j, const T &m, X &theta, bool &unlimited) {
lp_assert(m < 0 && this->m_column_types[j] == column_type::upper_bound);
limit_inf_on_upper_bound_m_neg(m, this->m_x[j], this->m_upper_bounds[j], theta, unlimited);
limit_inf_on_upper_bound_m_neg(m, this->m_x[j], this->m_upper_bounds[j],
theta, unlimited);
}
void limit_theta_on_basis_column_for_inf_case_m_neg_lower_bound(unsigned j, const T & m, X & theta, bool & unlimited) {
void limit_theta_on_basis_column_for_inf_case_m_neg_lower_bound(
unsigned j, const T &m, X &theta, bool &unlimited) {
lp_assert(m < 0 && this->m_column_types[j] == column_type::lower_bound);
limit_inf_on_bound_m_neg(m, this->m_x[j], this->m_lower_bounds[j], theta, unlimited);
limit_inf_on_bound_m_neg(m, this->m_x[j], this->m_lower_bounds[j], theta,
unlimited);
}
void limit_theta_on_basis_column_for_inf_case_m_pos_lower_bound(unsigned j, const T & m, X & theta, bool & unlimited) {
void limit_theta_on_basis_column_for_inf_case_m_pos_lower_bound(
unsigned j, const T &m, X &theta, bool &unlimited) {
lp_assert(m > 0 && this->m_column_types[j] == column_type::lower_bound);
limit_inf_on_lower_bound_m_pos(m, this->m_x[j], this->m_lower_bounds[j], theta, unlimited);
limit_inf_on_lower_bound_m_pos(m, this->m_x[j], this->m_lower_bounds[j],
theta, unlimited);
}
void limit_theta_on_basis_column_for_inf_case_m_pos_upper_bound(unsigned j, const T & m, X & theta, bool & unlimited) {
void limit_theta_on_basis_column_for_inf_case_m_pos_upper_bound(
unsigned j, const T &m, X &theta, bool &unlimited) {
lp_assert(m > 0 && this->m_column_types[j] == column_type::upper_bound);
limit_inf_on_bound_m_pos(m, this->m_x[j], this->m_upper_bounds[j], theta, unlimited);
limit_inf_on_bound_m_pos(m, this->m_x[j], this->m_upper_bounds[j], theta,
unlimited);
};
void get_bound_on_variable_and_update_leaving_precisely(unsigned j, vector<unsigned> & leavings, T m, X & t, T & abs_of_d_of_leaving);
void get_bound_on_variable_and_update_leaving_precisely(
unsigned j, vector<unsigned> &leavings, T m, X &t,
T &abs_of_d_of_leaving);
X get_max_bound(vector<X> & b);
X get_max_bound(vector<X> &b);
#ifdef Z3DEBUG
void check_Ax_equal_b();
@ -291,56 +297,55 @@ public:
// return 0 if the reduced cost at entering is close enough to the refreshed
// 1 if it is way off, and 2 if it is unprofitable
int refresh_reduced_cost_at_entering_and_check_that_it_is_off(unsigned entering);
int refresh_reduced_cost_at_entering_and_check_that_it_is_off(
unsigned entering);
void backup_and_normalize_costs();
void advance_on_entering_and_leaving(int entering, int leaving, X & t);
void advance_on_entering_and_leaving_tableau(int entering, int leaving, X & t);
void advance_on_entering_equal_leaving(int entering, X & t);
void advance_on_entering_equal_leaving_tableau(int entering, X & t);
void advance_on_entering_and_leaving_tableau(int entering, int leaving, X &t);
void advance_on_entering_equal_leaving_tableau(int entering, X &t);
bool need_to_switch_costs() const {
if (this->m_settings.simplex_strategy() == simplex_strategy_enum::tableau_rows)
if (this->m_settings.simplex_strategy() ==
simplex_strategy_enum::tableau_rows)
return false;
// lp_assert(calc_current_x_is_feasible() == current_x_is_feasible());
// lp_assert(calc_current_x_is_feasible() ==
// current_x_is_feasible());
return this->current_x_is_feasible() == this->using_infeas_costs();
}
void advance_on_entering(int entering);
void advance_on_entering_tableau(int entering);
void advance_on_entering_precise(int entering);
void push_forward_offset_in_non_basis(unsigned & offset_in_nb);
void push_forward_offset_in_non_basis(unsigned &offset_in_nb);
unsigned get_number_of_non_basic_column_to_try_for_enter();
// returns the number of iterations
unsigned solve();
void find_feasible_solution();
// bool is_tiny() const {return this->m_m < 10 && this->m_n < 20;}
void one_iteration_tableau();
// this version assumes that the leaving already has the right value, and does not update it
void update_x_tableau_rows(unsigned entering, unsigned leaving, const X& delta) {
// this version assumes that the leaving already has the right value, and does
// not update it
void update_x_tableau_rows(unsigned entering, unsigned leaving,
const X &delta) {
this->add_delta_to_x(entering, delta);
if (!this->using_infeas_costs()) {
for (const auto & c : this->m_A.m_columns[entering]) {
for (const auto &c : this->m_A.m_columns[entering]) {
if (leaving != this->m_basis[c.var()]) {
this->add_delta_to_x_and_track_feasibility(this->m_basis[c.var()], - delta * this->m_A.get_val(c));
this->add_delta_to_x_and_track_feasibility(
this->m_basis[c.var()], -delta * this->m_A.get_val(c));
}
}
} else { // using_infeas_costs() == true
lp_assert(this->column_is_feasible(entering));
lp_assert(this->m_costs[entering] == zero_of_type<T>());
// m_d[entering] can change because of the cost change for basic columns.
for (const auto & c : this->m_A.m_columns[entering]) {
for (const auto &c : this->m_A.m_columns[entering]) {
unsigned j = this->m_basis[c.var()];
if (j != leaving)
this->add_delta_to_x(j, -delta * this->m_A.get_val(c));
@ -353,15 +358,15 @@ public:
}
}
void update_basis_and_x_tableau_rows(int entering, int leaving, X const & tt) {
void update_basis_and_x_tableau_rows(int entering, int leaving, X const &tt) {
lp_assert(entering != leaving);
update_x_tableau_rows(entering, leaving, tt);
this->pivot_column_tableau(entering, this->m_basis_heading[leaving]);
this->change_basis(entering, leaving);
}
void advance_on_entering_and_leaving_tableau_rows(int entering, int leaving, const X &theta ) {
void advance_on_entering_and_leaving_tableau_rows(int entering, int leaving,
const X &theta) {
update_basis_and_x_tableau_rows(entering, leaving, theta);
this->track_column_feasibility(entering);
}
@ -376,7 +381,7 @@ public:
return j;
}
const X& get_val_for_leaving(unsigned j) const {
const X &get_val_for_leaving(unsigned j) const {
lp_assert(!this->column_is_feasible(j));
switch (this->m_column_types[j]) {
case column_type::fixed:
@ -397,7 +402,6 @@ public:
}
}
void one_iteration_tableau_rows() {
int leaving = find_smallest_inf_column();
if (leaving == -1) {
@ -417,35 +421,41 @@ public:
}
}
T a_ent;
int entering = find_beneficial_column_in_row_tableau_rows(this->m_basis_heading[leaving], a_ent);
int entering = find_beneficial_column_in_row_tableau_rows(
this->m_basis_heading[leaving], a_ent);
if (entering == -1) {
this->set_status(lp_status::INFEASIBLE);
return;
}
const X& new_val_for_leaving = get_val_for_leaving(leaving);
const X &new_val_for_leaving = get_val_for_leaving(leaving);
X theta = (this->m_x[leaving] - new_val_for_leaving) / a_ent;
this->m_x[leaving] = new_val_for_leaving;
this->remove_column_from_inf_set(leaving);
advance_on_entering_and_leaving_tableau_rows(entering, leaving, theta );
advance_on_entering_and_leaving_tableau_rows(entering, leaving, theta);
if (this->current_x_is_feasible())
this->set_status(lp_status::OPTIMAL);
}
void decide_on_status_when_cannot_find_entering() {
lp_assert(!need_to_switch_costs());
this->set_status(this->current_x_is_feasible()? lp_status::OPTIMAL: lp_status::INFEASIBLE);
this->set_status(this->current_x_is_feasible() ? lp_status::OPTIMAL
: lp_status::INFEASIBLE);
}
void limit_theta_on_basis_column_for_feas_case_m_neg_no_check(unsigned j, const T & m, X & theta, bool & unlimited) {
void limit_theta_on_basis_column_for_feas_case_m_neg_no_check(
unsigned j, const T &m, X &theta, bool &unlimited) {
lp_assert(m < 0);
limit_theta((this->m_lower_bounds[j] - this->m_x[j]) / m, theta, unlimited);
if (theta < zero_of_type<X>()) theta = zero_of_type<X>();
if (theta < zero_of_type<X>())
theta = zero_of_type<X>();
}
bool limit_inf_on_bound_m_neg(const T & m, const X & x, const X & bound, X & theta, bool & unlimited) {
bool limit_inf_on_bound_m_neg(const T &m, const X &x, const X &bound,
X &theta, bool &unlimited) {
// x gets smaller
lp_assert(m < 0);
if (this->below_bound(x, bound)) return false;
if (this->below_bound(x, bound))
return false;
if (this->above_bound(x, bound)) {
limit_theta((bound - x) / m, theta, unlimited);
} else {
@ -455,10 +465,12 @@ public:
return true;
}
bool limit_inf_on_bound_m_pos(const T & m, const X & x, const X & bound, X & theta, bool & unlimited) {
bool limit_inf_on_bound_m_pos(const T &m, const X &x, const X &bound,
X &theta, bool &unlimited) {
// x gets larger
lp_assert(m > 0);
if (this->above_bound(x, bound)) return false;
if (this->above_bound(x, bound))
return false;
if (this->below_bound(x, bound)) {
limit_theta((bound - x) / m, theta, unlimited);
} else {
@ -469,16 +481,17 @@ public:
return true;
}
void limit_inf_on_lower_bound_m_pos(const T & m, const X & x, const X & bound, X & theta, bool & unlimited) {
void limit_inf_on_lower_bound_m_pos(const T &m, const X &x, const X &bound,
X &theta, bool &unlimited) {
// x gets larger
lp_assert(m > 0);
if (this->below_bound(x, bound)) {
limit_theta((bound - x) / m, theta, unlimited);
}
}
void limit_inf_on_upper_bound_m_neg(const T & m, const X & x, const X & bound, X & theta, bool & unlimited) {
void limit_inf_on_upper_bound_m_neg(const T &m, const X &x, const X &bound,
X &theta, bool &unlimited) {
// x gets smaller
lp_assert(m < 0);
if (this->above_bound(x, bound)) {
@ -486,15 +499,18 @@ public:
}
}
void limit_theta_on_basis_column_for_inf_case_m_pos_boxed(unsigned j, const T & m, X & theta, bool & unlimited) {
const X & x = this->m_x[j];
const X & lbound = this->m_lower_bounds[j];
void limit_theta_on_basis_column_for_inf_case_m_pos_boxed(unsigned j,
const T &m,
X &theta,
bool &unlimited) {
const X &x = this->m_x[j];
const X &lbound = this->m_lower_bounds[j];
if (this->below_bound(x, lbound)) {
limit_theta((lbound - x) / m, theta, unlimited);
} else {
const X & ubound = this->m_upper_bounds[j];
if (this->below_bound(x, ubound)){
const X &ubound = this->m_upper_bounds[j];
if (this->below_bound(x, ubound)) {
limit_theta((ubound - x) / m, theta, unlimited);
} else if (!this->above_bound(x, ubound)) {
theta = zero_of_type<X>();
@ -503,15 +519,18 @@ public:
}
}
void limit_theta_on_basis_column_for_inf_case_m_neg_boxed(unsigned j, const T & m, X & theta, bool & unlimited) {
void limit_theta_on_basis_column_for_inf_case_m_neg_boxed(unsigned j,
const T &m,
X &theta,
bool &unlimited) {
// lp_assert(m < 0 && this->m_column_type[j] == column_type::boxed);
const X & x = this->m_x[j];
const X & ubound = this->m_upper_bounds[j];
const X &x = this->m_x[j];
const X &ubound = this->m_upper_bounds[j];
if (this->above_bound(x, ubound)) {
limit_theta((ubound - x) / m, theta, unlimited);
} else {
const X & lbound = this->m_lower_bounds[j];
if (this->above_bound(x, lbound)){
const X &lbound = this->m_lower_bounds[j];
if (this->above_bound(x, lbound)) {
limit_theta((lbound - x) / m, theta, unlimited);
} else if (!this->below_bound(x, lbound)) {
theta = zero_of_type<X>();
@ -519,20 +538,11 @@ public:
}
}
}
void limit_theta_on_basis_column_for_feas_case_m_pos(unsigned j, const T & m, X & theta, bool & unlimited) {
lp_assert(m > 0);
if (this->below_bound(this->m_x[j], this->m_upper_bounds[j])) {
limit_theta((this->m_upper_bounds[j] - this->m_x[j]) / m, theta, unlimited);
if (theta < zero_of_type<X>()) {
theta = zero_of_type<X>();
unlimited = false;
}
}
}
void limit_theta_on_basis_column_for_feas_case_m_pos_no_check(unsigned j, const T & m, X & theta, bool & unlimited ) {
void limit_theta_on_basis_column_for_feas_case_m_pos_no_check(
unsigned j, const T &m, X &theta, bool &unlimited) {
lp_assert(m > 0);
limit_theta( (this->m_upper_bounds[j] - this->m_x[j]) / m, theta, unlimited);
limit_theta((this->m_upper_bounds[j] - this->m_x[j]) / m, theta, unlimited);
if (theta < zero_of_type<X>()) {
theta = zero_of_type<X>();
}
@ -543,29 +553,36 @@ public:
// x[j] + t * m >= this->m_lower_bounds[j]( if m < 0 )
// or
// x[j] + t * m <= this->m_upper_bounds[j] ( if m > 0)
void limit_theta_on_basis_column(unsigned j, T m, X & theta, bool & unlimited) {
void limit_theta_on_basis_column(unsigned j, T m, X &theta, bool &unlimited) {
switch (this->m_column_types[j]) {
case column_type::free_column: break;
case column_type::free_column:
break;
case column_type::upper_bound:
if (this->current_x_is_feasible()) {
if (m > 0)
limit_theta_on_basis_column_for_feas_case_m_pos_no_check(j, m, theta, unlimited);
limit_theta_on_basis_column_for_feas_case_m_pos_no_check(j, m, theta,
unlimited);
} else { // inside of feasibility_loop
if (m > 0)
limit_theta_on_basis_column_for_inf_case_m_pos_upper_bound(j, m, theta, unlimited);
limit_theta_on_basis_column_for_inf_case_m_pos_upper_bound(
j, m, theta, unlimited);
else
limit_theta_on_basis_column_for_inf_case_m_neg_upper_bound(j, m, theta, unlimited);
limit_theta_on_basis_column_for_inf_case_m_neg_upper_bound(
j, m, theta, unlimited);
}
break;
case column_type::lower_bound:
if (this->current_x_is_feasible()) {
if (m < 0)
limit_theta_on_basis_column_for_feas_case_m_neg_no_check(j, m, theta, unlimited);
limit_theta_on_basis_column_for_feas_case_m_neg_no_check(j, m, theta,
unlimited);
} else {
if (m < 0)
limit_theta_on_basis_column_for_inf_case_m_neg_lower_bound(j, m, theta, unlimited);
limit_theta_on_basis_column_for_inf_case_m_neg_lower_bound(
j, m, theta, unlimited);
else
limit_theta_on_basis_column_for_inf_case_m_pos_lower_bound(j, m, theta, unlimited);
limit_theta_on_basis_column_for_inf_case_m_pos_lower_bound(
j, m, theta, unlimited);
}
break;
// case fixed:
@ -574,71 +591,75 @@ public:
// break;
// }
// if (m < 0)
// limit_theta_on_basis_column_for_inf_case_m_neg_fixed(j, m, theta);
// limit_theta_on_basis_column_for_inf_case_m_neg_fixed(j, m,
// theta);
// else
// limit_theta_on_basis_column_for_inf_case_m_pos_fixed(j, m, theta);
// limit_theta_on_basis_column_for_inf_case_m_pos_fixed(j, m,
// theta);
// break;
case column_type::fixed:
case column_type::boxed:
if (this->current_x_is_feasible()) {
if (m > 0) {
limit_theta_on_basis_column_for_feas_case_m_pos_no_check(j, m, theta, unlimited);
limit_theta_on_basis_column_for_feas_case_m_pos_no_check(j, m, theta,
unlimited);
} else {
limit_theta_on_basis_column_for_feas_case_m_neg_no_check(j, m, theta, unlimited);
limit_theta_on_basis_column_for_feas_case_m_neg_no_check(j, m, theta,
unlimited);
}
} else {
if (m > 0) {
limit_theta_on_basis_column_for_inf_case_m_pos_boxed(j, m, theta, unlimited);
limit_theta_on_basis_column_for_inf_case_m_pos_boxed(j, m, theta,
unlimited);
} else {
limit_theta_on_basis_column_for_inf_case_m_neg_boxed(j, m, theta, unlimited);
limit_theta_on_basis_column_for_inf_case_m_neg_boxed(j, m, theta,
unlimited);
}
}
break;
default:
lp_unreachable();
UNREACHABLE();
}
if (!unlimited && theta < zero_of_type<X>()) {
theta = zero_of_type<X>();
}
}
bool column_is_benefitial_for_entering_basis(unsigned j) const;
bool column_is_benefitial_for_entering_basis_precise(unsigned j) const;
bool can_enter_basis(unsigned j);
void init_infeasibility_costs();
void init_infeasibility_cost_for_column(unsigned j);
T get_infeasibility_cost_for_column(unsigned j) const;
void init_infeasibility_costs_for_changed_basis_only();
void print_column(unsigned j, std::ostream & out);
void print_column(unsigned j, std::ostream &out);
void print_bound_info_and_x(unsigned j, std::ostream & out);
void print_bound_info_and_x(unsigned j, std::ostream &out);
bool basis_column_is_set_correctly(unsigned j) const {
return this->m_A.m_columns[j].size() == 1;
}
bool basis_columns_are_set_correctly() const {
for (unsigned j : this->m_basis)
if(!basis_column_is_set_correctly(j))
if (!basis_column_is_set_correctly(j))
return false;
return this->m_basis_heading.size() == this->m_A.column_count() && this->m_basis.size() == this->m_A.row_count();
return this->m_basis_heading.size() == this->m_A.column_count() &&
this->m_basis.size() == this->m_A.row_count();
}
void init_run_tableau();
void update_x_tableau(unsigned entering, const X & delta);
void update_x_tableau(unsigned entering, const X &delta);
void update_inf_cost_for_column_tableau(unsigned j);
// the delta is between the old and the new cost (old - new)
void update_reduced_cost_for_basic_column_cost_change(const T & delta, unsigned j) {
// the delta is between the old and the new cost (old - new)
void update_reduced_cost_for_basic_column_cost_change(const T &delta,
unsigned j) {
lp_assert(this->m_basis_heading[j] >= 0);
unsigned i = static_cast<unsigned>(this->m_basis_heading[j]);
for (const row_cell<T> & rc : this->m_A.m_rows[i]) {
for (const row_cell<T> &rc : this->m_A.m_rows[i]) {
unsigned k = rc.var();
if (k == j)
continue;
@ -646,7 +667,7 @@ public:
}
}
bool update_basis_and_x_tableau(int entering, int leaving, X const & tt);
bool update_basis_and_x_tableau(int entering, int leaving, X const &tt);
void init_reduced_costs_tableau();
void init_tableau_rows() {
m_bland_mode_tableau = false;
@ -654,69 +675,24 @@ public:
m_left_basis_tableau.resize(this->m_A.column_count());
m_left_basis_repeated = 0;
}
// stage1 constructor
lp_primal_core_solver(static_matrix<T, X> & A,
vector<X> & b, // the right side vector
vector<X> & x, // the number of elements in x needs to be at least as large as the number of columns in A
vector<unsigned> & basis,
vector<unsigned> & nbasis,
vector<int> & heading,
vector<T> & costs,
const vector<column_type> & column_type_array,
const vector<X> & lower_bound_values,
const vector<X> & upper_bound_values,
lp_settings & settings,
const column_namer& column_names):
lp_core_solver_base<T, X>(A, // b,
basis,
nbasis,
heading,
x,
costs,
settings,
column_names,
column_type_array,
lower_bound_values,
upper_bound_values),
// stage1 constructor
lp_primal_core_solver(
static_matrix<T, X> &A,
vector<X> &b, // the right side vector
vector<X> &x, // the number of elements in x needs to be at least as large
// as the number of columns in A
vector<unsigned> &basis, vector<unsigned> &nbasis, vector<int> &heading,
vector<T> &costs, const vector<column_type> &column_type_array,
const vector<X> &lower_bound_values, const vector<X> &upper_bound_values,
lp_settings &settings, const column_namer &column_names)
: lp_core_solver_base<T, X>(A, // b,
basis, nbasis, heading, x, costs, settings,
column_names, column_type_array,
lower_bound_values, upper_bound_values),
m_bland_mode_threshold(1000) {
this->set_status(lp_status::UNKNOWN);
}
bool initial_x_is_correct() {
std::set<unsigned> basis_set;
for (unsigned i = 0; i < this->m_A.row_count(); i++) {
basis_set.insert(this->m_basis[i]);
}
for (unsigned j = 0; j < this->m_n(); j++) {
if (this->column_has_lower_bound(j) && this->m_x[j] < numeric_traits<T>::zero()) {
LP_OUT(this->m_settings, "low bound for variable " << j << " does not hold: this->m_x[" << j << "] = " << this->m_x[j] << " is negative " << std::endl);
return false;
}
if (this->column_has_upper_bound(j) && this->m_x[j] > this->m_upper_bounds[j]) {
LP_OUT(this->m_settings, "upper bound for " << j << " does not hold: " << this->m_upper_bounds[j] << ">" << this->m_x[j] << std::endl);
return false;
}
if (basis_set.find(j) != basis_set.end()) continue;
if (this->m_column_types[j] == column_type::lower_bound) {
if (numeric_traits<T>::zero() != this->m_x[j]) {
LP_OUT(this->m_settings, "only low bound is set for " << j << " but low bound value " << numeric_traits<T>::zero() << " is not equal to " << this->m_x[j] << std::endl);
return false;
}
}
if (this->m_column_types[j] == column_type::boxed) {
if (this->m_upper_bounds[j] != this->m_x[j] && !numeric_traits<T>::is_zero(this->m_x[j])) {
return false;
}
}
}
return true;
}
friend core_solver_pretty_printer<T, X>;
};
}
} // namespace lp

View file

@ -53,10 +53,6 @@ void lp_primal_core_solver<T, X>::sort_non_basis() {
template <typename T, typename X>
bool lp_primal_core_solver<T, X>::column_is_benefitial_for_entering_basis(unsigned j) const {
return column_is_benefitial_for_entering_basis_precise(j);
}
template <typename T, typename X>
bool lp_primal_core_solver<T, X>::column_is_benefitial_for_entering_basis_precise(unsigned j) const {
const T& dj = this->m_d[j];
TRACE("lar_solver", tout << "dj=" << dj << "\n";);
switch (this->m_column_types[j]) {
@ -88,56 +84,12 @@ bool lp_primal_core_solver<T, X>::column_is_benefitial_for_entering_basis_precis
}
break;
default:
lp_unreachable();
UNREACHABLE();
break;
}
return false;
}
template <typename T, typename X>
int lp_primal_core_solver<T, X>::choose_entering_column_presize(unsigned number_of_benefitial_columns_to_go_over) { // at this moment m_y = cB * B(-1)
if (number_of_benefitial_columns_to_go_over == 0)
return -1;
if (this->m_basis_sort_counter == 0) {
sort_non_basis();
this->m_basis_sort_counter = 20;
}
else {
this->m_basis_sort_counter--;
}
unsigned j_nz = this->m_m() + 1; // this number is greater than the max column size
std::list<unsigned>::iterator entering_iter = m_non_basis_list.end();
for (auto non_basis_iter = m_non_basis_list.begin(); number_of_benefitial_columns_to_go_over && non_basis_iter != m_non_basis_list.end(); ++non_basis_iter) {
unsigned j = *non_basis_iter;
if (!column_is_benefitial_for_entering_basis(j))
continue;
// if we are here then j is a candidate to enter the basis
unsigned t = this->m_columns_nz[j];
if (t < j_nz) {
j_nz = t;
entering_iter = non_basis_iter;
if (number_of_benefitial_columns_to_go_over)
number_of_benefitial_columns_to_go_over--;
} else if (t == j_nz && this->m_settings.random_next() % 2 == 0) {
entering_iter = non_basis_iter;
}
}// while (number_of_benefitial_columns_to_go_over && initial_offset_in_non_basis != offset_in_nb);
if (entering_iter == m_non_basis_list.end())
return -1;
unsigned entering = *entering_iter;
m_sign_of_entering_delta = this->m_d[entering] > 0 ? 1 : -1;
m_non_basis_list.erase(entering_iter);
m_non_basis_list.push_back(entering);
return entering;
}
template <typename T, typename X>
int lp_primal_core_solver<T, X>::choose_entering_column(unsigned number_of_benefitial_columns_to_go_over) { // at this moment m_y = cB * B(-1)
return choose_entering_column_presize(number_of_benefitial_columns_to_go_over);
}
template <typename T, typename X> bool lp_primal_core_solver<T, X>::try_jump_to_another_bound_on_entering(unsigned entering,
const X & theta,
X & t,
@ -278,24 +230,6 @@ template <typename T, typename X> void lp_primal_core_solver<T, X>::backup_an
template <typename T, typename X>
void lp_primal_core_solver<T, X>::advance_on_entering_equal_leaving(int entering, X & t) {
}
template <typename T, typename X>void lp_primal_core_solver<T, X>::advance_on_entering_and_leaving(int entering, int leaving, X & t) {
}
template <typename T, typename X> void lp_primal_core_solver<T, X>::advance_on_entering_precise(int entering) {
lp_assert(false);
}
template <typename T, typename X> void lp_primal_core_solver<T, X>::advance_on_entering(int entering) {
lp_assert(false);
}
template <typename T, typename X> void lp_primal_core_solver<T, X>::push_forward_offset_in_non_basis(unsigned & offset_in_nb) {
if (++offset_in_nb == this->m_nbasis.size())
offset_in_nb = 0;
@ -377,7 +311,7 @@ lp_primal_core_solver<T, X>::get_infeasibility_cost_for_column(unsigned j) const
ret = numeric_traits<T>::zero();
break;
default:
lp_assert(false);
UNREACHABLE();
ret = numeric_traits<T>::zero(); // does not matter
break;
}
@ -427,7 +361,7 @@ lp_primal_core_solver<T, X>::init_infeasibility_cost_for_column(unsigned j) {
this->m_costs[j] = numeric_traits<T>::zero();
break;
default:
lp_assert(false);
UNREACHABLE();
break;
}
@ -458,7 +392,7 @@ template <typename T, typename X> void lp_primal_core_solver<T, X>::print_column
out << "( _" << this->m_x[j] << "_)" << std::endl;
break;
default:
lp_unreachable();
UNREACHABLE();
}
}
@ -480,7 +414,7 @@ template <typename T, typename X> void lp_primal_core_solver<T, X>::print_bound_
out << "inf, inf" << std::endl;
break;
default:
lp_assert(false);
UNREACHABLE();
break;
}
}

View file

@ -122,7 +122,7 @@ unsigned lp_primal_core_solver<T, X>::solve() {
}
break;
case lp_status::TENTATIVE_UNBOUNDED:
lp_assert(false);
UNREACHABLE();
break;
case lp_status::UNBOUNDED:
if (this->current_x_is_infeasible()) {
@ -132,7 +132,7 @@ unsigned lp_primal_core_solver<T, X>::solve() {
break;
case lp_status::UNSTABLE:
lp_assert(false);
UNREACHABLE();
break;
default:

View file

@ -31,7 +31,7 @@ std::string column_type_to_string(column_type t) {
case column_type::lower_bound: return "lower_bound";
case column_type::upper_bound: return "upper_bound";
case column_type::free_column: return "free_column";
default: lp_unreachable();
default: UNREACHABLE();
}
return "unknown"; // it is unreachable
}
@ -50,7 +50,7 @@ const char* lp_status_to_string(lp_status status) {
case lp_status::UNSTABLE: return "UNSTABLE";
case lp_status::CANCELLED: return "CANCELLED";
default:
lp_unreachable();
UNREACHABLE();
}
return "UNKNOWN"; // it is unreachable
}
@ -63,7 +63,7 @@ lp_status lp_status_from_string(std::string status) {
if (status == "FEASIBLE") return lp_status::FEASIBLE;
if (status == "TIME_EXHAUSTED") return lp_status::TIME_EXHAUSTED;
if (status == "EMPTY") return lp_status::EMPTY;
lp_unreachable();
UNREACHABLE();
return lp_status::UNKNOWN; // it is unreachable
}

View file

@ -141,7 +141,6 @@ inline void throw_exception(std::string && str) {
typedef z3_exception exception;
#define lp_assert(_x_) { SASSERT(_x_); }
inline void lp_unreachable() { lp_assert(false); }
template <typename X> inline X zero_of_type() { return numeric_traits<X>::zero(); }
template <typename X> inline X one_of_type() { return numeric_traits<X>::one(); }
template <typename X> inline bool is_zero(const X & v) { return numeric_traits<X>::is_zero(v); }

View file

@ -171,7 +171,7 @@ struct solver::imp {
lit = m_nlsat->mk_ineq_literal(nlsat::atom::kind::EQ, 1, ps, is_even);
break;
default:
lp_assert(false); // unreachable
UNREACHABLE(); // unreachable
}
m_nlsat->mk_clause(1, &lit, a);
}

View file

@ -107,8 +107,8 @@ public:
template <typename X, typename Y>
struct convert_struct {
static X convert(const Y & y){ return X(y);}
static bool below_bound_numeric(const X &, const X &, const Y &) { /*lp_unreachable();*/ return false;}
static bool above_bound_numeric(const X &, const X &, const Y &) { /*lp_unreachable();*/ return false; }
static bool below_bound_numeric(const X &, const X &, const Y &) { /*UNREACHABLE();*/ return false;}
static bool above_bound_numeric(const X &, const X &, const Y &) { /*UNREACHABLE();*/ return false; }
};
@ -190,7 +190,7 @@ struct numeric_pair {
}
numeric_pair operator/(const numeric_pair &) const {
// lp_unreachable();
// UNREACHABLE();
}
@ -199,7 +199,7 @@ struct numeric_pair {
}
numeric_pair operator*(const numeric_pair & /*a*/) const {
// lp_unreachable();
// UNREACHABLE();
}
numeric_pair& operator+=(const numeric_pair & a) {
@ -275,14 +275,14 @@ numeric_pair<T> operator/(const numeric_pair<T> & r, const X & a) {
return numeric_pair<T>(r.x / a, r.y / a);
}
template <typename T> double get_double(const lp::numeric_pair<T> & ) { /* lp_unreachable(); */ return 0;}
template <typename T> double get_double(const lp::numeric_pair<T> & ) { /* UNREACHABLE(); */ return 0;}
template <typename T>
class numeric_traits<lp::numeric_pair<T>> {
public:
static lp::numeric_pair<T> zero() { return lp::numeric_pair<T>(numeric_traits<T>::zero(), numeric_traits<T>::zero()); }
static bool is_zero(const lp::numeric_pair<T> & v) { return numeric_traits<T>::is_zero(v.x) && numeric_traits<T>::is_zero(v.y); }
static double get_double(const lp::numeric_pair<T> & v){ return numeric_traits<T>::get_double(v.x); } // just return the double of the first coordinate
static double one() { /*lp_unreachable();*/ return 0;}
static double one() { /*UNREACHABLE();*/ return 0;}
static bool is_pos(const numeric_pair<T> &p) {
return numeric_traits<T>::is_pos(p.x) ||
(numeric_traits<T>::is_zero(p.x) && numeric_traits<T>::is_pos(p.y));

View file

@ -31,7 +31,6 @@ template std::set<std::pair<unsigned, unsigned>> lp::static_matrix<lp::mpq, lp::
template void static_matrix<mpq, mpq>::add_column_to_vector(mpq const&, unsigned int, mpq*) const;
template void static_matrix<mpq, mpq>::add_columns_at_the_end(unsigned int);
template bool static_matrix<mpq, mpq>::is_correct() const;
template void static_matrix<mpq, mpq>::copy_column_to_indexed_vector(unsigned int, indexed_vector<mpq>&) const;
template mpq static_matrix<mpq, mpq>::get_balance() const;
template mpq static_matrix<mpq, mpq>::get_elem(unsigned int, unsigned int) const;
@ -47,7 +46,6 @@ template static_matrix<mpq, mpq>::static_matrix(unsigned int, unsigned int);
#ifdef Z3DEBUG
template bool static_matrix<mpq, numeric_pair<mpq> >::is_correct() const;
#endif
template void static_matrix<mpq, numeric_pair<mpq> >::copy_column_to_indexed_vector(unsigned int, indexed_vector<mpq>&) const;
template mpq static_matrix<mpq, numeric_pair<mpq> >::get_elem(unsigned int, unsigned int) const;
template void static_matrix<mpq, numeric_pair<mpq> >::init_empty_matrix(unsigned int, unsigned int);
template void static_matrix<mpq, numeric_pair<mpq> >::set(unsigned int, unsigned int, mpq const&);

View file

@ -168,8 +168,6 @@ public:
std::set<std::pair<unsigned, unsigned>> get_domain();
void copy_column_to_indexed_vector(unsigned j, indexed_vector<T> & v) const;
T get_max_abs_in_row(unsigned row) const;
void add_column_to_vector (const T & a, unsigned j, T * v) const {
for (const auto & it : m_columns[j]) {
@ -222,7 +220,7 @@ public:
virtual void set_number_of_columns(unsigned /*n*/) { }
#endif
T get_max_val_in_row(unsigned /* i */) const { lp_unreachable(); }
T get_max_val_in_row(unsigned /* i */) const { UNREACHABLE(); }
T get_balance() const;

View file

@ -174,14 +174,6 @@ std::set<std::pair<unsigned, unsigned>> static_matrix<T, X>::get_domain() {
return ret;
}
template <typename T, typename X> void static_matrix<T, X>::copy_column_to_indexed_vector (unsigned j, indexed_vector<T> & v) const {
lp_assert(j < m_columns.size());
for (auto & it : m_columns[j]) {
const T& val = get_val(it);
if (!is_zero(val))
v.set_value(val, it.var());
}
}
template <typename T, typename X> T static_matrix<T, X>::get_max_abs_in_row(unsigned row) const {
T ret = numeric_traits<T>::zero();

View file

@ -130,7 +130,7 @@ struct gomory_test {
void report_conflict_from_gomory_cut(mpq &k) {
lp_assert(false);
UNREACHABLE();
}
void adjust_term_and_k_for_some_ints_case_gomory(lar_term& t, mpq& k, mpq &lcm_den) {

View file

@ -1365,7 +1365,7 @@ void test_gomory_cut_0() {
if (j == 2)
return zero_of_type<mpq>();
if (j == 3) return mpq(3);
lp_assert(false);
UNREACHABLE();
return zero_of_type<mpq>();
},
[](unsigned j) { // at_low_p
@ -1375,7 +1375,7 @@ void test_gomory_cut_0() {
return true;
if (j == 3)
return true;
lp_assert(false);
UNREACHABLE();
return false;
},
[](unsigned j) { // at_upper
@ -1385,31 +1385,31 @@ void test_gomory_cut_0() {
return true;
if (j == 3)
return false;
lp_assert(false);
UNREACHABLE();
return false;
},
[](unsigned j) { // lower_bound
if (j == 1) {
lp_assert(false); //unlimited from below
UNREACHABLE(); //unlimited from below
return impq(0);
}
if (j == 2)
return impq(0);
if (j == 3)
return impq(3);
lp_assert(false);
UNREACHABLE();
return impq(0);
},
[](unsigned j) { // upper
if (j == 1) {
lp_assert(false); //unlimited from above
UNREACHABLE(); //unlimited from above
return impq(0);
}
if (j == 2)
return impq(0);
if (j == 3)
return impq(10);
lp_assert(false);
UNREACHABLE();
return impq(0);
},
[] (unsigned) { return 0; },
@ -1437,7 +1437,7 @@ void test_gomory_cut_1() {
return mpq(4363334, 2730001);
if (j == 3)
return mpq(1);
lp_assert(false);
UNREACHABLE();
return zero_of_type<mpq>();
},
[](unsigned j) { // at_low_p
@ -1447,7 +1447,7 @@ void test_gomory_cut_1() {
return false;
if (j == 3)
return true;
lp_assert(false);
UNREACHABLE();
return false;
},
[](unsigned j) { // at_upper
@ -1457,19 +1457,19 @@ void test_gomory_cut_1() {
return false;
if (j == 3)
return true;
lp_assert(false);
UNREACHABLE();
return false;
},
[](unsigned j) { // lower_bound
if (j == 1) {
lp_assert(false); //unlimited from below
UNREACHABLE(); //unlimited from below
return impq(0);
}
if (j == 2)
return impq(1);
if (j == 3)
return impq(1);
lp_assert(false);
UNREACHABLE();
return impq(0);
},
[](unsigned j) { // upper
@ -1480,7 +1480,7 @@ void test_gomory_cut_1() {
return impq(3333);
if (j == 3)
return impq(10000);
lp_assert(false);
UNREACHABLE();
return impq(0);
},
[] (unsigned) { return 0; },

View file

@ -272,7 +272,7 @@ namespace lp {
} else if (el.m_head == "+") {
add_sum(c, el.m_elems);
} else {
lp_assert(false); // unexpected input
UNREACHABLE(); // unexpected input
}
}