mirror of
https://github.com/Z3Prover/z3
synced 2025-06-02 20:31:21 +00:00
adding factorization
This commit is contained in:
parent
a352a6638a
commit
c2b353ba72
2 changed files with 86 additions and 1 deletions
|
@ -30,6 +30,8 @@ namespace dd {
|
||||||
m_dmark_level = 0;
|
m_dmark_level = 0;
|
||||||
m_disable_gc = false;
|
m_disable_gc = false;
|
||||||
m_is_new_node = false;
|
m_is_new_node = false;
|
||||||
|
if (s == mod2N_e && power_of_2 == 1)
|
||||||
|
s = mod2_e;
|
||||||
m_semantics = s;
|
m_semantics = s;
|
||||||
m_mod2N = rational::power_of_two(power_of_2);
|
m_mod2N = rational::power_of_two(power_of_2);
|
||||||
m_power_of_2 = power_of_2;
|
m_power_of_2 = power_of_2;
|
||||||
|
@ -685,12 +687,61 @@ namespace dd {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* factor p into lc*v^degree + rest
|
||||||
|
* such that degree(rest, v) < degree
|
||||||
|
* Initial implementation is very naive
|
||||||
|
* - memoize intermediary results
|
||||||
|
*/
|
||||||
|
void pdd_manager::factor(pdd const& p, unsigned v, unsigned degree, pdd& lc, pdd& rest) {
|
||||||
|
unsigned level_v = m_var2level[v];
|
||||||
|
if (degree == 0) {
|
||||||
|
lc = p;
|
||||||
|
rest = zero();
|
||||||
|
}
|
||||||
|
else if (level(p.root) < level_v) {
|
||||||
|
lc = zero();
|
||||||
|
rest = p;
|
||||||
|
}
|
||||||
|
else if (level(p.root) > level_v) {
|
||||||
|
pdd lc1 = zero(), rest1 = zero();
|
||||||
|
pdd vv = mk_var(p.var());
|
||||||
|
factor(p.hi(), v, degree, lc, rest);
|
||||||
|
factor(p.lo(), v, degree, lc1, rest1);
|
||||||
|
lc += lc1;
|
||||||
|
rest += rest1;
|
||||||
|
lc *= vv;
|
||||||
|
rest *= vv;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
unsigned d = 0;
|
||||||
|
pdd r = p;
|
||||||
|
while (d < degree && !r.is_val() && level(r.root) == level_v) {
|
||||||
|
d++;
|
||||||
|
r = r.hi();
|
||||||
|
}
|
||||||
|
if (d == degree) {
|
||||||
|
lc = r;
|
||||||
|
r = p;
|
||||||
|
rest = zero();
|
||||||
|
pdd pow = one();
|
||||||
|
for (unsigned i = 0; i < degree; r = r.hi(), pow *= mk_var(v), ++i)
|
||||||
|
rest += pow * r.lo();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lc = zero();
|
||||||
|
rest = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool pdd_manager::is_linear(pdd const& p) {
|
bool pdd_manager::is_linear(pdd const& p) {
|
||||||
return is_linear(p.root);
|
return is_linear(p.root);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Determine whether p is a binary polynomials
|
Determine whether p is a binary polynomial
|
||||||
of the form v1, x*v1 + v2, or x*v1 + y*v2 + v3
|
of the form v1, x*v1 + v2, or x*v1 + y*v2 + v3
|
||||||
where v1, v2 are values.
|
where v1, v2 are values.
|
||||||
*/
|
*/
|
||||||
|
@ -952,6 +1003,35 @@ namespace dd {
|
||||||
return m_degree[p];
|
return m_degree[p];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned pdd_manager::degree(PDD p, unsigned v) {
|
||||||
|
init_mark();
|
||||||
|
unsigned level_v = level(v);
|
||||||
|
unsigned max_d = 0, d = 0;
|
||||||
|
m_todo.push_back(p);
|
||||||
|
while (!m_todo.empty()) {
|
||||||
|
PDD r = m_todo.back();
|
||||||
|
if (is_marked(r))
|
||||||
|
m_todo.pop_back();
|
||||||
|
else if (is_val(r))
|
||||||
|
m_todo.pop_back();
|
||||||
|
else if (level(r) < level_v)
|
||||||
|
m_todo.pop_back();
|
||||||
|
else if (level(r) == level_v) {
|
||||||
|
d = 1;
|
||||||
|
while (!is_val(hi(r)) && level(hi(r)) == level_v) {
|
||||||
|
++d;
|
||||||
|
r = hi(r);
|
||||||
|
}
|
||||||
|
max_d = std::max(d, max_d);
|
||||||
|
m_todo.pop_back();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_todo.push_back(lo(r)).push_back(hi(r));
|
||||||
|
}
|
||||||
|
return max_d;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
double pdd_manager::tree_size(pdd const& p) {
|
double pdd_manager::tree_size(pdd const& p) {
|
||||||
init_mark();
|
init_mark();
|
||||||
|
|
|
@ -225,6 +225,9 @@ namespace dd {
|
||||||
bool is_dmarked(unsigned i) const { return m_dmark[i] == m_dmark_level; }
|
bool is_dmarked(unsigned i) const { return m_dmark[i] == m_dmark_level; }
|
||||||
unsigned degree(pdd const& p) const;
|
unsigned degree(pdd const& p) const;
|
||||||
unsigned degree(PDD p) const;
|
unsigned degree(PDD p) const;
|
||||||
|
unsigned degree(PDD p, unsigned v);
|
||||||
|
|
||||||
|
void factor(pdd const& p, unsigned v, unsigned degree, pdd& lc, pdd& rest);
|
||||||
|
|
||||||
bool var_is_leaf(PDD p, unsigned v);
|
bool var_is_leaf(PDD p, unsigned v);
|
||||||
|
|
||||||
|
@ -358,6 +361,7 @@ namespace dd {
|
||||||
pdd rev_sub(rational const& r) const { return m.sub(m.mk_val(r), *this); }
|
pdd rev_sub(rational const& r) const { return m.sub(m.mk_val(r), *this); }
|
||||||
pdd reduce(pdd const& other) const { return m.reduce(*this, other); }
|
pdd reduce(pdd const& other) const { return m.reduce(*this, other); }
|
||||||
bool different_leading_term(pdd const& other) const { return m.different_leading_term(*this, other); }
|
bool different_leading_term(pdd const& other) const { return m.different_leading_term(*this, other); }
|
||||||
|
void factor(unsigned v, unsigned degree, pdd& lc, pdd& rest) { m.factor(*this, v, degree, lc, rest); }
|
||||||
|
|
||||||
pdd subst_val(vector<std::pair<unsigned, rational>> const& s) const { return m.subst_val(*this, s); }
|
pdd subst_val(vector<std::pair<unsigned, rational>> const& s) const { return m.subst_val(*this, s); }
|
||||||
pdd subst_val(unsigned v, rational const& val) const { return m.subst_val(*this, v, val); }
|
pdd subst_val(unsigned v, rational const& val) const { return m.subst_val(*this, v, val); }
|
||||||
|
@ -371,6 +375,7 @@ namespace dd {
|
||||||
unsigned dag_size() const { return m.dag_size(*this); }
|
unsigned dag_size() const { return m.dag_size(*this); }
|
||||||
double tree_size() const { return m.tree_size(*this); }
|
double tree_size() const { return m.tree_size(*this); }
|
||||||
unsigned degree() const { return m.degree(*this); }
|
unsigned degree() const { return m.degree(*this); }
|
||||||
|
unsigned degree(unsigned v) const { return m.degree(root, v); }
|
||||||
unsigned_vector const& free_vars() const { return m.free_vars(*this); }
|
unsigned_vector const& free_vars() const { return m.free_vars(*this); }
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue