mirror of
https://github.com/Z3Prover/z3
synced 2025-04-10 19:27:06 +00:00
add cancel to hnf_cutter
Signed-off-by: Lev Nachmanson <levnach@hotmail.com> exit earlier on a large matrix in hnf_cutter Signed-off-by: Lev Nachmanson <levnach@hotmail.com> call hnf only for the boundary points Signed-off-by: Lev Nachmanson <levnach@hotmail.com> fix a bug in hnf_cutter initialization Signed-off-by: Lev Nachmanson <levnach@hotmail.com> initialize has_bounds in lar_solver::get_equality_for_term_on_corrent_x Signed-off-by: Lev Nachmanson <levnach@hotmail.com> initialize has_bounds in lar_solver::get_equality_for_term_on_corrent_x Signed-off-by: Lev Nachmanson <levnach@hotmail.com> initialize has_bounds in lar_solver::get_equality_for_term_on_corrent_x Signed-off-by: Lev Nachmanson <levnach@hotmail.com> initialize has_bounds in lar_solver::get_equality_for_term_on_corrent_x Signed-off-by: Lev Nachmanson <levnach@hotmail.com> fixes in determinant_of_rectangular_matrix calculations Signed-off-by: Lev Nachmanson <levnach@hotmail.com> changes in debug code Signed-off-by: Lev Nachmanson <levnach@hotmail.com> init m_hnf_cut_period from globals settings Signed-off-by: Lev Nachmanson <levnach@hotmail.com> fix some warnings Signed-off-by: Lev Nachmanson <levnach@hotmail.com> Lev2 (#66) * log quantifiers only if present Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * merge and fix some warnings Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> remove a comment Signed-off-by: Lev Nachmanson <levnach@hotmail.com> simplify gomory cut return's logic Signed-off-by: Lev Nachmanson <levnach@hotmail.com> simplify uniformly int_solver::check() Signed-off-by: Lev Nachmanson <levnach@hotmail.com> making new arith solver default for LIA (#67) * log quantifiers only if present Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * merge and fix some warnings Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * set new arith as default for LIA Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> remove chase_cut_solver Signed-off-by: Lev Nachmanson <levnach@hotmail.com> remove integer_domain Signed-off-by: Lev Nachmanson <levnach@hotmail.com> restore call for find_cube() Signed-off-by: Lev Nachmanson <levnach@hotmail.com> remove a method Signed-off-by: Lev Nachmanson <levnach@hotmail.com> remove some debug code Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
parent
82eb80de6d
commit
9be49ff6ff
|
@ -25,11 +25,11 @@ Revision History:
|
|||
enum arith_solver_id {
|
||||
AS_NO_ARITH, // 0
|
||||
AS_DIFF_LOGIC, // 1
|
||||
AS_ARITH, // 2
|
||||
AS_OLD_ARITH, // 2
|
||||
AS_DENSE_DIFF_LOGIC, // 3
|
||||
AS_UTVPI, // 4
|
||||
AS_OPTINF, // 5
|
||||
AS_LRA // 6
|
||||
AS_NEW_ARITH // 6
|
||||
};
|
||||
|
||||
enum bound_prop_mode {
|
||||
|
@ -113,7 +113,7 @@ struct theory_arith_params {
|
|||
theory_arith_params(params_ref const & p = params_ref()):
|
||||
m_arith_eq2ineq(false),
|
||||
m_arith_process_all_eqs(false),
|
||||
m_arith_mode(AS_ARITH),
|
||||
m_arith_mode(AS_NEW_ARITH),
|
||||
m_arith_auto_config_simplex(false),
|
||||
m_arith_blands_rule_threshold(1000),
|
||||
m_arith_propagate_eqs(true),
|
||||
|
|
|
@ -730,11 +730,11 @@ namespace smt {
|
|||
}
|
||||
|
||||
void setup::setup_i_arith() {
|
||||
if (AS_LRA == m_params.m_arith_mode) {
|
||||
setup_r_arith();
|
||||
if (AS_OLD_ARITH == m_params.m_arith_mode) {
|
||||
m_context.register_plugin(alloc(smt::theory_i_arith, m_manager, m_params));
|
||||
}
|
||||
else {
|
||||
m_context.register_plugin(alloc(smt::theory_i_arith, m_manager, m_params));
|
||||
setup_r_arith();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -747,7 +747,7 @@ namespace smt {
|
|||
case AS_OPTINF:
|
||||
m_context.register_plugin(alloc(smt::theory_inf_arith, m_manager, m_params));
|
||||
break;
|
||||
case AS_LRA:
|
||||
case AS_NEW_ARITH:
|
||||
setup_r_arith();
|
||||
break;
|
||||
default:
|
||||
|
@ -811,12 +811,15 @@ namespace smt {
|
|||
case AS_OPTINF:
|
||||
m_context.register_plugin(alloc(smt::theory_inf_arith, m_manager, m_params));
|
||||
break;
|
||||
case AS_LRA:
|
||||
setup_r_arith();
|
||||
case AS_OLD_ARITH:
|
||||
if (m_params.m_arith_int_only && int_only)
|
||||
m_context.register_plugin(alloc(smt::theory_i_arith, m_manager, m_params));
|
||||
else
|
||||
m_context.register_plugin(alloc(smt::theory_mi_arith, m_manager, m_params));
|
||||
break;
|
||||
default:
|
||||
if (m_params.m_arith_int_only && int_only)
|
||||
m_context.register_plugin(alloc(smt::theory_i_arith, m_manager, m_params));
|
||||
setup_i_arith();
|
||||
else
|
||||
m_context.register_plugin(alloc(smt::theory_mi_arith, m_manager, m_params));
|
||||
break;
|
||||
|
|
|
@ -307,7 +307,7 @@ class theory_lra::imp {
|
|||
m_solver->settings().bound_propagation() = BP_NONE != propagation_mode();
|
||||
m_solver->set_track_pivoted_rows(lp.bprop_on_pivoted_rows());
|
||||
m_solver->settings().m_int_gomory_cut_period = ctx().get_fparams().m_arith_branch_cut_ratio;
|
||||
m_solver->settings().m_int_cuts_etc_period = ctx().get_fparams().m_arith_branch_cut_ratio;
|
||||
m_solver->settings().m_hnf_cut_period = ctx().get_fparams().m_arith_branch_cut_ratio;
|
||||
m_solver->settings().m_int_chase_cut_solver_period = std::max(8u, ctx().get_fparams().m_arith_branch_cut_ratio);
|
||||
m_solver->settings().m_int_run_gcd_test = ctx().get_fparams().m_arith_gcd_test;
|
||||
|
||||
|
@ -1302,7 +1302,7 @@ public:
|
|||
case lp::lia_move::cut: {
|
||||
++m_stats.m_gomory_cuts;
|
||||
// m_explanation implies term <= k
|
||||
app_ref b = mk_bound(term, k, false);
|
||||
app_ref b = mk_bound(term, k, !upper);
|
||||
m_eqs.reset();
|
||||
m_core.reset();
|
||||
m_params.reset();
|
||||
|
@ -2533,10 +2533,10 @@ public:
|
|||
struct scoped_arith_mode {
|
||||
smt_params& p;
|
||||
scoped_arith_mode(smt_params& p) : p(p) {
|
||||
p.m_arith_mode = AS_ARITH;
|
||||
p.m_arith_mode = AS_OLD_ARITH;
|
||||
}
|
||||
~scoped_arith_mode() {
|
||||
p.m_arith_mode = AS_LRA;
|
||||
p.m_arith_mode = AS_NEW_ARITH;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2544,7 +2544,7 @@ public:
|
|||
if (dump_lemmas()) {
|
||||
ctx().display_lemma_as_smt_problem(m_core.size(), m_core.c_ptr(), m_eqs.size(), m_eqs.c_ptr(), false_literal);
|
||||
}
|
||||
if (m_arith_params.m_arith_mode != AS_LRA) return true;
|
||||
if (m_arith_params.m_arith_mode != AS_NEW_ARITH) return true;
|
||||
scoped_arith_mode _sa(ctx().get_fparams());
|
||||
context nctx(m, ctx().get_fparams(), ctx().get_params());
|
||||
add_background(nctx);
|
||||
|
@ -2559,7 +2559,7 @@ public:
|
|||
if (dump_lemmas()) {
|
||||
ctx().display_lemma_as_smt_problem(m_core.size(), m_core.c_ptr(), m_eqs.size(), m_eqs.c_ptr(), lit);
|
||||
}
|
||||
if (m_arith_params.m_arith_mode != AS_LRA) return true;
|
||||
if (m_arith_params.m_arith_mode != AS_NEW_ARITH) return true;
|
||||
scoped_arith_mode _sa(ctx().get_fparams());
|
||||
context nctx(m, ctx().get_fparams(), ctx().get_params());
|
||||
m_core.push_back(~lit);
|
||||
|
@ -2574,7 +2574,7 @@ public:
|
|||
}
|
||||
|
||||
bool validate_eq(enode* x, enode* y) {
|
||||
if (m_arith_params.m_arith_mode == AS_LRA) return true;
|
||||
if (m_arith_params.m_arith_mode == AS_NEW_ARITH) return true;
|
||||
context nctx(m, ctx().get_fparams(), ctx().get_params());
|
||||
add_background(nctx);
|
||||
nctx.assert_expr(m.mk_not(m.mk_eq(x->get_owner(), y->get_owner())));
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
#include "util/lp/stacked_unordered_set.h"
|
||||
#include "util/lp/int_set.h"
|
||||
#include "util/stopwatch.h"
|
||||
#include "util/lp/integer_domain.h"
|
||||
#include "util/lp/stacked_map.h"
|
||||
#include <cstdlib>
|
||||
#include "test/lp/gomory_test.h"
|
||||
|
@ -3121,152 +3120,6 @@ void get_random_interval(bool& neg_inf, bool& pos_inf, int& x, int &y) {
|
|||
lp_assert((neg_inf || (0 <= x && x <= 100)) && (pos_inf || (0 <= y && y <= 100)));
|
||||
}
|
||||
|
||||
void test_integer_domain_intersection(integer_domain<int> & d) {
|
||||
// int x, y; bool neg_inf, pos_inf;
|
||||
// get_random_interval(neg_inf, pos_inf, x, y);
|
||||
// if (neg_inf) {
|
||||
// if (!pos_inf) {
|
||||
// d.intersect_with_upper_bound(y);
|
||||
// }
|
||||
// }
|
||||
// else if (pos_inf)
|
||||
// d.intersect_with_lower_bound(x);
|
||||
// else
|
||||
// d.intersect_with_interval(x, y);
|
||||
}
|
||||
|
||||
void test_integer_domain_union(integer_domain<int> & d) {
|
||||
int x, y; bool neg_inf, pos_inf;
|
||||
get_random_interval(neg_inf, pos_inf, x, y);
|
||||
if (neg_inf) {
|
||||
if (!pos_inf) {
|
||||
d.unite_with_interval_neg_inf_x(y);
|
||||
}
|
||||
else
|
||||
d.init_to_contain_all();
|
||||
}
|
||||
else if (pos_inf)
|
||||
d.unite_with_interval_x_pos_inf(x);
|
||||
else
|
||||
d.unite_with_interval(x, y);
|
||||
|
||||
lp_assert(d.is_correct());
|
||||
}
|
||||
|
||||
|
||||
void test_integer_domain_randomly(integer_domain<int> & d) {
|
||||
int i = my_random() % 10;
|
||||
if (i == 0)
|
||||
test_integer_domain_intersection(d);
|
||||
else
|
||||
test_integer_domain_union(d);
|
||||
}
|
||||
|
||||
void test_integer_domain() {
|
||||
#ifdef Z3DEBUG
|
||||
|
||||
std::cout << "test_integer_domain\n";
|
||||
unsigned e0 = 0;
|
||||
unsigned e1 = 1;
|
||||
unsigned e2 = 2;
|
||||
unsigned e3 = 3; // these are explanations
|
||||
unsigned e4 = 4;
|
||||
unsigned e5 = 5;
|
||||
integer_domain<unsigned> d;
|
||||
unsigned l0 = 0, l1 = 1, l2 = 3;
|
||||
unsigned u0 = 10, u1 = 9, u2 = 8;
|
||||
d.push();
|
||||
d.intersect_with_lower_bound(l0, e0);
|
||||
unsigned b;
|
||||
unsigned e;
|
||||
bool r = d.get_lower_bound_with_expl(b, e);
|
||||
lp_assert(r && b == l0 && e == e0);
|
||||
d.push();
|
||||
d.intersect_with_upper_bound(u0, e1);
|
||||
r = d.get_upper_bound_with_expl(b, e);
|
||||
lp_assert(r && b == u0 && e == e1);
|
||||
r = d.get_lower_bound_with_expl(b, e);
|
||||
lp_assert(r && b == l0 && e == e0);
|
||||
d.pop();
|
||||
r = d.get_upper_bound_with_expl(b, e);
|
||||
lp_assert(!r);
|
||||
d.intersect_with_upper_bound(u0, e1);
|
||||
d.push();
|
||||
d.intersect_with_lower_bound(l1, e2);
|
||||
d.intersect_with_upper_bound(u1, e3);
|
||||
d.push();
|
||||
d.intersect_with_lower_bound(l2, e4);
|
||||
d.intersect_with_upper_bound(u2, e5);
|
||||
lp_assert(d.is_empty() == false);
|
||||
d.print(std::cout);
|
||||
d.pop();
|
||||
r = d.get_lower_bound_with_expl(b, e);
|
||||
lp_assert(r && b == l1 && e == e2);
|
||||
d.print(std::cout);
|
||||
d.pop(2);
|
||||
d.print(std::cout);
|
||||
lp_assert(d.has_neg_inf() && d.has_pos_inf());
|
||||
#endif
|
||||
// integer_domain<int> d;
|
||||
// std::vector<integer_domain<int>> stack;
|
||||
// for (int i = 0; i < 10000; i++) {
|
||||
// test_integer_domain_randomly(d);
|
||||
// stack.push_back(d);
|
||||
// d.push();
|
||||
// if (i > 0 && i%100 == 0) {
|
||||
// if (stack.size() == 0) continue;
|
||||
// unsigned k = my_random() % stack.size();
|
||||
// if (k == 0)
|
||||
// k = 1;
|
||||
// d.pop(k);
|
||||
// d.restore_domain();
|
||||
// for (unsigned j = 0; j + 1 < k; j++) {
|
||||
// stack.pop_back();
|
||||
// }
|
||||
// std::cout<<"comparing i = " << i << std::endl;
|
||||
// lp_assert(d == *stack.rbegin());
|
||||
// stack.pop_back();
|
||||
// }
|
||||
// //d.print(std::cout);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
void test_resolve_with_tight_constraint(chase_cut_solver& cs,
|
||||
lp::chase_cut_solver::polynomial&i ,
|
||||
unsigned int j,
|
||||
chase_cut_solver::polynomial& ti) {
|
||||
|
||||
// std::cout << "resolve constraint ";
|
||||
// cs.print_polynomial(std::cout, i);
|
||||
// std::cout << " for " << cs.get_column_name(j) << " by using poly ";
|
||||
// cs.print_polynomial(std::cout, ti);
|
||||
// std::cout << std::endl;
|
||||
// bool j_coeff_is_one = ti.coeff(j) == 1;
|
||||
// chase_cut_solver::polynomial result;
|
||||
// cs.resolve(i, j, j_coeff_is_one, ti);
|
||||
// std::cout << "resolve result is ";
|
||||
// cs.print_polynomial(std::cout, i);
|
||||
// std::cout << std::endl;
|
||||
}
|
||||
|
||||
typedef chase_cut_solver::monomial mono;
|
||||
|
||||
void test_resolve(chase_cut_solver& cs, unsigned constraint_index, unsigned i0) {
|
||||
var_index x = 0;
|
||||
var_index y = 1;
|
||||
var_index z = 2;
|
||||
std::cout << "test_resolve\n";
|
||||
|
||||
chase_cut_solver::polynomial i; i += mono(2, x);i += mono(-3,y);
|
||||
i+= mono(4, z);
|
||||
i.m_a = 5;
|
||||
chase_cut_solver::polynomial ti; ti += mono(1, x); ti+= mono(1,y);ti.m_a = 3;
|
||||
test_resolve_with_tight_constraint(cs, i, x, ti);
|
||||
test_resolve_with_tight_constraint(cs, i, y ,ti);
|
||||
}
|
||||
|
||||
|
||||
void test_gomory_cut_0() {
|
||||
gomory_test g(
|
||||
|
@ -3688,15 +3541,29 @@ void test_larger_generated_hnf() {
|
|||
std::cout << "test_larger_generated_rank_hnf" << std::endl;
|
||||
general_matrix A;
|
||||
vector<mpq> v;
|
||||
v.push_back(zero_of_type<mpq>());
|
||||
v.push_back(zero_of_type<mpq>());
|
||||
v.push_back(zero_of_type<mpq>());
|
||||
A.push_row(v);
|
||||
v.clear();
|
||||
v.push_back(mpq(5));
|
||||
v.push_back(mpq(6));
|
||||
v.push_back(mpq(3));
|
||||
v.push_back(mpq(1));
|
||||
A.push_row(v);
|
||||
v.clear();
|
||||
v.push_back(mpq(5));
|
||||
v.push_back(mpq(26));
|
||||
v.push_back(mpq(2));
|
||||
v.push_back(mpq(3));
|
||||
v.push_back(mpq(7));
|
||||
A.push_row(v);
|
||||
v.clear();
|
||||
v.push_back(mpq(5));
|
||||
v.push_back(mpq(6));
|
||||
v.push_back(mpq(3));
|
||||
v.push_back(mpq(1));
|
||||
A.push_row(v);
|
||||
v.clear();
|
||||
v.push_back(mpq(5));
|
||||
v.push_back(mpq(2));
|
||||
v.push_back(mpq(3));
|
||||
v.push_back(mpq(7));
|
||||
A.push_row(v);
|
||||
call_hnf(A);
|
||||
std::cout << "test_larger_generated_rank_hnf passed" << std::endl;
|
||||
|
@ -3750,10 +3617,6 @@ void test_lp_local(int argn, char**argv) {
|
|||
test_gomory_cut();
|
||||
return finalize(0);
|
||||
}
|
||||
if (args_parser.option_is_used("-intd")) {
|
||||
test_integer_domain();
|
||||
return finalize(0);
|
||||
}
|
||||
|
||||
if (args_parser.option_is_used("--test_mpq")) {
|
||||
test_rationals();
|
||||
|
|
|
@ -4,7 +4,6 @@ z3_add_component(lp
|
|||
binary_heap_priority_queue.cpp
|
||||
binary_heap_upair_queue.cpp
|
||||
bound_propagator.cpp
|
||||
chase_cut_solver.cpp
|
||||
core_solver_pretty_printer.cpp
|
||||
dense_matrix.cpp
|
||||
eta_matrix.cpp
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2017 Microsoft Corporation
|
||||
Author: Nikolaj Bjorner, Lev Nachmanson
|
||||
*/
|
||||
#include "util/lp/chase_cut_solver.h"
|
||||
namespace lp {
|
||||
mpq polynomial::m_local_zero = zero_of_type<mpq>();
|
||||
|
||||
size_t constraint_hash::operator() (const constraint* c) const { return c->id(); }
|
||||
|
||||
bool constraint_equal::operator() (const constraint* a, const constraint * b) const { return a->id() == b->id(); }
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, pp_poly const& p) {
|
||||
p.s.print_polynomial(out, p.p);
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, pp_constraint const& c) {
|
||||
c.s.print_constraint(out, c.c);
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -18,6 +18,7 @@ Revision History:
|
|||
|
||||
--*/
|
||||
#pragma once
|
||||
#include <functional>
|
||||
namespace lp {
|
||||
class general_matrix {
|
||||
// fields
|
||||
|
@ -72,12 +73,18 @@ public:
|
|||
|
||||
#ifdef Z3DEBUG
|
||||
void print(std::ostream & out, unsigned blanks = 0) const {
|
||||
print_matrix<mpq>(m_data, out, blanks);
|
||||
unsigned m = row_count();
|
||||
unsigned n = column_count();
|
||||
general_matrix g(m, n);
|
||||
for (unsigned i = 0; i < m; i++)
|
||||
for (unsigned j = 0; j < n; j++)
|
||||
g[i][j] = (*this)[i][j];
|
||||
print_matrix<mpq>(g.m_data, out, blanks);
|
||||
}
|
||||
void print(std::ostream & out, const char * ss) const {
|
||||
std::string s(ss);
|
||||
out << s;
|
||||
print(out, s.size());
|
||||
print(out, static_cast<unsigned>(s.size()));
|
||||
}
|
||||
|
||||
void print_submatrix(std::ostream & out, unsigned k, unsigned blanks = 0) const {
|
||||
|
|
|
@ -20,7 +20,6 @@ $1$ at $i$-th position. Then we need to find the row vector $e_iU^{-1}=t$. Notic
|
|||
We find $e_iH^{-1} = f$ by solving $e_i = fH$ and then $fA$ gives us $t$.
|
||||
|
||||
Author:
|
||||
Nikolaj Bjorner (nbjorner)
|
||||
Lev Nachmanson (levnach)
|
||||
|
||||
Revision History:
|
||||
|
@ -104,15 +103,13 @@ void extended_gcd_minimal_uv(const mpq & a, const mpq & b, mpq & d, mpq & u, mpq
|
|||
|
||||
|
||||
|
||||
template <typename M> bool prepare_pivot_for_lower_triangle(M &m, unsigned r, svector<unsigned> & basis_rows) {
|
||||
lp_assert(m.row_count() <= m.column_count());
|
||||
template <typename M> bool prepare_pivot_for_lower_triangle(M &m, unsigned r) {
|
||||
for (unsigned i = r; i < m.row_count(); i++) {
|
||||
for (unsigned j = r; j < m.column_count(); j++) {
|
||||
if (!is_zero(m[i][j])) {
|
||||
if (i != r) {
|
||||
m.transpose_rows(i, r);
|
||||
}
|
||||
basis_rows.push_back(i);
|
||||
if (j != r) {
|
||||
m.transpose_columns(j, r);
|
||||
}
|
||||
|
@ -123,7 +120,8 @@ template <typename M> bool prepare_pivot_for_lower_triangle(M &m, unsigned r, sv
|
|||
return false;
|
||||
}
|
||||
|
||||
template <typename M> void pivot_column_non_fractional(M &m, unsigned & r) {
|
||||
template <typename M> void pivot_column_non_fractional(M &m, unsigned r) {
|
||||
lp_assert(!is_zero(m[r][r]));
|
||||
lp_assert(m.row_count() <= m.column_count());
|
||||
for (unsigned j = r + 1; j < m.column_count(); j++) {
|
||||
for (unsigned i = r + 1; i < m.row_count(); i++) {
|
||||
|
@ -134,37 +132,36 @@ template <typename M> void pivot_column_non_fractional(M &m, unsigned & r) {
|
|||
lp_assert(is_int(m[i][j]));
|
||||
}
|
||||
}
|
||||
|
||||
// debug
|
||||
for (unsigned k = r + 1; k < m.row_count(); k++) {
|
||||
m[k][r] = zero_of_type<mpq>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// returns the rank of the matrix
|
||||
template <typename M> void to_lower_triangle_non_fractional(M &m, svector<unsigned> & basis_rows ) {
|
||||
template <typename M> unsigned to_lower_triangle_non_fractional(M &m) {
|
||||
lp_assert(m.row_count() <= m.column_count());
|
||||
unsigned i = 0;
|
||||
for (; i < m.row_count() - 1; i++) {
|
||||
if (!prepare_pivot_for_lower_triangle(m, i, basis_rows)) {
|
||||
return;
|
||||
for (; i < m.row_count(); i++) {
|
||||
if (!prepare_pivot_for_lower_triangle(m, i)) {
|
||||
return i;
|
||||
}
|
||||
pivot_column_non_fractional(m, i);
|
||||
}
|
||||
lp_assert(i == m.row_count() - 1);
|
||||
// go over the last row and try to find a non-zero in the row to the right of diagonal
|
||||
for (unsigned j = i; j < m.column_count(); j++) {
|
||||
if (!is_zero(m[i][j])) {
|
||||
basis_rows.push_back(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
lp_assert(i == m.row_count());
|
||||
return i;
|
||||
}
|
||||
template <typename M>
|
||||
mpq gcd_of_row_starting_from_diagonal(const M& m, unsigned i) {
|
||||
mpq g = zero_of_type<mpq>();
|
||||
unsigned j = i;
|
||||
for (; j < m.column_count() && is_zero(j); j++) {
|
||||
for (; j < m.column_count() && is_zero(g); j++) {
|
||||
const auto & t = m[i][j];
|
||||
if (!is_zero(t))
|
||||
g = t;
|
||||
g = abs(t);
|
||||
}
|
||||
lp_assert(!is_zero(g));
|
||||
for (; j < m.column_count(); j++) {
|
||||
const auto & t = m[i][j];
|
||||
if (!is_zero(t))
|
||||
|
@ -183,10 +180,15 @@ template <typename M> mpq determinant_of_rectangular_matrix(const M& m, svector<
|
|||
// m[r-1][r-1], m[r-1][r], ..., m[r-1]m[m.column_count() - 1] give the determinants of all minors of rank r.
|
||||
// The gcd of these minors is the return value
|
||||
auto mc = m;
|
||||
to_lower_triangle_non_fractional(mc, basis_rows);
|
||||
if (basis_rows.size() == 0)
|
||||
unsigned rank = to_lower_triangle_non_fractional(mc);
|
||||
if (rank == 0)
|
||||
return one_of_type<mpq>();
|
||||
return gcd_of_row_starting_from_diagonal(mc, basis_rows.size() - 1);
|
||||
|
||||
for (unsigned i = 0; i < rank; i++) {
|
||||
basis_rows.push_back(mc.adjust_row(i));
|
||||
}
|
||||
TRACE("hnf_calc", tout << "basis_rows = "; print_vector(basis_rows, tout); mc.print(tout, "mc = "););
|
||||
return gcd_of_row_starting_from_diagonal(mc, rank - 1);
|
||||
}
|
||||
|
||||
template <typename M> mpq determinant(const M& m) {
|
||||
|
@ -499,9 +501,7 @@ private:
|
|||
m_W[k][j] -= u * m_W[k][m_i];
|
||||
// m_W[k][j] = mod_R_balanced(m_W[k][j]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool is_unit_matrix(const M& u) const {
|
||||
unsigned m = u.row_count();
|
||||
|
@ -597,8 +597,8 @@ public:
|
|||
hnf(M & A, const mpq & d) :
|
||||
#ifdef Z3DEBUG
|
||||
m_H(A),
|
||||
#endif
|
||||
m_A_orig(A),
|
||||
#endif
|
||||
m_W(A),
|
||||
m_buffer(std::max(A.row_count(), A.column_count())),
|
||||
m_m(A.row_count()),
|
||||
|
|
|
@ -11,7 +11,6 @@ Abstract:
|
|||
|
||||
Author:
|
||||
Lev Nachmanson (levnach)
|
||||
Nikolaj Bjorner (nbjorner)
|
||||
|
||||
Revision History:
|
||||
|
||||
|
@ -33,13 +32,21 @@ class hnf_cutter {
|
|||
vector<mpq> m_right_sides;
|
||||
unsigned m_row_count;
|
||||
unsigned m_column_count;
|
||||
std::function<unsigned ()> m_random_next;
|
||||
lp_settings & m_settings;
|
||||
public:
|
||||
hnf_cutter(std::function<unsigned()> random) : m_random_next(random) {}
|
||||
hnf_cutter(lp_settings & settings) : m_row_count(0), m_column_count(0), m_settings(settings) {}
|
||||
|
||||
unsigned row_count() const {
|
||||
return m_row_count;
|
||||
}
|
||||
|
||||
const vector<const lar_term*>& terms() const { return m_terms; }
|
||||
const vector<mpq> & right_sides() const { return m_right_sides; }
|
||||
void clear() {
|
||||
// m_A will be filled from scratch in init_matrix_A
|
||||
m_var_register.clear();
|
||||
m_terms.clear();
|
||||
m_right_sides.clear();
|
||||
m_row_count = m_column_count = 0;
|
||||
}
|
||||
void add_term(const lar_term* t, const mpq &rs) {
|
||||
|
@ -95,15 +102,14 @@ public:
|
|||
int ret = -1;
|
||||
int n = 0;
|
||||
for (int i = 0; i < static_cast<int>(b.size()); i++) {
|
||||
if (!is_int(b[i])) {
|
||||
if (n == 0 ) {
|
||||
lp_assert(ret == -1);
|
||||
n = 1;
|
||||
if (is_int(b[i])) continue;
|
||||
if (n == 0 ) {
|
||||
lp_assert(ret == -1);
|
||||
n = 1;
|
||||
ret = i;
|
||||
} else {
|
||||
if (m_settings.random_next() % (++n) == 0) {
|
||||
ret = i;
|
||||
} else {
|
||||
if (m_random_next() % (++n) == 0) {
|
||||
ret = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -144,11 +150,28 @@ public:
|
|||
t.add_monomial(row[j], m_var_register.local_var_to_user_var(j));
|
||||
}
|
||||
}
|
||||
|
||||
lia_move create_cut(lar_term& t, mpq& k, explanation& ex, bool & upper) {
|
||||
#ifdef Z3DEBUG
|
||||
vector<mpq> transform_to_local_columns(const vector<impq> & x) const {
|
||||
vector<mpq> ret;
|
||||
lp_assert(m_column_count <= m_var_register.size());
|
||||
for (unsigned j = 0; j < m_column_count;j++) {
|
||||
lp_assert(is_zero(x[m_var_register.local_var_to_user_var(j)].y));
|
||||
ret.push_back(x[m_var_register.local_var_to_user_var(j)].x);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
lia_move create_cut(lar_term& t, mpq& k, explanation& ex, bool & upper
|
||||
#ifdef Z3DEBUG
|
||||
,
|
||||
const vector<mpq> & x0
|
||||
#endif
|
||||
) {
|
||||
init_matrix_A();
|
||||
svector<unsigned> basis_rows;
|
||||
mpq d = hnf_calc::determinant_of_rectangular_matrix(m_A, basis_rows);
|
||||
if (m_settings.get_cancel_flag())
|
||||
return lia_move::undef;
|
||||
if (basis_rows.size() < m_A.row_count())
|
||||
m_A.shrink_to_rank(basis_rows);
|
||||
|
||||
|
@ -156,10 +179,10 @@ public:
|
|||
// general_matrix A_orig = m_A;
|
||||
|
||||
vector<mpq> b = create_b(basis_rows);
|
||||
vector<mpq> bcopy = b;
|
||||
lp_assert(m_A * x0 == b);
|
||||
// vector<mpq> bcopy = b;
|
||||
find_h_minus_1_b(h.W(), b);
|
||||
|
||||
lp_assert(bcopy == h.W().take_first_n_columns(b.size()) * b);
|
||||
// lp_assert(bcopy == h.W().take_first_n_columns(b.size()) * b);
|
||||
int cut_row = find_cut_row_index(b);
|
||||
if (cut_row == -1) {
|
||||
return lia_move::undef;
|
||||
|
@ -181,7 +204,6 @@ public:
|
|||
vector<mpq> row(m_A.column_count());
|
||||
get_ei_H_minus_1(cut_row, h.W(), row);
|
||||
vector<mpq> f = row * m_A;
|
||||
|
||||
fill_term(f, t);
|
||||
k = floor(b[cut_row]);
|
||||
upper = true;
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
|
||||
#include "util/lp/int_solver.h"
|
||||
#include "util/lp/lar_solver.h"
|
||||
#include "util/lp/chase_cut_solver.h"
|
||||
#include "util/lp/lp_utils.h"
|
||||
#include <utility>
|
||||
#include "util/lp/monomial.h"
|
||||
namespace lp {
|
||||
|
||||
|
||||
|
@ -32,22 +32,15 @@ void int_solver::trace_inf_rows() const {
|
|||
);
|
||||
}
|
||||
|
||||
bool int_solver::all_columns_are_bounded() const {
|
||||
for (unsigned j = 0; j < m_lar_solver->column_count(); j++)
|
||||
if (m_lar_solver->column_is_bounded(j) == false)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool int_solver::has_inf_int() const {
|
||||
return m_lar_solver->has_inf_int();
|
||||
}
|
||||
|
||||
int int_solver::find_inf_int_base_column() {
|
||||
unsigned inf_int_count;
|
||||
unsigned inf_int_count = 0;
|
||||
int j = find_inf_int_boxed_base_column_with_smallest_range(inf_int_count);
|
||||
if (j != -1)
|
||||
return j;
|
||||
if (j != -1)
|
||||
return j;
|
||||
if (inf_int_count == 0)
|
||||
return -1;
|
||||
unsigned k = random() % inf_int_count;
|
||||
|
@ -55,22 +48,17 @@ int int_solver::find_inf_int_base_column() {
|
|||
}
|
||||
|
||||
int int_solver::get_kth_inf_int(unsigned k) const {
|
||||
unsigned inf_int_count = 0;
|
||||
for (unsigned j : m_lar_solver->r_basis()) {
|
||||
if (! column_is_int_inf(j) )
|
||||
continue;
|
||||
if (inf_int_count++ == k)
|
||||
for (unsigned j : m_lar_solver->r_basis())
|
||||
if (column_is_int_inf(j) && k-- == 0)
|
||||
return j;
|
||||
}
|
||||
lp_assert(false);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int int_solver::find_inf_int_nbasis_column() const {
|
||||
for (unsigned j : m_lar_solver->r_nbasis())
|
||||
if (! column_is_int_inf(j) )
|
||||
return j;
|
||||
|
||||
if (!column_is_int_inf(j))
|
||||
return j;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -80,7 +68,7 @@ int int_solver::find_inf_int_boxed_base_column_with_smallest_range(unsigned & in
|
|||
mpq range;
|
||||
mpq new_range;
|
||||
mpq small_range_thresold(1024);
|
||||
unsigned n;
|
||||
unsigned n = 0;
|
||||
lar_core_solver & lcs = m_lar_solver->m_mpq_lar_core_solver;
|
||||
|
||||
for (unsigned j : m_lar_solver->r_basis()) {
|
||||
|
@ -93,24 +81,14 @@ int int_solver::find_inf_int_boxed_base_column_with_smallest_range(unsigned & in
|
|||
new_range = lcs.m_r_upper_bounds()[j].x - lcs.m_r_lower_bounds()[j].x;
|
||||
if (new_range > small_range_thresold)
|
||||
continue;
|
||||
if (result == -1) {
|
||||
if (result == -1 || new_range < range) {
|
||||
result = j;
|
||||
range = new_range;
|
||||
n = 1;
|
||||
continue;
|
||||
}
|
||||
if (new_range < range) {
|
||||
n = 1;
|
||||
else if (new_range == range && settings().random_next() % (++n) == 0) {
|
||||
lp_assert(n > 1);
|
||||
result = j;
|
||||
range = new_range;
|
||||
continue;
|
||||
}
|
||||
if (new_range == range) {
|
||||
lp_assert(n >= 1);
|
||||
if (settings().random_next() % (++n) == 0) {
|
||||
result = j;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -272,18 +250,10 @@ void int_solver::gomory_cut_adjust_t_and_k(vector<std::pair<mpq, unsigned>> & po
|
|||
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>();
|
||||
TRACE("current_solution_is_inf_on_cut",
|
||||
if (is_pos(sign)) {
|
||||
tout << "v = " << v << " k = " << (*m_k) << std::endl;
|
||||
if (v <=(*m_k)) {
|
||||
tout << "v <= k - it should not happen!\n";
|
||||
}
|
||||
} else {
|
||||
if (v >= (*m_k)) {
|
||||
tout << "v > k - it should not happen!\n";
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -362,8 +332,7 @@ lia_move int_solver::mk_gomory_cut( unsigned inf_col, const row_strip<mpq> & row
|
|||
a.neg();
|
||||
if (is_real(x_j))
|
||||
real_case_in_gomory_cut(a, x_j, f_0, one_min_f_0);
|
||||
else {
|
||||
if (a.is_int()) continue; // f_j will be zero and no monomial will be added
|
||||
else if (!a.is_int()) { // f_j will be zero and no monomial will be added
|
||||
some_int_columns = true;
|
||||
int_case_in_gomory_cut(a, x_j, lcm_den, f_0, one_min_f_0);
|
||||
}
|
||||
|
@ -392,14 +361,14 @@ int int_solver::find_free_var_in_gomory_row(const row_strip<mpq>& row) {
|
|||
|
||||
lia_move int_solver::proceed_with_gomory_cut(unsigned j) {
|
||||
const row_strip<mpq>& row = m_lar_solver->get_row(row_of_basic_column(j));
|
||||
int free_j = find_free_var_in_gomory_row(row);
|
||||
if (free_j != -1)
|
||||
return lia_move::undef;
|
||||
if (!is_gomory_cut_target(row)) {
|
||||
return lia_move::undef;
|
||||
}
|
||||
|
||||
*m_upper = false;
|
||||
if (-1 != find_free_var_in_gomory_row(row))
|
||||
return lia_move::undef;
|
||||
|
||||
if (!is_gomory_cut_target(row))
|
||||
return lia_move::undef;
|
||||
|
||||
*m_upper = true;
|
||||
return mk_gomory_cut(j, row);
|
||||
}
|
||||
|
||||
|
@ -420,29 +389,7 @@ unsigned int_solver::row_of_basic_column(unsigned j) const {
|
|||
// }
|
||||
|
||||
|
||||
typedef chase_cut_solver::monomial mono;
|
||||
|
||||
// it produces an inequality coeff*x <= rs
|
||||
template <typename T>
|
||||
void int_solver::get_int_coeffs_from_constraint(const lar_base_constraint* c,
|
||||
vector<mono>& coeffs, T & rs) {
|
||||
lp_assert(c->m_kind != EQ); // it is not implemented, we need to create two inequalities in this case
|
||||
int sign = ((int)c->m_kind > 0) ? -1 : 1;
|
||||
vector<std::pair<T, var_index>> lhs = c->get_left_side_coefficients();
|
||||
T den = denominator(c->m_right_side);
|
||||
for (auto & kv : lhs) {
|
||||
lp_assert(!is_term(kv.second));
|
||||
lp_assert(is_int(kv.second)); // not implemented for real vars!
|
||||
den = lcm(den, denominator(kv.first));
|
||||
}
|
||||
lp_assert(den > 0);
|
||||
for (auto& kv : lhs) {
|
||||
coeffs.push_back(mono(den * kv.first * sign, kv.second));
|
||||
}
|
||||
rs = den * c->m_right_side * sign;
|
||||
if (kind_is_strict(c->m_kind))
|
||||
rs--;
|
||||
}
|
||||
typedef monomial mono;
|
||||
|
||||
|
||||
// this will allow to enable and disable tracking of the pivot rows
|
||||
|
@ -462,36 +409,6 @@ struct pivoted_rows_tracking_control {
|
|||
}
|
||||
};
|
||||
|
||||
void int_solver::copy_explanations_from_chase_cut_solver() {
|
||||
TRACE("propagate_and_backjump_step_int",
|
||||
for (unsigned j: m_chase_cut_solver.m_explanation)
|
||||
m_lar_solver->print_constraint(m_lar_solver->constraints()[j], tout););
|
||||
|
||||
for (unsigned j : m_chase_cut_solver.m_explanation) {
|
||||
m_ex->push_justification(j);
|
||||
}
|
||||
m_chase_cut_solver.m_explanation.clear();
|
||||
}
|
||||
|
||||
void int_solver::copy_values_from_chase_cut_solver() {
|
||||
for (unsigned j = 0; j < m_lar_solver->A_r().column_count() && j < m_chase_cut_solver.number_of_vars(); j++) {
|
||||
if (!m_chase_cut_solver.var_is_active(j))
|
||||
continue;
|
||||
if (!is_int(j)) {
|
||||
continue;
|
||||
}
|
||||
m_lar_solver->m_mpq_lar_core_solver.m_r_x[j] = m_chase_cut_solver.var_value(j);
|
||||
lp_assert(m_lar_solver->column_value_is_int(j));
|
||||
}
|
||||
}
|
||||
|
||||
void int_solver::catch_up_in_adding_constraints_to_chase_cut_solver() {
|
||||
lp_assert(m_chase_cut_solver.number_of_asserts() <= m_lar_solver->constraints().size());
|
||||
for (unsigned j = m_chase_cut_solver.number_of_asserts(); j < m_lar_solver->constraints().size(); j++) {
|
||||
add_constraint_to_chase_cut_solver(j, m_lar_solver->constraints()[j]);
|
||||
}
|
||||
}
|
||||
|
||||
impq int_solver::get_cube_delta_for_term(const lar_term& t) const {
|
||||
if (t.size() == 2) {
|
||||
bool seen_minus = false;
|
||||
|
@ -541,9 +458,9 @@ bool int_solver::tighten_terms_for_cube() {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool int_solver::find_cube() {
|
||||
lia_move int_solver::find_cube() {
|
||||
if (m_branch_cut_counter % settings().m_int_find_cube_period != 0)
|
||||
return false;
|
||||
return lia_move::undef;
|
||||
|
||||
settings().st().m_cube_calls++;
|
||||
TRACE("cube",
|
||||
|
@ -551,26 +468,25 @@ bool int_solver::find_cube() {
|
|||
display_column(tout, j);
|
||||
m_lar_solver->print_terms(tout);
|
||||
);
|
||||
m_lar_solver->push();
|
||||
if(!tighten_terms_for_cube()) {
|
||||
m_lar_solver->pop();
|
||||
return false;
|
||||
|
||||
lar_solver::scoped_push _sp(*m_lar_solver);
|
||||
if (!tighten_terms_for_cube()) {
|
||||
return lia_move::undef;
|
||||
}
|
||||
|
||||
lp_status st = m_lar_solver->find_feasible_solution();
|
||||
if (st != lp_status::FEASIBLE && st != lp_status::OPTIMAL) {
|
||||
TRACE("cube", tout << "cannot find a feasiblie solution";);
|
||||
m_lar_solver->pop();
|
||||
_sp.pop();
|
||||
move_non_basic_columns_to_bounds();
|
||||
find_feasible_solution();
|
||||
lp_assert(m_chase_cut_solver.cancel() || is_feasible());
|
||||
// it can happen that we found an integer solution here
|
||||
return !m_lar_solver->r_basis_has_inf_int();
|
||||
return !m_lar_solver->r_basis_has_inf_int()? lia_move::sat: lia_move::undef;
|
||||
}
|
||||
m_lar_solver->pop();
|
||||
_sp.pop();
|
||||
m_lar_solver->round_to_integer_solution();
|
||||
lp_assert(m_chase_cut_solver.cancel() || is_feasible());
|
||||
return true;
|
||||
settings().st().m_cube_success++;
|
||||
return lia_move::sat;
|
||||
}
|
||||
|
||||
void int_solver::find_feasible_solution() {
|
||||
|
@ -589,55 +505,26 @@ lia_move int_solver::run_gcd_test() {
|
|||
return lia_move::undef;
|
||||
}
|
||||
|
||||
lia_move int_solver::call_chase_cut_solver() {
|
||||
if ((m_branch_cut_counter) % settings().m_int_chase_cut_solver_period != 0 || !all_columns_are_bounded())
|
||||
return lia_move::undef;
|
||||
TRACE("check_main_int", tout<<"chase_cut_solver";);
|
||||
catch_up_in_adding_constraints_to_chase_cut_solver();
|
||||
auto check_res = m_chase_cut_solver.check();
|
||||
settings().st().m_chase_cut_solver_calls++;
|
||||
switch (check_res) {
|
||||
case chase_cut_solver::lbool::l_false:
|
||||
copy_explanations_from_chase_cut_solver();
|
||||
settings().st().m_chase_cut_solver_false++;
|
||||
return lia_move::conflict;
|
||||
case chase_cut_solver::lbool::l_true:
|
||||
settings().st().m_chase_cut_solver_true++;
|
||||
copy_values_from_chase_cut_solver();
|
||||
lp_assert(m_lar_solver->all_constraints_hold());
|
||||
return lia_move::sat;
|
||||
case chase_cut_solver::lbool::l_undef:
|
||||
settings().st().m_chase_cut_solver_undef++;
|
||||
if (m_chase_cut_solver.try_getting_cut(*m_t, *m_k, m_lar_solver->m_mpq_lar_core_solver.m_r_x)) {
|
||||
m_lar_solver->subs_term_columns(*m_t);
|
||||
TRACE("chase_cut_solver_cuts",
|
||||
tout<<"precut from chase_cut_solver:"; m_lar_solver->print_term(*m_t, tout); tout << " <= " << *m_k << std::endl;);
|
||||
|
||||
return lia_move::cut;
|
||||
}
|
||||
default:
|
||||
return lia_move::undef;
|
||||
}
|
||||
}
|
||||
|
||||
lia_move int_solver::gomory_cut() {
|
||||
TRACE("check_main_int", tout << "gomory";);
|
||||
if ((m_branch_cut_counter) % settings().m_int_gomory_cut_period != 0)
|
||||
return lia_move::undef;
|
||||
|
||||
if (move_non_basic_columns_to_bounds()) {
|
||||
lp_status st = m_lar_solver->find_feasible_solution();
|
||||
if (st != lp_status::FEASIBLE && st != lp_status::OPTIMAL) {
|
||||
TRACE("arith_int", tout << "give_up\n";);
|
||||
return lia_move::undef;
|
||||
}
|
||||
#if Z3DEBUG
|
||||
lp_status st =
|
||||
#endif
|
||||
m_lar_solver->find_feasible_solution();
|
||||
#if Z3DEBUG
|
||||
lp_assert(st == lp_status::FEASIBLE || st == lp_status::OPTIMAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
int j = find_inf_int_base_column();
|
||||
if (j == -1) {
|
||||
j = find_inf_int_nbasis_column();
|
||||
return j == -1? lia_move::sat : create_branch_on_column(j);
|
||||
}
|
||||
lia_move r = proceed_with_gomory_cut(j);
|
||||
if (r != lia_move::undef)
|
||||
return r;
|
||||
return create_branch_on_column(j);
|
||||
return proceed_with_gomory_cut(j);
|
||||
}
|
||||
|
||||
|
||||
|
@ -645,39 +532,49 @@ bool int_solver::try_add_term_to_A_for_hnf(unsigned i) {
|
|||
mpq rs;
|
||||
const lar_term* t = m_lar_solver->terms()[i];
|
||||
for (const auto & p : *t) {
|
||||
if (!is_int(p.var()))
|
||||
if (!is_int(p.var())) {
|
||||
lp_assert(false);
|
||||
return false; // todo : the mix case!
|
||||
}
|
||||
}
|
||||
if (m_lar_solver->get_equality_for_term_on_corrent_x(i, rs)) {
|
||||
bool has_bounds;
|
||||
if (m_lar_solver->get_equality_and_right_side_for_term_on_corrent_x(i, rs, has_bounds)) {
|
||||
m_hnf_cutter.add_term(t, rs);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return !has_bounds;
|
||||
}
|
||||
|
||||
bool int_solver::hnf_matrix_is_empty() const { return true; }
|
||||
|
||||
bool int_solver::prepare_matrix_A_for_hnf_cut() {
|
||||
bool int_solver::init_terms_for_hnf_cut() {
|
||||
m_hnf_cutter.clear();
|
||||
for (unsigned i = 0; i < m_lar_solver->terms().size(); i++) {
|
||||
bool r = try_add_term_to_A_for_hnf(i);
|
||||
if (!r && settings().hnf_cutter_exit_if_x_is_not_on_bound_or_mixed )
|
||||
return false;
|
||||
try_add_term_to_A_for_hnf(i);
|
||||
}
|
||||
return true;
|
||||
return m_hnf_cutter.row_count() < settings().limit_on_rows_for_hnf_cutter;
|
||||
}
|
||||
|
||||
|
||||
lia_move int_solver::make_hnf_cut() {
|
||||
if (!prepare_matrix_A_for_hnf_cut()) {
|
||||
if (!init_terms_for_hnf_cut()) {
|
||||
return lia_move::undef;
|
||||
}
|
||||
settings().st().m_hnf_cutter_calls++;
|
||||
lia_move r = m_hnf_cutter.create_cut(*m_t, *m_k, *m_ex, *m_upper);
|
||||
TRACE("hnf_cut", tout << "settings().st().m_hnf_cutter_calls = " << settings().st().m_hnf_cutter_calls;);
|
||||
#ifdef Z3DEBUG
|
||||
vector<mpq> x0 = m_hnf_cutter.transform_to_local_columns(m_lar_solver->m_mpq_lar_core_solver.m_r_x);
|
||||
#endif
|
||||
lia_move r = m_hnf_cutter.create_cut(*m_t, *m_k, *m_ex, *m_upper
|
||||
#ifdef Z3DEBUG
|
||||
, x0
|
||||
#endif
|
||||
);
|
||||
CTRACE("hnf_cut", r == lia_move::cut, tout<< "cut:"; m_lar_solver->print_term(*m_t, tout); tout << " <= " << *m_k << std::endl;);
|
||||
if (r == lia_move::cut)
|
||||
if (r == lia_move::cut) {
|
||||
lp_assert(current_solution_is_inf_on_cut());
|
||||
settings().st().m_hnf_cuts++;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -689,43 +586,42 @@ lia_move int_solver::hnf_cut() {
|
|||
}
|
||||
|
||||
lia_move int_solver::check(lar_term& t, mpq& k, explanation& ex, bool & upper) {
|
||||
if (!has_inf_int())
|
||||
return lia_move::sat;
|
||||
if (!has_inf_int()) return lia_move::sat;
|
||||
|
||||
m_t = &t; m_k = &k; m_ex = &ex; m_upper = &upper;
|
||||
if (run_gcd_test() == lia_move::conflict)
|
||||
return lia_move::conflict;
|
||||
|
||||
lia_move r = run_gcd_test();
|
||||
if (r != lia_move::undef) return r;
|
||||
|
||||
pivoted_rows_tracking_control pc(m_lar_solver);
|
||||
|
||||
if(settings().m_int_pivot_fixed_vars_from_basis)
|
||||
m_lar_solver->pivot_fixed_vars_from_basis();
|
||||
|
||||
if (patch_nbasic_columns() == lia_move::sat)
|
||||
return lia_move::sat;
|
||||
r = patch_nbasic_columns();
|
||||
if (r != lia_move::undef) return r;
|
||||
|
||||
++m_branch_cut_counter;
|
||||
if (find_cube()){
|
||||
settings().st().m_cube_success++;
|
||||
return lia_move::sat;
|
||||
}
|
||||
|
||||
lia_move r = call_chase_cut_solver();
|
||||
if (r != lia_move::undef)
|
||||
return r;
|
||||
|
||||
r = hnf_cut();
|
||||
if (r != lia_move::undef)
|
||||
return r;
|
||||
r = find_cube();
|
||||
if (r != lia_move::undef) return r;
|
||||
|
||||
if ((m_branch_cut_counter) % settings().m_int_gomory_cut_period == 0) {
|
||||
return gomory_cut();
|
||||
}
|
||||
int j = find_inf_int_base_column();
|
||||
if (j == -1) {
|
||||
j = find_inf_int_nbasis_column();
|
||||
if (j == -1)
|
||||
return lia_move::sat;
|
||||
}
|
||||
return create_branch_on_column(j);
|
||||
r = hnf_cut();
|
||||
if (r != lia_move::undef) return r;
|
||||
|
||||
r = gomory_cut();
|
||||
return (r == lia_move::undef)? branch_or_sat() : r;
|
||||
}
|
||||
|
||||
lia_move int_solver::branch_or_sat() {
|
||||
int j = find_any_inf_int_column_basis_first();
|
||||
return j == -1? lia_move::sat : create_branch_on_column(j);
|
||||
}
|
||||
|
||||
int int_solver::find_any_inf_int_column_basis_first() {
|
||||
int j = find_inf_int_base_column();
|
||||
if (j != -1)
|
||||
return j;
|
||||
return find_inf_int_nbasis_column();
|
||||
}
|
||||
|
||||
bool int_solver::move_non_basic_column_to_bounds(unsigned j) {
|
||||
|
@ -751,7 +647,7 @@ bool int_solver::move_non_basic_column_to_bounds(unsigned j) {
|
|||
if (val != lcs.m_r_upper_bounds()[j]) {
|
||||
set_value_for_nbasic_column(j, lcs.m_r_upper_bounds()[j]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (is_int(j) && !val.is_int()) {
|
||||
|
@ -845,6 +741,7 @@ void int_solver::patch_nbasic_column(unsigned j) {
|
|||
tout << "patching with 0\n";);
|
||||
}
|
||||
}
|
||||
|
||||
lia_move int_solver::patch_nbasic_columns() {
|
||||
settings().st().m_patches++;
|
||||
lp_assert(is_feasible());
|
||||
|
@ -931,6 +828,7 @@ bool int_solver::gcd_test_for_row(static_matrix<mpq, numeric_pair<mpq>> & A, uns
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
@ -948,10 +846,8 @@ void int_solver::fill_explanation_from_fixed_columns(const row_strip<mpq> & row)
|
|||
bool int_solver::gcd_test() {
|
||||
auto & A = m_lar_solver->A_r(); // getting the matrix
|
||||
for (unsigned i = 0; i < A.row_count(); i++)
|
||||
if (!gcd_test_for_row(A, i)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!gcd_test_for_row(A, i))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1022,19 +918,15 @@ linear_combination_iterator<mpq> * int_solver::get_column_iterator(unsigned j) {
|
|||
}
|
||||
*/
|
||||
|
||||
|
||||
int_solver::int_solver(lar_solver* lar_slv) :
|
||||
m_lar_solver(lar_slv),
|
||||
m_branch_cut_counter(0),
|
||||
m_chase_cut_solver([this](unsigned j) {return m_lar_solver->get_column_name(j);},
|
||||
[this](unsigned j, std::ostream &o) {m_lar_solver->print_constraint(j, o);},
|
||||
[this]() {return m_lar_solver->A_r().column_count();},
|
||||
[this](unsigned j) {return get_value(j);},
|
||||
settings()),
|
||||
m_hnf_cutter([this](){ return settings().random_next(); })
|
||||
{
|
||||
m_hnf_cutter(settings()) {
|
||||
m_lar_solver->set_int_solver(this);
|
||||
}
|
||||
|
||||
|
||||
bool int_solver::has_low(unsigned j) const {
|
||||
switch (m_lar_solver->m_mpq_lar_core_solver.m_column_types()[j]) {
|
||||
case column_type::fixed:
|
||||
|
@ -1067,6 +959,7 @@ void set_lower(impq & l,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void set_upper(impq & u,
|
||||
bool & inf_u,
|
||||
impq const & v) {
|
||||
|
@ -1386,22 +1279,6 @@ bool int_solver::is_term(unsigned j) const {
|
|||
return m_lar_solver->column_corresponds_to_term(j);
|
||||
}
|
||||
|
||||
void int_solver::add_constraint_to_chase_cut_solver(unsigned ci, const lar_base_constraint * c) {
|
||||
vector<mono> coeffs;
|
||||
mpq rs;
|
||||
get_int_coeffs_from_constraint<mpq>(c, coeffs, rs);
|
||||
m_chase_cut_solver.add_ineq(coeffs, -rs, ci);
|
||||
}
|
||||
|
||||
void int_solver::pop(unsigned k) {
|
||||
m_chase_cut_solver.pop_trail(k);
|
||||
while (m_chase_cut_solver.number_of_asserts() > m_lar_solver->constraints().size())
|
||||
m_chase_cut_solver.pop_last_assert();
|
||||
m_chase_cut_solver.pop_constraints();
|
||||
}
|
||||
|
||||
void int_solver::push() { m_chase_cut_solver.push(); }
|
||||
|
||||
unsigned int_solver::column_count() const { return m_lar_solver->column_count(); }
|
||||
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ Revision History:
|
|||
#include "util/lp/static_matrix.h"
|
||||
#include "util/lp/int_set.h"
|
||||
#include "util/lp/lar_term.h"
|
||||
#include "util/lp/chase_cut_solver.h"
|
||||
#include "util/lp/lar_constraints.h"
|
||||
#include "util/lp/hnf_cutter.h"
|
||||
#include "util/lp/lia_move.h"
|
||||
|
@ -38,10 +37,9 @@ struct lp_constraint;
|
|||
class int_solver {
|
||||
public:
|
||||
// fields
|
||||
lar_solver * m_lar_solver;
|
||||
lar_solver *m_lar_solver;
|
||||
unsigned m_branch_cut_counter;
|
||||
chase_cut_solver m_chase_cut_solver;
|
||||
lar_term* m_t; // the term to return in the cut
|
||||
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
|
||||
|
@ -96,6 +94,8 @@ private:
|
|||
const impq & get_value(unsigned j) const;
|
||||
bool column_is_int_inf(unsigned j) const;
|
||||
void trace_inf_rows() const;
|
||||
lia_move branch_or_sat();
|
||||
int find_any_inf_int_column_basis_first();
|
||||
int find_inf_int_base_column();
|
||||
int find_inf_int_boxed_base_column_with_smallest_range(unsigned&);
|
||||
int get_kth_inf_int(unsigned) const;
|
||||
|
@ -139,20 +139,10 @@ private:
|
|||
unsigned random();
|
||||
bool has_inf_int() const;
|
||||
lia_move create_branch_on_column(int j);
|
||||
void catch_up_in_adding_constraints_to_chase_cut_solver();
|
||||
public:
|
||||
template <typename T>
|
||||
void fill_chase_cut_solver_vars();
|
||||
template <typename T>
|
||||
void get_int_coeffs_from_constraint(const lar_base_constraint* c, vector<chase_cut_solver::monomial>& coeff, T & rs);
|
||||
bool is_term(unsigned j) const;
|
||||
void add_constraint_to_chase_cut_solver(unsigned,const lar_base_constraint*);
|
||||
void copy_explanations_from_chase_cut_solver();
|
||||
void pop(unsigned);
|
||||
void push();
|
||||
void copy_values_from_chase_cut_solver();
|
||||
bool left_branch_is_more_narrow_than_right(unsigned);
|
||||
bool find_cube();
|
||||
lia_move find_cube();
|
||||
bool tighten_terms_for_cube();
|
||||
bool tighten_term_for_cube(unsigned);
|
||||
unsigned column_count() const;
|
||||
|
@ -161,11 +151,10 @@ public:
|
|||
void find_feasible_solution();
|
||||
int find_inf_int_nbasis_column() const;
|
||||
lia_move run_gcd_test();
|
||||
lia_move call_chase_cut_solver();
|
||||
lia_move gomory_cut();
|
||||
lia_move hnf_cut();
|
||||
lia_move make_hnf_cut();
|
||||
bool prepare_matrix_A_for_hnf_cut();
|
||||
bool init_terms_for_hnf_cut();
|
||||
bool hnf_matrix_is_empty() const;
|
||||
bool try_add_term_to_A_for_hnf(unsigned term_index);
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -331,7 +331,6 @@ void lar_solver::push() {
|
|||
m_term_count.push();
|
||||
m_constraint_count = m_constraints.size();
|
||||
m_constraint_count.push();
|
||||
m_int_solver->push();
|
||||
}
|
||||
|
||||
void lar_solver::clean_popped_elements(unsigned n, int_set& set) {
|
||||
|
@ -396,7 +395,6 @@ void lar_solver::pop(unsigned k) {
|
|||
lp_assert(sizes_are_correct());
|
||||
lp_assert((!m_settings.use_tableau()) || m_mpq_lar_core_solver.m_r_solver.reduced_costs_are_correct_tableau());
|
||||
m_status = m_mpq_lar_core_solver.m_r_solver.current_x_is_feasible()? lp_status::OPTIMAL: lp_status::UNKNOWN;
|
||||
m_int_solver->pop(k);
|
||||
}
|
||||
|
||||
vector<constraint_index> lar_solver::get_all_constraint_indices() const {
|
||||
|
@ -1476,17 +1474,9 @@ bool lar_solver::strategy_is_undecided() const {
|
|||
return m_settings.simplex_strategy() == simplex_strategy_enum::undecided;
|
||||
}
|
||||
|
||||
void lar_solver::catch_up_in_updating_int_solver() {
|
||||
for (unsigned i = 0; i < constraints().size(); i++) {
|
||||
m_int_solver->add_constraint_to_chase_cut_solver(i, constraints()[i]);
|
||||
}
|
||||
}
|
||||
|
||||
var_index lar_solver::add_var(unsigned ext_j, bool is_int) {
|
||||
if (is_int)
|
||||
m_has_int_var = true;
|
||||
if (is_int && !has_int_var())
|
||||
catch_up_in_updating_int_solver();
|
||||
|
||||
TRACE("add_var", tout << "adding var " << ext_j << (is_int? " int" : " nonint") << std::endl;);
|
||||
var_index i;
|
||||
|
@ -2217,9 +2207,10 @@ void lar_solver::round_to_integer_solution() {
|
|||
}
|
||||
}
|
||||
|
||||
bool lar_solver::get_equality_for_term_on_corrent_x(unsigned term_index, mpq & rs) const {
|
||||
bool lar_solver::get_equality_for_term_on_corrent_x(unsigned term_index, mpq & rs, bool & has_bounds) const {
|
||||
unsigned tj = term_index + m_terms_start_index;
|
||||
auto it = m_ext_vars_to_columns.find(tj);
|
||||
has_bounds = false;
|
||||
if (it == m_ext_vars_to_columns.end())
|
||||
return false;
|
||||
unsigned j = it->second.internal_j();
|
||||
|
@ -2227,6 +2218,7 @@ bool lar_solver::get_equality_for_term_on_corrent_x(unsigned term_index, mpq & r
|
|||
impq term_val;
|
||||
bool term_val_ready = false;
|
||||
if (slv.column_has_upper_bound(j)) {
|
||||
has_bounds = true;
|
||||
const impq & b = slv.m_upper_bounds[j];
|
||||
lp_assert(is_zero(b.y) && is_int(b.x));
|
||||
term_val = terms()[term_index]->apply(m_mpq_lar_core_solver.m_r_x);
|
||||
|
@ -2237,6 +2229,7 @@ bool lar_solver::get_equality_for_term_on_corrent_x(unsigned term_index, mpq & r
|
|||
}
|
||||
}
|
||||
if (slv.column_has_lower_bound(j)) {
|
||||
has_bounds = true;
|
||||
if (!term_val_ready)
|
||||
term_val = terms()[term_index]->apply(m_mpq_lar_core_solver.m_r_x);
|
||||
const impq & b = slv.m_lower_bounds[j];
|
||||
|
@ -2247,7 +2240,7 @@ bool lar_solver::get_equality_for_term_on_corrent_x(unsigned term_index, mpq & r
|
|||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -298,9 +298,17 @@ public:
|
|||
static void clean_popped_elements(unsigned n, int_set& set);
|
||||
|
||||
static void shrink_inf_set_after_pop(unsigned n, int_set & set);
|
||||
|
||||
|
||||
void pop(unsigned k);
|
||||
|
||||
class scoped_push {
|
||||
lar_solver& m_solver;
|
||||
bool m_pop;
|
||||
public:
|
||||
scoped_push(lar_solver& s):m_solver(s), m_pop(true) { s.push(); }
|
||||
~scoped_push() { if (m_pop) m_solver.pop(); }
|
||||
void pop() { SASSERT(m_pop); m_solver.pop(); m_pop = false; }
|
||||
};
|
||||
|
||||
vector<constraint_index> get_all_constraint_indices() const;
|
||||
|
||||
|
@ -579,6 +587,6 @@ public:
|
|||
unsigned column_count() const { return A_r().column_count(); }
|
||||
const vector<unsigned> & r_basis() const { return m_mpq_lar_core_solver.r_basis(); }
|
||||
const vector<unsigned> & r_nbasis() const { return m_mpq_lar_core_solver.r_nbasis(); }
|
||||
bool get_equality_for_term_on_corrent_x(unsigned i, mpq &rs) const;
|
||||
bool get_equality_and_right_side_for_term_on_corrent_x(unsigned i, mpq &rs, bool & has_bounds) const;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -133,54 +133,77 @@ private:
|
|||
};
|
||||
|
||||
default_lp_resource_limit m_default_resource_limit;
|
||||
lp_resource_limit* m_resource_limit;
|
||||
lp_resource_limit* m_resource_limit;
|
||||
// used for debug output
|
||||
std::ostream* m_debug_out;
|
||||
std::ostream* m_debug_out;
|
||||
// used for messages, for example, the computation progress messages
|
||||
std::ostream* m_message_out;
|
||||
std::ostream* m_message_out;
|
||||
|
||||
stats m_stats;
|
||||
random_gen m_rand;
|
||||
stats m_stats;
|
||||
random_gen m_rand;
|
||||
|
||||
public:
|
||||
unsigned reps_in_scaler;
|
||||
unsigned reps_in_scaler;
|
||||
// when the absolute value of an element is less than pivot_epsilon
|
||||
// in pivoting, we treat it as a zero
|
||||
double pivot_epsilon;
|
||||
double pivot_epsilon;
|
||||
// see Chatal, page 115
|
||||
double positive_price_epsilon;
|
||||
double positive_price_epsilon;
|
||||
// a quatation "if some choice of the entering vairable leads to an eta matrix
|
||||
// whose diagonal element in the eta column is less than e2 (entering_diag_epsilon) in magnitude, the this choice is rejected ...
|
||||
double entering_diag_epsilon;
|
||||
int c_partial_pivoting; // this is the constant c from page 410
|
||||
unsigned depth_of_rook_search;
|
||||
bool using_partial_pivoting;
|
||||
double entering_diag_epsilon;
|
||||
int c_partial_pivoting; // this is the constant c from page 410
|
||||
unsigned depth_of_rook_search;
|
||||
bool using_partial_pivoting;
|
||||
// dissertation of Achim Koberstein
|
||||
// if Bx - b is different at any component more that refactor_epsilon then we refactor
|
||||
double refactor_tolerance;
|
||||
double pivot_tolerance;
|
||||
double zero_tolerance;
|
||||
double drop_tolerance;
|
||||
double tolerance_for_artificials;
|
||||
double can_be_taken_to_basis_tolerance;
|
||||
double refactor_tolerance;
|
||||
double pivot_tolerance;
|
||||
double zero_tolerance;
|
||||
double drop_tolerance;
|
||||
double tolerance_for_artificials;
|
||||
double can_be_taken_to_basis_tolerance;
|
||||
|
||||
unsigned percent_of_entering_to_check; // we try to find a profitable column in a percentage of the columns
|
||||
bool use_scaling;
|
||||
double scaling_maximum;
|
||||
double scaling_minimum;
|
||||
double harris_feasibility_tolerance; // page 179 of Istvan Maros
|
||||
double ignore_epsilon_of_harris;
|
||||
unsigned max_number_of_iterations_with_no_improvements;
|
||||
unsigned max_total_number_of_iterations;
|
||||
double time_limit; // the maximum time limit of the total run time in seconds
|
||||
unsigned percent_of_entering_to_check; // we try to find a profitable column in a percentage of the columns
|
||||
bool use_scaling;
|
||||
double scaling_maximum;
|
||||
double scaling_minimum;
|
||||
double harris_feasibility_tolerance; // page 179 of Istvan Maros
|
||||
double ignore_epsilon_of_harris;
|
||||
unsigned max_number_of_iterations_with_no_improvements;
|
||||
unsigned max_total_number_of_iterations;
|
||||
double time_limit; // the maximum time limit of the total run time in seconds
|
||||
// dual section
|
||||
double dual_feasibility_tolerance; // // page 71 of the PhD thesis of Achim Koberstein
|
||||
double primal_feasibility_tolerance; // page 71 of the PhD thesis of Achim Koberstein
|
||||
double relative_primal_feasibility_tolerance; // page 71 of the PhD thesis of Achim Koberstein
|
||||
bool hnf_cutter_exit_if_x_is_not_on_bound_or_mixed = true;
|
||||
|
||||
bool m_bound_propagation;
|
||||
double dual_feasibility_tolerance; // // page 71 of the PhD thesis of Achim Koberstein
|
||||
double primal_feasibility_tolerance; // page 71 of the PhD thesis of Achim Koberstein
|
||||
double relative_primal_feasibility_tolerance; // page 71 of the PhD thesis of Achim Koberstein
|
||||
// end of dual section
|
||||
bool m_bound_propagation;
|
||||
bool presolve_with_double_solver_for_lar;
|
||||
simplex_strategy_enum m_simplex_strategy;
|
||||
|
||||
int report_frequency;
|
||||
bool print_statistics;
|
||||
unsigned column_norms_update_frequency;
|
||||
bool scale_with_ratio;
|
||||
double density_threshold;
|
||||
bool use_breakpoints_in_feasibility_search;
|
||||
unsigned max_row_length_for_bound_propagation;
|
||||
bool backup_costs;
|
||||
unsigned column_number_threshold_for_using_lu_in_lar_solver;
|
||||
unsigned m_int_gomory_cut_period;
|
||||
unsigned m_int_chase_cut_solver_period;
|
||||
unsigned m_int_find_cube_period;
|
||||
unsigned m_hnf_cut_period;
|
||||
bool m_int_run_gcd_test;
|
||||
unsigned m_chase_cut_solver_cycle_on_var;
|
||||
bool m_int_pivot_fixed_vars_from_basis;
|
||||
bool m_int_patch_only_integer_values;
|
||||
unsigned limit_on_rows_for_hnf_cutter;
|
||||
|
||||
unsigned random_next() { return m_rand(); }
|
||||
void set_random_seed(unsigned s) { m_rand.set_seed(s); }
|
||||
|
||||
bool bound_progation() const {
|
||||
return m_bound_propagation;
|
||||
}
|
||||
|
@ -237,12 +260,12 @@ public:
|
|||
m_int_gomory_cut_period(4),
|
||||
m_int_chase_cut_solver_period(8),
|
||||
m_int_find_cube_period(4),
|
||||
m_int_cuts_etc_period(4),
|
||||
m_hnf_cut_period(4),
|
||||
m_int_run_gcd_test(true),
|
||||
m_chase_cut_solver_cycle_on_var(10),
|
||||
m_int_pivot_fixed_vars_from_basis(false),
|
||||
m_int_patch_only_integer_values(true)
|
||||
m_int_patch_only_integer_values(true),
|
||||
limit_on_rows_for_hnf_cutter(100)
|
||||
{}
|
||||
|
||||
void set_resource_limit(lp_resource_limit& lim) { m_resource_limit = &lim; }
|
||||
|
@ -312,8 +335,6 @@ public:
|
|||
return is_eps_small_general<T>(t, tolerance_for_artificials);
|
||||
}
|
||||
// the method of lar solver to use
|
||||
bool presolve_with_double_solver_for_lar;
|
||||
simplex_strategy_enum m_simplex_strategy;
|
||||
simplex_strategy_enum simplex_strategy() const {
|
||||
return m_simplex_strategy;
|
||||
}
|
||||
|
@ -335,29 +356,9 @@ public:
|
|||
return m_simplex_strategy == simplex_strategy_enum::tableau_rows;
|
||||
}
|
||||
|
||||
int report_frequency;
|
||||
bool print_statistics;
|
||||
unsigned column_norms_update_frequency;
|
||||
bool scale_with_ratio;
|
||||
double density_threshold; // need to tune it up, todo
|
||||
#ifdef Z3DEBUG
|
||||
static unsigned ddd; // used for debugging
|
||||
#endif
|
||||
bool use_breakpoints_in_feasibility_search;
|
||||
unsigned random_next() { return m_rand(); }
|
||||
void set_random_seed(unsigned s) { m_rand.set_seed(s); }
|
||||
unsigned max_row_length_for_bound_propagation;
|
||||
bool backup_costs;
|
||||
unsigned column_number_threshold_for_using_lu_in_lar_solver;
|
||||
unsigned m_int_gomory_cut_period;
|
||||
unsigned m_int_chase_cut_solver_period;
|
||||
unsigned m_int_find_cube_period;
|
||||
unsigned m_int_cuts_etc_period;
|
||||
unsigned m_hnf_cut_period;
|
||||
bool m_int_run_gcd_test;
|
||||
unsigned m_chase_cut_solver_cycle_on_var;
|
||||
bool m_int_pivot_fixed_vars_from_basis;
|
||||
bool m_int_patch_only_integer_values;
|
||||
}; // end of lp_settings class
|
||||
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ Revision History:
|
|||
#include <unordered_set>
|
||||
#include <set>
|
||||
#include <stack>
|
||||
#include <map>
|
||||
namespace lp {
|
||||
template<class A,
|
||||
class B,
|
||||
|
|
Loading…
Reference in a new issue