mirror of
https://github.com/Z3Prover/z3
synced 2025-04-26 18:45:33 +00:00
adding Boolean propagation, watch; and factoring
This commit is contained in:
parent
f01da40e49
commit
fa3886136b
15 changed files with 341 additions and 134 deletions
|
@ -914,14 +914,10 @@ namespace dd {
|
|||
bool pdd_manager::resolve(unsigned v, pdd const& p, pdd const& q, pdd& r) {
|
||||
unsigned const l = p.degree(v);
|
||||
unsigned const m = q.degree(v);
|
||||
if (l < m) {
|
||||
// no reduction
|
||||
// no reduction
|
||||
if (l < m || m == 0)
|
||||
return false;
|
||||
}
|
||||
if (m == 0) {
|
||||
// no reduction (result would still contain v^l)
|
||||
return false;
|
||||
}
|
||||
|
||||
pdd a = zero();
|
||||
pdd b = zero();
|
||||
pdd c = zero();
|
||||
|
@ -938,6 +934,100 @@ namespace dd {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduce polynomial a with respect to b by eliminating terms using v
|
||||
*
|
||||
* a := a1*v^l + a2
|
||||
* b := b1*v^m + b2
|
||||
* l >= m
|
||||
* q, r := quot_rem(a1, b1)
|
||||
* r = 0
|
||||
* result := reduce(v, q*b2*v^{l-m}, b) + reduce(v, a2, b)
|
||||
*/
|
||||
pdd pdd_manager::reduce(unsigned v, pdd const& a, pdd const& b) {
|
||||
unsigned const l = a.degree(v);
|
||||
unsigned const m = b.degree(v);
|
||||
// no reduction
|
||||
if (l < m || m == 0)
|
||||
return a;
|
||||
|
||||
pdd a1 = zero();
|
||||
pdd a2 = zero();
|
||||
pdd b1 = zero();
|
||||
pdd b2 = zero();
|
||||
pdd q = zero();
|
||||
pdd r = zero();
|
||||
a.factor(v, l, a1, a2);
|
||||
b.factor(v, m, b1, b2);
|
||||
|
||||
quot_rem(a1, b1, q, r);
|
||||
if (r.is_zero()) {
|
||||
std::cout << a1 << " " << b1 << " " << q << "\n";
|
||||
SASSERT(q * b1 == a1);
|
||||
a1 = -q * pow(mk_var(v), l - m) * b2;
|
||||
if (l > m)
|
||||
a1 = reduce(v, a1, b);
|
||||
}
|
||||
else
|
||||
a1 = a1 * pow(mk_var(v), l);
|
||||
a2 = a2.reduce(v, b);
|
||||
|
||||
pdd result = a1 + a2;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* quotient/remainder of 'a' divided by 'b'
|
||||
* a := x*hi + lo
|
||||
* x > level(b):
|
||||
* hi = q1*b + r1
|
||||
* lo = q2*b + r2
|
||||
* x*hi + lo = (x*q1 + q2)*b + (x*r1 + r2)
|
||||
* q := x*q1 + q2
|
||||
* r := x*r1 + r2
|
||||
* Some special cases.
|
||||
* General multi-variable polynomial division is TBD.
|
||||
*/
|
||||
void pdd_manager::quot_rem(pdd const& a, pdd const& b, pdd& q, pdd& r) {
|
||||
if (level(a.root) > level(b.root)) {
|
||||
pdd q1(*this), q2(*this), r1(*this), r2(*this);
|
||||
quot_rem(a.hi(), b, q1, r1);
|
||||
quot_rem(a.lo(), b, q2, r2);
|
||||
q = mk_var(a.var()) * q1 + q2;
|
||||
r = mk_var(a.var()) * r1 + r2;
|
||||
}
|
||||
else if (level(a.root) < level(b.root)) {
|
||||
q = zero();
|
||||
r = a;
|
||||
}
|
||||
else if (a == b) {
|
||||
q = one();
|
||||
r = zero();
|
||||
}
|
||||
else if (a.is_val() && b.is_val() && divides(b.val(), a.val())) {
|
||||
q = mk_val(a.val() / b.val());
|
||||
r = zero();
|
||||
}
|
||||
else if (a.is_val() || b.is_val()) {
|
||||
q = zero();
|
||||
r = a;
|
||||
}
|
||||
else {
|
||||
SASSERT(level(a.root) == level(b.root));
|
||||
pdd q1(*this), q2(*this), r1(*this), r2(*this);
|
||||
quot_rem(a.hi(), b.hi(), q1, r1);
|
||||
quot_rem(a.lo(), b.lo(), q2, r2);
|
||||
if (q1 == q2 && r1.is_zero() && r2.is_zero()) {
|
||||
q = q1;
|
||||
r = zero();
|
||||
}
|
||||
else {
|
||||
q = zero();
|
||||
r = a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the largest j such that 2^j divides p.
|
||||
*/
|
||||
|
|
|
@ -23,6 +23,11 @@ Abstract:
|
|||
|
||||
- try_spoly(a, b, c) returns true if lt(a) and lt(b) have a non-trivial overlap. c is the resolvent (S polynomial).
|
||||
|
||||
- reduce(v, a, b) reduces 'a' using b = 0 with respect to eliminating v.
|
||||
Given b = v^l*b1 + b2, where l is the leading coefficient of v in b
|
||||
Given a = v^m*a1 + b2, where m >= l is the leading coefficient of v in b.
|
||||
reduce(a1, b1)*v^{m - l} + reduce(v, a2, b);
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2019-12-17
|
||||
|
@ -333,6 +338,8 @@ namespace dd {
|
|||
pdd subst_val(pdd const& a, vector<std::pair<unsigned, rational>> const& s);
|
||||
pdd subst_val(pdd const& a, unsigned v, rational const& val);
|
||||
bool resolve(unsigned v, pdd const& p, pdd const& q, pdd& r);
|
||||
pdd reduce(unsigned v, pdd const& a, pdd const& b);
|
||||
void quot_rem(pdd const& a, pdd const& b, pdd& q, pdd& r);
|
||||
pdd pow(pdd const& p, unsigned j);
|
||||
|
||||
bool is_linear(PDD p) { return degree(p) == 1; }
|
||||
|
@ -419,6 +426,7 @@ namespace dd {
|
|||
void factor(unsigned v, unsigned degree, pdd& lc, pdd& rest) const { m.factor(*this, v, degree, lc, rest); }
|
||||
bool factor(unsigned v, unsigned degree, pdd& lc) const { return m.factor(*this, v, degree, lc); }
|
||||
bool resolve(unsigned v, pdd const& other, pdd& result) { return m.resolve(v, *this, other, result); }
|
||||
pdd reduce(unsigned v, pdd const& other) const { return m.reduce(v, *this, other); }
|
||||
|
||||
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); }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue