3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-12 04:03:39 +00:00

port more from hybridSMT

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
Lev Nachmanson 2024-08-08 12:14:33 -10:00 committed by Lev Nachmanson
parent 209366ba55
commit 1a5bddb4f0
10 changed files with 3061 additions and 4044 deletions

View file

@ -7,7 +7,10 @@ z3_add_component(nlsat
nlsat_simplify.cpp nlsat_simplify.cpp
nlsat_solver.cpp nlsat_solver.cpp
nlsat_types.cpp nlsat_types.cpp
COMPONENT_DEPENDENCIES nlsat_simple_checker.cpp
nlsat_variable_ordering_strategy.cpp
nlsat_symmetry_checker.cpp
COMPONENT_DEPENDENCIES
polynomial polynomial
sat sat
PYG_FILES PYG_FILES

View file

@ -3,7 +3,10 @@ def_module_params('nlsat',
description='nonlinear solver', description='nonlinear solver',
export=True, export=True,
params=(max_memory_param(), params=(max_memory_param(),
('linxi_simple_check', BOOL, False, "linxi precheck about variables sign"),
('linxi_variable_ordering_strategy', UINT, 0, "linxi Variable Ordering Strategy, 0 for none, 1 for BROWN, 2 for TRIANGULAR, 3 for ONLYPOLY"),
('cell_sample', BOOL, True, "cell sample projection"), ('cell_sample', BOOL, True, "cell sample projection"),
('linxi_symmetry_check', BOOL, False, "linxi symmetry check and learning"),
('lazy', UINT, 0, "how lazy the solver is."), ('lazy', UINT, 0, "how lazy the solver is."),
('reorder', BOOL, True, "reorder variables."), ('reorder', BOOL, True, "reorder variables."),
('log_lemmas', BOOL, False, "display lemmas as self-contained SMT formulas"), ('log_lemmas', BOOL, False, "display lemmas as self-contained SMT formulas"),

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#include "math/polynomial/algebraic_numbers.h"
#include "nlsat/nlsat_clause.h"
namespace nlsat {
class Simple_Checker {
struct imp;
imp * m_imp;
public:
// Simple_Checker(solver &_sol, pmanager &_pm, anum_manager &_am, const clause_vector &_clauses, clause_vector &_learned, const atom_vector &_atoms, const unsigned &_arith_var_num);
Simple_Checker(pmanager &_pm, anum_manager &_am, const clause_vector &_clauses, literal_vector &_learned_unit, const atom_vector &_atoms, const unsigned &_arith_var_num);
~Simple_Checker();
bool operator()();
};
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,356 @@
#include "nlsat/nlsat_symmetry_checker.h"
struct Debug_Tracer {
std::string tag_str;
Debug_Tracer(std::string _tag_str) {
tag_str = _tag_str;
TRACE("linxi_symmetry_checker",
tout << "Debug_Tracer begin\n";
tout << tag_str << "\n";
);
}
~Debug_Tracer() {
TRACE("linxi_symmetry_checker",
tout << "Debug_Tracer end\n";
tout << tag_str << "\n";
);
}
};
// #define _LINXI_DEBUG
#ifdef _LINXI_DEBUG
#define LINXI_DEBUG_CORE(x) std::stringstream DEBUG_ss_##x; DEBUG_ss_##x << __FUNCTION__ << " " << __FILE__ << ":" << __LINE__; Debug_Tracer DEBUG_dt_##x(DEBUG_ss_##x.str());
#define LINXI_DEBUG_TRANS(x) LINXI_DEBUG_CORE(x);
#define LINXI_DEBUG LINXI_DEBUG_TRANS(__LINE__);
#define LINXI_HERE TRACE("linxi_symmetry_checker", tout << "here\n";);
#else
#define LINXI_DEBUG { }((void) 0 );
#define LINXI_HERE { }((void) 0 );
#endif
namespace nlsat {
struct Symmetry_Checker::imp {
// solver &sol;
pmanager &pm;
unsynch_mpq_manager &qm;
const clause_vector &clauses;
const atom_vector &atoms;
const bool_vector &is_int;
const unsigned arith_var_num;
// vector<unsigned long long> vars_hash;
vector<vector<unsigned>> vars_occur;
bool is_check;
var tx, ty;
struct Variable_Information {
unsigned long long hash_value;
unsigned deg;
var x;
bool is_int;
bool operator< (const Variable_Information &rhs) const {
return hash_value < rhs.hash_value;
}
bool operator== (const Variable_Information &rhs) const {
if (hash_value != rhs.hash_value)
return false;
if (deg != rhs.deg)
return false;
if (x != rhs.x)
return false;
if (is_int != rhs.is_int)
return false;
return true;
}
bool operator!= (const Variable_Information &rhs) const {
return !(*this == rhs);
}
};
unsigned long long VAR_BASE = 601;
void collect_var_info(Variable_Information &var_info, var x, unsigned deg) {
LINXI_DEBUG;
if (is_check) {
if (x == tx) {
x = ty;
}
else if (x == ty) {
x = tx;
}
else {
// do nothing
}
}
else {
vars_occur[x].push_back(deg);
}
var_info.deg = deg;
var_info.x = x;
var_info.is_int = is_int[x];
var_info.hash_value = 0;
for (unsigned i = 0; i < deg; ++i) {
var_info.hash_value = var_info.hash_value*VAR_BASE + (unsigned long long)x;
}
var_info.hash_value = var_info.hash_value*VAR_BASE + (unsigned long long)var_info.is_int;
}
struct Monomial_Information {
unsigned long long hash_value;
unsigned long long coef;
vector<Variable_Information> vars_info;
bool operator< (const Monomial_Information &rhs) const {
return hash_value < rhs.hash_value;
}
bool operator== (const Monomial_Information &rhs) const {
if (hash_value != rhs.hash_value)
return false;
if (coef != rhs.coef)
return false;
if (vars_info.size() != rhs.vars_info.size())
return false;
for (unsigned i = 0, sz = vars_info.size(); i < sz; ++i) {
if (vars_info[i] != rhs.vars_info[i])
return false;
}
return true;
}
bool operator!= (const Monomial_Information &rhs) const {
return !(*this == rhs);
}
};
unsigned long long MONO_BASE = 99991;
void collect_mono_info(Monomial_Information &mono_info, monomial *m, unsigned long long coef) {
LINXI_DEBUG;
unsigned sz = pm.size(m);
mono_info.vars_info.resize(sz);
for (unsigned i = 0; i < sz; ++i) {
collect_var_info(mono_info.vars_info[i], pm.get_var(m, i), pm.degree(m, i));
}
mono_info.coef = coef;
mono_info.hash_value = coef;
std::sort(mono_info.vars_info.begin(), mono_info.vars_info.end());
for (unsigned i = 0; i < sz; ++i) {
mono_info.hash_value = mono_info.hash_value*MONO_BASE + mono_info.vars_info[i].hash_value;
}
}
struct Polynomial_Information {
unsigned long long hash_value;
bool is_even;
vector<Monomial_Information> monos_info;
bool operator< (const Polynomial_Information &rhs) const {
return hash_value < rhs.hash_value;
}
bool operator== (const Polynomial_Information &rhs) const {
if (hash_value != rhs.hash_value)
return false;
if (is_even != rhs.is_even)
return false;
if (monos_info.size() != rhs.monos_info.size())
return false;
for (unsigned i = 0, sz = monos_info.size(); i < sz; ++i) {
if (monos_info[i] != rhs.monos_info[i])
return false;
}
return true;
}
bool operator!= (const Polynomial_Information &rhs) const {
return !(*this == rhs);
}
};
unsigned long long POLY_BASE = 99991;
void collect_poly_info(Polynomial_Information &poly_info, poly *p, bool is_even) {
LINXI_DEBUG;
unsigned sz = pm.size(p);
poly_info.monos_info.resize(sz);
for (unsigned i = 0; i < sz; ++i) {
collect_mono_info(poly_info.monos_info[i], pm.get_monomial(p, i), qm.get_uint64(pm.coeff(p, i)));
}
poly_info.hash_value = 0;
std::sort(poly_info.monos_info.begin(), poly_info.monos_info.end());
for (unsigned i = 0; i < sz; ++i) {
poly_info.hash_value = poly_info.hash_value*POLY_BASE + poly_info.monos_info[i].hash_value;
}
poly_info.is_even = is_even;
if (is_even) {
poly_info.hash_value = poly_info.hash_value*poly_info.hash_value;
}
}
struct Atom_Information {
unsigned long long hash_value;
atom::kind akd;
vector<Polynomial_Information> polys_info;
bool operator< (const Atom_Information &rhs) const {
return hash_value < rhs.hash_value;
}
bool operator== (const Atom_Information &rhs) const {
if (hash_value != rhs.hash_value)
return false;
if (akd != rhs.akd)
return false;
if (polys_info.size() != rhs.polys_info.size())
return false;
for (unsigned i = 0, sz = polys_info.size(); i < sz; ++i) {
if (polys_info[i] != rhs.polys_info[i])
return false;
}
return true;
}
bool operator!= (const Atom_Information &rhs) const {
return !(*this == rhs);
}
};
unsigned long long ATOM_BASE = 233;
void collect_atom_info(Atom_Information &atom_info, ineq_atom *iat) {
LINXI_DEBUG;
unsigned sz = iat->size();
atom_info.polys_info.resize(sz);
for (unsigned i = 0; i < sz; ++i) {
collect_poly_info(atom_info.polys_info[i], iat->p(i), iat->is_even(i));
}
atom_info.hash_value = 0;
std::sort(atom_info.polys_info.begin(), atom_info.polys_info.end());
for (unsigned i = 0; i < sz; ++i) {
atom_info.hash_value = atom_info.hash_value*ATOM_BASE + atom_info.polys_info[i].hash_value;
}
atom_info.akd = iat->get_kind();
atom_info.hash_value = atom_info.hash_value*ATOM_BASE + (unsigned long long)atom_info.akd;
}
struct Literal_Information {
unsigned long long hash_value;
vector<Atom_Information> atom_info; // not atoms
bool operator< (const Literal_Information &rhs) const {
return hash_value < rhs.hash_value;
}
bool operator== (const Literal_Information &rhs) const {
if (hash_value != rhs.hash_value)
return false;
if (atom_info.size() != rhs.atom_info.size())
return false;
for (unsigned i = 0, sz = atom_info.size(); i < sz; ++i) {
if (atom_info[i] != rhs.atom_info[i])
return false;
}
return true;
}
bool operator!= (const Literal_Information &rhs) const {
return !(*this == rhs);
}
};
void collect_lit_info(Literal_Information &lit_info, literal lit) {
LINXI_DEBUG;
atom *at = atoms[lit.var()];
if (at == nullptr || !at->is_ineq_atom()) {
lit_info.hash_value = lit.to_uint();
}
else {
lit_info.atom_info.resize(1);
collect_atom_info(lit_info.atom_info[0], to_ineq_atom(at));
lit_info.hash_value = lit_info.atom_info[0].hash_value;
}
}
struct Clause_Information {
unsigned long long hash_value;
vector<Literal_Information> lits_info;
bool operator< (const Clause_Information &rhs) const {
return hash_value < rhs.hash_value;
}
bool operator== (const Clause_Information &rhs) const {
if (hash_value != rhs.hash_value)
return false;
if (lits_info.size() != rhs.lits_info.size())
return false;
for (unsigned i = 0, sz = lits_info.size(); i < sz; ++i) {
if (lits_info[i] != rhs.lits_info[i])
return false;
}
return true;
}
bool operator!= (const Clause_Information &rhs) const {
return !(*this == rhs);
}
};
unsigned long long CLA_BASE = 9973;
void collect_cla_info(Clause_Information &cla_info, clause *cla) {
LINXI_DEBUG;
unsigned sz = cla->size();
cla_info.lits_info.resize(sz);
for (unsigned i = 0; i < sz; ++i) {
literal lit = (*cla)[i];
collect_lit_info(cla_info.lits_info[i], lit);
}
cla_info.hash_value = 0;
std::sort(cla_info.lits_info.begin(), cla_info.lits_info.end());
for (unsigned i = 0; i < sz; ++i) {
cla_info.hash_value = cla_info.hash_value*CLA_BASE + cla_info.lits_info[i].hash_value;
}
}
void collect_clas_info(vector<Clause_Information> &clas_info) {
LINXI_DEBUG;
unsigned sz = clauses.size();
clas_info.resize(sz);
for (unsigned i = 0; i < sz; ++i) {
collect_cla_info(clas_info[i], clauses[i]);
}
std::sort(clas_info.begin(), clas_info.end());
if (!is_check) {
for (unsigned i = 0; i < arith_var_num; ++i) {
std::sort(vars_occur[i].begin(), vars_occur[i].begin());
}
}
}
vector<Clause_Information> ori_clas_info;
imp(pmanager &_pm, unsynch_mpq_manager &_qm, const clause_vector &_clauses, const atom_vector &_atoms, const bool_vector &_is_int, const unsigned &_arith_var_num) :
// sol(_sol),
pm(_pm),
qm(_qm),
clauses(_clauses),
atoms(_atoms),
is_int(_is_int),
arith_var_num(_arith_var_num),
is_check(false) {
vars_occur.resize(arith_var_num);
collect_clas_info(ori_clas_info);
// vars_hash.resize(arith_var_num, 0);
}
vector<Clause_Information> check_clas_info;
bool check_occur_same(var x, var y) {
if (vars_occur[x].size() != vars_occur[y].size())
return false;
for (unsigned i = 0, sz = vars_occur[x].size(); i < sz; ++i) {
if (vars_occur[x][i] != vars_occur[y][i])
return false;
}
return true;
}
bool check_symmetry(var x, var y) {
if (!check_occur_same(x, y)) {
return false;
}
is_check = true;
tx = x, ty = y;
collect_clas_info(check_clas_info);
for (unsigned i = 0, sz = clauses.size(); i < sz; ++i) {
if (ori_clas_info[i] != check_clas_info[i])
return false;
}
return true;
}
};
Symmetry_Checker::Symmetry_Checker(pmanager &_pm, unsynch_mpq_manager &_qm, const clause_vector &_clauses, const atom_vector &_atoms, const bool_vector &_is_int, const unsigned &_arith_var_num) {
LINXI_DEBUG;
// m_imp = alloc(imp, _sol, _pm, _am, _clauses, _learned, _atoms, _arith_var_num);
m_imp = alloc(imp, _pm, _qm, _clauses, _atoms, _is_int, _arith_var_num);
}
Symmetry_Checker::~Symmetry_Checker() {
LINXI_DEBUG;
dealloc(m_imp);
}
// bool Symmetry_Checker::operator()() {
// LINXI_DEBUG;
// }
bool Symmetry_Checker::check_symmetry(var x, var y) {
return m_imp->check_symmetry(x, y);
}
}

View file

@ -0,0 +1,13 @@
#include "nlsat/nlsat_clause.h"
namespace nlsat {
class Symmetry_Checker {
struct imp;
imp * m_imp;
public:
// Simple_Checker(solver &_sol, pmanager &_pm, anum_manager &_am, const clause_vector &_clauses, clause_vector &_learned, const atom_vector &_atoms, const unsigned &_arith_var_num);
Symmetry_Checker(pmanager &_pm, unsynch_mpq_manager &_qm, const clause_vector &_clauses, const atom_vector &_atoms, const bool_vector &_is_int, const unsigned &_arith_var_num);
~Symmetry_Checker();
bool check_symmetry(var x, var y);
};
}

View file

@ -0,0 +1,282 @@
#include "nlsat/nlsat_variable_ordering_strategy.h"
namespace nlsat {
struct VOS_Var_Info_Collector::imp {
pmanager & pm;
atom_vector const & m_atoms;
unsigned num_vars;
Variable_Ordering_Strategy_Type m_vos_type;
/** Maximum degree of this variable. */
unsigned_vector m_max_degree;
/** Sum of degrees of this variable within all polynomials. */
unsigned_vector m_sum_poly_degree;
/** Number of polynomials that contain this variable. */
unsigned_vector m_num_polynomials;
/** Maximum degree of the leading coefficient of this variable. */
unsigned_vector m_max_lc_degree;
/** Maximum of total degrees of terms that contain this variable. */
unsigned_vector m_max_terms_tdegree;
/** Sum of degrees of this variable within all terms. */
unsigned_vector m_sum_term_degree;
/** Number of terms that contain this variable. */
unsigned_vector m_num_terms;
unsigned_vector m_num_uni;
numeral_vector m_coeffs;
imp(pmanager & _pm, atom_vector const & atoms, unsigned _num_vars, unsigned _vos_type):
pm(_pm),
m_atoms(atoms),
num_vars(_num_vars),
m_vos_type(Variable_Ordering_Strategy_Type(_vos_type)) {
m_max_degree.resize(num_vars, 0);
m_sum_poly_degree.resize(num_vars, 0);
m_num_polynomials.resize(num_vars, 0);
if (m_vos_type != ONLYPOLY) {
m_max_lc_degree.resize(num_vars, 0);
m_max_terms_tdegree.resize(num_vars, 0);
m_sum_term_degree.resize(num_vars, 0);
m_num_terms.resize(num_vars, 0);
m_num_uni.resize(num_vars, 0);
m_coeffs.resize(num_vars, 0);
}
}
void collect(monomial * m) {
unsigned mdeg = 0;
for (unsigned i = 0, sz = pm.size(m); i < sz; ++i) {
var x = pm.get_var(m, i);
mdeg += pm.degree_of(m, x);
++m_num_terms[x];
}
for (unsigned i = 0, sz = pm.size(m); i < sz; ++i) {
var x = pm.get_var(m, i);
m_sum_term_degree[x] += mdeg;
if (mdeg > m_max_terms_tdegree[x])
m_max_terms_tdegree[x] = mdeg;
unsigned lc_deg = mdeg - pm.degree_of(m, x);
if (lc_deg > m_max_lc_degree[x])
m_max_lc_degree[x] = lc_deg;
}
}
void collect(poly * p) {
var_vector vec_vars;
pm.vars(p, vec_vars);
if (m_vos_type == UNIVARIATE) {
if (vec_vars.size() == 1)
++m_num_uni[vec_vars[0]];
}
for (unsigned i = 0, sz = vec_vars.size(); i < sz; ++i) {
var x = vec_vars[i];
unsigned k = pm.degree(p, x);
++m_num_polynomials[x];
m_sum_poly_degree[x] += k;
if (k > m_max_degree[x])
m_max_degree[x] = k;
if (m_vos_type == FEATURE){
for (unsigned kl = 0; kl <= k; kl++) {
scoped_numeral curr(pm.m());
if (pm.const_coeff(p, x, kl, curr)) {
pm.m().abs(curr);
if (pm.m().gt(curr, m_coeffs[x])) {
pm.m().set(m_coeffs[x], curr);
}
}
}
}
}
if (m_vos_type != ONLYPOLY && m_vos_type != UNIVARIATE){
for (unsigned i = 0, sz = pm.size(p); i < sz; ++i) {
collect(pm.get_monomial(p, i));
}
}
}
void collect(literal l) {
bool_var b = l.var();
atom * a = m_atoms[b];
if (a == nullptr)
return;
if (a->is_ineq_atom()) {
unsigned sz = to_ineq_atom(a)->size();
for (unsigned i = 0; i < sz; i++) {
collect(to_ineq_atom(a)->p(i));
}
}
else {
collect(to_root_atom(a)->p());
}
}
void collect(clause const & c) {
unsigned sz = c.size();
for (unsigned i = 0; i < sz; i++)
collect(c[i]);
}
void collect(clause_vector const & cs) {
unsigned sz = cs.size();
for (unsigned i = 0; i < sz; i++)
collect(*(cs[i]));
}
struct univariate_reorder_lt {
VOS_Var_Info_Collector::imp const *m_info;
univariate_reorder_lt(VOS_Var_Info_Collector::imp const *info):m_info(info) {}
bool operator()(var x, var y) const {
if (m_info->m_num_uni[x] != m_info->m_num_uni[y])
return m_info->m_num_uni[x] > m_info->m_num_uni[y];
return x < y;
}
};
struct feature_reorder_lt {
VOS_Var_Info_Collector::imp const *m_info;
feature_reorder_lt(VOS_Var_Info_Collector::imp const * info): m_info(info){}
bool operator()(var x, var y) const {
if (m_info->m_max_degree[x] != m_info->m_max_degree[y])
return m_info->m_max_degree[x] > m_info->m_max_degree[y];
if (m_info->m_max_terms_tdegree[x] != m_info->m_max_terms_tdegree[y])
return m_info->m_max_terms_tdegree[x] > m_info->m_max_terms_tdegree[y];
if (!m_info->pm.m().eq(m_info->m_coeffs[x], m_info->m_coeffs[y])) {
return m_info->pm.m().lt(m_info->m_coeffs[x], m_info->m_coeffs[y]);
}
return x < y;
}
};
struct brown_reorder_lt {
VOS_Var_Info_Collector::imp const *m_info;
brown_reorder_lt(VOS_Var_Info_Collector::imp const *info):m_info(info) {}
bool operator()(var x, var y) const {
// if (a.max_degree != b.max_degree)
// return a.max_degree > b.max_degree;
// if (a.max_terms_tdegree != b.max_terms_tdegree)
// return a.max_terms_tdegree > b.max_terms_tdegree;
// return a.num_terms > b.num_terms;
if (m_info->m_max_degree[x] != m_info->m_max_degree[y])
return m_info->m_max_degree[x] > m_info->m_max_degree[y];
if (m_info->m_max_terms_tdegree[x] != m_info->m_max_terms_tdegree[y])
return m_info->m_max_terms_tdegree[x] > m_info->m_max_terms_tdegree[y];
if (m_info->m_num_terms[x] != m_info->m_num_terms[y])
return m_info->m_num_terms[x] > m_info->m_num_terms[y];
return x < y;
}
};
struct triangular_reorder_lt {
const VOS_Var_Info_Collector::imp *m_info;
triangular_reorder_lt(VOS_Var_Info_Collector::imp const *info):m_info(info) {}
bool operator()(var x, var y) const {
// if (a.max_degree != b.max_degree)
// return a.max_degree > b.max_degree;
// if (a.max_lc_degree != b.max_lc_degree)
// return a.max_lc_degree > b.max_lc_degree;
// return a.sum_poly_degree > b.sum_poly_degree;
if (m_info->m_max_degree[x] != m_info->m_max_degree[y])
return m_info->m_max_degree[x] > m_info->m_max_degree[y];
if (m_info->m_max_lc_degree[x] != m_info->m_max_lc_degree[y])
return m_info->m_max_lc_degree[x] > m_info->m_max_lc_degree[y];
if (m_info->m_sum_poly_degree[x] != m_info->m_sum_poly_degree[y])
return m_info->m_sum_poly_degree[x] > m_info->m_sum_poly_degree[y];
return x < y;
}
};
struct onlypoly_reorder_lt {
const VOS_Var_Info_Collector::imp *m_info;
onlypoly_reorder_lt(VOS_Var_Info_Collector::imp const *info):m_info(info) {}
bool operator()(var x, var y) const {
// high degree first
if (m_info->m_max_degree[x] != m_info->m_max_degree[y])
return m_info->m_max_degree[x] > m_info->m_max_degree[y];
//
if (m_info->m_sum_poly_degree[x] != m_info->m_sum_poly_degree[y])
return m_info->m_sum_poly_degree[x] > m_info->m_sum_poly_degree[y];
// more constrained first
if (m_info->m_num_polynomials[x] != m_info->m_num_polynomials[y])
return m_info->m_num_polynomials[x] > m_info->m_num_polynomials[y];
return x < y;
}
};
bool check_invariant() const {return true;} // what is the invariant
void operator()(var_vector &perm) {
var_vector new_order;
for (var x = 0; x < num_vars; x++) {
new_order.push_back(x);
}
if (m_vos_type == BROWN) {
std::sort(new_order.begin(), new_order.end(), brown_reorder_lt(this));
}
else if (m_vos_type == TRIANGULAR) {
std::sort(new_order.begin(), new_order.end(), triangular_reorder_lt(this));
}
else if (m_vos_type == ONLYPOLY) {
std::sort(new_order.begin(), new_order.end(), onlypoly_reorder_lt(this));
}
else if(m_vos_type == UNIVARIATE){
std::sort(new_order.begin(), new_order.end(), univariate_reorder_lt(this));
}
else if(m_vos_type == FEATURE){
std::sort(new_order.begin(), new_order.end(), feature_reorder_lt(this));
}
else {
UNREACHABLE();
}
TRACE("linxi_reorder",
tout << "new order: ";
for (unsigned i = 0; i < num_vars; i++)
tout << new_order[i] << " ";
tout << "\n";
);
perm.resize(num_vars, 0);
for (var x = 0; x < num_vars; x++) {
perm[new_order[x]] = x;
}
SASSERT(check_invariant());
}
// std::ostream& display(std::ostream & out, display_var_proc const & proc) {
// unsigned sz = m_num_occs.size();
// for (unsigned i = 0; i < sz; i++) {
// proc(out, i); out << " -> " << m_max_degree[i] << " : " << m_num_occs[i] << "\n";
// }
// return out;
// }
// std::ostream& display(std::ostream & out, display_var_proc const & proc) {
// for (unsigned i = 0; i < num_vars; ++i) {
// proc(out, i); out << " -> " << m_max_degree[i] << " : " << m_sum_poly_degree[i] << "\n";
// }
// return out;
// }
};
VOS_Var_Info_Collector::VOS_Var_Info_Collector(pmanager & _pm, atom_vector const & _atoms, unsigned _num_vars, unsigned _vos_type) {
m_imp = alloc(imp, _pm, _atoms, _num_vars, _vos_type);
}
VOS_Var_Info_Collector::~VOS_Var_Info_Collector() {
dealloc(m_imp);
}
void VOS_Var_Info_Collector::collect(clause_vector const & cs) {
m_imp->collect(cs);
}
void VOS_Var_Info_Collector::operator()(var_vector &perm) {
m_imp->operator()(perm);
}
}

View file

@ -0,0 +1,27 @@
#include "nlsat/nlsat_clause.h"
#include "math/polynomial/algebraic_numbers.h"
#include "math/polynomial/polynomial.h"
namespace nlsat {
typedef polynomial::manager::scoped_numeral scoped_numeral;
typedef polynomial::manager::numeral_vector numeral_vector;
// enum Variable_Ordering_Strategy_Type {NONE = 0, BROWN, TRIANGULAR, ONLYPOLY};
enum Variable_Ordering_Strategy_Type {NONE = 0, BROWN, TRIANGULAR, ONLYPOLY, UNIVARIATE, FEATURE, ROOT};
class VOS_Var_Info_Collector {
struct imp;
imp * m_imp;
public:
VOS_Var_Info_Collector(pmanager & _pm, atom_vector const & atoms, unsigned _num_vars, unsigned _vos_type);
~VOS_Var_Info_Collector();
void operator()(var_vector &perm);
void collect(clause_vector const & cs);
};
}

View file

@ -23,6 +23,8 @@ Notes:
#include "nlsat/tactic/qfnra_nlsat_tactic.h" #include "nlsat/tactic/qfnra_nlsat_tactic.h"
#include "tactic/smtlogics/smt_tactic.h" #include "tactic/smtlogics/smt_tactic.h"
#include "tactic/smtlogics/qflra_tactic.h"
static tactic * mk_qfnra_sat_solver(ast_manager& m, params_ref const& p, unsigned bv_size) { static tactic * mk_qfnra_sat_solver(ast_manager& m, params_ref const& p, unsigned bv_size) {
params_ref nra2sat_p = p; params_ref nra2sat_p = p;
nra2sat_p.set_uint("nla2bv_max_bv_size", p.get_uint("nla2bv_max_bv_size", bv_size)); nra2sat_p.set_uint("nla2bv_max_bv_size", p.get_uint("nla2bv_max_bv_size", bv_size));
@ -32,24 +34,305 @@ static tactic * mk_qfnra_sat_solver(ast_manager& m, params_ref const& p, unsigne
mk_fail_if_undecided_tactic()); mk_fail_if_undecided_tactic());
} }
tactic * mk_multilinear_ls_tactic(ast_manager & m, params_ref const & p, unsigned ls_time = 60) {
params_ref p_mls = p;
p_mls.set_bool("use_ls", true);
p_mls.set_uint("ls_time",ls_time);
return using_params(mk_smt_tactic(m), p_mls);
}
tactic * linxi_mk_qfnra_very_small_solver(ast_manager& m, params_ref const& p) {
ptr_vector<tactic> ts;
{
params_ref p_sc = p;
p_sc.set_bool("linxi_simple_check", true);
// p_sc.set_uint("seed", 997);
ts.push_back(try_for(and_then(mk_qfnra_nlsat_tactic(m, p_sc), mk_fail_if_undecided_tactic()), 10 * 1000));
}
{
params_ref p_heuristic = p;
// p_heuristic.set_uint("seed", 233);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_heuristic), 4 * 1000));
params_ref p_order_4 = p;
p_order_4.set_uint("linxi_variable_ordering_strategy", 4);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_4), 4 * 1000));
params_ref p_order_3 = p;
p_order_3.set_uint("linxi_variable_ordering_strategy", 3);
// p_order_3.set_uint("seed", 17);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_3), 6 * 1000));
params_ref p_order_1 = p;
p_order_1.set_uint("linxi_variable_ordering_strategy", 1);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_1), 8 * 1000));
params_ref p_order_5 = p;
p_order_5.set_uint("linxi_variable_ordering_strategy", 5);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_5), 8 * 1000));
params_ref p_order_2 = p;
p_order_2.set_uint("linxi_variable_ordering_strategy", 2);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_2), 10 * 1000));
}
{
ts.push_back(mk_multilinear_ls_tactic(m, p, 60));
}
{
params_ref p_l = p;
p_l.set_bool("arith.greatest_error_pivot", true);
ts.push_back(and_then(try_for(using_params(mk_smt_tactic(m), p_l), 300 * 1000), mk_fail_if_undecided_tactic()));
}
for (unsigned i = 0; i < 200; ++i) { // 3s * 200 = 600s
params_ref p_i = p;
p_i.set_uint("seed", i);
p_i.set_bool("shuffle_vars", true);
// if ((i & 1) == 0)
// p_i.set_bool("randomize", false);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_i), 3 * 1000));
}
{
ts.push_back(mk_qfnra_nlsat_tactic(m, p));
}
return or_else(ts.size(), ts.data());
}
tactic * linxi_mk_qfnra_small_solver(ast_manager& m, params_ref const& p) {
ptr_vector<tactic> ts;
{
params_ref p_sc = p;
p_sc.set_bool("linxi_simple_check", true);
// p_sc.set_uint("seed", 997);
ts.push_back(try_for(and_then(mk_qfnra_nlsat_tactic(m, p_sc), mk_fail_if_undecided_tactic()), 20 * 1000));
}
{
params_ref p_heuristic = p;
// p_heuristic.set_uint("seed", 233);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_heuristic), 5 * 1000));
params_ref p_order_4 = p;
p_order_4.set_uint("linxi_variable_ordering_strategy", 4);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_4), 5 * 1000));
params_ref p_order_3 = p;
p_order_3.set_uint("linxi_variable_ordering_strategy", 3);
// p_order_3.set_uint("seed", 17);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_3), 10 * 1000));
params_ref p_order_1 = p;
p_order_1.set_uint("linxi_variable_ordering_strategy", 1);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_1), 15 * 1000));
params_ref p_order_5 = p;
p_order_5.set_uint("linxi_variable_ordering_strategy", 5);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_5), 15 * 1000));
params_ref p_order_2 = p;
p_order_2.set_uint("linxi_variable_ordering_strategy", 2);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_2), 20 * 1000));
}
{
ts.push_back(mk_multilinear_ls_tactic(m, p, 70));
}
{
params_ref p_l = p;
p_l.set_bool("arith.greatest_error_pivot", true);
ts.push_back(and_then(try_for(using_params(mk_smt_tactic(m), p_l), 350 * 1000), mk_fail_if_undecided_tactic()));
}
for (unsigned i = 0; i < 100; ++i) { // 5s * 100 = 500s
params_ref p_i = p;
p_i.set_uint("seed", i);
p_i.set_bool("shuffle_vars", true);
// if ((i & 1) == 0)
// p_i.set_bool("randomize", false);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_i), 5 * 1000));
}
{
ts.push_back(mk_qfnra_nlsat_tactic(m, p));
}
return or_else(ts.size(), ts.data());
}
tactic * linxi_mk_qfnra_middle_solver(ast_manager& m, params_ref const& p) {
ptr_vector<tactic> ts;
{
params_ref p_sc = p;
p_sc.set_bool("linxi_simple_check", true);
// p_sc.set_uint("seed", 997);
ts.push_back(try_for(and_then(mk_qfnra_nlsat_tactic(m, p_sc), mk_fail_if_undecided_tactic()), 30 * 1000));
}
{
params_ref p_heuristic = p;
// p_heuristic.set_uint("seed", 233);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_heuristic), 10 * 1000));
params_ref p_order_4 = p;
p_order_4.set_uint("linxi_variable_ordering_strategy", 4);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_4), 15 * 1000));
params_ref p_order_3 = p;
p_order_3.set_uint("linxi_variable_ordering_strategy", 3);
// p_order_3.set_uint("seed", 17);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_3), 15 * 1000));
params_ref p_order_1 = p;
p_order_1.set_uint("linxi_variable_ordering_strategy", 1);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_1), 20 * 1000));
params_ref p_order_5 = p;
p_order_5.set_uint("linxi_variable_ordering_strategy", 5);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_5), 20 * 1000));
params_ref p_order_2 = p;
p_order_2.set_uint("linxi_variable_ordering_strategy", 2);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_2), 25 * 1000));
}
{
ts.push_back(mk_multilinear_ls_tactic(m, p, 80));
}
{
params_ref p_l = p;
p_l.set_bool("arith.greatest_error_pivot", true);
ts.push_back(and_then(try_for(using_params(mk_smt_tactic(m), p_l), 375 * 1000), mk_fail_if_undecided_tactic()));
}
for (unsigned i = 0; i < 40; ++i) { // 10s * 40 = 400s
params_ref p_i = p;
p_i.set_uint("seed", i);
p_i.set_bool("shuffle_vars", true);
// if ((i & 1) == 0)
// p_i.set_bool("randomize", false);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_i), 10 * 1000));
}
{
ts.push_back(mk_qfnra_nlsat_tactic(m, p));
}
return or_else(ts.size(), ts.data());
}
tactic * linxi_mk_qfnra_large_solver(ast_manager& m, params_ref const& p) {
ptr_vector<tactic> ts;
{
params_ref p_sc = p;
p_sc.set_bool("linxi_simple_check", true);
// p_sc.set_uint("seed", 997);
ts.push_back(try_for(and_then(mk_qfnra_nlsat_tactic(m, p_sc), mk_fail_if_undecided_tactic()), 50 * 1000));
}
{
params_ref p_order_4 = p;
p_order_4.set_uint("linxi_variable_ordering_strategy", 4);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_4), 15 * 1000));
params_ref p_order_3 = p;
p_order_3.set_uint("linxi_variable_ordering_strategy", 3);
// p_order_3.set_uint("seed", 17);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_3), 30 * 1000));
params_ref p_order_1 = p;
p_order_1.set_uint("linxi_variable_ordering_strategy", 1);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_1), 40 * 1000));
params_ref p_order_5 = p;
p_order_5.set_uint("linxi_variable_ordering_strategy", 5);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_5), 40 * 1000));
params_ref p_order_2 = p;
p_order_2.set_uint("linxi_variable_ordering_strategy", 2);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_2), 50 * 1000));
}
{
ts.push_back(mk_multilinear_ls_tactic(m, p, 90));
}
{
params_ref p_l = p;
p_l.set_bool("arith.greatest_error_pivot", true);
ts.push_back(and_then(try_for(using_params(mk_smt_tactic(m), p_l), 400 * 1000), mk_fail_if_undecided_tactic()));
}
for (unsigned i = 0; i < 10; ++i) { // 20s * 10 = 200s
params_ref p_i = p;
p_i.set_uint("seed", i);
p_i.set_bool("shuffle_vars", true);
// if ((i & 1) == 0)
// p_i.set_bool("randomize", false);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_i), 20 * 1000));
}
{
ts.push_back(mk_qfnra_nlsat_tactic(m, p));
}
return or_else(ts.size(), ts.data());
}
tactic * linxi_mk_qfnra_very_large_solver(ast_manager& m, params_ref const& p) {
ptr_vector<tactic> ts;
{
params_ref p_sc = p;
p_sc.set_bool("linxi_simple_check", true);
// p_sc.set_uint("seed", 997);
ts.push_back(try_for(and_then(mk_qfnra_nlsat_tactic(m, p_sc), mk_fail_if_undecided_tactic()), 100 * 1000));
}
{
params_ref p_order_1 = p;
p_order_1.set_uint("linxi_variable_ordering_strategy", 1);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_1), 80 * 1000));
params_ref p_order_5 = p;
p_order_5.set_uint("linxi_variable_ordering_strategy", 5);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_5), 80 * 1000));
params_ref p_order_2 = p;
p_order_2.set_uint("linxi_variable_ordering_strategy", 2);
ts.push_back(try_for(mk_qfnra_nlsat_tactic(m, p_order_2), 100 * 1000));
}
{
ts.push_back(mk_multilinear_ls_tactic(m, p, 100));
}
{
params_ref p_l = p;
p_l.set_bool("arith.greatest_error_pivot", true);
ts.push_back(and_then(try_for(using_params(mk_smt_tactic(m), p_l), 425 * 1000), mk_fail_if_undecided_tactic()));
}
{
ts.push_back(mk_qfnra_nlsat_tactic(m, p));
}
return or_else(ts.size(), ts.data());
}
const double VERY_SMALL_THRESHOLD = 30.0;
const double SMALL_THRESHOLD = 80.0;
const double MIDDLE_THRESHOLD = 300.0;
const double LARGE_THRESHOLD = 600.0;
tactic * linxi_mk_qfnra_mixed_solver(ast_manager& m, params_ref const& p) {
return cond(mk_lt(mk_memory_probe(), mk_const_probe(VERY_SMALL_THRESHOLD)),
linxi_mk_qfnra_very_small_solver(m, p),
cond(mk_lt(mk_memory_probe(), mk_const_probe(SMALL_THRESHOLD)),
linxi_mk_qfnra_small_solver(m, p),
cond(mk_lt(mk_memory_probe(), mk_const_probe(MIDDLE_THRESHOLD)),
linxi_mk_qfnra_middle_solver(m, p),
cond(mk_lt(mk_memory_probe(), mk_const_probe(LARGE_THRESHOLD)),
linxi_mk_qfnra_large_solver(m, p),
linxi_mk_qfnra_very_large_solver(m, p)
)
)
)
);
}
tactic * mk_qfnra_tactic(ast_manager & m, params_ref const& p) { tactic * mk_qfnra_tactic(ast_manager & m, params_ref const& p) {
params_ref p0 = p;
p0.set_bool("inline_vars", true);
params_ref p1 = p;
p1.set_uint("seed", 11);
p1.set_bool("factor", false);
params_ref p2 = p;
p2.set_uint("seed", 13);
p2.set_bool("factor", false);
return and_then(mk_simplify_tactic(m, p), return and_then(mk_simplify_tactic(m, p),
mk_propagate_values_tactic(m, p), mk_propagate_values_tactic(m, p),
or_else(try_for(mk_qfnra_nlsat_tactic(m, p0), 5000), // mk_multilinear_ls_tactic(m, p)
try_for(mk_qfnra_nlsat_tactic(m, p1), 10000), linxi_mk_qfnra_mixed_solver(m, p)
mk_qfnra_sat_solver(m, p, 4), );
and_then(try_for(mk_smt_tactic(m), 5000), mk_fail_if_undecided_tactic()),
mk_qfnra_sat_solver(m, p, 6),
mk_qfnra_nlsat_tactic(m, p2)));
} }