mirror of
https://github.com/Z3Prover/z3
synced 2025-06-22 22:03:39 +00:00
add tuned implementation
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
78b022491d
commit
6ad55cc8f6
4 changed files with 230 additions and 23 deletions
|
@ -362,6 +362,13 @@ namespace dd {
|
|||
}
|
||||
}
|
||||
|
||||
// a = s*x + t, where s is a constant, b = u*x + v, where u is a constant.
|
||||
// since x is the maximal variable, it does not occur in t or v.
|
||||
// thus, both a and b are linear in x
|
||||
bool pdd_manager::spoly_is_invertible(pdd const& a, pdd const& b) {
|
||||
return a.is_var() && b.is_var() && a.hi().is_val() && b.hi().is_val() && a.var() == b.var();
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare leading monomials.
|
||||
* The pdd format makes lexicographic comparison easy: compare based on
|
||||
|
@ -609,6 +616,38 @@ namespace dd {
|
|||
return m_tree_size[p.root];
|
||||
}
|
||||
|
||||
unsigned_vector const& pdd_manager::free_vars(pdd const& p) {
|
||||
return free_vars_except(p, zero());
|
||||
}
|
||||
|
||||
unsigned_vector const& pdd_manager::free_vars_except(pdd const& p, pdd const& q) {
|
||||
init_mark();
|
||||
m_free_vars.reset();
|
||||
m_todo.push_back(q.root);
|
||||
while (!m_todo.empty()) {
|
||||
PDD r = m_todo.back();
|
||||
m_todo.pop_back();
|
||||
if (is_val(r) || is_marked(r)) continue;
|
||||
set_mark(r);
|
||||
set_mark(m_var2pdd[var(r)]);
|
||||
if (!is_marked(lo(r))) m_todo.push_back(lo(r));
|
||||
if (!is_marked(hi(r))) m_todo.push_back(hi(r));
|
||||
}
|
||||
m_todo.push_back(p.root);
|
||||
while (!m_todo.empty()) {
|
||||
PDD r = m_todo.back();
|
||||
m_todo.pop_back();
|
||||
if (is_val(r) || is_marked(r)) continue;
|
||||
PDD v = m_var2pdd[var(r)];
|
||||
if (!is_marked(v)) m_free_vars.push_back(var(r));
|
||||
set_mark(r);
|
||||
set_mark(v);
|
||||
if (!is_marked(lo(r))) m_todo.push_back(lo(r));
|
||||
if (!is_marked(hi(r))) m_todo.push_back(hi(r));
|
||||
}
|
||||
return m_free_vars;
|
||||
}
|
||||
|
||||
|
||||
void pdd_manager::alloc_free_nodes(unsigned n) {
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
|
|
|
@ -148,6 +148,7 @@ namespace dd {
|
|||
bool m_is_new_node;
|
||||
unsigned m_max_num_pdd_nodes;
|
||||
bool m_mod2_semantics;
|
||||
unsigned_vector m_free_vars;
|
||||
|
||||
PDD make_node(unsigned level, PDD l, PDD r);
|
||||
PDD insert_node(pdd_node const& n);
|
||||
|
@ -221,7 +222,7 @@ namespace dd {
|
|||
|
||||
void set_mod2_semantics() { m_mod2_semantics = true; }
|
||||
void set_max_num_nodes(unsigned n) { m_max_num_pdd_nodes = n; }
|
||||
void set_var_order(unsigned_vector const& levels); // TBD: set variable order (m_var2level, m_level2var) before doing anything else.
|
||||
void set_var_order(unsigned_vector const& levels); // TBD: set variable order (m_var2level, m_level2var) before doing anything else.
|
||||
|
||||
pdd mk_var(unsigned i);
|
||||
pdd mk_val(rational const& r);
|
||||
|
@ -234,11 +235,19 @@ namespace dd {
|
|||
pdd mul(pdd const& a, pdd const& b);
|
||||
pdd mul(rational const& c, pdd const& b);
|
||||
pdd reduce(pdd const& a, pdd const& b);
|
||||
|
||||
// create an spoly r if leading monomials of a and b overlap
|
||||
bool try_spoly(pdd const& a, pdd const& b, pdd& r);
|
||||
|
||||
// true if b can be computed using a and the result of spoly
|
||||
bool spoly_is_invertible(pdd const& a, pdd const& b);
|
||||
bool lt(pdd const& a, pdd const& b);
|
||||
bool different_leading_term(pdd const& a, pdd const& b);
|
||||
double tree_size(pdd const& p);
|
||||
|
||||
unsigned_vector const& free_vars(pdd const& p);
|
||||
unsigned_vector const& free_vars_except(pdd const& p, pdd const& q);
|
||||
|
||||
std::ostream& display(std::ostream& out);
|
||||
std::ostream& display(std::ostream& out, pdd const& b);
|
||||
|
||||
|
@ -260,6 +269,7 @@ namespace dd {
|
|||
pdd hi() const { return pdd(m->hi(root), m); }
|
||||
unsigned var() const { return m->var(root); }
|
||||
rational const& val() const { SASSERT(is_val()); return m->val(root); }
|
||||
bool is_var() const { return !m->is_val(root); }
|
||||
bool is_val() const { return m->is_val(root); }
|
||||
bool is_zero() const { return m->is_zero(root); }
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue