I am writing a BV encoding of a problem which requires converting
some Int
to BitVec
and viceversa.
In mathsat
/optimathsat
one can use:
((_ to_bv BITS) <int_term>) ; Int => BitVec
(sbv_to_int <bv_term>) ; Signed BitVec => Int
(ubv_to_int <bv_term>) ; Unsigned BitVec => Int
In z3
one can use:
((_ int2bv BITS) <int_term>) ; Int => BitVec
??? ; Signed BitVec => Int
(bv2int <bv_term>) ; Unsigned BitVec => Int
In CVC4
one can use:
((_ int2bv BITS) <int_term>) ; Int => BitVec
??? ; Signed BitVec => Int
??? ; Unsigned BitVec => Int
Q:
- does
z3
's have abv2int
function for SignedBitVec
? (It appears no.) - does
CVC4
have anybv2int
function at all? (I have no clue.) - is there some place where these conversion functions are documented? (The SMT-LIB webpage about Logics/Theories does not appear to have any information about them.)
note: I am limited by the text-based SMT-LIB interface (no API solution).
SMTLib does define
bv2nat
andnat2bv
:See here: http://smtlib.cs.uiowa.edu/theories-FixedSizeBitVectors.shtml
Both CVC4 and z3 should support these two operations. (If not, you should report it to them!)
For everything else, you'll have to do the math yourself. SMTLib is decidedly agnostic about "sign" of a bit-vector; it attributes no sign to a given vector, but instead it provides signed and unsigned version of arithmetic operators when they are different. (For instance, there's only one version of addition since it doesn't matter if you have signed or unsigned bit-vectors for that operation, but for comparisons we get
bvult
,bvslt
etc.)From these two functions, you can define your other variants. For instance, to do signed-bitvector
x
of length 8 to integer, I'd go:That is, you check the top bit of
x
:If it's 0, then you just convert it using
bv2nat
. (You can skip the top bit as you know it's 0, as a small optimization.)If the top bit is
1
, then the value is what you converted by skipping the top bit, and you subtract 128 (= 2^(8-1)), from it. In general, you'll subtract 2^(m-1) wherem
is the size of the bitvector.One gotcha: You cannot make an SMTLib function that does this for you for all bit-vector sizes. This is because SMTLib does not allow users to define size-polymorphic functions. You can, however, generate as many of such functions as you want by declaring them on the fly, or simply generate the corresponding expressions whenever needed.
Other operations are similarly encodable using similar tricks. Please ask specific questions if you run into issues.