mirror of
https://github.com/Z3Prover/z3
synced 2025-04-28 19:35:50 +00:00
patching merge (#6780)
* patching merge * fix the format and some warnings Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * a fix in the delta calculation * test patching * try a new version of get_patching_deltas Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * remove dead code from lp_tst and try optimizing patching * add comments, replace VERIFY with lp_assert Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * cleanup --------- Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
parent
b2c035ea3f
commit
30a2ced9aa
13 changed files with 1989 additions and 1800 deletions
|
@ -2,7 +2,7 @@
|
|||
Copyright (c) 2017 Microsoft Corporation
|
||||
Author: Nikolaj Bjorner, Lev Nachmanson
|
||||
*/
|
||||
|
||||
// clang-format off
|
||||
#include "math/lp/lar_solver.h"
|
||||
#include "smt/params/smt_params_helper.hpp"
|
||||
|
||||
|
@ -41,7 +41,6 @@ namespace lp {
|
|||
for (auto t : m_terms)
|
||||
delete t;
|
||||
}
|
||||
|
||||
|
||||
bool lar_solver::sizes_are_correct() const {
|
||||
lp_assert(A_r().column_count() == m_mpq_lar_core_solver.m_r_solver.m_column_types.size());
|
||||
|
@ -50,7 +49,6 @@ namespace lp {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
std::ostream& lar_solver::print_implied_bound(const implied_bound& be, std::ostream& out) const {
|
||||
out << "implied bound\n";
|
||||
unsigned v = be.m_j;
|
||||
|
@ -1354,8 +1352,8 @@ namespace lp {
|
|||
}
|
||||
|
||||
bool lar_solver::term_is_int(const vector<std::pair<mpq, unsigned int>>& coeffs) const {
|
||||
for (auto const& p : coeffs)
|
||||
if (!(column_is_int(p.second) && p.first.is_int()))
|
||||
for (auto const& [coeff, v] : coeffs)
|
||||
if (!(column_is_int(v) && coeff.is_int()))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -1386,7 +1384,7 @@ namespace lp {
|
|||
// the lower/upper bound is not strict.
|
||||
// the LP obtained by making the bound strict is infeasible
|
||||
// -> the column has to be fixed
|
||||
bool lar_solver::is_fixed_at_bound(column_index const& j) {
|
||||
bool lar_solver::is_fixed_at_bound(column_index const& j, vector<std::tuple<explanation, column_index, bool, mpq>>& bounds) {
|
||||
if (column_is_fixed(j))
|
||||
return false;
|
||||
mpq val;
|
||||
|
@ -1395,50 +1393,56 @@ namespace lp {
|
|||
lp::lconstraint_kind k;
|
||||
if (column_has_upper_bound(j) &&
|
||||
get_upper_bound(j).x == val) {
|
||||
verbose_stream() << "check upper " << j << "\n";
|
||||
push();
|
||||
if (column_is_int(j))
|
||||
k = LE, val -= 1;
|
||||
else
|
||||
k = LT;
|
||||
auto ci = mk_var_bound(j, k, val);
|
||||
update_column_type_and_bound(j, k, val, ci);
|
||||
push();
|
||||
k = column_is_int(j) ? LE : LT;
|
||||
auto ci = mk_var_bound(j, k, column_is_int(j) ? val - 1 : val);
|
||||
update_column_type_and_bound(j, k, column_is_int(j) ? val - 1 : val, ci);
|
||||
auto st = find_feasible_solution();
|
||||
bool infeasible = st == lp_status::INFEASIBLE;
|
||||
if (infeasible) {
|
||||
explanation exp;
|
||||
get_infeasibility_explanation(exp);
|
||||
unsigned_vector cis;
|
||||
exp.remove(ci);
|
||||
verbose_stream() << "tight upper bound " << j << " " << val << "\n";
|
||||
bounds.push_back({exp, j, true, val});
|
||||
}
|
||||
pop(1);
|
||||
return st == lp_status::INFEASIBLE;
|
||||
return infeasible;
|
||||
}
|
||||
if (column_has_lower_bound(j) &&
|
||||
get_lower_bound(j).x == val) {
|
||||
verbose_stream() << "check lower " << j << "\n";
|
||||
push();
|
||||
if (column_is_int(j))
|
||||
k = GE, val += 1;
|
||||
else
|
||||
k = GT;
|
||||
auto ci = mk_var_bound(j, k, val);
|
||||
update_column_type_and_bound(j, k, val, ci);
|
||||
k = column_is_int(j) ? GE : GT;
|
||||
auto ci = mk_var_bound(j, k, column_is_int(j) ? val + 1 : val);
|
||||
update_column_type_and_bound(j, k, column_is_int(j) ? val + 1 : val, ci);
|
||||
auto st = find_feasible_solution();
|
||||
bool infeasible = st == lp_status::INFEASIBLE;
|
||||
if (infeasible) {
|
||||
explanation exp;
|
||||
get_infeasibility_explanation(exp);
|
||||
exp.remove(ci);
|
||||
verbose_stream() << "tight lower bound " << j << " " << val << "\n";
|
||||
bounds.push_back({exp, j, false, val});
|
||||
}
|
||||
pop(1);
|
||||
return st == lp_status::INFEASIBLE;
|
||||
return infeasible;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool lar_solver::has_fixed_at_bound() {
|
||||
bool lar_solver::has_fixed_at_bound(vector<std::tuple<explanation, column_index, bool, mpq>>& bounds) {
|
||||
verbose_stream() << "has-fixed-at-bound\n";
|
||||
unsigned num_fixed = 0;
|
||||
for (unsigned j = 0; j < A_r().m_columns.size(); ++j) {
|
||||
auto ci = column_index(j);
|
||||
if (is_fixed_at_bound(ci)) {
|
||||
++num_fixed;
|
||||
if (is_fixed_at_bound(ci, bounds))
|
||||
verbose_stream() << "fixed " << j << "\n";
|
||||
}
|
||||
}
|
||||
verbose_stream() << "num fixed " << num_fixed << "\n";
|
||||
if (num_fixed > 0)
|
||||
verbose_stream() << "num fixed " << bounds.size() << "\n";
|
||||
if (!bounds.empty())
|
||||
find_feasible_solution();
|
||||
return num_fixed > 0;
|
||||
return !bounds.empty();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1617,6 +1621,18 @@ namespace lp {
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief ensure there is a column index corresponding to vi
|
||||
* If vi is already a column, just return vi
|
||||
* If vi is for a term, then create a row that uses the term.
|
||||
*/
|
||||
var_index lar_solver::ensure_column(var_index vi) {
|
||||
if (lp::tv::is_term(vi))
|
||||
return to_column(vi);
|
||||
else
|
||||
return vi;
|
||||
}
|
||||
|
||||
|
||||
void lar_solver::add_row_from_term_no_constraint(const lar_term* term, unsigned term_ext_index) {
|
||||
TRACE("dump_terms", print_term(*term, tout) << std::endl;);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue