mirror of
https://github.com/Z3Prover/z3
synced 2025-11-03 13:07:53 +00:00
* Introduce X-macro-based trace tag definition - Created trace_tags.def to centralize TRACE tag definitions - Each tag includes a symbolic name and description - Set up enum class TraceTag for type-safe usage in TRACE macros * Add script to generate Markdown documentation from trace_tags.def - Python script parses trace_tags.def and outputs trace_tags.md * Refactor TRACE_NEW to prepend TraceTag and pass enum to is_trace_enabled * trace: improve trace tag handling system with hierarchical tagging - Introduce hierarchical tag-class structure: enabling a tag class activates all child tags - Unify TRACE, STRACE, SCTRACE, and CTRACE under enum TraceTag - Implement initial version of trace_tag.def using X(tag, tag_class, description) (class names and descriptions to be refined in a future update) * trace: replace all string-based TRACE tags with enum TraceTag - Migrated all TRACE, STRACE, SCTRACE, and CTRACE macros to use enum TraceTag values instead of raw string literals * trace : add cstring header * trace : Add Markdown documentation generation from trace_tags.def via mk_api_doc.py * trace : rename macro parameter 'class' to 'tag_class' and remove Unicode comment in trace_tags.h. * trace : Add TODO comment for future implementation of tag_class activation * trace : Disable code related to tag_class until implementation is ready (#7663).
282 lines
12 KiB
C++
282 lines
12 KiB
C++
#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(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);
|
|
}
|
|
}
|