I would like to know how iZ3 can be used to extract symmetric interpolants. Internally iZ3 uses FOCI and FOCI does have symmetric interpolant extraction.
FOCI does not accept smt format So i wanted to know if there is any method of extracting symmetric interpolants from iz3 itself
Thanks in advance
You can get symmetric interpolants as a special case of tree interpolants. Here's an example:
(declare-const a Int)
(declare-const b Int)
(declare-const c Int)
(declare-const d Int)
(compute-interpolant
(and
(interp (<= 0 a))
(interp (and (= a b) (= b c)))
(interp (and (= c d) (<= d -1)))))
Here is z3's output:
unsat
(>= a 0)
(= a c)
(<= c (- 1))
Have a look at the tutorial at http://rise4fun.com/iZ3/tutorial/guide under "Tree interpolants".
Related
I am trying to find a solution for the function penta(n) = (n * (3n -1)) / 2 and where penta (z) = penta (a) + penta(b) for all number positives. That works until the integer division (div) is part ofthe definition, but when it is added in the definition I either got a timeout or an unknown.
I would expect to get 8 , 7 , 4. Any idea on what I did wrongly?
(declare-const a Int)
(declare-const b Int)
(declare-const z Int)
(define-fun penta ((n Int)) Int (div (* (- (* 3 n ) 1) n) 2) )
(assert (= (penta z) (+ (penta a) (penta b)) ))
(assert (> a 1))
(assert (> b 1))
(assert (> z 1))
(check-sat)
(get-model)
I am using the version on the http://rise4fun.com/Z3 website and the version 4.1 (x64).
The main issue is that the problem uses integer multiplication between two non-numeric arguments. There are no decision procedures for general Diophantine problems so Z3 does a best effort, which does not favor model enumeration.
When you don't use integer division, Z3 will try a partial heuristic based on
converting the problem into finite domain bit-vectors to find models. It invokes
this heuristic by performing a syntactic check on the formulas. THe syntactic check fails when you use the operator (div .. 2).
You can encode (div x 2) so the heuristic picks up the problem
by introducing fresh variables and bounding them:
(declare-const penta_z Int)
(declare-const penta_a Int)
(declare-const penta_b Int)
(assert (or (= (* 2 penta_z) (penta z)) (= (+ 1 (* 2 penta_z)) (penta z))))
(assert (or (= (* 2 penta_a) (penta a)) (= (+ 1 (* 2 penta_a)) (penta a))))
(assert (or (= (* 2 penta_b) (penta b)) (= (+ 1 (* 2 penta_b)) (penta b))))
(assert (= penta_z (+ penta_a penta_b) ))
(assert (> a 1))
(assert (> b 1))
(assert (> z 1))
(assert (>= penta_z 0))
(assert (<= penta_z 100))
You can also directly encode your problem using bit-vectors although this starts getting error prone because you have to deal with how to handle overflows.
I am a beginner user of Z3. Recently, I have been using z3 to verify some problems. Here is one problem I tried: (x < 0 && y < 0) implies x/y >= 0, below are the programs I wrote:
(declare-const x Int)
(declare-const y Int)
(define-fun assumption() Bool
(and (< x 0) (< y 0))
)
(define-fun predicate() Bool
(<= 0 (div x y))
)
(assert (not (=> assumption predicate)))
(check-sat)
When I use 'z3 -smt2 filename' to verify this program, it works and return unsat. However, when I later modify the program to:
(declare-const x Int)
(declare-const y Int)
(define-fun assumption() Bool
(and (< x 0) (< y 0))
)
(define-fun predicate() Bool
(<= 0 (div (* -1 x) (* -1 y)))
)
(assert (not (=> assumption predicate)))
(check-sat)
This cause z3 to timeout when I changed 'x/y' to (-1 * x)/(-1 * y) and somehow I need to add -1 there. I am confused why this happened and why multiplied by a constant makes this problem more complex.
Can somebody help figure out why this happened?
Thank you!
There is very limited support for non-linear arithmetic, such as division where the divisor is a variable.
So Z3 will do a best effort, but in no way be sure to provide decisions on every formula with non-linear arithmetical operations. So for example, you can enter Diophantine equations into Z3, but not expect it to provide sat/unsat answers.
Rather than trying some infinite search, Z3 may prefer to give up and return unknown.
(Note: This is just a comment instead of an answer. I have to do so because I don't have sufficient reputation to add a comment.)
Here is the quote from the Z3 guide about integer division, modulo and reminder operators:
Z3 also has support for division, integer division, modulo and remainder operators. Internally, they are all mapped to multiplication.
(declare-const a Int)
(declare-const r1 Int)
(declare-const r2 Int)
(declare-const r3 Int)
(declare-const r4 Int)
(declare-const r5 Int)
(declare-const r6 Int)
(assert (= a 10))
(assert (= r1 (div a 4))) ; integer division
(assert (= r2 (mod a 4))) ; mod
(assert (= r3 (rem a 4))) ; remainder
(assert (= r4 (div a (- 4)))) ; integer division
(assert (= r5 (mod a (- 4)))) ; mod
(assert (= r6 (rem a (- 4)))) ; remainder
(declare-const b Real)
(declare-const c Real)
(assert (>= b (/ c 3.0)))
(assert (>= c 20.0))
(check-sat)
(get-model)
In Z3, division by zero is allowed, but the result is not specified. Division is not a partial function. Actually, in Z3 all functions are total, although the result may be underspecified in some cases like division by zero.
It is unclear what is the behavior when the arguments are negative. In other words, the mapping to multiplication for these operations is not clear.
This is the reduction of a more interesting problem, in which the missing property was (for positive k,M and N), that ((k % M) * N) < M*N. Below is an encoding of the simpler problem that a <= b ==> (a*c) <= (b*c). Such a query succeeds (we get unsat), but if the expression b is replaced by b+1 (as in the second query below) then we get unknown, which seems surprising. Is this the expected behaviour? Are there options to improve the handling of such inequalities? I tried with and without configuration options, and various versions of Z3, including the current unstable branch. Any tips would be much appreciated!
(declare-const a Int)
(declare-const b Int)
(declare-const c Int)
(assert (> a 0))
(assert (> b 0))
(assert (> c 0))
(assert (<= a b))
(assert (not (<= (* a c) (* b c))))
(check-sat)
(assert (<= a (+ b 1)))
(assert (not (<= (* a c) (* (+ b 1) c))))
(check-sat)
This falls into nonlinear integer arithmetic (which has an undecidable decision problem, see, e.g., How does Z3 handle non-linear integer arithmetic? ), so it's actually not too surprising Z3 returns unknown for some examples, although I guess a bit surprising that it toggled between unsat and unknown for quite similar examples.
If it works for your application, you can try a type coercion: encode the constants as Real instead of Int. This will allow you to use Z3's complete solver for nonlinear real arithmetic and returns unsat with check-sat.
Alternatively, you can force Z3 to use the nonlinear solver even for the integer encoding with (check-sat-using qfnra-nlsat) as in the following based on your example (rise4fun link: http://rise4fun.com/Z3/87GW ):
(declare-const a Int)
(declare-const b Int)
(declare-const c Int)
(assert (> a 0))
(assert (> b 0))
(assert (> c 0))
(assert (<= a b))
(assert (not (<= (* a c) (* b c))))
;(check-sat)
(check-sat-using qfnra-nlsat) ; unsat
(assert (<= a (+ b 1)))
(assert (not (<= (* a c) (* (+ b 1) c))))
; (check-sat)
(check-sat-using qfnra-nlsat) ; unsat
Some more questions and answers on similar subjects:
Combining nonlinear Real with linear Int
z3 fails with this system of equations
Using Z3Py online to prove that n^5 <= 5 ^n for n >= 5
Can z3 always give result when handling nonlinear real arithmetic
Z3 Theorem Prover: Pythagorean Theorem (Non-Linear Artithmetic)
I have 3 variables a, b and c. I need to calculate c = absolute(b-a).
I encode this statement in Z3 as
(assert (>= c 0))
(assert (or (= c (- a b) (= c (- b a))))
I was thinking, is there a more efficient way of writing it in Z3?
Does Z3 have internal support for calculating absolute value?
Also, I hope there won't be any performance penalty for writing code like this, rather than using some other way.
Your encoding is correct. However, users usually encode the absolute value function using
(define-fun absolute ((x Int)) Int
(ite (>= x 0) x (- x)))
Then, they can write constraints such as:
(assert (= c (absolute (- a b))))
Here is the complete example (also available online at rise4fun):
(define-fun absolute ((x Int)) Int
(ite (>= x 0) x (- x)))
(declare-const a Int)
(declare-const b Int)
(declare-const c Int)
(assert (= a 3))
(assert (= b 4))
(assert (= c (absolute (- a b))))
(check-sat)
(get-model)
I have a file containing:
(declare-const a Int)
(declare-const b Int)
(declare-const c Int)
(declare-const d Real)
(declare-const e Real)
(assert (> a (+ b 2)))
(assert (= a (+ (* 2 c) 10)))
(assert (<= (+ c b) 1000))
(assert (>= d e))
(check-sat)
(get-model)
and, according to the online tutorial, running z3 on this file should return:
sat
(model
(define-fun c () Int
(- 5))
(define-fun a () Int
0)
(define-fun b () Int
(- 3))
(define-fun d ()
Real 0.0)
(define-fun e ()
Real 0.0)
)
So I know this is legal Z3 input. However, whenever I run "z3 [option] " all I get is error messages no matter what option I choose -- including none. Can someone tell me how to correctly invoke Z3 on the input file?
Regards.
Z3 supports many input formats. It uses the file extension to guess which parser will be used. If the extension is .smt2. It will use the SMT 2.0 parser. You can also specify which parser should be used. The option -smt2 will force Z3 to use the SMT 2.0 parser. Finally, Z3 does not enable model construction by default. So, you should use the option MODEL=true, or add the command (set-option :produce-models true) in the beginning of your script.
If you want to use a very old version of Z3, you will have to use SMT 1.0 format.
This format is described at: http://goedel.cs.uiowa.edu/smtlib/papers/format-v1.2-r06.08.30.pdf
That being said, I strongly encourage you to upgrade. The SMT 1.0 is not very user friendly, and most documentation/tutorials for SMT are in SMT 2.0 format.
Here is your example in this format:
(benchmark file
:extrafuns ((a Int) (b Int) (c Int) (d Real) (e Real))
:assumption (> a (+ b 2))
:assumption (= a (+ (* 2 c) 10))
:assumption (<= (+ c b) 1000)
:assumption (>= d e)
:formula true)