3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-06 14:13:23 +00:00

fixes to fixed

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2024-08-26 18:42:32 -07:00
parent 9fcddc5774
commit 6488e33915
2 changed files with 73 additions and 70 deletions

View file

@ -363,13 +363,13 @@ namespace bv {
break; break;
} }
case OP_CONCAT: { case OP_CONCAT: {
SASSERT(e->get_num_args() == 2); unsigned bw = 0;
auto const& a = wval(e->get_arg(0)); for (unsigned i = e->get_num_args(); i-- > 0; ) {
auto const& b = wval(e->get_arg(1)); auto const& a = wval(e->get_arg(i));
for (unsigned i = 0; i < b.bw; ++i) for (unsigned j = 0; j < a.bw; ++j)
val.eval.set(i, b.get_bit(i)); val.eval.set(j + bw, a.get_bit(j));
for (unsigned i = 0; i < a.bw; ++i) bw += a.bw;
val.eval.set(i + b.bw, a.get_bit(i)); }
break; break;
} }
case OP_EXTRACT: { case OP_EXTRACT: {

View file

@ -340,85 +340,88 @@ namespace bv {
break; break;
} }
case OP_BADD: { case OP_BADD: {
SASSERT(e->get_num_args() == 2);
auto& a = ev.wval(e->get_arg(0));
auto& b = ev.wval(e->get_arg(1));
bool pfixed = true; bool pfixed = true;
for (unsigned i = 0; i < v.bw; ++i) { for (unsigned i = 0; i < v.bw; ++i) {
if (pfixed && a.fixed.get(i) && b.fixed.get(i)) for (unsigned j = 0; pfixed && j < e->get_num_args(); ++j) {
v.fixed.set(i, true); auto& a = ev.wval(e->get_arg(j));
else if (!pfixed && a.fixed.get(i) && b.fixed.get(i) && pfixed &= a.fixed.get(i);
!a.get_bit(i) && !b.get_bit(i)) {
pfixed = true;
v.fixed.set(i, false);
}
else {
pfixed = false;
v.fixed.set(i, false);
} }
v.fixed.set(i, pfixed);
} }
break; break;
} }
case OP_BMUL: { case OP_BMUL: {
SASSERT(e->get_num_args() == 2); if (e->get_num_args() == 2) {
auto& a = ev.wval(e->get_arg(0)); SASSERT(e->get_num_args() == 2);
auto& b = ev.wval(e->get_arg(1)); auto& a = ev.wval(e->get_arg(0));
unsigned j = 0, k = 0, zj = 0, zk = 0, hzj = 0, hzk = 0; auto& b = ev.wval(e->get_arg(1));
// i'th bit depends on bits j + k = i unsigned j = 0, k = 0, zj = 0, zk = 0, hzj = 0, hzk = 0;
// if the first j, resp k bits are 0, the bits j + k are 0 // i'th bit depends on bits j + k = i
for (; j < v.bw; ++j) // if the first j, resp k bits are 0, the bits j + k are 0
if (!a.fixed.get(j)) for (; j < v.bw; ++j)
break; if (!a.fixed.get(j))
for (; k < v.bw; ++k) break;
if (!b.fixed.get(k)) for (; k < v.bw; ++k)
break; if (!b.fixed.get(k))
for (; zj < v.bw; ++zj) break;
if (!a.fixed.get(zj) || a.get_bit(zj)) for (; zj < v.bw; ++zj)
break; if (!a.fixed.get(zj) || a.get_bit(zj))
for (; zk < v.bw; ++zk) break;
if (!b.fixed.get(zk) || b.get_bit(zk)) for (; zk < v.bw; ++zk)
break; if (!b.fixed.get(zk) || b.get_bit(zk))
for (; hzj < v.bw; ++hzj) break;
if (!a.fixed.get(v.bw - hzj - 1) || a.get_bit(v.bw - hzj - 1)) for (; hzj < v.bw; ++hzj)
break; if (!a.fixed.get(v.bw - hzj - 1) || a.get_bit(v.bw - hzj - 1))
for (; hzk < v.bw; ++hzk) break;
if (!b.fixed.get(v.bw - hzk - 1) || b.get_bit(v.bw - hzk - 1)) for (; hzk < v.bw; ++hzk)
break; if (!b.fixed.get(v.bw - hzk - 1) || b.get_bit(v.bw - hzk - 1))
break;
if (j > 0 && k > 0) { if (j > 0 && k > 0) {
for (unsigned i = 0; i < std::min(k, j); ++i) { for (unsigned i = 0; i < std::min(k, j); ++i) {
SASSERT(!v.get_bit(i)); SASSERT(!v.get_bit(i));
v.fixed.set(i, true); v.fixed.set(i, true);
}
}
// lower zj + jk bits are 0
if (zk > 0 || zj > 0) {
for (unsigned i = 0; i < zk + zj; ++i) {
SASSERT(!v.get_bit(i));
v.fixed.set(i, true);
}
}
// upper bits are 0, if enough high order bits of a, b are 0.
// TODO - buggy
if (false && hzj < v.bw && hzk < v.bw && hzj + hzk > v.bw) {
hzj = v.bw - hzj;
hzk = v.bw - hzk;
for (unsigned i = hzj + hzk - 1; i < v.bw; ++i) {
SASSERT(!v.get_bit(i));
v.fixed.set(i, true);
}
} }
} }
// lower zj + jk bits are 0 else {
if (zk > 0 || zj > 0) { bool pfixed = true;
for (unsigned i = 0; i < zk + zj; ++i) { for (unsigned i = 0; i < v.bw; ++i) {
SASSERT(!v.get_bit(i)); for (unsigned j = 0; pfixed && j < e->get_num_args(); ++j) {
v.fixed.set(i, true); auto& a = ev.wval(e->get_arg(j));
} pfixed &= a.fixed.get(i);
} }
// upper bits are 0, if enough high order bits of a, b are 0. v.fixed.set(i, pfixed);
// TODO - buggy
if (false && hzj < v.bw && hzk < v.bw && hzj + hzk > v.bw) {
hzj = v.bw - hzj;
hzk = v.bw - hzk;
for (unsigned i = hzj + hzk - 1; i < v.bw; ++i) {
SASSERT(!v.get_bit(i));
v.fixed.set(i, true);
} }
} }
break; break;
} }
case OP_CONCAT: { case OP_CONCAT: {
SASSERT(e->get_num_args() == 2); unsigned bw = 0;
auto& a = ev.wval(e->get_arg(0)); for (unsigned i = e->get_num_args(); i-- > 0; ) {
auto& b = ev.wval(e->get_arg(1)); auto& a = ev.wval(e->get_arg(i));
for (unsigned i = 0; i < b.bw; ++i) for (unsigned j = 0; j < a.bw; ++j)
v.fixed.set(i, b.fixed.get(i)); v.fixed.set(bw + j, a.fixed.get(j));
for (unsigned i = 0; i < a.bw; ++i) bw += a.bw;
v.fixed.set(i + b.bw, a.fixed.get(i)); }
break; break;
} }
case OP_EXTRACT: { case OP_EXTRACT: {