For the following formula
(declare-fun i () Int)
(declare-fun #I () Int)
(declare-fun r2 () (Array Int Int))
(assert (= i 4))
(assert (forall ((#I Int))
(! (=> (and (>= #I 0) (< #I i)) (= (select r2 #I) 0))
:weight 10
:skolemid test
:qid test)))
(check-sat)
(get-model)
The Java API returns:
SATISFIABLE
(define-fun i () Int 4)
(define-fun #I () Int (- 1))
Why it generate specific value for quantifier variable "#I"?
Note that #I is declared twice:
(declare-fun #I () Int)
...
(assert (forall ((#I Int)) ...
Thus, it is indeed both, existential and universal. I've taken the liberty of copying this over into our issue tracker. As discussed there, this is not a bug: "Within the term namespace, bound variables can shadow one another as well as function symbol names ..." is what the SMT2 standard says (Remark 2, Sec. 3.3).
Related
I am currently trying to use Z3 to encode a simple program logic for an untyped language with sets.
My symbolic execution engine needs to prove the validity of the following formula:
To this end, we ask Z3 to check the satisfiability of:
which we then encode as the following SMT-LIB formula:
(define-sort Set () (Array Real Bool))
(define-fun singleton ((x Real)) Set
(store
((as const (Array Real Bool)) false)
x
true))
(define-fun set-union ((x Set) (y Set)) Set
((_ map (or (Bool Bool) Bool)) x y))
(declare-const head Real)
(declare-const tail Set)
(declare-const result Set)
(declare-const value Real)
(assert (forall ((x Real)) (=> (select tail x) (> x head))))
(assert (> head value))
(assert
(forall ((result Set))
(let ((phi1
(forall ((x Real)) (=> (select result x) (> x value))))
(phi2
(= result (union (singleton head) tail))))
(not (and phi1 phi2)))))
(check-sat)
When given this formula, the solver immediately outputs unknown.
My guess is that the problem lies on quantifying over a variable that is bound to a set.
To check this, I simplified the formula above, obtaining:
which we then encode as the following SMT-LIB formula:
(define-sort Set () (Array Real Bool))
(define-fun singleton ((x Real)) Set
(store
((as const (Array Real Bool)) false)
x
true))
(define-fun set-union ((x Set) (y Set)) Set
((_ map (or (Bool Bool) Bool)) x y))
(declare-const head Real)
(declare-const tail Set)
(declare-const result Set)
(declare-const value Real)
(assert (forall ((x Real))(=> (select tail x) (> x head))))
(assert (> head value))
(assert
(not
(forall ((x Real))
(=> (select (union (singleton head) tail) x)
(not (<= x value))))))
(check-sat)
When given this formula, the solver immediately outputs
unsat.
This confirms my guess that the problem lies on the quantification
over a variable that is bound to a set.
My question is whether or not Z3 supports formulae that include
quantification over sets. And, if so, what am I doing wrong?
Quantifier reasoning is always hard for SMT solvers, and in this case you have nested quantifiers. I'm not surprised to hear Z3 simply said Unknown in the first case. Also note that you are quantifying over what's essentially a function (Sets as you implemented are really functions), which makes it even more difficult. But even if you quantified over simpler things, nested quantifiers are never going to be easy to discharge.
Did you try skolemizing your formula, putting it into prenex-normal form, and getting rid of the existentials? That might get you a bit further though you might have to come up with appropriate patterns for instantiation.
(set-option :smt.mbqi true)
(declare-fun R(Int) Int)
(declare-const a Int)
(assert (= (R 0) 0))
(assert (forall ((n Int)) (=> (> n 0) (= (R n ) (+ (R (- n 1)) 1)))))
(assert (not (= a 5)))
(assert (not (= (R a) 5)))
(check-sat)
I have tried the above code in Z3,But Z3 unable to answer.Can you please guide me where i have made the mistake ?
As a general pattern don't expect MBQI to produce models
involving functions that
only have an infinite range of different values.
If you really must, then you can use the define-fun-rec construct to define
a recursive function. Z3 currently trusts that the definition
is well-formed (e.g., that the equation corresponding to the function
definition is satisfiable).
(set-option :smt.mbqi true)
(declare-fun F (Int) Int)
(define-fun-rec R ((n Int)) Int
(if (= n 0) 0
(if (> n 0) (+ (R (- n 1)) 1)
(F n))))
(declare-const a Int)
(assert (not (= a 5)))
(assert (not (= (R a) 5)))
(check-sat)
(get-model)
Z3 uses recursively defined functions passively during search: whenever
there is a candidate model for the ground portion of the constraints, it
checks that the function graph is adequately defined on the values of the candidate model. If it isn't, then the function definition is instantiated on the selected values until it is well defined on the values that are relevant
to the ground constraints.
I am using Z3 from the unstable branch to experiment with Horn clauses (commit 61385c8489b7fda11b518a67fe308ea3cfe28c3d). I could make Z3 infer a few loop invariants, which was nice. Yet, with the following simple examples I am puzzled by Z3's behavior. What am I missing here?
Example 1:
(set-logic HORN)
(declare-const C Int)
(assert (> C 2))
(check-sat)
(get-model)
I would expect a model but receive "unknown".
Example 2:
(set-logic HORN)
(define-fun step ((I Int) (I1 Int)) Bool (= I1 (+ I 1)))
(define-fun post ((I1 Int)) Bool (= I1 10))
(declare-fun pre (Int) Bool)
(assert (forall ((I Int) (I1 Int)) (=> (and (pre I) (step I I1)) (post I1))))
(check-sat)
(get-model)
I would expect a model telling me something about pre (e.g., that it is false or that it holds for 9), but receive
sat
(model )
Thanks.
I am executing your Example 1 with Z3 (both online and local) and I am obtaining
WARNING: unknown logic, ignoring set-logic command
sat
(model (define-fun C () Int 3) )
I am executing your Example 2 with mathsat (local) and I am obtaining
sat
( (C 3) )
I am executing your Example 2 with Z3 (both online and local) and I am obtaining
WARNING: unknown logic, ignoring set-logic command
sat
(model
(define-fun elem!0 () Int 0)
(define-fun elem!1 () Int 0)
(define-fun pre ((x!1 Int)) Bool false)
)
I'm using the latest Z3 version 3.2. I get an unexpected response from the "get-value" command. Here is the little script that I run in SMT-LIB2 compliant mode:
(set-option :produce-models true)
(declare-datatypes () ((Object o0 null)))
(declare-fun IF (Object) Int)
(declare-fun i2 () Int)
(assert (= (IF o0) i2))
(assert (= (IF null) 0))
(check-sat)
(get-value (i2))
The response is:
((i2 (IF o0)))
I expect to get just "0" back. Is there any way to ask Z3 to evaluate the returned term to a universe constant?
Here is the full model:
(model
;; universe for Object:
;; Object!val!0
;; -----------
;; definitions for universe elements:
(declare-fun Object!val!0 () Object)
;; cardinality constraint:
(forall ((x Object)) (= x Object!val!0))
;; -----------
(define-fun i2 () Int
(IF o0))
(define-fun IF ((x!1 Object)) Int
(ite (= x!1 Object!val!0) 0
0))
)
I'm also puzzled why o0 is not defined in the model.
This has been fixed in Z3 4.0.
Z3 4.0 will be released soon. In the meantime, you can use it online: http://rise4fun.com/Z3/75y
This link can be used to execute your example. Z3 4.0 produces the expected result.
Regarding the bug, the main problem is that Z3 is treating Object as an uninterpreted sort.
In Z3 3.2, you can workaround this bug by including
(set-option :auto-config false)
in the beginning of your script.
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)