case kind::BITVECTOR_UDIV:
op << "BVUDIV";
break;
+ case kind::BITVECTOR_UDIV_TOTAL:
+ op << "BVUDIV_TOTAL";
+ break;
case kind::BITVECTOR_UREM:
op << "BVUREM";
break;
+ case kind::BITVECTOR_UREM_TOTAL:
+ op << "BVUREM_TOTAL";
+ break;
case kind::BITVECTOR_SDIV:
op << "BVSDIV";
break;
case kind::BITVECTOR_SUB: out << "bvsub "; break;
case kind::BITVECTOR_NEG: out << "bvneg "; break;
case kind::BITVECTOR_UDIV: out << "bvudiv "; break;
+ case kind::BITVECTOR_UDIV_TOTAL: out << "bvudiv_total "; break;
case kind::BITVECTOR_UREM: out << "bvurem "; break;
+ case kind::BITVECTOR_UREM_TOTAL: out << "bvurem_total "; break;
case kind::BITVECTOR_SDIV: out << "bvsdiv "; break;
case kind::BITVECTOR_SREM: out << "bvsrem "; break;
case kind::BITVECTOR_SMOD: out << "bvsmod "; break;
Bits r;
uDivModRec(a, b, q, r, getSize(node));
+ // adding a special case for division by 0
+ std::vector<Node> iszero;
+ for (unsigned i = 0; i < b.size(); ++i) {
+ iszero.push_back(utils::mkNode(kind::IFF, b[i], utils::mkFalse()));
+ }
+ Node b_is_0 = utils::mkAnd(iszero);
+
+ for (unsigned i = 0; i < q.size(); ++i) {
+ q[i] = utils::mkNode(kind::ITE, b_is_0, utils::mkFalse(), q[i]);
+ r[i] = utils::mkNode(kind::ITE, b_is_0, utils::mkFalse(), r[i]);
+ }
// cache the remainder in case we need it later
Node remainder = mkNode(kind::BITVECTOR_UREM_TOTAL, node[0], node[1]);
Bits q;
uDivModRec(a, b, q, rem, getSize(node));
+ // adding a special case for division by 0
+ std::vector<Node> iszero;
+ for (unsigned i = 0; i < b.size(); ++i) {
+ iszero.push_back(utils::mkNode(kind::IFF, b[i], utils::mkFalse()));
+ }
+ Node b_is_0 = utils::mkAnd(iszero);
+
+ for (unsigned i = 0; i < q.size(); ++i) {
+ q[i] = utils::mkNode(kind::ITE, b_is_0, utils::mkFalse(), q[i]);
+ rem[i] = utils::mkNode(kind::ITE, b_is_0, utils::mkFalse(), rem[i]);
+ }
// cache the quotient in case we need it later
Node quotient = mkNode(kind::BITVECTOR_UDIV_TOTAL, node[0], node[1]);
BVDebug("bv-rewrite") << "RewriteRule<EvalUdiv>(" << node << ")" << std::endl;
BitVector a = node[0].getConst<BitVector>();
BitVector b = node[1].getConst<BitVector>();
- BitVector res = a.unsignedDiv(b);
+ BitVector res = a.unsignedDivTotal(b);
return utils::mkConst(res);
}
BVDebug("bv-rewrite") << "RewriteRule<EvalUrem>(" << node << ")" << std::endl;
BitVector a = node[0].getConst<BitVector>();
BitVector b = node[1].getConst<BitVector>();
- BitVector res = a.unsignedRem(b);
+ BitVector res = a.unsignedRemTotal(b);
return utils::mkConst(res);
}
Integer prod = d_value * y.d_value;
return BitVector(d_size, prod);
}
-
- BitVector unsignedDiv (const BitVector& y) const {
+ /**
+ * Total division function that returns 0 when the denominator is 0.
+ */
+ BitVector unsignedDivTotal (const BitVector& y) const {
CheckArgument(d_size == y.d_size, y);
- // TODO: decide whether we really want these semantics
if (y.d_value == 0) {
- return BitVector(d_size, Integer(0));
+ return BitVector(d_size, 0u);
}
CheckArgument(d_value >= 0, this);
CheckArgument(y.d_value > 0, y);
return BitVector(d_size, d_value.floorDivideQuotient(y.d_value));
}
-
- BitVector unsignedRem(const BitVector& y) const {
+ /**
+ * Total division function that returns 0 when the denominator is 0.
+ */
+ BitVector unsignedRemTotal(const BitVector& y) const {
CheckArgument(d_size == y.d_size, y);
- // TODO: decide whether we really want these semantics
if (y.d_value == 0) {
- return BitVector(d_size, d_value);
+ return BitVector(d_size, 0u);
}
CheckArgument(d_value >= 0, this);
CheckArgument(y.d_value > 0, y);