3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-28 19:35:50 +00:00

Polysat: add two more prototype rules (#5355)

* Add try_div to PDDs

* x>y is false when x==y

* First version of the other two prototype rules

* More band-aid fixes...
This commit is contained in:
Jakob Rath 2021-06-18 17:48:50 +02:00 committed by GitHub
parent 3e1cfcd538
commit c4963f4381
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 239 additions and 17 deletions

View file

@ -461,10 +461,17 @@ namespace dd {
* But such a multiplication would create nodes with non-integral coefficients.
*/
pdd pdd_manager::div(pdd const& a, rational const& c) {
pdd res(zero_pdd, this);
VERIFY(try_div(a, c, res));
return res;
}
bool pdd_manager::try_div(pdd const& a, rational const& c, pdd& out_result) {
if (m_semantics == free_e) {
// Don't cache separately for the free semantics;
// use 'mul' so we can share results for a/c and a*(1/c).
return mul(inv(c), a);
out_result = mul(inv(c), a);
return true;
}
SASSERT(c.is_int());
bool first = true;
@ -472,7 +479,11 @@ namespace dd {
scoped_push _sp(*this);
while (true) {
try {
return pdd(div_rec(a.root, c, null_pdd), this);
PDD res = div_rec(a.root, c, null_pdd);
if (res != null_pdd)
out_result = pdd(res, this);
SASSERT(well_formed());
return res != null_pdd;
}
catch (const mem_out &) {
try_gc();
@ -480,10 +491,9 @@ namespace dd {
first = false;
}
}
SASSERT(well_formed());
return pdd(zero_pdd, this);
}
/// Returns null_pdd if one of the coefficients is not divisible by c.
pdd_manager::PDD pdd_manager::div_rec(PDD a, rational const& c, PDD c_pdd) {
SASSERT(m_semantics != free_e);
SASSERT(c.is_int());
@ -491,8 +501,10 @@ namespace dd {
return zero_pdd;
if (is_val(a)) {
rational r = val(a) / c;
SASSERT(r.is_int());
return imk_val(r);
if (r.is_int())
return imk_val(r);
else
return null_pdd;
}
if (c_pdd == null_pdd)
c_pdd = imk_val(c);
@ -502,10 +514,14 @@ namespace dd {
return e2->m_result;
push(div_rec(lo(a), c, c_pdd));
push(div_rec(hi(a), c, c_pdd));
PDD r = make_node(level(a), read(2), read(1));
PDD l = read(2);
PDD h = read(1);
PDD res = null_pdd;
if (l != null_pdd && h != null_pdd)
res = make_node(level(a), l, h);
pop(2);
e1->m_result = r;
return r;
e1->m_result = res;
return res;
}
pdd pdd_manager::pow(pdd const &p, unsigned j) {

View file

@ -322,6 +322,7 @@ namespace dd {
pdd mul(pdd const& a, pdd const& b);
pdd mul(rational const& c, pdd const& b);
pdd div(pdd const& a, rational const& c);
bool try_div(pdd const& a, rational const& c, pdd& out_result);
pdd mk_or(pdd const& p, pdd const& q);
pdd mk_xor(pdd const& p, pdd const& q);
pdd mk_xor(pdd const& p, unsigned q);
@ -408,6 +409,7 @@ namespace dd {
pdd operator~() const { return m.mk_not(*this); }
pdd rev_sub(rational const& r) const { return m.sub(m.mk_val(r), *this); }
pdd div(rational const& other) const { return m.div(*this, other); }
bool try_div(rational const& other, pdd& out_result) const { return m.try_div(*this, other, out_result); }
pdd pow(unsigned j) const { return m.pow(*this, j); }
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); }