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:
parent
2841796a92
commit
44679d8f5b
33 changed files with 3172 additions and 403 deletions
|
@ -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
131
src/math/lp/lp_api.h
Normal 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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue