counterexample output of an aaary element of z3 tool
I try the following python code, and get an counterexample
from z3 import Solver, parse_smt2_string
s = Solver()
#str1="(declare-const x Int) (declare-const y Int) (declare-const z Int) (declare-const a1 (Array Int Int)) (declare-const a2 (Array Int Int)) (declare-const a3 (Array Int Int)) (assert (= (select a1 x) x)) (assert (= (store a1 x y) a1))"
str1="(define-sort A () (Array Int Int Int)) (define-fun bag-union ((x A) (y A)) A ((_ map (+ (Int Int) Int)) x y)) (declare-const s1 A) (declare-const s2 A) (declare-const s3 A) (assert (= s3 (bag-union s1 s2))) (assert (= (select s1 0 0) 5)) (assert (= (select s2 0 0) 3)) (assert (= (select s2 1 2) 4))"
s.add(parse_smt2_string(str1))
s.check()
m = s.model()
for d in m:
print(d,m[d])
if str(s.check())=="sat":
print(s.model())
m = s.model()
for d in m:
print(d,m[d])
(s2, [(1, 2) -> 4, (0, 0) -> 3, else -> 7719])
(s3, [(1, 2) -> 8859, (0, 0) -> 8, else -> 8955])
(s1, [(1, 2) -> 8855, (0, 0) -> 5, else -> 1236])
(k!1, [(1, 2) -> 4, (0, 0) -> 3, else -> 7719])
(k!2, [(1, 2) -> 8859, (0, 0) -> 8, else -> 8955])
(k!0, [(1, 2) -> 8855, (0, 0) -> 5, else -> 1236])
....
The lines such as (k!1, [(1, 2) -> 4, (0, 0) -> 3, else -> 7719]) confuse me?
They seem duplicate lines (s2, [(1, 2) -> 4, (0, 0) -> 3, else -> 7719.
Can I add an option not to show these lines?
You're mixing SMTLib and Python inputs into one; there's really no good reason to do this. Either program in Python, or in SMTLib. When you use z3 this way, you have no access to the variables you have defined. If you directly program in z3py, then you can simply query the values of the variables you have defined with ease. Other than that, your best bet is to simply check if the name is of the form k!n and skip it inside your for loop.
Also note that what will be printed in the output for these "auxiliary" model variables is quite z3 version dependent. When I run your program with the latest version of z3 from github sources, it prints:
(s2, Store(K(Int, 4), 0, 0, 3))
(s1, K(Int, 5))
(s3, Store(K(Int, 9), 0, 0, 8))
[s2 = Store(K(Int, 4), 0, 0, 3),
s1 = K(Int, 5),
s3 = Store(K(Int, 9), 0, 0, 8)]
(s2, Store(K(Int, 4), 0, 0, 3))
(s1, K(Int, 5))
(s3, Store(K(Int, 9), 0, 0, 8))
which has no mention of k!n variables. Mixing the two input languages this way is merely asking for a lot of confusion.
Related
I wanted to find the maximum value of a variable under some simple constraints. But the result is not the optimum (max). Indeed, we can add another constraint and the solver still find another solution...
I also tried this example in python with the Optimize solver and maximize(r), but I get the same result. I also checked the upper bound (with the upper method) and I get the same erroneous result (4).
I'm not used to playing with the optimization feature of Z3, I generally only make proof; that's why I'm almost sure that the mistake is mine...
For now, I use a loop over the check-sat in python and iteratively add a constraint (r > result). It's working but it's neither elegant nor efficient...
; (set-logic QF_LIA)
(define-const x Int 9)
(define-const a Int 3)
(define-const b Int 4)
(define-const c Int 4)
(define-const d Int 5)
(declare-const i Int)
(declare-const j Int)
(declare-const t Int)
(declare-const r Int)
(assert (>= i 0))
(assert (>= j 0))
(assert (= t (+ (* i b) (* j d) 1)))
(assert (= r (+ (* i a) (* j c) c)))
(assert (<= t x))
(maximize r)
(check-sat)
;sat
(get-model)
;(model
; (define-fun i () Int
; 0)
; (define-fun j () Int
; 0)
; (define-fun r () Int
; 4)
; (define-fun t () Int
; 1)
;)
(get-value (r))
;((r 4))
(assert (> r 4))
(check-sat)
;sat
(get-model)
;(model
; (define-fun i () Int
; 2)
; (define-fun j () Int
; 0)
; (define-fun r () Int
; 10)
; (define-fun t () Int
; 9)
;)
$ z3 --version
Z3 version 4.8.7 - 64 bit
I cannot replicate this. When I run your program, it gives me r = 10, and if I then further assert (> r 10), then I get unsat.
However, I'm using z3 4.8.13, and I noticed that your z3 version is rather old, 4.8.7; which dates to late 2019. See if you can upgrade: https://github.com/Z3Prover/z3/releases
(The latest released version is 4.8.12; though you can also directly build from their GitHub sources, which will be tagged 4.8.13.)
Please report back if you still see the issue after upgrading.
I want to capture the assertion inside fac.
int f( x )
{
if( x == 1) return 1;
else{
assert( x > 0 );
return 2;
}
}
int g (x)
{ assert( x > 5 );
return f(x-1) + f(x-2);
}
I want an smt2 code for this.
I can do this by striping the argument and making it global with unique name (also rename inside f), then do this 3 times each with a different name for function. Like below :
( declare-const x1 Int )
(define-fun f1 () Int
( ite ( x1 > 0) 1 2 )
)
(assert (> x1 0))
( declare-const x2 Int )
(define-fun f2 () Int
( ite ( x2 > 0) 1 2 )
)
(assert (> x2 0))
( declare-const x3 Int )
(define-fun g1 () Int
( + f1 f2 )
)
(assert (> x3 5))
I don't want to this. Is there any other way to do this without repeating ?
EDIT
My purpose is to find values violating the asserts.
As far as I know, it is not possible to embed assertions within function definitions.
What I would try to do is to separate the expected behavior, the input assumptions and the output guarantees (if any).
Example:
(define-fun f ((x Int)) Int
(ite (= x 1) 1 2)
)
(define-fun f-helper ((x Int)) Bool
(< 0 x)
)
(define-fun g ((x Int)) Int
(+ (f (- x 1)) (f (- x 2)))
)
(define-fun g-helper ((x Int)) Bool
(and (< 5 x)
(f-helper (- x 1))
(f-helper (- x 2))
)
)
(declare-const x Int)
(declare-const y Int)
(assert (and (= y (g x))
(g-helper x)
))
(check-sat)
(get-model)
In this example we use f to model the behavior of the original function f, and f-helper to model the assumptions of f. The output, using the online Z3 tool, is as follows:
sat
(model
(define-fun x () Int
6)
(define-fun y () Int
4)
)
I would conclude saying that this approach could become tricky as soon as f and g are used inside both positive and negative contexts.. in this case one should pay extra attention that the polarity of the assertions is correct wrt. the expected result.
I have a problem with quantifier.
Let a(0) = 0, and a(n+1) would be either a(n)+1 or a(n)+2 based on the value of x(n). We may expect that for any kind of x(.) and for all n, a(n) <= n*2.
Here is the code for Z3:
(declare-fun a (Int) Int)
(declare-fun x (Int) Int)
(declare-fun N () Int)
(assert (forall
((n Int))
(=> (>= n 0)
(= (a (+ n 1))
(ite (> (x n) 0)
(+ (a n) 1)
(+ (a n) 2)
)
)
)
))
(assert (= (a 0) 0))
(assert (> (a N) (+ N N)))
(check-sat)
(get-model)
I hope Z3 could return "unsat", while it always "timeout".
I wonder if Z3 could handle this kind of quantifier, and if somebody could give some advice.
Thanks.
The formula is SAT, for N < 0, the graph of a is underspecified.
But the default quantifier instantiation engine can't determine this. You can take advantage of that you are defining a recursive function to enforce a different engine.
;(declare-fun a (Int) Int)
(declare-fun x (Int) Int)
(declare-fun y (Int) Int)
(declare-fun N () Int)
(define-fun-rec a ((n Int)) Int
(if (> n 0) (if (> (x (- n 1)) 0) (+ (a (- n 1)) 1) (+ (a (- n 1)) 2)) (y n)))
(assert (= (a 0) 0))
(assert (> (a N) (+ N N)))
(check-sat)
(get-model)
As Malte writes, there is no support for induction on such formulas so don't expect Z3 to produce induction proofs. It does find inductive invariants on a class of Horn clause formulas, but it requires a transformation to cast arbitrary formulas into this format.
Thanks, Malte and Nikolaj.
The variable N should be bounded:
(assert (> N 0))
(assert (< N 10000))
I replace
(assert (> (a N) (+ N N)))
with
(assert (and
(not (> (a N) (+ N N)))
(> (a (+ N 1)) (+ (+ N 1) (+ N 1)))
))
and it works for both definition of a(n).
Does this a kind of inductive proof as you mentioned?
Here are the two blocks of code, and both of them return "unsat":
(declare-fun a (Int) Int)
(declare-fun x (Int) Int)
(declare-fun N () Int)
(assert (forall
((n Int))
(=> (>= n 0)
(= (a (+ n 1))
(ite (> (x n) 0)
(+ (a n) 1)
(+ (a n) 2)
)
))
))
(assert (= (a 0) 0))
(assert (> N 0))
(assert (< N 10000))
;(assert (> (a N) (+ N N)))
(assert (and
(not (> (a N) (+ N N)))
(> (a (+ N 1)) (+ (+ N 1) (+ N 1)))
))
(check-sat)
;(get-model)
and
(declare-fun x (Int) Int)
(declare-fun y (Int) Int)
(declare-fun N () Int)
(define-fun-rec a ((n Int)) Int
(if (> n 0)
(if (> (x (- n 1)) 0) (+ (a (- n 1)) 1) (+ (a (- n 1)) 2)) (y n)))
(assert (= (a 0) 0))
(assert (> N 0))
(assert (< N 10000))
;(assert (> (a N) (+ N N)))
(assert (and
(not (> (a N) (+ N N)))
(> (a (+ N 1)) (+ (+ N 1) (+ N 1)))
))
(check-sat)
;(get-model)
It seems that uninterpret functions treat arguments as unordered.
For example,
(declare-fun Lturn (Int Int Int) Bool)
(assert (forall ((x Int) (y Int) (z Int))
(not (= (Lturn x y z) (Lturn x z y)))))
(check-sat)
The result is UNSAT.
The above code is available here: http://rise4fun.com/Z3/hkpwO
To overcome this situation, I tried using array:
(declare-fun Lturn ((Array Int Int)) Bool)
(assert (forall ((A1 (Array Int Int)) (A2 (Array Int Int)))
(=> (and (= (select A1 1) (select A2 1))
(= (select A1 2) (select A2 3))
(= (select A1 3) (select A2 2)))
(not (= (Lturn A1) (Lturn A2))))))
(check-sat)
The result is "unknown."
The above code is available here: http://rise4fun.com/Z3/bdTL
Is there any method to let the Array version be SAT?
Function arguments are not unordered. Can you give a function Lturn that would make your assertion SAT? Here's a simpler case with just two arguments: http://rise4fun.com/Z3/Zsjs
For x == 0 && y == 0 && z == 0 there is no function such that f(x, y, z) != f(x, z, y) because f(0, 0, 0) != f(0, 0, 0) is always false.
Using the Z3 .NET API I'm trying to do something similar as the following example which I have taken from the Z3 Guide:
(define-sort A () (Array Int Int Int))
(define-fun bag-union ((x A) (y A)) A
((_ map (+ (Int Int) Int)) x y))
(declare-const s1 A)
(declare-const s2 A)
(declare-const s3 A)
(assert (= s3 (bag-union s1 s2)))
(assert (= (select s1 0 0) 5))
(assert (= (select s2 0 0) 3))
(assert (= (select s2 1 2) 4))
(check-sat)
(get-model)
How do I define the + function such that I can use it in MkMap?
MkMap expects a function declaration, so you need to get a reference to the + function declaration, which you can do by using MkAdd and getting a reference to its function declaration with .FuncDecl:
Context z3 = new Context();
Sort twoInt = z3.MkTupleSort(z3.MkSymbol("twoInt"), new Symbol[] { z3.MkSymbol("a"), z3.MkSymbol("b") }, new Sort[] { z3.IntSort, z3.IntSort });
Sort A = z3.MkArraySort(twoInt, z3.IntSort);
ArrayExpr x = z3.MkArrayConst("x", twoInt, z3.IntSort);
ArrayExpr y = z3.MkArrayConst("y", twoInt, z3.IntSort);
ArrayExpr map = z3.MkMap(z3.MkAdd(z3.MkIntConst("a"), z3.MkIntConst("b")).FuncDecl, x, y);