mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 09:05:31 +00:00
remove offsets from terms
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
dcda39e76e
commit
d75b6fd9c1
9 changed files with 159 additions and 153 deletions
|
@ -17,10 +17,6 @@ const impq & bound_propagator::get_upper_bound(unsigned j) const {
|
|||
}
|
||||
void bound_propagator::try_add_bound(mpq v, unsigned j, bool is_low, bool coeff_before_j_is_pos, unsigned row_or_term_index, bool strict) {
|
||||
j = m_lar_solver.adjust_column_index_to_term_index(j);
|
||||
if (m_lar_solver.is_term(j)) {
|
||||
// lp treats terms as not having a free coefficient, restoring it below for the outside consumption
|
||||
v += m_lar_solver.get_term(j).m_v;
|
||||
}
|
||||
|
||||
lconstraint_kind kind = is_low? GE : LE;
|
||||
if (strict)
|
||||
|
|
|
@ -45,7 +45,7 @@ class gomory::imp {
|
|||
void int_case_in_gomory_cut(const mpq & a, unsigned j,
|
||||
mpq & lcm_den, const mpq& f0, const mpq& one_minus_f0) {
|
||||
lp_assert(is_int(j) && !a.is_int());
|
||||
mpq fj = fractional_part(a);
|
||||
mpq fj = fractional_part(a);
|
||||
TRACE("gomory_cut_detail",
|
||||
tout << a << " j=" << j << " k = " << m_k;
|
||||
tout << ", fj: " << fj << ", ";
|
||||
|
@ -56,10 +56,9 @@ class gomory::imp {
|
|||
mpq new_a;
|
||||
if (at_lower(j)) {
|
||||
new_a = fj <= one_minus_f0 ? fj / one_minus_f0 : ((1 - fj) / f0);
|
||||
m_k.addmul(new_a, lower_bound(j).x);
|
||||
// m_k += (new_a * lower_bound(j).x);
|
||||
lp_assert(new_a.is_pos());
|
||||
m_ex.push_justification(column_lower_bound_constraint(j), new_a);
|
||||
m_k.addmul(new_a, lower_bound(j).x);
|
||||
m_ex.push_justification(column_lower_bound_constraint(j), new_a);
|
||||
}
|
||||
else {
|
||||
lp_assert(at_upper(j));
|
||||
|
@ -67,7 +66,6 @@ class gomory::imp {
|
|||
new_a = - (fj <= f0 ? fj / f0 : ((1 - fj) / one_minus_f0));
|
||||
lp_assert(new_a.is_neg());
|
||||
m_k.addmul(new_a, upper_bound(j).x);
|
||||
// m_k += (new_a * upper_bound(j).x);
|
||||
m_ex.push_justification(column_upper_bound_constraint(j), new_a);
|
||||
}
|
||||
m_t.add_monomial(new_a, j);
|
||||
|
@ -251,9 +249,12 @@ class gomory::imp {
|
|||
std::ostream& dump_term_le_k(std::ostream & out) const {
|
||||
return dump_term_sum(out << "(<= ") << " " << m_k << ")";
|
||||
}
|
||||
|
||||
void dump_the_cut_assert(std::ostream & out) const {
|
||||
dump_term_le_k(out << "(assert (not ") << "))\n";
|
||||
}
|
||||
|
||||
|
||||
void dump_cut_and_constraints_as_smt_lemma(std::ostream& out) const {
|
||||
dump_declarations(out);
|
||||
dump_the_row(out);
|
||||
|
@ -284,7 +285,6 @@ public:
|
|||
mpq one_min_f0 = 1 - f0;
|
||||
for (const auto & p : m_row) {
|
||||
unsigned j = p.var();
|
||||
|
||||
if (j == m_inf_col) {
|
||||
lp_assert(p.coeff() == one_of_type<mpq>());
|
||||
TRACE("gomory_cut_detail", tout << "seeing basic var";);
|
||||
|
@ -306,11 +306,11 @@ public:
|
|||
adjust_term_and_k_for_some_ints_case_gomory(lcm_den);
|
||||
lp_assert(m_int_solver.current_solution_is_inf_on_cut());
|
||||
TRACE("gomory_cut_detail", dump_cut_and_constraints_as_smt_lemma(tout););
|
||||
m_int_solver.m_lar_solver->subs_term_columns(m_t, m_k);
|
||||
TRACE("gomory_cut_detail", dump_cut_and_constraints_as_smt_lemma(tout););
|
||||
m_int_solver.m_lar_solver->subs_term_columns(m_t);
|
||||
TRACE("gomory_cut", print_linear_combination_of_column_indices_only(m_t, tout << "gomory cut:"); tout << " <= " << m_k << std::endl;);
|
||||
return lia_move::cut;
|
||||
}
|
||||
|
||||
imp(lar_term & t, mpq & k, explanation& ex, unsigned basic_inf_int_j, const row_strip<mpq>& row, const int_solver& int_slv ) :
|
||||
m_t(t),
|
||||
m_k(k),
|
||||
|
|
|
@ -125,19 +125,19 @@ constraint_index int_solver::column_lower_bound_constraint(unsigned j) const {
|
|||
|
||||
bool int_solver::current_solution_is_inf_on_cut() const {
|
||||
const auto & x = m_lar_solver->m_mpq_lar_core_solver.m_r_x;
|
||||
impq v = m_t->apply(x);
|
||||
mpq sign = *m_upper ? one_of_type<mpq>() : -one_of_type<mpq>();
|
||||
CTRACE("current_solution_is_inf_on_cut", v * sign <= (*m_k) * sign,
|
||||
tout << "m_upper = " << *m_upper << std::endl;
|
||||
tout << "v = " << v << ", k = " << (*m_k) << std::endl;
|
||||
impq v = m_t.apply(x);
|
||||
mpq sign = m_upper ? one_of_type<mpq>() : -one_of_type<mpq>();
|
||||
CTRACE("current_solution_is_inf_on_cut", v * sign <= m_k * sign,
|
||||
tout << "m_upper = " << m_upper << std::endl;
|
||||
tout << "v = " << v << ", k = " << m_k << std::endl;
|
||||
);
|
||||
return v * sign > (*m_k) * sign;
|
||||
return v * sign > m_k * sign;
|
||||
}
|
||||
|
||||
lia_move int_solver::mk_gomory_cut( unsigned inf_col, const row_strip<mpq> & row) {
|
||||
lp_assert(column_is_int_inf(inf_col));
|
||||
|
||||
gomory gc(*m_t, *m_k, *m_ex, inf_col, row, *this);
|
||||
gomory gc(m_t, m_k, m_ex, inf_col, row, *this);
|
||||
return gc.create_cut();
|
||||
}
|
||||
|
||||
|
@ -147,7 +147,7 @@ lia_move int_solver::proceed_with_gomory_cut(unsigned j) {
|
|||
if (!is_gomory_cut_target(row))
|
||||
return create_branch_on_column(j);
|
||||
|
||||
*m_upper = true;
|
||||
m_upper = true;
|
||||
return mk_gomory_cut(j, row);
|
||||
}
|
||||
|
||||
|
@ -373,21 +373,21 @@ lia_move int_solver::make_hnf_cut() {
|
|||
#else
|
||||
vector<mpq> x0;
|
||||
#endif
|
||||
lia_move r = m_hnf_cutter.create_cut(*m_t, *m_k, *m_ex, *m_upper, x0);
|
||||
lia_move r = m_hnf_cutter.create_cut(m_t, m_k, m_ex, m_upper, x0);
|
||||
|
||||
if (r == lia_move::cut) {
|
||||
TRACE("hnf_cut",
|
||||
m_lar_solver->print_term(*m_t, tout << "cut:");
|
||||
tout << " <= " << *m_k << std::endl;
|
||||
m_lar_solver->print_term(m_t, tout << "cut:");
|
||||
tout << " <= " << m_k << std::endl;
|
||||
for (unsigned i : m_hnf_cutter.constraints_for_explanation()) {
|
||||
m_lar_solver->print_constraint(i, tout);
|
||||
}
|
||||
);
|
||||
lp_assert(current_solution_is_inf_on_cut());
|
||||
settings().st().m_hnf_cuts++;
|
||||
m_ex->clear();
|
||||
m_ex.clear();
|
||||
for (unsigned i : m_hnf_cutter.constraints_for_explanation()) {
|
||||
m_ex->push_justification(i);
|
||||
m_ex.push_justification(i);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
|
@ -403,10 +403,13 @@ lia_move int_solver::hnf_cut() {
|
|||
return lia_move::undef;
|
||||
}
|
||||
|
||||
lia_move int_solver::check(lar_term& t, mpq& k, explanation& ex, bool & upper) {
|
||||
lia_move int_solver::check() {
|
||||
if (!has_inf_int()) return lia_move::sat;
|
||||
|
||||
m_t = &t; m_k = &k; m_ex = &ex; m_upper = &upper;
|
||||
m_t.clear();
|
||||
m_k.reset();
|
||||
m_ex.clear();
|
||||
m_upper = false;
|
||||
lia_move r = run_gcd_test();
|
||||
if (r != lia_move::undef) return r;
|
||||
|
||||
|
@ -646,8 +649,8 @@ bool int_solver::gcd_test_for_row(static_matrix<mpq, numeric_pair<mpq>> & A, uns
|
|||
void int_solver::add_to_explanation_from_fixed_or_boxed_column(unsigned j) {
|
||||
constraint_index lc, uc;
|
||||
m_lar_solver->get_bound_constraint_witnesses_for_column(j, lc, uc);
|
||||
m_ex->m_explanation.push_back(std::make_pair(mpq(1), lc));
|
||||
m_ex->m_explanation.push_back(std::make_pair(mpq(1), uc));
|
||||
m_ex.m_explanation.push_back(std::make_pair(mpq(1), lc));
|
||||
m_ex.m_explanation.push_back(std::make_pair(mpq(1), uc));
|
||||
}
|
||||
void int_solver::fill_explanation_from_fixed_columns(const row_strip<mpq> & row) {
|
||||
for (const auto & c : row) {
|
||||
|
@ -1042,20 +1045,20 @@ const impq& int_solver::lower_bound(unsigned j) const {
|
|||
|
||||
lia_move int_solver::create_branch_on_column(int j) {
|
||||
TRACE("check_main_int", tout << "branching" << std::endl;);
|
||||
lp_assert(m_t->is_empty());
|
||||
lp_assert(m_t.is_empty());
|
||||
lp_assert(j != -1);
|
||||
m_t->add_monomial(mpq(1), m_lar_solver->adjust_column_index_to_term_index(j));
|
||||
m_t.add_monomial(mpq(1), m_lar_solver->adjust_column_index_to_term_index(j));
|
||||
if (is_free(j)) {
|
||||
*m_upper = true;
|
||||
*m_k = mpq(0);
|
||||
m_upper = true;
|
||||
m_k = mpq(0);
|
||||
} else {
|
||||
*m_upper = left_branch_is_more_narrow_than_right(j);
|
||||
*m_k = *m_upper? floor(get_value(j)) : ceil(get_value(j));
|
||||
m_upper = left_branch_is_more_narrow_than_right(j);
|
||||
m_k = m_upper? floor(get_value(j)) : ceil(get_value(j));
|
||||
}
|
||||
|
||||
TRACE("arith_int", tout << "branching v" << j << " = " << get_value(j) << "\n";
|
||||
display_column(tout, j);
|
||||
tout << "k = " << *m_k << std::endl;
|
||||
tout << "k = " << m_k << std::endl;
|
||||
);
|
||||
return lia_move::branch;
|
||||
|
||||
|
|
|
@ -39,19 +39,23 @@ public:
|
|||
// fields
|
||||
lar_solver *m_lar_solver;
|
||||
unsigned m_number_of_calls;
|
||||
lar_term *m_t; // the term to return in the cut
|
||||
mpq *m_k; // the right side of the cut
|
||||
explanation *m_ex; // the conflict explanation
|
||||
bool *m_upper; // we have a cut m_t*x <= k if m_upper is true nad m_t*x >= k otherwise
|
||||
lar_term m_t; // the term to return in the cut
|
||||
mpq m_k; // the right side of the cut
|
||||
explanation m_ex; // the conflict explanation
|
||||
bool m_upper; // we have a cut m_t*x <= k if m_upper is true nad m_t*x >= k otherwise
|
||||
hnf_cutter m_hnf_cutter;
|
||||
// methods
|
||||
int_solver(lar_solver* lp);
|
||||
|
||||
// main function to check that the solution provided by lar_solver is valid for integral values,
|
||||
// or provide a way of how it can be adjusted.
|
||||
lia_move check(lar_term& t, mpq& k, explanation& ex, bool & upper);
|
||||
lia_move check();
|
||||
lar_term const& get_term() const { return m_t; }
|
||||
mpq const& get_offset() const { return m_k; }
|
||||
explanation const& get_explanation() const { return m_ex; }
|
||||
bool is_upper() const { return m_upper; }
|
||||
|
||||
bool move_non_basic_column_to_bounds(unsigned j);
|
||||
lia_move check_wrapper(lar_term& t, mpq& k, explanation& ex);
|
||||
bool is_base(unsigned j) const;
|
||||
bool is_real(unsigned j) const;
|
||||
const impq & lower_bound(unsigned j) const;
|
||||
|
|
|
@ -75,7 +75,7 @@ struct lar_term_constraint: public lar_base_constraint {
|
|||
}
|
||||
unsigned size() const override { return m_term->size();}
|
||||
lar_term_constraint(const lar_term *t, lconstraint_kind kind, const mpq& right_side) : lar_base_constraint(kind, right_side), m_term(t) { }
|
||||
mpq get_free_coeff_of_left_side() const override { return m_term->m_v;}
|
||||
// mpq get_free_coeff_of_left_side() const override { return m_term->m_v;}
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ bool lar_solver::implied_bound_is_correctly_explained(implied_bound const & be,
|
|||
kind = static_cast<lconstraint_kind>(-kind);
|
||||
}
|
||||
rs_of_evidence /= ratio;
|
||||
rs_of_evidence += t->m_v * ratio;
|
||||
// rs_of_evidence += t->m_v * ratio;
|
||||
}
|
||||
|
||||
return kind == be.kind() && rs_of_evidence == be.m_bound;
|
||||
|
@ -602,7 +602,7 @@ void lar_solver::register_monoid_in_map(std::unordered_map<var_index, mpq> & coe
|
|||
|
||||
|
||||
void lar_solver::substitute_terms_in_linear_expression(const vector<std::pair<mpq, var_index>>& left_side_with_terms,
|
||||
vector<std::pair<mpq, var_index>> &left_side, mpq & free_coeff) const {
|
||||
vector<std::pair<mpq, var_index>> &left_side) const {
|
||||
std::unordered_map<var_index, mpq> coeffs;
|
||||
for (auto & t : left_side_with_terms) {
|
||||
unsigned j = t.second;
|
||||
|
@ -613,7 +613,6 @@ void lar_solver::substitute_terms_in_linear_expression(const vector<std::pair<mp
|
|||
for (auto & p : term.coeffs()){
|
||||
register_monoid_in_map(coeffs, t.first * p.second , p.first);
|
||||
}
|
||||
free_coeff += t.first * term.m_v;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -955,9 +954,9 @@ bool lar_solver::constraint_holds(const lar_base_constraint & constr, std::unord
|
|||
mpq left_side_val = get_left_side_val(constr, var_map);
|
||||
switch (constr.m_kind) {
|
||||
case LE: return left_side_val <= constr.m_right_side;
|
||||
case LT: return left_side_val < constr.m_right_side;
|
||||
case LT: return left_side_val < constr.m_right_side;
|
||||
case GE: return left_side_val >= constr.m_right_side;
|
||||
case GT: return left_side_val > constr.m_right_side;
|
||||
case GT: return left_side_val > constr.m_right_side;
|
||||
case EQ: return left_side_val == constr.m_right_side;
|
||||
default:
|
||||
lp_unreachable();
|
||||
|
@ -976,8 +975,10 @@ bool lar_solver::the_relations_are_of_same_type(const vector<std::pair<mpq, unsi
|
|||
flip_kind(m_constraints[con_ind]->m_kind);
|
||||
if (kind == GT || kind == LT)
|
||||
strict = true;
|
||||
if (kind == GE || kind == GT) n_of_G++;
|
||||
else if (kind == LE || kind == LT) n_of_L++;
|
||||
if (kind == GE || kind == GT)
|
||||
n_of_G++;
|
||||
else if (kind == LE || kind == LT)
|
||||
n_of_L++;
|
||||
}
|
||||
the_kind_of_sum = n_of_G ? GE : (n_of_L ? LE : EQ);
|
||||
if (strict)
|
||||
|
@ -1117,7 +1118,7 @@ bool lar_solver::has_upper_bound(var_index var, constraint_index& ci, mpq& value
|
|||
bool lar_solver::has_value(var_index var, mpq& value) const {
|
||||
if (is_term(var)) {
|
||||
lar_term const& t = get_term(var);
|
||||
value = t.m_v;
|
||||
value = 0;
|
||||
for (auto const& cv : t) {
|
||||
impq const& r = get_column_value(cv.var());
|
||||
if (!numeric_traits<mpq>::is_zero(r.y)) return false;
|
||||
|
@ -1229,8 +1230,7 @@ std::ostream& lar_solver::print_constraints(std::ostream& out) const {
|
|||
|
||||
std::ostream& lar_solver::print_terms(std::ostream& out) const {
|
||||
for (auto it : m_terms) {
|
||||
print_term(*it, out);
|
||||
out << "\n";
|
||||
print_term(*it, out) << "\n";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
@ -1244,9 +1244,6 @@ std::ostream& lar_solver::print_left_side_of_constraint(const lar_base_constrain
|
|||
}
|
||||
|
||||
std::ostream& lar_solver::print_term(lar_term const& term, std::ostream & out) const {
|
||||
if (!numeric_traits<mpq>::is_zero(term.m_v)) {
|
||||
out << term.m_v << " + ";
|
||||
}
|
||||
bool first = true;
|
||||
for (const auto p : term) {
|
||||
mpq val = p.coeff();
|
||||
|
@ -1270,9 +1267,6 @@ std::ostream& lar_solver::print_term(lar_term const& term, std::ostream & out) c
|
|||
}
|
||||
|
||||
std::ostream& lar_solver::print_term_as_indices(lar_term const& term, std::ostream & out) const {
|
||||
if (!numeric_traits<mpq>::is_zero(term.m_v)) {
|
||||
out << term.m_v << " + ";
|
||||
}
|
||||
print_linear_combination_of_column_indices_only(term, out);
|
||||
return out;
|
||||
}
|
||||
|
@ -1497,7 +1491,7 @@ bool lar_solver::term_is_int(const lar_term * t) const {
|
|||
for (auto const & p : t->m_coeffs)
|
||||
if (! (column_is_int(p.first) && p.second.is_int()))
|
||||
return false;
|
||||
return t->m_v.is_int();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lar_solver::var_is_int(var_index v) const {
|
||||
|
@ -1598,17 +1592,13 @@ void lar_solver::add_new_var_to_core_fields_for_mpq(bool register_in_basis) {
|
|||
}
|
||||
|
||||
|
||||
var_index lar_solver::add_term_undecided(const vector<std::pair<mpq, var_index>> & coeffs,
|
||||
const mpq &m_v) {
|
||||
push_and_register_term(new lar_term(coeffs, m_v));
|
||||
var_index lar_solver::add_term_undecided(const vector<std::pair<mpq, var_index>> & coeffs) {
|
||||
push_and_register_term(new lar_term(coeffs));
|
||||
return m_terms_start_index + m_terms.size() - 1;
|
||||
}
|
||||
|
||||
#if Z3DEBUG_CHECK_UNIQUE_TERMS
|
||||
bool lar_solver::term_coeffs_are_ok(const vector<std::pair<mpq, var_index>> & coeffs, const mpq& v) {
|
||||
if (coeffs.empty()) {
|
||||
return is_zero(v);
|
||||
}
|
||||
bool lar_solver::term_coeffs_are_ok(const vector<std::pair<mpq, var_index>> & coeffs) {
|
||||
|
||||
for (const auto & p : coeffs) {
|
||||
if (column_is_real(p.second))
|
||||
|
@ -1643,12 +1633,11 @@ void lar_solver::push_and_register_term(lar_term* t) {
|
|||
}
|
||||
|
||||
// terms
|
||||
var_index lar_solver::add_term(const vector<std::pair<mpq, var_index>> & coeffs,
|
||||
const mpq &m_v) {
|
||||
var_index lar_solver::add_term(const vector<std::pair<mpq, var_index>> & coeffs) {
|
||||
if (strategy_is_undecided())
|
||||
return add_term_undecided(coeffs, m_v);
|
||||
return add_term_undecided(coeffs);
|
||||
|
||||
push_and_register_term(new lar_term(coeffs, m_v));
|
||||
push_and_register_term(new lar_term(coeffs));
|
||||
unsigned adjusted_term_index = m_terms.size() - 1;
|
||||
var_index ret = m_terms_start_index + adjusted_term_index;
|
||||
if (use_tableau() && !coeffs.empty()) {
|
||||
|
@ -1656,13 +1645,12 @@ var_index lar_solver::add_term(const vector<std::pair<mpq, var_index>> & coeffs,
|
|||
if (m_settings.bound_propagation())
|
||||
m_rows_with_changed_bounds.insert(A_r().row_count() - 1);
|
||||
}
|
||||
CTRACE("add_term_lar_solver", !m_v.is_zero(), print_term(*m_terms.back(), tout););
|
||||
lp_assert(m_var_register.size() == A_r().column_count());
|
||||
return ret;
|
||||
}
|
||||
|
||||
void lar_solver::add_row_from_term_no_constraint(const lar_term * term, unsigned term_ext_index) {
|
||||
TRACE("dump_terms", print_term(*term, tout); tout << std::endl;);
|
||||
TRACE("dump_terms", print_term(*term, tout) << std::endl;);
|
||||
register_new_ext_var_index(term_ext_index, term_is_int(term));
|
||||
// j will be a new variable
|
||||
unsigned j = A_r().column_count();
|
||||
|
@ -1744,9 +1732,8 @@ void lar_solver::add_var_bound_on_constraint_for_term(var_index j, lconstraint_k
|
|||
// lp_assert(!term_is_int(m_terms[adjusted_term_index]) || right_side.is_int());
|
||||
unsigned term_j;
|
||||
if (m_var_register.external_is_used(j, term_j)) {
|
||||
mpq rs = right_side - m_terms[adjusted_term_index]->m_v;
|
||||
m_constraints.push_back(new lar_term_constraint(m_terms[adjusted_term_index], kind, right_side));
|
||||
update_column_type_and_bound(term_j, kind, rs, ci);
|
||||
update_column_type_and_bound(term_j, kind, right_side, ci);
|
||||
}
|
||||
else {
|
||||
add_constraint_from_term_and_create_new_column_row(j, m_terms[adjusted_term_index], kind, right_side);
|
||||
|
@ -1755,11 +1742,10 @@ void lar_solver::add_var_bound_on_constraint_for_term(var_index j, lconstraint_k
|
|||
|
||||
constraint_index lar_solver::add_constraint(const vector<std::pair<mpq, var_index>>& left_side_with_terms, lconstraint_kind kind_par, const mpq& right_side_parm) {
|
||||
vector<std::pair<mpq, var_index>> left_side;
|
||||
mpq rs = -right_side_parm;
|
||||
substitute_terms_in_linear_expression(left_side_with_terms, left_side, rs);
|
||||
unsigned term_index = add_term(left_side, zero_of_type<mpq>());
|
||||
substitute_terms_in_linear_expression(left_side_with_terms, left_side);
|
||||
unsigned term_index = add_term(left_side);
|
||||
constraint_index ci = m_constraints.size();
|
||||
add_var_bound_on_constraint_for_term(term_index, kind_par, -rs, ci);
|
||||
add_var_bound_on_constraint_for_term(term_index, kind_par, right_side_parm, ci);
|
||||
return ci;
|
||||
}
|
||||
|
||||
|
@ -1768,7 +1754,7 @@ void lar_solver::add_constraint_from_term_and_create_new_column_row(unsigned ter
|
|||
|
||||
add_row_from_term_no_constraint(term, term_j);
|
||||
unsigned j = A_r().column_count() - 1;
|
||||
update_column_type_and_bound(j, kind, right_side - term->m_v, m_constraints.size());
|
||||
update_column_type_and_bound(j, kind, right_side, m_constraints.size());
|
||||
m_constraints.push_back(new lar_term_constraint(term, kind, right_side));
|
||||
lp_assert(A_r().column_count() == m_mpq_lar_core_solver.m_r_solver.m_costs.size());
|
||||
}
|
||||
|
@ -2266,15 +2252,6 @@ void lar_solver::set_cut_strategy(unsigned cut_frequency) {
|
|||
}
|
||||
}
|
||||
|
||||
void lar_solver::adjust_cut_for_terms(const lar_term& t, mpq & rs) {
|
||||
for (const auto& p : t) {
|
||||
if (!is_term(p.var())) continue;
|
||||
const lar_term & p_term = get_term(p.var());
|
||||
if (p_term.m_v.is_zero()) continue;
|
||||
rs -= p.coeff() * p_term.m_v;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace lp
|
||||
|
||||
|
|
|
@ -164,13 +164,11 @@ public:
|
|||
|
||||
|
||||
// terms
|
||||
var_index add_term(const vector<std::pair<mpq, var_index>> & coeffs,
|
||||
const mpq &m_v);
|
||||
var_index add_term(const vector<std::pair<mpq, var_index>> & coeffs);
|
||||
|
||||
var_index add_term_undecided(const vector<std::pair<mpq, var_index>> & coeffs,
|
||||
const mpq &m_v);
|
||||
var_index add_term_undecided(const vector<std::pair<mpq, var_index>> & coeffs);
|
||||
|
||||
bool term_coeffs_are_ok(const vector<std::pair<mpq, var_index>> & coeffs, const mpq& v);
|
||||
bool term_coeffs_are_ok(const vector<std::pair<mpq, var_index>> & coeffs);
|
||||
void push_and_register_term(lar_term* t);
|
||||
|
||||
void add_row_for_term(const lar_term * term, unsigned term_ext_index);
|
||||
|
@ -331,7 +329,7 @@ public:
|
|||
|
||||
|
||||
void substitute_terms_in_linear_expression( const vector<std::pair<mpq, var_index>>& left_side_with_terms,
|
||||
vector<std::pair<mpq, var_index>> &left_side, mpq & free_coeff) const;
|
||||
vector<std::pair<mpq, var_index>> &left_side) const;
|
||||
|
||||
|
||||
void detect_rows_of_bound_change_column_for_nbasic_column(unsigned j);
|
||||
|
@ -534,7 +532,7 @@ public:
|
|||
return m_columns_to_ul_pairs()[j].lower_bound_witness();
|
||||
}
|
||||
|
||||
void subs_term_columns(lar_term& t, mpq & rs) {
|
||||
void subs_term_columns(lar_term& t) {
|
||||
vector<std::pair<unsigned,unsigned>> columns_to_subs;
|
||||
for (const auto & m : t.m_coeffs) {
|
||||
unsigned tj = adjust_column_index_to_term_index(m.first);
|
||||
|
@ -548,7 +546,6 @@ public:
|
|||
mpq v = it->second;
|
||||
t.m_coeffs.erase(it);
|
||||
t.m_coeffs[p.second] = v;
|
||||
rs -= v * lt.m_v;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -585,6 +582,5 @@ public:
|
|||
lar_term get_term_to_maximize(unsigned ext_j) const;
|
||||
void set_cut_strategy(unsigned cut_frequency);
|
||||
bool sum_first_coords(const lar_term& t, mpq & val) const;
|
||||
void adjust_cut_for_terms(const lar_term& t, mpq & rs);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
#include "util/lp/indexed_vector.h"
|
||||
namespace lp {
|
||||
struct lar_term {
|
||||
// the term evaluates to sum of m_coeffs + m_v
|
||||
// the term evaluates to sum of m_coeffs
|
||||
std::unordered_map<unsigned, mpq> m_coeffs;
|
||||
mpq m_v;
|
||||
// mpq m_v;
|
||||
lar_term() {}
|
||||
void add_monomial(const mpq& c, unsigned j) {
|
||||
auto it = m_coeffs.find(j);
|
||||
|
@ -37,7 +37,7 @@ struct lar_term {
|
|||
}
|
||||
|
||||
bool is_empty() const {
|
||||
return m_coeffs.size() == 0 && is_zero(m_v);
|
||||
return m_coeffs.size() == 0; // && is_zero(m_v);
|
||||
}
|
||||
|
||||
unsigned size() const { return static_cast<unsigned>(m_coeffs.size()); }
|
||||
|
@ -46,8 +46,7 @@ struct lar_term {
|
|||
return m_coeffs;
|
||||
}
|
||||
|
||||
lar_term(const vector<std::pair<mpq, unsigned>>& coeffs,
|
||||
const mpq & v) : m_v(v) {
|
||||
lar_term(const vector<std::pair<mpq, unsigned>>& coeffs) {
|
||||
for (const auto & p : coeffs) {
|
||||
add_monomial(p.first, p.second);
|
||||
}
|
||||
|
@ -87,7 +86,7 @@ struct lar_term {
|
|||
|
||||
template <typename T>
|
||||
T apply(const vector<T>& x) const {
|
||||
T ret = T(m_v);
|
||||
T ret(0);
|
||||
for (const auto & t : m_coeffs) {
|
||||
ret += t.second * x[t.first];
|
||||
}
|
||||
|
@ -96,7 +95,6 @@ struct lar_term {
|
|||
|
||||
void clear() {
|
||||
m_coeffs.clear();
|
||||
m_v = zero_of_type<mpq>();
|
||||
}
|
||||
|
||||
struct ival {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue