3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 17:15:31 +00:00

arith_solver (#4733)

* porting arithmetic solver

* integrating arithmetic

* lp

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>

* na

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2020-10-16 10:49:46 -07:00 committed by GitHub
parent 2841796a92
commit 44679d8f5b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
33 changed files with 3172 additions and 403 deletions

View file

@ -321,7 +321,7 @@ public:
var_index add_named_var(unsigned ext_j, bool is_integer, const std::string&);
lp_status maximize_term(unsigned j_or_term, impq &term_max);
inline
core_solver_pretty_printer<lp::mpq, lp::impq> pp(std::ostream& out) { return
core_solver_pretty_printer<lp::mpq, lp::impq> pp(std::ostream& out) const { return
core_solver_pretty_printer<lp::mpq, lp::impq>(m_mpq_lar_core_solver.m_r_solver, out); }
void get_infeasibility_explanation(explanation &) const;
inline void backup_x() { m_backup_x = m_mpq_lar_core_solver.m_r_x; }

131
src/math/lp/lp_api.h Normal file
View file

@ -0,0 +1,131 @@
/*++
Copyright (c) 2017 Microsoft Corporation
Author:
Lev Nachmanson (levnach)
Nikolaj Bjorner (nbjorner)
--*/
#pragma once
#include "util/inf_rational.h"
#include "util/optional.h"
namespace lp_api {
typedef int bool_var;
typedef int theory_var;
enum bound_kind { lower_t, upper_t };
inline std::ostream& operator<<(std::ostream& out, bound_kind const& k) {
switch (k) {
case lower_t: return out << "<=";
case upper_t: return out << ">=";
}
return out;
}
class bound {
bool_var m_bv;
theory_var m_var;
lp::lpvar m_vi;
bool m_is_int;
rational m_value;
bound_kind m_bound_kind;
lp::constraint_index m_constraints[2];
public:
bound(bool_var bv, theory_var v, lp::lpvar vi, bool is_int, rational const& val, bound_kind k, lp::constraint_index ct, lp::constraint_index cf) :
m_bv(bv),
m_var(v),
m_vi(vi),
m_is_int(is_int),
m_value(val),
m_bound_kind(k) {
m_constraints[0] = cf;
m_constraints[1] = ct;
}
virtual ~bound() {}
theory_var get_var() const { return m_var; }
lp::tv tv() const { return lp::tv::raw(m_vi); }
bool_var get_bv() const { return m_bv; }
bound_kind get_bound_kind() const { return m_bound_kind; }
bool is_int() const { return m_is_int; }
rational const& get_value() const { return m_value; }
lp::constraint_index get_constraint(bool b) const { return m_constraints[b]; }
inf_rational get_value(bool is_true) const {
if (is_true)
return inf_rational(m_value); // v >= value or v <= value
if (m_is_int) {
SASSERT(m_value.is_int());
rational const& offset = (m_bound_kind == lower_t) ? rational::minus_one() : rational::one();
return inf_rational(m_value + offset); // v <= value - 1 or v >= value + 1
}
else {
return inf_rational(m_value, m_bound_kind != lower_t); // v <= value - epsilon or v >= value + epsilon
}
}
virtual std::ostream& display(std::ostream& out) const {
return out << m_value << " " << get_bound_kind() << " v" << get_var();
}
};
inline std::ostream& operator<<(std::ostream& out, bound const& b) {
return b.display(out);
}
typedef optional<inf_rational> opt_inf_rational;
struct stats {
unsigned m_assert_lower;
unsigned m_assert_upper;
unsigned m_bounds_propagations;
unsigned m_num_iterations;
unsigned m_num_iterations_with_no_progress;
unsigned m_need_to_solve_inf;
unsigned m_fixed_eqs;
unsigned m_conflicts;
unsigned m_bound_propagations1;
unsigned m_bound_propagations2;
unsigned m_assert_diseq;
unsigned m_gomory_cuts;
unsigned m_assume_eqs;
unsigned m_branch;
stats() { reset(); }
void reset() {
memset(this, 0, sizeof(*this));
}
void collect_statistics(statistics& st) const {
st.update("arith-lower", m_assert_lower);
st.update("arith-upper", m_assert_upper);
st.update("arith-propagations", m_bounds_propagations);
st.update("arith-iterations", m_num_iterations);
st.update("arith-pivots", m_need_to_solve_inf);
st.update("arith-plateau-iterations", m_num_iterations_with_no_progress);
st.update("arith-fixed-eqs", m_fixed_eqs);
st.update("arith-conflicts", m_conflicts);
st.update("arith-bound-propagations-lp", m_bound_propagations1);
st.update("arith-bound-propagations-cheap", m_bound_propagations2);
st.update("arith-diseq", m_assert_diseq);
st.update("arith-gomory-cuts", m_gomory_cuts);
st.update("arith-assume-eqs", m_assume_eqs);
st.update("arith-branch", m_branch);
}
};
}

View file

@ -27,6 +27,7 @@ Revision History:
#include <cstring>
#include "math/lp/lp_utils.h"
#include "util/stopwatch.h"
#include "util/statistics.h"
#include "math/lp/lp_types.h"
namespace lp {
@ -126,6 +127,26 @@ struct statistics {
unsigned m_cheap_eqs;
statistics() { reset(); }
void reset() { memset(this, 0, sizeof(*this)); }
void collect_statistics(::statistics& st) const {
st.update("arith-factorizations", m_num_factorizations);
st.update("arith-make-feasible", m_make_feasible);
st.update("arith-max-columns", m_max_cols);
st.update("arith-max-rows", m_max_rows);
st.update("arith-gcd-calls", m_gcd_calls);
st.update("arith-gcd-conflict", m_gcd_conflicts);
st.update("arith-cube-calls", m_cube_calls);
st.update("arith-cube-success", m_cube_success);
st.update("arith-patches", m_patches);
st.update("arith-patches-success", m_patches_success);
st.update("arith-hnf-calls", m_hnf_cutter_calls);
st.update("arith-horner-calls", m_horner_calls);
st.update("arith-horner-conflicts", m_horner_conflicts);
st.update("arith-horner-cross-nested-forms", m_cross_nested_forms);
st.update("arith-grobner-calls", m_grobner_calls);
st.update("arith-grobner-conflicts", m_grobner_conflicts);
st.update("arith-cheap-eqs", m_cheap_eqs);
}
};
struct lp_settings {