mirror of
https://github.com/Z3Prover/z3
synced 2025-07-19 10:52:02 +00:00
Arith min max (#6864)
* prepare for dependencies Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * snapshot Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * more refactoring Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * more refactoring Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * build Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * pass in u_dependency_manager Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * address NYIs Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * more refactoring names Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * eq_explanation update Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * add outline of bounds improvement functionality Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * fix unit tests Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * remove unused structs Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * more bounds Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * more bounds Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * convert more internals to use u_dependency instead of constraint_index Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * convert more internals to use u_dependency instead of constraint_index Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * remember to push/pop scopes Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * use the main function for updating bounds Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * remove reset of shared dep manager Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * disable improve-bounds, add statistics Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> --------- Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
c3b344ec47
commit
5e3df9ee77
40 changed files with 630 additions and 529 deletions
|
@ -23,7 +23,7 @@ typedef lp::lar_term term;
|
|||
|
||||
core::core(lp::lar_solver& s, params_ref const& p, reslimit & lim) :
|
||||
m_evars(),
|
||||
m_lar_solver(s),
|
||||
lra(s),
|
||||
m_reslim(lim),
|
||||
m_params(p),
|
||||
m_tangents(this),
|
||||
|
@ -69,7 +69,7 @@ lp::lar_term core::subs_terms_to_columns(const lp::lar_term& t) const {
|
|||
for (lp::lar_term::ival p : t) {
|
||||
lpvar j = p.column();
|
||||
if (lp::tv::is_term(j))
|
||||
j = m_lar_solver.map_term_index_to_column_index(j);
|
||||
j = lra.map_term_index_to_column_index(j);
|
||||
r.add_monomial(p.coeff(), j);
|
||||
}
|
||||
return r;
|
||||
|
@ -133,7 +133,7 @@ void core::add_monic(lpvar v, unsigned sz, lpvar const* vs) {
|
|||
for (unsigned i = 0; i < sz; i++) {
|
||||
lpvar j = vs[i];
|
||||
if (lp::tv::is_term(j))
|
||||
j = m_lar_solver.map_term_index_to_column_index(j);
|
||||
j = lra.map_term_index_to_column_index(j);
|
||||
m_add_buffer[i] = j;
|
||||
}
|
||||
m_emons.add(v, m_add_buffer);
|
||||
|
@ -154,7 +154,7 @@ void core::pop(unsigned n) {
|
|||
rational core::product_value(const monic& m) const {
|
||||
rational r(1);
|
||||
for (auto j : m.vars()) {
|
||||
r *= m_lar_solver.get_column_value(j).x;
|
||||
r *= lra.get_column_value(j).x;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
@ -167,10 +167,10 @@ bool core::check_monic(const monic& m) const {
|
|||
if (!is_relevant(m.var()))
|
||||
return true;
|
||||
#endif
|
||||
if (m_lar_solver.column_is_int(m.var()) && !m_lar_solver.get_column_value(m.var()).is_int())
|
||||
if (lra.column_is_int(m.var()) && !lra.get_column_value(m.var()).is_int())
|
||||
return true;
|
||||
|
||||
bool ret = product_value(m) == m_lar_solver.get_column_value(m.var()).x;
|
||||
bool ret = product_value(m) == lra.get_column_value(m.var()).x;
|
||||
CTRACE("nla_solver_check_monic", !ret, print_monic(m, tout) << '\n';);
|
||||
return ret;
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ std::ostream& core::print_product(const T & m, std::ostream& out) const {
|
|||
for (lpvar v : m) {
|
||||
if (!first) out << "*"; else first = false;
|
||||
if (lp_settings().print_external_var_name())
|
||||
out << "(" << m_lar_solver.get_variable_name(v) << "=" << val(v) << ")";
|
||||
out << "(" << lra.get_variable_name(v) << "=" << val(v) << ")";
|
||||
else
|
||||
out << "(j" << v << " = " << val(v) << ")";
|
||||
|
||||
|
@ -228,7 +228,7 @@ std::ostream & core::print_factor_with_vars(const factor& f, std::ostream& out)
|
|||
|
||||
std::ostream& core::print_monic(const monic& m, std::ostream& out) const {
|
||||
if (lp_settings().print_external_var_name())
|
||||
out << "([" << m.var() << "] = " << m_lar_solver.get_variable_name(m.var()) << " = " << val(m.var()) << " = ";
|
||||
out << "([" << m.var() << "] = " << lra.get_variable_name(m.var()) << " = " << val(m.var()) << " = ";
|
||||
else
|
||||
out << "(j" << m.var() << " = " << val(m.var()) << " = ";
|
||||
print_product(m.vars(), out) << ")\n";
|
||||
|
@ -271,7 +271,7 @@ std::ostream& core::print_explanation(const lp::explanation& exp, std::ostream&
|
|||
unsigned i = 0;
|
||||
for (auto p : exp) {
|
||||
out << "(" << p.ci() << ")";
|
||||
m_lar_solver.constraints().display(out, [this](lpvar j) { return var_str(j);}, p.ci());
|
||||
lra.constraints().display(out, [this](lpvar j) { return var_str(j);}, p.ci());
|
||||
if (++i < exp.size())
|
||||
out << " ";
|
||||
}
|
||||
|
@ -316,21 +316,20 @@ bool core::explain_lower_bound(const lp::lar_term& t, const rational& rs, lp::ex
|
|||
bool core::explain_coeff_lower_bound(const lp::lar_term::ival& p, rational& bound, lp::explanation& e) const {
|
||||
const rational& a = p.coeff();
|
||||
SASSERT(!a.is_zero());
|
||||
unsigned c; // the index for the lower or the upper bound
|
||||
if (a.is_pos()) {
|
||||
unsigned c = m_lar_solver.get_column_lower_bound_witness(p.column());
|
||||
if (c + 1 == 0)
|
||||
auto* dep = lra.get_column_lower_bound_witness(p.column());
|
||||
if (!dep)
|
||||
return false;
|
||||
bound = a * m_lar_solver.get_lower_bound(p.column()).x;
|
||||
e.push_back(c);
|
||||
bound = a * lra.get_lower_bound(p.column()).x;
|
||||
lra.push_explanation(dep, e);
|
||||
return true;
|
||||
}
|
||||
// a.is_neg()
|
||||
c = m_lar_solver.get_column_upper_bound_witness(p.column());
|
||||
if (c + 1 == 0)
|
||||
auto* dep = lra.get_column_upper_bound_witness(p.column());
|
||||
if (!dep)
|
||||
return false;
|
||||
bound = a * m_lar_solver.get_upper_bound(p.column()).x;
|
||||
e.push_back(c);
|
||||
bound = a * lra.get_upper_bound(p.column()).x;
|
||||
lra.push_explanation(dep, e);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -338,21 +337,20 @@ bool core::explain_coeff_upper_bound(const lp::lar_term::ival& p, rational& boun
|
|||
const rational& a = p.coeff();
|
||||
lpvar j = p.column();
|
||||
SASSERT(!a.is_zero());
|
||||
unsigned c; // the index for the lower or the upper bound
|
||||
if (a.is_neg()) {
|
||||
unsigned c = m_lar_solver.get_column_lower_bound_witness(j);
|
||||
if (c + 1 == 0)
|
||||
auto *dep = lra.get_column_lower_bound_witness(j);
|
||||
if (!dep)
|
||||
return false;
|
||||
bound = a * m_lar_solver.get_lower_bound(j).x;
|
||||
e.push_back(c);
|
||||
bound = a * lra.get_lower_bound(j).x;
|
||||
lra.push_explanation(dep, e);
|
||||
return true;
|
||||
}
|
||||
// a.is_pos()
|
||||
c = m_lar_solver.get_column_upper_bound_witness(j);
|
||||
if (c + 1 == 0)
|
||||
auto* dep = lra.get_column_upper_bound_witness(j);
|
||||
if (!dep)
|
||||
return false;
|
||||
bound = a * m_lar_solver.get_upper_bound(j).x;
|
||||
e.push_back(c);
|
||||
bound = a * lra.get_upper_bound(j).x;
|
||||
lra.push_explanation(dep, e);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -413,12 +411,12 @@ bool core::explain_by_equiv(const lp::lar_term& t, lp::explanation& e) const {
|
|||
return false;
|
||||
|
||||
m_evars.explain(signed_var(i, false), signed_var(j, sign), e);
|
||||
TRACE("nla_solver", tout << "explained :"; m_lar_solver.print_term_as_indices(t, tout););
|
||||
TRACE("nla_solver", tout << "explained :"; lra.print_term_as_indices(t, tout););
|
||||
return true;
|
||||
}
|
||||
|
||||
void core::mk_ineq_no_expl_check(new_lemma& lemma, lp::lar_term& t, llc cmp, const rational& rs) {
|
||||
TRACE("nla_solver_details", m_lar_solver.print_term_as_indices(t, tout << "t = "););
|
||||
TRACE("nla_solver_details", lra.print_term_as_indices(t, tout << "t = "););
|
||||
lemma |= ineq(cmp, t, rs);
|
||||
CTRACE("nla_solver", ineq_holds(ineq(cmp, t, rs)), print_ineq(ineq(cmp, t, rs), tout) << "\n";);
|
||||
SASSERT(!ineq_holds(ineq(cmp, t, rs)));
|
||||
|
@ -485,18 +483,18 @@ int core::vars_sign(const svector<lpvar>& v) {
|
|||
}
|
||||
|
||||
bool core::has_upper_bound(lpvar j) const {
|
||||
return m_lar_solver.column_has_upper_bound(j);
|
||||
return lra.column_has_upper_bound(j);
|
||||
}
|
||||
|
||||
bool core::has_lower_bound(lpvar j) const {
|
||||
return m_lar_solver.column_has_lower_bound(j);
|
||||
return lra.column_has_lower_bound(j);
|
||||
}
|
||||
const rational& core::get_upper_bound(unsigned j) const {
|
||||
return m_lar_solver.get_upper_bound(j).x;
|
||||
return lra.get_upper_bound(j).x;
|
||||
}
|
||||
|
||||
const rational& core::get_lower_bound(unsigned j) const {
|
||||
return m_lar_solver.get_lower_bound(j).x;
|
||||
return lra.get_lower_bound(j).x;
|
||||
}
|
||||
|
||||
bool core::zero_is_an_inner_point_of_bounds(lpvar j) const {
|
||||
|
@ -540,26 +538,26 @@ bool core::sign_contradiction(const monic& m) const {
|
|||
|
||||
bool core::var_is_fixed_to_zero(lpvar j) const {
|
||||
return
|
||||
m_lar_solver.column_is_fixed(j) &&
|
||||
m_lar_solver.get_lower_bound(j) == lp::zero_of_type<lp::impq>();
|
||||
lra.column_is_fixed(j) &&
|
||||
lra.get_lower_bound(j) == lp::zero_of_type<lp::impq>();
|
||||
}
|
||||
bool core::var_is_fixed_to_val(lpvar j, const rational& v) const {
|
||||
return
|
||||
m_lar_solver.column_is_fixed(j) &&
|
||||
m_lar_solver.get_lower_bound(j) == lp::impq(v);
|
||||
lra.column_is_fixed(j) &&
|
||||
lra.get_lower_bound(j) == lp::impq(v);
|
||||
}
|
||||
|
||||
bool core::var_is_fixed(lpvar j) const {
|
||||
return m_lar_solver.column_is_fixed(j);
|
||||
return lra.column_is_fixed(j);
|
||||
}
|
||||
|
||||
bool core::var_is_free(lpvar j) const {
|
||||
return m_lar_solver.column_is_free(j);
|
||||
return lra.column_is_free(j);
|
||||
}
|
||||
|
||||
|
||||
std::ostream & core::print_ineq(const ineq & in, std::ostream & out) const {
|
||||
m_lar_solver.print_term_as_indices(in.term(), out);
|
||||
lra.print_term_as_indices(in.term(), out);
|
||||
out << " " << lconstraint_kind_string(in.cmp()) << " " << in.rs();
|
||||
return out;
|
||||
}
|
||||
|
@ -569,14 +567,14 @@ std::ostream & core::print_var(lpvar j, std::ostream & out) const {
|
|||
print_monic(m_emons[j], out);
|
||||
}
|
||||
|
||||
m_lar_solver.print_column_info(j, out);
|
||||
lra.print_column_info(j, out);
|
||||
signed_var jr = m_evars.find(j);
|
||||
out << "root=";
|
||||
if (jr.sign()) {
|
||||
out << "-";
|
||||
}
|
||||
|
||||
out << m_lar_solver.get_variable_name(jr.var()) << "\n";
|
||||
out << lra.get_variable_name(jr.var()) << "\n";
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -643,11 +641,11 @@ void core::trace_print_monic_and_factorization(const monic& rm, const factorizat
|
|||
|
||||
|
||||
bool core::var_has_positive_lower_bound(lpvar j) const {
|
||||
return m_lar_solver.column_has_lower_bound(j) && m_lar_solver.get_lower_bound(j) > lp::zero_of_type<lp::impq>();
|
||||
return lra.column_has_lower_bound(j) && lra.get_lower_bound(j) > lp::zero_of_type<lp::impq>();
|
||||
}
|
||||
|
||||
bool core::var_has_negative_upper_bound(lpvar j) const {
|
||||
return m_lar_solver.column_has_upper_bound(j) && m_lar_solver.get_upper_bound(j) < lp::zero_of_type<lp::impq>();
|
||||
return lra.column_has_upper_bound(j) && lra.get_upper_bound(j) < lp::zero_of_type<lp::impq>();
|
||||
}
|
||||
|
||||
bool core::var_is_separated_from_zero(lpvar j) const {
|
||||
|
@ -684,10 +682,10 @@ template bool core::mon_has_zero<unsigned_vector>(const unsigned_vector& product
|
|||
|
||||
|
||||
lp::lp_settings& core::lp_settings() {
|
||||
return m_lar_solver.settings();
|
||||
return lra.settings();
|
||||
}
|
||||
const lp::lp_settings& core::lp_settings() const {
|
||||
return m_lar_solver.settings();
|
||||
return lra.settings();
|
||||
}
|
||||
|
||||
unsigned core::random() { return lp_settings().random_next(); }
|
||||
|
@ -695,7 +693,7 @@ unsigned core::random() { return lp_settings().random_next(); }
|
|||
|
||||
// we look for octagon constraints here, with a left part +-x +- y
|
||||
void core::collect_equivs() {
|
||||
const lp::lar_solver& s = m_lar_solver;
|
||||
const lp::lar_solver& s = lra;
|
||||
|
||||
for (unsigned i = 0; i < s.terms().size(); i++) {
|
||||
if (!s.term_is_used_as_row(i))
|
||||
|
@ -737,7 +735,7 @@ bool core::is_octagon_term(const lp::lar_term& t, bool & sign, lpvar& i, lpvar &
|
|||
return true;
|
||||
}
|
||||
|
||||
void core::add_equivalence_maybe(const lp::lar_term *t, lpci c0, lpci c1) {
|
||||
void core::add_equivalence_maybe(const lp::lar_term* t, u_dependency* c0, u_dependency* c1) {
|
||||
bool sign;
|
||||
lpvar i, j;
|
||||
if (!is_octagon_term(*t, sign, i, j))
|
||||
|
@ -866,7 +864,7 @@ std::unordered_set<lpvar> core::collect_vars(const lemma& l) const {
|
|||
}
|
||||
}
|
||||
for (auto p : l.expl()) {
|
||||
const auto& c = m_lar_solver.constraints()[p.ci()];
|
||||
const auto& c = lra.constraints()[p.ci()];
|
||||
for (const auto& r : c.coeffs()) {
|
||||
insert_j(r.second);
|
||||
}
|
||||
|
@ -1125,8 +1123,8 @@ new_lemma& new_lemma::explain_equiv(lpvar a, lpvar b) {
|
|||
|
||||
new_lemma& new_lemma::explain_var_separated_from_zero(lpvar j) {
|
||||
SASSERT(c.var_is_separated_from_zero(j));
|
||||
if (c.m_lar_solver.column_has_upper_bound(j) &&
|
||||
(c.m_lar_solver.get_upper_bound(j)< lp::zero_of_type<lp::impq>()))
|
||||
if (c.lra.column_has_upper_bound(j) &&
|
||||
(c.lra.get_upper_bound(j)< lp::zero_of_type<lp::impq>()))
|
||||
explain_existing_upper_bound(j);
|
||||
else
|
||||
explain_existing_lower_bound(j);
|
||||
|
@ -1136,7 +1134,7 @@ new_lemma& new_lemma::explain_var_separated_from_zero(lpvar j) {
|
|||
new_lemma& new_lemma::explain_existing_lower_bound(lpvar j) {
|
||||
SASSERT(c.has_lower_bound(j));
|
||||
lp::explanation ex;
|
||||
ex.push_back(c.m_lar_solver.get_column_lower_bound_witness(j));
|
||||
c.lra.push_explanation(c.lra.get_column_lower_bound_witness(j), ex);
|
||||
*this &= ex;
|
||||
TRACE("nla_solver", tout << j << ": " << *this << "\n";);
|
||||
return *this;
|
||||
|
@ -1145,7 +1143,7 @@ new_lemma& new_lemma::explain_existing_lower_bound(lpvar j) {
|
|||
new_lemma& new_lemma::explain_existing_upper_bound(lpvar j) {
|
||||
SASSERT(c.has_upper_bound(j));
|
||||
lp::explanation ex;
|
||||
ex.push_back(c.m_lar_solver.get_column_upper_bound_witness(j));
|
||||
c.lra.push_explanation(c.lra.get_column_upper_bound_witness(j), ex);
|
||||
*this &= ex;
|
||||
return *this;
|
||||
}
|
||||
|
@ -1155,7 +1153,7 @@ std::ostream& new_lemma::display(std::ostream & out) const {
|
|||
|
||||
for (auto p : lemma.expl()) {
|
||||
out << "(" << p.ci() << ") ";
|
||||
c.m_lar_solver.constraints().display(out, [this](lpvar j) { return c.var_str(j);}, p.ci());
|
||||
c.lra.constraints().display(out, [this](lpvar j) { return c.var_str(j);}, p.ci());
|
||||
}
|
||||
out << " ==> ";
|
||||
if (lemma.ineqs().empty()) {
|
||||
|
@ -1303,7 +1301,7 @@ bool core::has_real(const monic& m) const {
|
|||
bool core::is_patch_blocked(lpvar u, const lp::impq& ival) const {
|
||||
TRACE("nla_solver", tout << "u = " << u << '\n';);
|
||||
if (m_cautious_patching &&
|
||||
(!m_lar_solver.inside_bounds(u, ival) || (var_is_int(u) && ival.is_int() == false))) {
|
||||
(!lra.inside_bounds(u, ival) || (var_is_int(u) && ival.is_int() == false))) {
|
||||
TRACE("nla_solver", tout << "u = " << u << " blocked, for feas or integr\n";);
|
||||
return true; // block
|
||||
}
|
||||
|
@ -1334,7 +1332,7 @@ bool core::is_patch_blocked(lpvar u, const lp::impq& ival) const {
|
|||
bool core::try_to_patch(const rational& v) {
|
||||
auto is_blocked = [this](lpvar u, const lp::impq& iv) { return is_patch_blocked(u, iv); };
|
||||
auto change_report = [this](lpvar u) { update_to_refine_of_var(u); };
|
||||
return m_lar_solver.try_to_patch(m_patched_var, v, is_blocked, change_report);
|
||||
return lra.try_to_patch(m_patched_var, v, is_blocked, change_report);
|
||||
}
|
||||
|
||||
bool in_power(const svector<lpvar>& vs, unsigned l) {
|
||||
|
@ -1343,7 +1341,7 @@ bool in_power(const svector<lpvar>& vs, unsigned l) {
|
|||
}
|
||||
|
||||
bool core::to_refine_is_correct() const {
|
||||
for (unsigned j = 0; j < m_lar_solver.number_of_vars(); j++) {
|
||||
for (unsigned j = 0; j < lra.number_of_vars(); j++) {
|
||||
if (!is_monic_var(j)) continue;
|
||||
bool valid = check_monic(emons()[j]);
|
||||
if (valid == m_to_refine.contains(j)) {
|
||||
|
@ -1435,17 +1433,17 @@ void core::patch_monomials() {
|
|||
NOT_IMPLEMENTED_YET();
|
||||
m_cautious_patching = false;
|
||||
patch_monomials_on_to_refine();
|
||||
m_lar_solver.push();
|
||||
lra.push();
|
||||
save_tableau();
|
||||
constrain_nl_in_tableau();
|
||||
if (solve_tableau() && integrality_holds()) {
|
||||
m_lar_solver.pop(1);
|
||||
lra.pop(1);
|
||||
} else {
|
||||
m_lar_solver.pop();
|
||||
lra.pop();
|
||||
restore_tableau();
|
||||
m_lar_solver.clear_inf_heap();
|
||||
lra.clear_inf_heap();
|
||||
}
|
||||
SASSERT(m_lar_solver.ax_is_correct());
|
||||
SASSERT(lra.ax_is_correct());
|
||||
}
|
||||
|
||||
void core::constrain_nl_in_tableau() {
|
||||
|
@ -1507,11 +1505,11 @@ void core::check_bounded_divisions(vector<lemma>& l_vec) {
|
|||
lbool core::check(vector<lemma>& l_vec) {
|
||||
lp_settings().stats().m_nla_calls++;
|
||||
TRACE("nla_solver", tout << "calls = " << lp_settings().stats().m_nla_calls << "\n";);
|
||||
m_lar_solver.get_rid_of_inf_eps();
|
||||
lra.get_rid_of_inf_eps();
|
||||
m_lemma_vec = &l_vec;
|
||||
if (!(m_lar_solver.get_status() == lp::lp_status::OPTIMAL ||
|
||||
m_lar_solver.get_status() == lp::lp_status::FEASIBLE)) {
|
||||
TRACE("nla_solver", tout << "unknown because of the m_lar_solver.m_status = " << m_lar_solver.get_status() << "\n";);
|
||||
if (!(lra.get_status() == lp::lp_status::OPTIMAL ||
|
||||
lra.get_status() == lp::lp_status::FEASIBLE)) {
|
||||
TRACE("nla_solver", tout << "unknown because of the lra.m_status = " << lra.get_status() << "\n";);
|
||||
return l_undef;
|
||||
}
|
||||
|
||||
|
@ -1528,6 +1526,9 @@ lbool core::check(vector<lemma>& l_vec) {
|
|||
|
||||
if (l_vec.empty() && !done())
|
||||
m_monomial_bounds();
|
||||
|
||||
if (l_vec.empty() && !done() && improve_bounds())
|
||||
return l_false;
|
||||
|
||||
if (l_vec.empty() && !done() && run_horner)
|
||||
m_horner.horner_lemmas();
|
||||
|
@ -1635,21 +1636,21 @@ bool core::no_lemmas_hold() const {
|
|||
}
|
||||
|
||||
lbool core::test_check(vector<lemma>& l) {
|
||||
m_lar_solver.set_status(lp::lp_status::OPTIMAL);
|
||||
lra.set_status(lp::lp_status::OPTIMAL);
|
||||
return check(l);
|
||||
}
|
||||
|
||||
std::ostream& core::print_terms(std::ostream& out) const {
|
||||
for (unsigned i = 0; i< m_lar_solver.terms().size(); i++) {
|
||||
for (unsigned i = 0; i< lra.terms().size(); i++) {
|
||||
unsigned ext = lp::tv::mask_term(i);
|
||||
if (!m_lar_solver.var_is_registered(ext)) {
|
||||
if (!lra.var_is_registered(ext)) {
|
||||
out << "term is not registered\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
const lp::lar_term & t = *m_lar_solver.terms()[i];
|
||||
const lp::lar_term & t = *lra.terms()[i];
|
||||
out << "term:"; print_term(t, out) << std::endl;
|
||||
lpvar j = m_lar_solver.external_to_local(ext);
|
||||
lpvar j = lra.external_to_local(ext);
|
||||
print_var(j, out);
|
||||
}
|
||||
return out;
|
||||
|
@ -1677,7 +1678,7 @@ std::ostream& core::print_term( const lp::lar_term& t, std::ostream& out) const
|
|||
|
||||
std::unordered_set<lpvar> core::get_vars_of_expr_with_opening_terms(const nex *e ) {
|
||||
auto ret = get_vars_of_expr(e);
|
||||
auto & ls = m_lar_solver;
|
||||
auto & ls = lra;
|
||||
svector<lpvar> added;
|
||||
for (auto j : ret) {
|
||||
added.push_back(j);
|
||||
|
@ -1685,7 +1686,7 @@ std::unordered_set<lpvar> core::get_vars_of_expr_with_opening_terms(const nex *e
|
|||
for (unsigned i = 0; i < added.size(); ++i) {
|
||||
lpvar j = added[i];
|
||||
if (ls.column_corresponds_to_term(j)) {
|
||||
const auto& t = m_lar_solver.get_term(lp::tv::raw(ls.local_to_external(j)));
|
||||
const auto& t = lra.get_term(lp::tv::raw(ls.local_to_external(j)));
|
||||
for (auto p : t) {
|
||||
if (ret.find(p.column()) == ret.end()) {
|
||||
added.push_back(p.column());
|
||||
|
@ -1705,7 +1706,7 @@ bool core::is_nl_var(lpvar j) const {
|
|||
|
||||
unsigned core::get_var_weight(lpvar j) const {
|
||||
unsigned k;
|
||||
switch (m_lar_solver.get_column_type(j)) {
|
||||
switch (lra.get_column_type(j)) {
|
||||
|
||||
case lp::column_type::fixed:
|
||||
k = 0;
|
||||
|
@ -1734,7 +1735,7 @@ unsigned core::get_var_weight(lpvar j) const {
|
|||
|
||||
|
||||
void core::set_active_vars_weights(nex_creator& nc) {
|
||||
nc.set_number_of_vars(m_lar_solver.column_count());
|
||||
nc.set_number_of_vars(lra.column_count());
|
||||
for (lpvar j : active_var_set())
|
||||
nc.set_var_weight(j, get_var_weight(j));
|
||||
}
|
||||
|
@ -1744,8 +1745,8 @@ bool core::influences_nl_var(lpvar j) const {
|
|||
j = lp::tv::unmask_term(j);
|
||||
if (is_nl_var(j))
|
||||
return true;
|
||||
for (const auto & c : m_lar_solver.A_r().m_columns[j]) {
|
||||
lpvar basic_in_row = m_lar_solver.r_basis()[c.var()];
|
||||
for (const auto & c : lra.A_r().m_columns[j]) {
|
||||
lpvar basic_in_row = lra.r_basis()[c.var()];
|
||||
if (is_nl_var(basic_in_row))
|
||||
return true;
|
||||
}
|
||||
|
@ -1762,9 +1763,32 @@ void core::set_use_nra_model(bool m) {
|
|||
void core::collect_statistics(::statistics & st) {
|
||||
st.update("arith-nla-explanations", m_stats.m_nla_explanations);
|
||||
st.update("arith-nla-lemmas", m_stats.m_nla_lemmas);
|
||||
st.update("arith-nra-calls", m_stats.m_nra_calls);
|
||||
st.update("arith-nra-calls", m_stats.m_nra_calls);
|
||||
st.update("arith-bounds-improvements", m_stats.m_bounds_improvements);
|
||||
}
|
||||
|
||||
bool core::improve_bounds() {
|
||||
return false;
|
||||
|
||||
uint_set seen;
|
||||
bool bounds_improved = false;
|
||||
auto insert = [&](lpvar v) {
|
||||
if (seen.contains(v))
|
||||
return;
|
||||
seen.insert(v);
|
||||
if (lra.improve_bound(v, false))
|
||||
bounds_improved = true, m_stats.m_bounds_improvements++;
|
||||
if (lra.improve_bound(v, true))
|
||||
bounds_improved = true, m_stats.m_bounds_improvements++;
|
||||
};
|
||||
for (auto & m : m_emons) {
|
||||
insert(m.var());
|
||||
for (auto v : m.vars())
|
||||
insert(v);
|
||||
}
|
||||
return bounds_improved;
|
||||
}
|
||||
|
||||
|
||||
} // end of nla
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue