Node TheoryBV::ppRewrite(TNode t)
{
+ Debug("bv-pp-rewrite") << "TheoryBV::ppRewrite " << t << "\n";
Node res = t;
if (RewriteRule<BitwiseEq>::applies(t)) {
Node result = RewriteRule<BitwiseEq>::run<false>(t);
std::vector<Node> equalities;
Slicer::splitEqualities(t, equalities);
res = utils::mkAnd(equalities);
+ } else if (RewriteRule<UltPlusOne>::applies(t)) {
+ Node result = RewriteRule<UltPlusOne>::run<false>(t);
+ res = Rewriter::rewrite(result);
}
// if(t.getKind() == kind::EQUAL &&
if (options::bvAbstraction() && t.getType().isBoolean()) {
d_abstractionModule->addInputAtom(res);
}
+ Debug("bv-pp-rewrite") << "to " << res << "\n";
return res;
}
XorSimplify,
BitwiseSlicing,
// rules to simplify bitblasting
- BBPlusNeg
- };
+ BBPlusNeg,
+ UltPlusOne
+};
inline std::ostream& operator << (std::ostream& out, RewriteRuleId ruleId) {
case BitwiseSlicing : out << "BitwiseSlicing"; return out;
case ExtractSignExtend : out << "ExtractSignExtend"; return out;
case MultDistrib: out << "MultDistrib"; return out;
+ case UltPlusOne: out << "UltPlusOne"; return out;
default:
Unreachable();
}
RewriteRule<BVToNatEliminate> rule116;
RewriteRule<IntToBVEliminate> rule117;
RewriteRule<MultDistrib> rule118;
+ RewriteRule<UltPlusOne> rule119;
};
template<> inline
return utils::mkNode(kind::BITVECTOR_PLUS, term1, term2, term3);
}
+/**
+ * x < y + 1 <=> (not y < x) and y != 1...1
+ *
+ * @param node
+ *
+ * @return
+ */
+template<> inline
+bool RewriteRule<UltPlusOne>::applies(TNode node) {
+ if (node.getKind() != kind::BITVECTOR_ULT) return false;
+ TNode x = node[0];
+ TNode y1 = node[1];
+ if (y1.getKind() != kind::BITVECTOR_PLUS) return false;
+ if (y1[0].getKind() != kind::CONST_BITVECTOR &&
+ y1[1].getKind() != kind::CONST_BITVECTOR)
+ return false;
+ TNode one = y1[0].getKind() == kind::CONST_BITVECTOR ? y1[0] : y1[1];
+ if (one != utils::mkConst(utils::getSize(one), 1)) return false;
+ return true;
+}
+
+template<> inline
+Node RewriteRule<UltPlusOne>::apply(TNode node) {
+ Debug("bv-rewrite") << "RewriteRule<UltPlusOne>(" << node << ")" << std::endl;
+ TNode x = node[0];
+ TNode y1 = node[1];
+ TNode y = y1[0].getKind() != kind::CONST_BITVECTOR ? y1[0] : y1[1];
+ unsigned size = utils::getSize(x);
+ Node not_y_eq_1 = utils::mkNode(kind::NOT, utils::mkNode(kind::EQUAL, y, utils::mkOnes(size)));
+ Node not_y_lt_x = utils::mkNode(kind::NOT, utils::mkNode(kind::BITVECTOR_ULT, y, x));
+ return utils::mkNode(kind::AND, not_y_eq_1, not_y_lt_x);
+}
// /**