mirror of
https://github.com/Z3Prover/z3
synced 2025-04-27 02:45:51 +00:00
fixes to new solver, add mode for using nlsat solver eagerly from nla_core
This commit is contained in:
parent
9a975a4523
commit
8412ecbdbf
22 changed files with 156 additions and 164 deletions
|
@ -51,6 +51,7 @@ z3_add_component(lp
|
|||
util
|
||||
polynomial
|
||||
nlsat
|
||||
smt_params
|
||||
)
|
||||
|
||||
include_directories(${src_SOURCE_DIR})
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#include "math/lp/lar_solver.h"
|
||||
#include "smt/params/smt_params_helper.hpp"
|
||||
|
||||
/*
|
||||
Copyright (c) 2017 Microsoft Corporation
|
||||
Author: Nikolaj Bjorner, Lev Nachmanson
|
||||
|
@ -14,6 +16,14 @@ namespace lp {
|
|||
|
||||
lp_settings const& lar_solver::settings() const { return m_settings; }
|
||||
|
||||
void lar_solver::updt_params(params_ref const& _p) {
|
||||
smt_params_helper p(_p);
|
||||
set_track_pivoted_rows(p.arith_bprop_on_pivoted_rows());
|
||||
set_cut_strategy(p.arith_branch_cut_ratio());
|
||||
m_settings.updt_params(_p);
|
||||
}
|
||||
|
||||
|
||||
void clear() {
|
||||
lp_assert(false); // not implemented
|
||||
}
|
||||
|
|
|
@ -515,6 +515,7 @@ public:
|
|||
unsigned column_to_reported_index(unsigned j) const;
|
||||
lp_settings & settings();
|
||||
lp_settings const & settings() const;
|
||||
void updt_params(params_ref const& p);
|
||||
column_type get_column_type(unsigned j) const { return m_mpq_lar_core_solver.m_column_types()[j]; }
|
||||
const impq & get_lower_bound(unsigned j) const { return m_mpq_lar_core_solver.m_r_lower_bounds()[j]; }
|
||||
const impq & get_upper_bound(unsigned j) const { return m_mpq_lar_core_solver.m_r_upper_bounds()[j]; }
|
||||
|
|
|
@ -19,7 +19,18 @@ Revision History:
|
|||
--*/
|
||||
#include <memory>
|
||||
#include "util/vector.h"
|
||||
#include "smt/params/smt_params_helper.hpp"
|
||||
#include "math/lp/lp_settings_def.h"
|
||||
template bool lp::vectors_are_equal<double>(vector<double> const&, vector<double> const&);
|
||||
template bool lp::vectors_are_equal<lp::mpq>(vector<lp::mpq > const&, vector<lp::mpq> const&);
|
||||
|
||||
void lp::lp_settings::updt_params(params_ref const& _p) {
|
||||
smt_params_helper p(_p);
|
||||
m_enable_hnf = p.arith_enable_hnf();
|
||||
m_cheap_eqs = p.arith_propagate_eqs();
|
||||
print_statistics = p.arith_print_stats();
|
||||
m_print_external_var_name = p.arith_print_ext_var_names();
|
||||
report_frequency = p.arith_rep_freq();
|
||||
m_simplex_strategy = static_cast<lp::simplex_strategy_enum>(p.arith_simplex_strategy());
|
||||
m_nlsat_delay = p.arith_nl_delay();
|
||||
}
|
||||
|
|
|
@ -25,9 +25,10 @@ Revision History:
|
|||
#include <limits>
|
||||
#include <iomanip>
|
||||
#include <cstring>
|
||||
#include "math/lp/lp_utils.h"
|
||||
#include "util/stopwatch.h"
|
||||
#include "util/statistics.h"
|
||||
#include "util/params.h"
|
||||
#include "math/lp/lp_utils.h"
|
||||
#include "math/lp/lp_types.h"
|
||||
|
||||
namespace lp {
|
||||
|
@ -174,141 +175,93 @@ private:
|
|||
random_gen m_rand;
|
||||
|
||||
public:
|
||||
void updt_params(params_ref const& p);
|
||||
bool enable_hnf() const { return m_enable_hnf; }
|
||||
bool& enable_hnf() { return m_enable_hnf; }
|
||||
unsigned nlsat_delay() const { return m_nlsat_delay; }
|
||||
bool int_run_gcd_test() const { return m_int_run_gcd_test; }
|
||||
bool& int_run_gcd_test() { return m_int_run_gcd_test; }
|
||||
unsigned reps_in_scaler;
|
||||
unsigned reps_in_scaler { 20 };
|
||||
// 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 { 0.00000001 };
|
||||
// see Chatal, page 115
|
||||
double positive_price_epsilon;
|
||||
double positive_price_epsilon { 1e-7 };
|
||||
// a quotation "if some choice of the entering variable 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 { 1e-8 };
|
||||
int c_partial_pivoting { 10 }; // this is the constant c from page 410
|
||||
unsigned depth_of_rook_search { 4 };
|
||||
bool using_partial_pivoting { true };
|
||||
// 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 { 1e-4 };
|
||||
double pivot_tolerance { 1e-6 };
|
||||
double zero_tolerance { 1e-12 };
|
||||
double drop_tolerance { 1e-14 };
|
||||
double tolerance_for_artificials { 1e-4 };
|
||||
double can_be_taken_to_basis_tolerance { 0.00001 };
|
||||
|
||||
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;
|
||||
unsigned percent_of_entering_to_check { 5 }; // we try to find a profitable column in a percentage of the columns
|
||||
bool use_scaling { true };
|
||||
double scaling_maximum { 1.0 };
|
||||
double scaling_minimum { 0.5 };
|
||||
double harris_feasibility_tolerance { 1e-7 }; // page 179 of Istvan Maros
|
||||
double ignore_epsilon_of_harris { 10e-5 };
|
||||
unsigned max_number_of_iterations_with_no_improvements { 2000000 };
|
||||
unsigned max_total_number_of_iterations { 2000000 };
|
||||
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
|
||||
double dual_feasibility_tolerance { 1e-7 }; // page 71 of the PhD thesis of Achim Koberstein
|
||||
double primal_feasibility_tolerance { 1e-7 }; // page 71 of the PhD thesis of Achim Koberstein
|
||||
double relative_primal_feasibility_tolerance { 1e-9 }; // page 71 of the PhD thesis of Achim Koberstein
|
||||
// end of dual section
|
||||
bool m_bound_propagation;
|
||||
bool presolve_with_double_solver_for_lar;
|
||||
bool m_bound_propagation { true };
|
||||
bool presolve_with_double_solver_for_lar { true };
|
||||
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_find_cube_period;
|
||||
int report_frequency { 1000 };
|
||||
bool print_statistics { false };
|
||||
unsigned column_norms_update_frequency { 12000 };
|
||||
bool scale_with_ratio { true };
|
||||
double density_threshold { 0.7 };
|
||||
bool use_breakpoints_in_feasibility_search { false };
|
||||
unsigned max_row_length_for_bound_propagation { 300 };
|
||||
bool backup_costs { true };
|
||||
unsigned column_number_threshold_for_using_lu_in_lar_solver { 4000 };
|
||||
unsigned m_int_gomory_cut_period { 4 };
|
||||
unsigned m_int_find_cube_period { 4 };
|
||||
private:
|
||||
unsigned m_hnf_cut_period;
|
||||
bool m_int_run_gcd_test;
|
||||
unsigned m_hnf_cut_period { 4 };
|
||||
bool m_int_run_gcd_test { true };
|
||||
public:
|
||||
unsigned limit_on_rows_for_hnf_cutter;
|
||||
unsigned limit_on_columns_for_hnf_cutter;
|
||||
unsigned limit_on_rows_for_hnf_cutter { 75 };
|
||||
unsigned limit_on_columns_for_hnf_cutter { 150 };
|
||||
private:
|
||||
bool m_enable_hnf;
|
||||
bool m_print_external_var_name;
|
||||
bool m_cheap_eqs;
|
||||
unsigned m_nlsat_delay;
|
||||
bool m_enable_hnf { true };
|
||||
bool m_print_external_var_name { false };
|
||||
bool m_cheap_eqs { false };
|
||||
public:
|
||||
bool print_external_var_name() const { return m_print_external_var_name; }
|
||||
bool& print_external_var_name() { return m_print_external_var_name; }
|
||||
bool cheap_eqs() const { return m_cheap_eqs;}
|
||||
bool& cheap_eqs() { return m_cheap_eqs;}
|
||||
unsigned hnf_cut_period() const { return m_hnf_cut_period; }
|
||||
void set_hnf_cut_period(unsigned period) { m_hnf_cut_period = period; }
|
||||
unsigned random_next() { return m_rand(); }
|
||||
void set_random_seed(unsigned s) { m_rand.set_seed(s); }
|
||||
|
||||
bool bound_progation() const {
|
||||
bool bound_progation() const {
|
||||
return m_bound_propagation;
|
||||
}
|
||||
|
||||
bool& bound_propagation() {
|
||||
return m_bound_propagation;
|
||||
}
|
||||
bool& bound_propagation() { return m_bound_propagation; }
|
||||
|
||||
lp_settings() : m_default_resource_limit(*this),
|
||||
m_resource_limit(&m_default_resource_limit),
|
||||
m_debug_out(&std::cout),
|
||||
m_message_out(&std::cout),
|
||||
reps_in_scaler(20),
|
||||
pivot_epsilon(0.00000001),
|
||||
positive_price_epsilon(1e-7),
|
||||
entering_diag_epsilon (1e-8),
|
||||
c_partial_pivoting (10), // this is the constant c from page 410
|
||||
depth_of_rook_search (4),
|
||||
using_partial_pivoting (true),
|
||||
// dissertation of Achim Koberstein
|
||||
// if Bx - b is different at any component more that refactor_epsilon then we refactor
|
||||
refactor_tolerance ( 1e-4),
|
||||
pivot_tolerance ( 1e-6),
|
||||
zero_tolerance ( 1e-12),
|
||||
drop_tolerance ( 1e-14),
|
||||
tolerance_for_artificials ( 1e-4),
|
||||
can_be_taken_to_basis_tolerance ( 0.00001),
|
||||
percent_of_entering_to_check ( 5),// we try to find a profitable column in a percentage of the columns
|
||||
use_scaling ( true),
|
||||
scaling_maximum ( 1),
|
||||
scaling_minimum ( 0.5),
|
||||
harris_feasibility_tolerance ( 1e-7), // page 179 of Istvan Maros
|
||||
ignore_epsilon_of_harris ( 10e-5),
|
||||
max_number_of_iterations_with_no_improvements ( 2000000),
|
||||
max_total_number_of_iterations ( 20000000),
|
||||
time_limit ( std::numeric_limits<double>::max()), // the maximum time limit of the total run time in seconds
|
||||
// dual section
|
||||
dual_feasibility_tolerance ( 1e-7), // // page 71 of the PhD thesis of Achim Koberstein
|
||||
primal_feasibility_tolerance ( 1e-7), // page 71 of the PhD thesis of Achim Koberstein
|
||||
relative_primal_feasibility_tolerance ( 1e-9), // page 71 of the PhD thesis of Achim Koberstein
|
||||
m_bound_propagation ( true),
|
||||
presolve_with_double_solver_for_lar(true),
|
||||
m_simplex_strategy(simplex_strategy_enum::tableau_rows),
|
||||
report_frequency(1000),
|
||||
print_statistics(false),
|
||||
column_norms_update_frequency(12000),
|
||||
scale_with_ratio(true),
|
||||
density_threshold(0.7),
|
||||
use_breakpoints_in_feasibility_search(false),
|
||||
max_row_length_for_bound_propagation(300),
|
||||
backup_costs(true),
|
||||
column_number_threshold_for_using_lu_in_lar_solver(4000),
|
||||
m_int_gomory_cut_period(4),
|
||||
m_int_find_cube_period(4),
|
||||
m_hnf_cut_period(4),
|
||||
m_int_run_gcd_test(true),
|
||||
limit_on_rows_for_hnf_cutter(75),
|
||||
limit_on_columns_for_hnf_cutter(150),
|
||||
m_enable_hnf(true),
|
||||
m_print_external_var_name(false)
|
||||
|
||||
m_simplex_strategy(simplex_strategy_enum::tableau_rows)
|
||||
{}
|
||||
|
||||
void set_resource_limit(lp_resource_limit& lim) { m_resource_limit = &lim; }
|
||||
|
|
|
@ -37,7 +37,9 @@ core::core(lp::lar_solver& s, reslimit & lim) :
|
|||
m_reslim(lim),
|
||||
m_use_nra_model(false),
|
||||
m_nra(s, lim, *this)
|
||||
{}
|
||||
{
|
||||
m_nlsat_delay = lp_settings().nlsat_delay();
|
||||
}
|
||||
|
||||
bool core::compare_holds(const rational& ls, llc cmp, const rational& rs) const {
|
||||
switch(cmp) {
|
||||
|
@ -1507,11 +1509,15 @@ lbool core::check(vector<lemma>& l_vec) {
|
|||
run_grobner();
|
||||
|
||||
if (l_vec.empty() && !done())
|
||||
m_basics.basic_lemma(true);
|
||||
m_basics.basic_lemma(true);
|
||||
|
||||
if (l_vec.empty() && !done())
|
||||
m_basics.basic_lemma(false);
|
||||
|
||||
if (!conflict_found() && !done() && should_run_bounded_nlsat())
|
||||
ret = bounded_nlsat();
|
||||
|
||||
|
||||
if (l_vec.empty() && !done()) {
|
||||
std::function<void(void)> check1 = [&]() { m_order.order_lemma(); };
|
||||
std::function<void(void)> check2 = [&]() { m_monotone.monotonicity_lemma(); };
|
||||
|
@ -1523,15 +1529,9 @@ lbool core::check(vector<lemma>& l_vec) {
|
|||
{ 1, check3 }};
|
||||
check_weighted(3, checks);
|
||||
|
||||
if (!conflict_found() && m_nla_settings.run_nra() && random() % 50 == 0 &&
|
||||
if (!conflict_found() && m_nla_settings.run_nra() && should_run_bounded_nlsat() &&
|
||||
lp_settings().stats().m_nla_calls > 500) {
|
||||
params_ref p;
|
||||
p.set_uint("max_conflicts", 100);
|
||||
m_nra.updt_params(p);
|
||||
ret = m_nra.check();
|
||||
p.set_uint("max_conflicts", UINT_MAX);
|
||||
m_nra.updt_params(p);
|
||||
m_stats.m_nra_calls++;
|
||||
ret = bounded_nlsat();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1554,6 +1554,30 @@ lbool core::check(vector<lemma>& l_vec) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool core::should_run_bounded_nlsat() {
|
||||
if (m_nlsat_delay > m_nlsat_fails)
|
||||
++m_nlsat_fails;
|
||||
return m_nlsat_delay <= m_nlsat_fails;
|
||||
}
|
||||
|
||||
lbool core::bounded_nlsat() {
|
||||
params_ref p;
|
||||
p.set_uint("max_conflicts", 100);
|
||||
scoped_rlimit sr(m_reslim, 100000);
|
||||
m_nra.updt_params(p);
|
||||
lbool ret = m_nra.check();
|
||||
p.set_uint("max_conflicts", UINT_MAX);
|
||||
m_nra.updt_params(p);
|
||||
m_stats.m_nra_calls++;
|
||||
if (ret == l_undef)
|
||||
++m_nlsat_delay;
|
||||
else {
|
||||
m_nlsat_fails = 0;
|
||||
m_nlsat_delay /= 2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool core::no_lemmas_hold() const {
|
||||
for (auto & l : * m_lemma_vec) {
|
||||
if (lemma_holds(l)) {
|
||||
|
|
|
@ -150,6 +150,11 @@ class core {
|
|||
};
|
||||
stats m_stats;
|
||||
friend class new_lemma;
|
||||
|
||||
unsigned m_nlsat_delay { 50 };
|
||||
unsigned m_nlsat_fails { 0 };
|
||||
bool should_run_bounded_nlsat();
|
||||
lbool bounded_nlsat();
|
||||
public:
|
||||
var_eqs<emonics> m_evars;
|
||||
lp::lar_solver& m_lar_solver;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue