Meaning of (_ bv0 32), (_ bv1 16) ... in SMT2 benchmarks - z3

I noticed that is some SMT2 benchmarks, notations like (_ bv0 32), (_ bv16 32), ... are used like, for instance, in:
QF_FP/schanda/spark/zeros_consistent_2.smt2
http://cvc4.cs.nyu.edu/benchmarks/smtlib2/QF_AUFBV/dwp_formulas/try5_small_difret_functions_wp_vdir.rev_xstrcoll_mtime.il.wp.smt2
http://rise4fun.com/Z3/e1s
However, this is no reference to such symbols in theories declarations:
http://smtlib.cs.uiowa.edu/theories.shtml
Any comment on that ? What is their meaning ?
Thanks !

(_ bv0 32) is a bitvector constant encoding the value 0 in 32 bits.
You can find the formal description in the Logic definition, under "Bitvector Constants" http://smtlib.cs.uiowa.edu/logics-all.shtml#QF_BV

Related

Boolean matrix times vector multiplication in Z3

How to multiply a variable Boolean matrix by a Boolean vector in Z3 in a nice way? The sizes of the matrix and of vectors are known and fixed.
In my case there is only one matrix and there is no need to pass it as an argument or return it as a result of a function, so the matrix can be global.
Does it help if the matrix is a square matrix?
My current solution is:
; Maybe some other matrix representation would be better?
(declare-datatypes () ((ColumnIndex c0 c1 c2)))
(declare-fun column (ColumnIndex) (_ BitVec 4))
(define-fun scalarTimesVector ((a (_ BitVec 1)) (v (_ BitVec 4))) (_ BitVec 4)
(ite (= a #b1) v (_ bv0 4))
)
(define-fun matrixTimesVector ((vector (_ BitVec 3))) (_ BitVec 4)
(bvor
(scalarTimesVector ((_ extract 0 0) vector) (column c0))
(scalarTimesVector ((_ extract 1 1) vector) (column c1))
(scalarTimesVector ((_ extract 2 2) vector) (column c2))
)
)
What you are doing is just fine, especially given your matrix size is constant and never change. SMTLib has no notion of loops, although recent versions do allow recursive definitions of functions that can be used for this effect. See this answer for a different but related question on how to use recursion: https://stackoverflow.com/a/51140049/936310. However, I'd recommend sticking to your current code for simplicity and wider support from a variety of solvers.
In my mind, SMTLib should really be "generated" instead of directly used; and most tools use it this way. If your programming needs get more complicated, I'd recommend using a higher-level interface instead. There are interfaces to Z3 and other solvers from pretty much any language you can imagine. Python and Haskell provide really high-level bindings that get rid of most of the boilerplate for you. You also have low-level bindings from C/C++/Java if that's your choice. See using floating point arithmetic with Z3 C++ APIs for a comparison of the styles.

Z3: iz3proof_itp::proof_error and iz3translation::unsupported error when using bitvectors

I am using the inbuilt interpolation feature on the latest (unstable branch) version of Z3. It works fine with SMT2 formulas containing integers. It does however, throw a iz3proof_itp::proof_error and a subsequent iz3translate::unsupported error (See Below) for the following SMT2 program -
(set-option :produce-models true)
(set-logic QF_AUFBV)
(declare-fun a () (_ BitVec 32))
(declare-fun b () (_ BitVec 32))
(declare-fun x1 () (_ BitVec 32))
(declare-fun x2 () (_ BitVec 32))
(declare-fun x3 () (_ BitVec 32))
(declare-fun y1 () (_ BitVec 32))
(declare-fun y2 () (_ BitVec 32))
(compute-interpolant
(= a (_ bv0 32))
(= b (bvneg (_ bv2 32)))
(= x1 (_ bv1 32))
(= y1 (_ bv0 32))
(= x2 (bvadd x1 a))
(= x3 (bvadd x2 b))
(= y2 (bvadd y1 a))
(bvsge x3 (_ bv0 32))
)
I tried it on the online version on rise4fun, and it worked fine. So after a bit of debugging, I found that the error is thrown from inside the function find_congruence_position in file iz3proof_itp.cpp.
So I made the following simple (maybe dangerous) change to the function to take care of the proof_error atleast for now -
Changing if(x == arg(arg(con,0),i) && (y == arg(arg(con,1),i)) at line 2431
to if((x == arg(arg(con,0),i) && (y == arg(arg(con,1),i))) || (y == arg(arg(con,0),i) && (x == arg(arg(con,1),i))))
I simply or'd the condition with its copy where x and y are interchanged - I had found that x and y sometimes have their values interchanged, maybe due to some proof techniques.
This did take care of the problem, I found that using equality and non-equality, along with bvadd or bvneg with BitVecs while computing interpolants worked. For example the following file worked -
(set-option :produce-models true)
(set-logic QF_AUFBV)
(declare-fun a () (_ BitVec 32))
(declare-fun b () (_ BitVec 32))
(compute-interpolant
(= a (_ bv0 32))
(= b (bvadd a (_ bv1 32)))
(= b (_ bv0 32))
)
But then I tried using relational operators, like bvsgt or bvsge, and it threw a new error -
terminate called after throwing an instance of 'iz3translation::unsupported'
I looked more into it, found out that the expression causing the problem was -
(not ((_ bit2bool 2) x2)) - it was assigned a PR_TH_LEMMA type and the UNKNOWN_THEORY kind. It seems that there is no support for such operations.
Since the online version is working, I'd like to know if it's possible to obtain that version. I read the previous questions and answers on StackOverflow, and I'm a bit confused. Some say BitVec theory is not supported (Although these posts are old), but then how is the online version working? Or am I doing something wrong? Any help is highly appreciated.
Actually, interpolation for bit vector arithmetic is not supported. It's interesting that it works on the web version. That version is quite old, however, and I think it predates the source-available version of Z3. I can think of two possible reasons why it works:
1) That version of interpolating Z3 used the "foci" prover as a backup. Whenever it encountered a part of the proof it didn't understand, it would package that part up as a lemma and reprove it using foci. The current version does not use foci (which is a third-party tool not available in source) and relies entirely on the proof generated by Z3.
2) The older version might have been doing bit-blasting in a different way. If all the non-local proof steps are purely propositional (using just the resolution rule) then it is easy to compute an interpolant.
As far as I understand it, however, computing interpolants from an efficient bit-vector solver (using all the known pre-processing tricks) is an open problem.

Z3 bitvector operations

How does one use the 'repeat' and 'rotate_left' bitvector operations?
More generally, where can I find detailed documentation of bitvector operations in the SMT2 scripting format used by Z3?
Everything I find seems to just go to tutorials, or broken links:
https://github.com/Z3Prover/z3/wiki/Documentation
http://research.microsoft.com/en-us/um/redmond/projects/z3/old/documentation.html
Trying to understand "repeat", "rotate_left", and "rotate_right" by guessing has been frustating. I cannot figure out how to use them. For example
(display (repeat #b01))
(display (repeat #b01 3))
(display (repeat 3))
(display (rotate_left #b0001 2))
gives
"repeat expects one non-zero integer parameter"
"repeat expects one argument"
"operator is applied to arguments of the wrong sort"
"rotate left expects one argument"
Where is the documentation? Hoping they didn't explain because all of this is standard, I also looked at smt-lib.org but that doesn't list these details either. So frustrating.
In addition to dejvuth's answer:
The SMT language is well documented (see smt-lib.org), for this particular issue the FixedSizeBitVectors theory and the QF_BV logic definition are relevant. The latter contains the definition for repeat:
((_ repeat i) (_ BitVec m) (_ BitVec i*m))
- ((_ repeat i) x) means concatenate i copies of x
Apart from those, David Cok wrote an excellent SMT2 tutorial.
The names of functions in the Z3 API is the same as in SMT2 where syntax permits, in this case prefixed with Z3_mk_ to indicate that they are functions that construct Z3 expressions.
For your example, you should write something like this
(declare-const a (_ BitVec 2))
(declare-const b (_ BitVec 6))
(assert (= a #b01))
(assert (= b ((_ repeat 3) a)))
(declare-const c (_ BitVec 4))
(declare-const d (_ BitVec 4))
(assert (= c #b0001))
(assert (= d ((_ rotate_left 2) c)))
(check-sat)
(get-model)
You will get
sat
(model
(define-fun d () (_ BitVec 4)
#x4)
(define-fun c () (_ BitVec 4)
#x1)
(define-fun b () (_ BitVec 6)
#b010101)
(define-fun a () (_ BitVec 2)
#b01)
)
A good document that I usually use is its API.

Is it possible to cast a bitvector of one bit into a boolean variable in SMTLib2?

I want to have a boolean variable that test if, e.g., the third bit of a bit vector is 0. The theory of bitvector allows to extract 1 bit as a bitvector, but not a boolean type. I wonder if I can do this cast. Thank you.
=== Update ===
I'm sorry if my question is not clear. But the answer of Nikolaj Bjorner is how to test a certain bit of a bit vector. While I want to assign the value of the first bit of a bit vector to a variable. I try to modify the example as follows:
(declare-fun x () (_ BitVec 5))
(declare-fun bit0 () Bool)
(assert (= (= #b1 ((_ extract 0 0) x)) bit0 ))
(check-sat)
And z3 complains:
(error "line 2 column 25: invalid declaration, builtin symbol bit0")
(error "line 3 column 44: invalid function application, sort mismatch on argument at position 2")
I need that variable bit0 for later use. Could you please give me a hint? Thanks.
Create an equality between the extraction of the third bit and a bit-vector with value 1 (and one bit).
E.g,
(declare-const x (_ BitVec 5))
(assert (= #b1 ((_ extract 2 2) x)))
(check-sat)
(get-model)
produces
sat
(model
(define-fun x () (_ BitVec 5)
#b00100)
)
What you are doing is just fine; it's just that bit0 is a reserved name. Just call it something else. (mybit0 would work, or some other unreserved name.)

How do I describe integer division in programming language this in Z3?

I am using SMT solver to help to analyze programs.
In programming languages, the following condition is satisfiable:
int x;
if((x/2) * 2 != x) {
//reachable
}
but for the integer type in mathmatics, this is not satisfiable.
Can I use Z3 to describe this?
Thanks.
Your example is also satisfiable in mathematical integer. You can find a model for x to be any odd integer.
In Z3, you should use machine integer i.e. bit-vectors for modeling:
(declare-const x (_ BitVec 32))
(assert (not (= (bvmul (bvsdiv x (_ bv2 32)) (_ bv2 32)) x)))
(check-sat)
(get-model)
This examplerise4fun link is indeed satisfiable.

Resources