Z3: an exception with int2bv - z3

(declare-const a Int)
(declare-const b Int)
(declare-const c (_ BitVec 32))
(declare-const d (_ BitVec 32))
(assert (= b (bv2int c)))
(assert (= c (int2bv a)))
(check-sat)
I am confused about the exception "int2bv expects one parameter" caused by the code above, how to use function int2bv correctly?

This is because int2bv is a parametric function and the SMT2 syntax for these is (_ f p1 p2 ...), so in this case the correct syntax is
((_ int2bv 32) a)
Note that int2bv is essentially treated as uninterpreted; the API documentation says:
"NB. This function is essentially treated as uninterpreted. So you cannot expect Z3 to precisely reflect the semantics of this function when solving constraints with this function." (from here)

Related

Is there any templating engine for smtlib2 (alternatively z3)?

I was wondering if there are is any way to represent an smtlib2 formula as a template. For instance:
(declare-fun b () (_ BitVec 16))
(declare-fun a () (_ BitVec 8))
(declare-fun c () (_ BitVec 32))
(assert (= c (bvor ((_ zero_extend 24) a) ((_ zero_extend 16) b))))
can be represented as (say using jinja2-style templating)
((declare-fun {{B_VAR}} () (_ BitVec {{B_VAR_SIZE}}))
(declare-fun {{A_VAR}} () (_ BitVec {{A_VAR_SIZE}}))
(declare-fun {{C_VAR}} () (_ BitVec {{C_VAR_SIZE}}))
(assert (= {{C_VAR}} (bvor ((_ zero_extend 24) {{A_VAR}}) ((_ zero_extend {{B_VAR_SIZE}}) {{B_VAR}}))))
And then the template can be rendered to represent an actual smtlib formula:
(declare-fun P () (_ BitVec 16))
(declare-fun Q () (_ BitVec 8))
(declare-fun R () (_ BitVec 32))
(assert (= R (bvor ((_ zero_extend 24) Q) ((_ zero_extend 16) P))))
Is there any natural way to do this other than use something like jinja2 and create my own template for every formula?
Alternatively, considering that I already have a z3::expr_vector that represents an SMT formula, is there a way to "templatize" it? My eventual goal is that I would like to "invoke" the templatized version with unique bitvector names for each invocation. Does the z3 C++ API have any methods which naturally allows one to achieve this?
There isn't anything in the z3 C++/Java API's to do this. However, if you're programming in C++ or Java, simply write a function that produces this expression. You're saying that you already have a z3::expr_vector; you should instead write a function that takes the relevant parts (i.e., variable names and sizes), and then constructs this final expression; i.e., regular programming using the z3 AST.

How to declare predicates over arbitrary sized bit bit vectors in z3?

I encountered a problem while trying to define some rules over bit vectors in z3. If I try to solve the following file with z3
(declare-rel FunnyFun ((_ BitVec 64)))
(declare-var A (_ BitVec 64))
(declare-var B (_ BitVec 64))
(rule (=> (= B (bvadd A #x0000000000000001))
(FunnyFun B)))
(declare-rel q1 ())
(rule (=> (FunnyFun #x0000000000000001) q1))
(query q1)
I get the error
(error "query failed: Rule contains infinite sorts in rule <null>:
FunnyFun(#0) :-
(= (:var 0) (bvadd (:var 1) #x0000000000000001)).
")
Funnily enough z3 instantly gives the expected result (sat) when using smaller bit widths:
(declare-rel FunnyFun ((_ BitVec 60)))
(declare-var A (_ BitVec 60))
(declare-var B (_ BitVec 60))
(rule (=> (= B (bvadd A #x000000000000001))
(FunnyFun B)))
(declare-rel q1 ())
(rule (=> (FunnyFun #x000000000000001) q1))
(query q1)
Is this a bug or am I missing some constraints (I assumed BitVec can have an arbitrary bit width)?
I tried different z3 version (4.6.0, 4.8.3 and 4.8.5) and all of them showed this behavior.
This limitation is by design. See here: https://github.com/Z3Prover/z3/issues/1698

Bitvector arithmetics on Z3

I'm trying to use Z3 to solve arithmetic equations using bitvector arithmetic. I was wondering if there is a way to handle also Real numbers. For example if I can specify a constant different from #x1 and use real number instead.
(set-option :pp.bv-literals false)
(declare-const x (_ BitVec 4))
(declare-const y (_ BitVec 4))
(assert (= (bvadd x y) #x1))
(check-sat)
(get-model)
Yes, both SMT-Lib (and Z3) fully support real numbers: http://smtlib.cs.uiowa.edu/theories-Reals.shtml
You can simply write your example as follows:
(declare-const x Real)
(declare-const y Real)
(assert (= (+ x y) 1))
(check-sat)
(get-model)
You can also mix/match Int/Real/Bitvector, so long as everything is properly typed. Here's an example showing how to use Ints and Reals together:
(declare-const a Int)
(declare-const b Int)
(declare-const c Int)
(declare-const d Real)
(declare-const e Real)
(assert (> e (+ (to_real (+ a b)) 2.0)))
(assert (= d (+ (to_real c) 0.5)))
(assert (> a b))
(check-sat)
(get-model)
However, note that conversion from bit-vectors to integers is usually uninterpreted. See here for a discussion: Z3 int2bv operation

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.

Z3: Extracting existential model-values

I'm playing around with Z3's QBVF solver, and wondering if it's possible to extract values from an existential assertion. To wit, let's say I have the following:
(assert (exists ((x (_ BitVec 16))) (forall ((y (_ BitVec 16))) (bvuge y x))))
This basically says that there is a "least" 16-bit unsigned value. Then, I can say:
(check-sat)
(get-model)
And Z3-3.0 happily responds:
sat
(model (define-fun x!0 () (_ BitVec 16)
#x0000)
)
Which is really cool. But what I want to do is to be able to extract pieces of that model via get-value. Unsurprisingly, none of the following seem to work
(get-value (x))
(get-value (x!0))
In each case Z3 rightly complains there's no such constant. Clearly Z3 has that information as evidenced by the response to the (check-sat) call. Is there any way to access the existential value automatically via get-value, or some other mechanism?
Thanks..
In Z3, get-value only allows the user to reference “global” declarations.
The existential variable x is a local declaration. Thus, it can’t be accessed using get-value.
By default, Z3 eliminates existential variables using a process called “skolemization”.
The idea is to replace existential variables with fresh constants and function symbols.
For example, the formula
exists x. forall y. exists z. P(x, y, z)
is converted into
forall y. P(x!1, y, z!1(y))
Note that z becomes a function because the choice of z may depend on y.
Wikipedia has an entry on skolem normal form
That being said, I never found a satisfactory solution for the problem you described.
For example, a formula may have many different existential variables with the same name.
So, it is not clear how to reference each instance in the get-value command in a non-ambiguous way.
A possible workaround for this limitation is to apply the skolemization step “by hand”, or at least for the variables you want to know the value.
For example,
(assert (exists ((x (_ BitVec 16))) (forall ((y (_ BitVec 16))) (bvuge y x))))
is written as:
(declare-const x (_ BitVec 16))
(assert (forall ((y (_ BitVec 16))) (bvuge y x)))
(check-sat)
(get-value x)
If the existential variable is nested in a universal quantifier such as:
(assert (forall ((y (_ BitVec 16))) (exists ((x (_ BitVec 16))) (bvuge y x))))
(check-sat)
(get-model)
A fresh skolem function can be used to obtain the value of x for each y.
The example above becomes:
(declare-fun sx ((_ BitVec 16)) (_ BitVec 16))
(assert (forall ((y (_ BitVec 16))) (bvuge y (sx y))))
(check-sat)
(get-model)
In this example, sx is the fresh function. The model, produced by Z3, will assign an interpretation for sx. In version 3.0, the interpretation is the identity function. This function can be used to obtain the value of x for each y.

Resources