{ op = MK_CONST(BitVectorRotateRight(AntlrInput::tokenToUnsigned($n))); }
| DIVISIBLE_TOK n=INTEGER_LITERAL
{ op = MK_CONST(Divisible(AntlrInput::tokenToUnsigned($n))); }
+ | INT2BV_TOK n=INTEGER_LITERAL
+ { op = MK_CONST(IntToBitVector(AntlrInput::tokenToUnsigned($n)));
+ if(PARSER_STATE->strictModeEnabled()) {
+ PARSER_STATE->parseError("bv2nat and int2bv are not part of SMT-LIB, and aren't available in SMT-LIB strict compliance mode");
+ } }
| badIndexedFunctionName
)
RPAREN_TOK
| BVSGT_TOK { $kind = CVC4::kind::BITVECTOR_SGT; }
| BVSGE_TOK { $kind = CVC4::kind::BITVECTOR_SGE; }
+ | BV2NAT_TOK { $kind = CVC4::kind::BITVECTOR_TO_NAT;
+ if(PARSER_STATE->strictModeEnabled()) {
+ PARSER_STATE->parseError("bv2nat and int2bv are not part of SMT-LIB, and aren't available in SMT-LIB strict compliance mode");
+ } }
+
| STRCON_TOK { $kind = CVC4::kind::STRING_CONCAT; }
| STRLEN_TOK { $kind = CVC4::kind::STRING_LENGTH; }
| STRINRE_TOK { $kind = CVC4::kind::STRING_IN_REGEXP; }
BVSLE_TOK : 'bvsle';
BVSGT_TOK : 'bvsgt';
BVSGE_TOK : 'bvsge';
+BV2NAT_TOK : 'bv2nat';
+INT2BV_TOK : 'int2bv';
//STRING
STRCST_TOK : 'str.const';
addOperator(kind::BITVECTOR_SIGN_EXTEND);
addOperator(kind::BITVECTOR_ROTATE_LEFT);
addOperator(kind::BITVECTOR_ROTATE_RIGHT);
+
+ addOperator(kind::INT_TO_BITVECTOR);
+ addOperator(kind::BITVECTOR_TO_NAT);
}
void Smt2::addStringOperators() {
case kind::BITVECTOR_SLE: out << "bvsle "; break;
case kind::BITVECTOR_SGT: out << "bvsgt "; break;
case kind::BITVECTOR_SGE: out << "bvsge "; break;
+ case kind::BITVECTOR_TO_NAT: out << "bv2nat "; break;
case kind::BITVECTOR_EXTRACT:
case kind::BITVECTOR_REPEAT:
case kind::BITVECTOR_SIGN_EXTEND:
case kind::BITVECTOR_ROTATE_LEFT:
case kind::BITVECTOR_ROTATE_RIGHT:
+ case kind::INT_TO_BITVECTOR:
printBvParameterizedOp(out, n);
out << ' ';
stillNeedToPrintParams = false;
out << "rotate_right "
<< n.getOperator().getConst<BitVectorRotateRight>().rotateRightAmount;
break;
+ case kind::INT_TO_BITVECTOR:
+ out << "int2bv "
+ << n.getOperator().getConst<IntToBitVector>().size;
+ break;
default:
out << n.getKind();
}
parameterized BITVECTOR_ROTATE_LEFT BITVECTOR_ROTATE_LEFT_OP 1 "bit-vector rotate left"
parameterized BITVECTOR_ROTATE_RIGHT BITVECTOR_ROTATE_RIGHT_OP 1 "bit-vector rotate right"
+constant INT_TO_BITVECTOR_OP \
+ ::CVC4::IntToBitVector \
+ "::CVC4::UnsignedHashFunction< ::CVC4::IntToBitVector >" \
+ "util/bitvector.h" \
+ "operator for the integer conversion to bit-vector"
+parameterized INT_TO_BITVECTOR INT_TO_BITVECTOR_OP 1 "integer conversion to bit-vector"
+operator BITVECTOR_TO_NAT 1 "bit-vector conversion to (nonnegative) integer"
+
typerule CONST_BITVECTOR ::CVC4::theory::bv::BitVectorConstantTypeRule
typerule BITVECTOR_AND ::CVC4::theory::bv::BitVectorFixedWidthTypeRule
typerule BITVECTOR_ZERO_EXTEND ::CVC4::theory::bv::BitVectorExtendTypeRule
typerule BITVECTOR_SIGN_EXTEND ::CVC4::theory::bv::BitVectorExtendTypeRule
+typerule BITVECTOR_TO_NAT ::CVC4::theory::bv::BitVectorConversionTypeRule
+typerule INT_TO_BITVECTOR ::CVC4::theory::bv::BitVectorConversionTypeRule
+
endtheory
SremEliminate,
ZeroExtendEliminate,
SignExtendEliminate,
+ BVToNatEliminate,
+ IntToBVEliminate,
+
/// ground term evaluation
EvalEquals,
EvalConcat,
case FailEq: out << "FailEq"; return out;
case SimplifyEq: out << "SimplifyEq"; return out;
case ReflexivityEq: out << "ReflexivityEq"; return out;
- case UgtEliminate: out << "UgtEliminate"; return out;
- case SgtEliminate: out << "SgtEliminate"; return out;
- case UgeEliminate: out << "UgeEliminate"; return out;
- case SgeEliminate: out << "SgeEliminate"; return out;
+ case UgtEliminate: out << "UgtEliminate"; return out;
+ case SgtEliminate: out << "SgtEliminate"; return out;
+ case UgeEliminate: out << "UgeEliminate"; return out;
+ case SgeEliminate: out << "SgeEliminate"; return out;
case RepeatEliminate: out << "RepeatEliminate"; return out;
case RotateLeftEliminate: out << "RotateLeftEliminate"; return out;
case RotateRightEliminate:out << "RotateRightEliminate";return out;
+ case BVToNatEliminate: out << "BVToNatEliminate"; return out;
+ case IntToBVEliminate: out << "IntToBVEliminate"; return out;
case NandEliminate: out << "NandEliminate"; return out;
case NorEliminate : out << "NorEliminate"; return out;
case SdivEliminate : out << "SdivEliminate"; return out;
case ExtractBitwise : out << "ExtractBitwise"; return out;
case ExtractNot : out << "ExtractNot"; return out;
case ExtractArith : out << "ExtractArith"; return out;
- case ExtractArith2 : out << "ExtractArith2"; return out;
+ case ExtractArith2 : out << "ExtractArith2"; return out;
case DoubleNeg : out << "DoubleNeg"; return out;
case NotConcat : out << "NotConcat"; return out;
case NotAnd : out << "NotAnd"; return out;
case BitwiseNotOr : out << "BitwiseNotOr"; return out;
case XorNot : out << "XorNot"; return out;
case LtSelf : out << "LtSelf"; return out;
- case LteSelf : out << "LteSelf"; return out;
+ case LteSelf : out << "LteSelf"; return out;
case UltZero : out << "UltZero"; return out;
case UleZero : out << "UleZero"; return out;
case ZeroUle : out << "ZeroUle"; return out;
RewriteRule<BitwiseEq> rule113;
RewriteRule<UltOne> rule114;
RewriteRule<SltZero> rule115;
-
+ RewriteRule<BVToNatEliminate> rule116;
+ RewriteRule<IntToBVEliminate> rule117;
};
template<> inline
return result;
}
+template<>
+bool RewriteRule<BVToNatEliminate>::applies(TNode node) {
+ return (node.getKind() == kind::BITVECTOR_TO_NAT);
+}
+
+template<>
+Node RewriteRule<BVToNatEliminate>::apply(TNode node) {
+ Debug("bv-rewrite") << "RewriteRule<BVToNatEliminate>(" << node << ")" << std::endl;
+
+ const unsigned size = utils::getSize(node[0]);
+ NodeManager* const nm = NodeManager::currentNM();
+ const Node z = nm->mkConst(Rational(0));
+ const Node bvone = nm->mkConst(BitVector(1u, 1u));
+
+ NodeBuilder<> result(kind::PLUS);
+ Integer i = 1;
+ for(unsigned bit = 0; bit < size; ++bit, i *= 2) {
+ Node cond = nm->mkNode(kind::EQUAL, nm->mkNode(nm->mkConst(BitVectorExtract(bit, bit)), node[0]), bvone);
+ result << nm->mkNode(kind::ITE, cond, nm->mkConst(Rational(i)), z);
+ }
+
+ return Node(result);
+}
+
+template<>
+bool RewriteRule<IntToBVEliminate>::applies(TNode node) {
+ return (node.getKind() == kind::INT_TO_BITVECTOR);
+}
+
+template<>
+Node RewriteRule<IntToBVEliminate>::apply(TNode node) {
+ Debug("bv-rewrite") << "RewriteRule<IntToBVEliminate>(" << node << ")" << std::endl;
+
+ const unsigned size = node.getOperator().getConst<IntToBitVector>().size;
+ NodeManager* const nm = NodeManager::currentNM();
+ const Node bvzero = nm->mkConst(BitVector(1u, 0u));
+ const Node bvone = nm->mkConst(BitVector(1u, 1u));
+
+ 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);
+}
+
template<>
bool RewriteRule<NandEliminate>::applies(TNode node) {
return (node.getKind() == kind::BITVECTOR_NAND &&
RewriteResponse TheoryBVRewriter::RewriteRotateLeft(TNode node, bool prerewrite){
Node resultNode = LinearRewriteStrategy
< RewriteRule<RotateLeftEliminate >
- >::apply(node);
+ >::apply(node);
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
}
+RewriteResponse TheoryBVRewriter::RewriteBVToNat(TNode node, bool prerewrite) {
+ Node resultNode = LinearRewriteStrategy
+ < RewriteRule<BVToNatEliminate>
+ >::apply(node);
+
+ return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
+}
+
+RewriteResponse TheoryBVRewriter::RewriteIntToBV(TNode node, bool prerewrite) {
+ Node resultNode = LinearRewriteStrategy
+ < RewriteRule<IntToBVEliminate>
+ >::apply(node);
+
+ return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
+}
+
RewriteResponse TheoryBVRewriter::RewriteEqual(TNode node, bool prerewrite) {
if (prerewrite) {
Node resultNode = LinearRewriteStrategy
d_rewriteTable [ kind::BITVECTOR_SIGN_EXTEND ] = RewriteSignExtend;
d_rewriteTable [ kind::BITVECTOR_ROTATE_RIGHT ] = RewriteRotateRight;
d_rewriteTable [ kind::BITVECTOR_ROTATE_LEFT ] = RewriteRotateLeft;
+
+ d_rewriteTable [ kind::BITVECTOR_TO_NAT ] = RewriteBVToNat;
+ d_rewriteTable [ kind::INT_TO_BITVECTOR ] = RewriteIntToBV;
}
Node TheoryBVRewriter::eliminateBVSDiv(TNode node) {
static RewriteResponse RewriteRotateRight(TNode node, bool prerewrite = false);
static RewriteResponse RewriteRotateLeft(TNode node, bool prerewrite = false);
+ static RewriteResponse RewriteBVToNat(TNode node, bool prerewrite = false);
+ static RewriteResponse RewriteIntToBV(TNode node, bool prerewrite = false);
+
public:
static RewriteResponse postRewrite(TNode node);
}
};
+class BitVectorConversionTypeRule {
+public:
+ inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check)
+ throw (TypeCheckingExceptionPrivate, AssertionException) {
+ if(n.getKind() == kind::BITVECTOR_TO_NAT) {
+ if(check && !n[0].getType(check).isBitVector()) {
+ throw TypeCheckingExceptionPrivate(n, "expecting bit-vector term");
+ }
+ return nodeManager->integerType();
+ }
+
+ if(n.getKind() == kind::INT_TO_BITVECTOR) {
+ size_t bvSize = n.getOperator().getConst<IntToBitVector>();
+ if(check && !n[0].getType(check).isInteger()) {
+ throw TypeCheckingExceptionPrivate(n, "expecting integer term");
+ }
+ return nodeManager->mkBitVectorType(bvSize);
+ }
+
+ InternalError("bv-conversion typerule invoked for non-bv-conversion kind");
+ }
+};
+
class CardinalityComputer {
public:
inline static Cardinality computeCardinality(TypeNode type) {
/**
* The structure representing the extraction operation for bit-vectors. The
- * operation map bit-vectors to bit-vector of size <code>high - low + 1</code>
+ * operation maps bit-vectors to bit-vector of size <code>high - low + 1</code>
* by taking the bits at indices <code>high ... low</code>
*/
struct CVC4_PUBLIC BitVectorExtract {
operator unsigned () const { return rotateRightAmount; }
};/* struct BitVectorRotateRight */
+struct CVC4_PUBLIC IntToBitVector {
+ unsigned size;
+ IntToBitVector(unsigned size)
+ : size(size) {}
+ operator unsigned () const { return size; }
+};/* struct IntToBitVector */
+
template <typename T>
struct CVC4_PUBLIC UnsignedHashFunction {
inline size_t operator()(const T& x) const {
return os << "[" << bv.bitIndex << "]";
}
+inline std::ostream& operator <<(std::ostream& os, const IntToBitVector& bv) CVC4_PUBLIC;
+inline std::ostream& operator <<(std::ostream& os, const IntToBitVector& bv) {
+ return os << "[" << bv.size << "]";
+}
+
}/* CVC4 namespace */
#endif /* __CVC4__BITVECTOR_H */