int TheoryBV::getReduction(int effort, Node n, Node& nr)
{
Trace("bv-ext") << "TheoryBV::checkExt : non-reduced : " << n << std::endl;
- NodeManager* const nm = NodeManager::currentNM();
if (n.getKind() == kind::BITVECTOR_TO_NAT)
{
nr = utils::eliminateBv2Nat(n);
}
else if (n.getKind() == kind::INT_TO_BITVECTOR)
{
- // taken from rewrite code
- const unsigned size = n.getOperator().getConst<IntToBitVector>().size;
- const Node bvzero = utils::mkZero(1);
- const Node bvone = utils::mkOne(1);
- std::vector<Node> v;
- Integer i = 2;
- while (v.size() < size)
- {
- Node cond = nm->mkNode(
- kind::GEQ,
- nm->mkNode(kind::INTS_MODULUS_TOTAL, n[0], nm->mkConst(Rational(i))),
- nm->mkConst(Rational(i, 2)));
- cond = Rewriter::rewrite(cond);
- v.push_back(nm->mkNode(kind::ITE, cond, bvone, bvzero));
- i *= 2;
- }
- NodeBuilder<> result(kind::BITVECTOR_CONCAT);
- result.append(v.rbegin(), v.rend());
- nr = Node(result);
+ nr = utils::eliminateBv2Nat(n);
return -1;
}
return 0;
//if( node[0].isConst() ){
//TODO? direct computation instead of term construction+rewriting
//}
-
- const unsigned size = node.getOperator().getConst<IntToBitVector>().size;
- NodeManager* const nm = NodeManager::currentNM();
- const Node bvzero = utils::mkZero(1);
- const Node bvone = utils::mkOne(1);
-
- std::vector<Node> v;
- Integer i = 2;
- while(v.size() < size) {
- Node cond = nm->mkNode(kind::GEQ, nm->mkNode(kind::INTS_MODULUS_TOTAL, node[0], nm->mkConst(Rational(i))), nm->mkConst(Rational(i, 2)));
- v.push_back(nm->mkNode(kind::ITE, cond, bvone, bvzero));
- i *= 2;
- }
-
- NodeBuilder<> result(kind::BITVECTOR_CONCAT);
- result.append(v.rbegin(), v.rend());
- return Node(result);
+ return utils::eliminateInt2Bv(node);
}
template <>
return children.size() == 1 ? children[0] : nm->mkNode(kind::PLUS, children);
}
+Node eliminateInt2Bv(TNode node)
+{
+ const uint32_t size = node.getOperator().getConst<IntToBitVector>().size;
+ NodeManager* const nm = NodeManager::currentNM();
+ const Node bvzero = utils::mkZero(1);
+ const Node bvone = utils::mkOne(1);
+
+ std::vector<Node> v;
+ Integer i = 2;
+ while (v.size() < size)
+ {
+ Node cond = nm->mkNode(
+ kind::GEQ,
+ nm->mkNode(kind::INTS_MODULUS_TOTAL, node[0], nm->mkConst(Rational(i))),
+ nm->mkConst(Rational(i, 2)));
+ v.push_back(nm->mkNode(kind::ITE, cond, bvone, bvzero));
+ i *= 2;
+ }
+ if (v.size() == 1)
+ {
+ return v[0];
+ }
+ NodeBuilder<> result(kind::BITVECTOR_CONCAT);
+ result.append(v.rbegin(), v.rend());
+ return Node(result);
+}
+
}/* CVC4::theory::bv::utils namespace */
}/* CVC4::theory::bv namespace */
}/* CVC4::theory namespace */
* where n is the bitwidth of x.
*/
Node eliminateBv2Nat(TNode node);
+/**
+ * Returns the rewritten form of node, which is a term of the form int2bv(x).
+ * The return value of this method is the concatenation term:
+ * (bvconcat ite( (>= (mod x (^ 2 n)) (^ 2 (n-1))) (_ bv1 1) (_ bv1 0))
+ * ...
+ * ite( (>= (mod x (^ 2 1)) (^ 2 0)) (_ bv1 1) (_ bv1 0)))
+ * where n is the bit-width of x.
+ */
+Node eliminateInt2Bv(TNode node);
}
}
}
regress1/bv/fuzz34.smtv1.smt2
regress1/bv/fuzz38.smtv1.smt2
regress1/bv/issue3654.smt2
+ regress1/bv/issue3776.smt2
regress1/bv/test-bv-abstraction.smt2
regress1/bv/unsound1.smt2
regress1/bvdiv2.smt2
--- /dev/null
+; COMMAND_LINE: --rewrite-divk
+; EXPECT: sat
+(set-logic QF_BVLIA)
+(declare-fun t () Int)
+(assert (= t (bv2nat ((_ int2bv 1) t))))
+(check-sat)