}
Node BvToBoolVisitor::getCache(TNode term) const {
- if (!hasCache(term)) {
+ if (!hasCache(term) || term.getKind() == kind::CONST_BITVECTOR) {
return term;
}
return d_cache.find(term)->second;
Kind kind = node.getKind();
return (kind == kind::BITVECTOR_ULT ||
kind == kind::BITVECTOR_ULE ||
+ kind == kind::BITVECTOR_SLT ||
+ kind == kind::BITVECTOR_SLE ||
kind == kind::EQUAL) &&
- node[0].getType().isBitVector() &&
- node[0].getType().getBitVectorSize() == 1;
+ isConvertibleBvTerm(node[0]) &&
+ isConvertibleBvTerm(node[1]);
}
bool BvToBoolVisitor::isConvertibleBvTerm(TNode node) {
return true;
}
+ if (kind == kind::ITE) {
+ return isConvertibleBvTerm(node[1]) && isConvertibleBvTerm(node[2]);
+ }
+
if (kind == kind::BITVECTOR_AND || kind == kind::BITVECTOR_OR ||
kind == kind::BITVECTOR_NOT || kind == kind::BITVECTOR_XOR) {
for (unsigned i = 0; i < node.getNumChildren(); ++i) {
Node result;
switch(kind) {
case kind::BITVECTOR_ULT: {
- TNode a = getBoolForBvTerm(node[0]);
- TNode b = getBoolForBvTerm(node[1]);
- Node a_eq_0 = utils::mkNode(kind::EQUAL, a, d_zero);
- Node b_eq_1 = utils::mkNode(kind::EQUAL, b, d_one);
+ Node a = getBoolForBvTerm(node[0]);
+ Node b = getBoolForBvTerm(node[1]);
+ Node a_eq_0 = utils::mkNode(kind::IFF, a, utils::mkFalse());
+ Node b_eq_1 = utils::mkNode(kind::IFF, b, utils::mkTrue());
result = utils::mkNode(kind::AND, a_eq_0, b_eq_1);
break;
}
case kind::BITVECTOR_ULE: {
- TNode a = getBoolForBvTerm(node[0]);
- TNode b = getBoolForBvTerm(node[1]);
- Node a_eq_0 = utils::mkNode(kind::EQUAL, a, d_zero);
- Node b_eq_1 = utils::mkNode(kind::EQUAL, b, d_one);
+ Node a = getBoolForBvTerm(node[0]);
+ Node b = getBoolForBvTerm(node[1]);
+ Node a_eq_0 = utils::mkNode(kind::IFF, a, utils::mkFalse());
+ Node b_eq_1 = utils::mkNode(kind::IFF, b, utils::mkTrue());
Node a_lt_b = utils::mkNode(kind::AND, a_eq_0, b_eq_1);
- Node a_eq_b = utils::mkNode(kind::EQUAL, a, b);
+ Node a_eq_b = utils::mkNode(kind::IFF, a, b);
result = utils::mkNode(kind::OR, a_lt_b, a_eq_b);
break;
}
+ case kind::BITVECTOR_SLT: {
+ Node a = getBoolForBvTerm(node[0]);
+ Node b = getBoolForBvTerm(node[1]);
+ Node a_eq_1 = utils::mkNode(kind::IFF, a, utils::mkTrue());
+ Node b_eq_0 = utils::mkNode(kind::IFF, b, utils::mkFalse());
+ result = utils::mkNode(kind::AND, a_eq_1, b_eq_0);
+ break;
+ }
+ case kind::BITVECTOR_SLE: {
+ Node a = getBoolForBvTerm(node[0]);
+ Node b = getBoolForBvTerm(node[1]);
+ Node a_eq_1 = utils::mkNode(kind::IFF, a, utils::mkTrue());
+ Node b_eq_0 = utils::mkNode(kind::IFF, b, utils::mkFalse());
+ Node a_slt_b = utils::mkNode(kind::AND, a_eq_1, b_eq_0);
+ Node a_eq_b = utils::mkNode(kind::IFF, a, b);
+ result = utils::mkNode(kind::OR, a_slt_b, a_eq_b);
+ break;
+ }
case kind::EQUAL: {
- TNode a = getBoolForBvTerm(node[0]);
- TNode b = getBoolForBvTerm(node[1]);
+ Node a = getBoolForBvTerm(node[0]);
+ Node b = getBoolForBvTerm(node[1]);
result = utils::mkNode(kind::IFF, a, b);
break;
}
default:
Unhandled();
}
+ Debug("bv-to-bool") << "BvToBoolVisitor::convertBvAtom " << node <<" => " << result << "\n";
Assert (result != Node());
return result;
}
return getBoolForBvTerm(node);
}
if (node.getKind() == kind::CONST_BITVECTOR) {
- return (node == d_one ? utils::mkTrue() : utils::mkFalse());
+ Node result = node == d_one ? utils::mkTrue() : utils::mkFalse();
+ storeBvToBool(node, result);
+ return result;
}
}
if (kind == kind::ITE) {
- TNode cond = getCache(node[0]);
- TNode true_branch = getBoolForBvTerm(node[1]);
- TNode false_branch = getBoolForBvTerm(node[2]);
+ Node cond = getCache(node[0]);
+ Node true_branch = getBoolForBvTerm(node[1]);
+ Node false_branch = getBoolForBvTerm(node[2]);
Node result = utils::mkNode(kind::ITE, cond, true_branch, false_branch);
storeBvToBool(node, result);
+ Debug("bv-to-bool") << "BvToBoolVisitor::convertBvTerm " << node <<" => " << result << "\n";
return result;
}
}
Node result = builder;
storeBvToBool(node, result);
+ Debug("bv-to-bool") << "BvToBoolVisitor::convertBvTerm " << node <<" => " << result << "\n";
return result;
}
Debug("bv-to-bool") << "BvToBoolVisitor visit (" << current << ", " << parent << ")\n";
Assert (!alreadyVisited(current, parent) &&
!hasCache(current));
-
- Node result;
+ Node result;
// make sure that the bv terms we are replacing to not occur in other contexts
check(current, parent);
result = builder;
}
}
- Assert (result != Node());
+ Assert (result != Node());
+ Debug("bv-to-bool") << " =>" << result <<"\n";
addToCache(current, result);
}
BvToBoolVisitor::return_type BvToBoolVisitor::done(TNode node) {
Assert (hasCache(node));
- return getCache(node);
+ Node result = getCache(node);
+ return result;
+}
+
+bool BvToBoolVisitor::hasBoolTerm(TNode node) {
+ return d_bvToBoolMap.find(node) != d_bvToBoolMap.end();
}
bool BvToBoolPreprocessor::matchesBooleanPatern(TNode current) {
void BvToBoolPreprocessor::liftBoolToBV(const std::vector<Node>& assertions, std::vector<Node>& new_assertions) {
- TNodeNodeMap candidates;
+ BvToBoolVisitor bvToBoolVisitor;
+
for (unsigned i = 0; i < assertions.size(); ++i) {
if (matchesBooleanPatern(assertions[i])) {
TNode assertion = assertions[i];
Assert (bv_var.getKind() == kind::VARIABLE &&
bv_var.getType().isBitVector() &&
bv_var.getType().getBitVectorSize() == 1);
- TNode bool_cond = assertion[1];
+ Node bool_cond = NodeVisitor<BvToBoolVisitor>::run(bvToBoolVisitor, assertion[1]);
Assert (bool_cond.getType().isBoolean());
- if (candidates.find(bv_var) == candidates.end()) {
+ if (!bvToBoolVisitor.hasBoolTerm(bv_var)) {
Debug("bv-to-bool") << "BBvToBoolPreprocessor::liftBvToBoolBV candidate: " << bv_var <<"\n";
- candidates[bv_var] = bool_cond;
+ bvToBoolVisitor.storeBvToBool(bv_var, bool_cond);
} else {
Debug("bv-to-bool") << "BvToBoolPreprocessor::liftBvToBoolBV multiple def " << bv_var <<"\n";
}
}
}
- BvToBoolVisitor bvToBoolVisitor(candidates);
for (unsigned i = 0; i < assertions.size(); ++i) {
Node new_assertion = NodeVisitor<BvToBoolVisitor>::run(bvToBoolVisitor,
assertions[i]);
- new_assertions.push_back(new_assertion);
+ new_assertions.push_back(new_assertion);
+ Trace("bv-to-bool") << " " << assertions[i] <<" => " << new_assertions[i] <<"\n";
}
}
namespace bv {
typedef __gnu_cxx::hash_set<TNode, TNodeHashFunction> TNodeSet;
-typedef __gnu_cxx::hash_map<TNode, Node, TNodeHashFunction> TNodeNodeMap;
+typedef __gnu_cxx::hash_map<Node, Node, TNodeHashFunction> NodeNodeMap;
class BvToBoolVisitor {
- TNodeNodeMap d_bvToBoolMap;
- TNodeNodeMap d_cache;
+ NodeNodeMap d_bvToBoolMap;
+ NodeNodeMap d_cache;
Node d_one;
Node d_zero;
bool isConvertibleBvTerm(TNode node);
bool isConvertibleBvAtom(TNode node);
Node getBoolForBvTerm(TNode node);
- void storeBvToBool(TNode bv_term, TNode bool_term);
Node convertBvAtom(TNode node);
Node convertBvTerm(TNode node);
void check(TNode current, TNode parent);
public:
typedef Node return_type;
- BvToBoolVisitor(TNodeNodeMap& bvToBool)
- : d_bvToBoolMap(bvToBool),
+ BvToBoolVisitor()
+ : d_bvToBoolMap(),
d_cache(),
d_one(utils::mkConst(BitVector(1, 1u))),
d_zero(utils::mkConst(BitVector(1, 0u)))
bool alreadyVisited(TNode current, TNode parent);
void visit(TNode current, TNode parent);
return_type done(TNode node);
+ void storeBvToBool(TNode bv_term, TNode bool_term);
+ bool hasBoolTerm(TNode node);
};