Z3: Java API for quantified formulas - z3

I am trying to use the JAVA API of Z3 to construct the following formula
(assert (forall ((x_0 fcn_sort_2) (x_1 fcn_sort_2))
(=> (and (= (domain x_0)
(domain x_1))
(forall ((y Int))
(= (alpha x_0 y)
(alpha x_1 y))))))
(= x_0 x_1)))))
by the following code
Sort[] types1 = new Sort[2]; // for x_0 and x_1
Expr[] xs1 = new Expr[2];
for (int j = 0; j < 2; j++) {
types1[j] = this.getZ3Sort("fcn_sort_2");
xs1[j] = ctx.mkConst(ctx.mkSymbol("x_" + Integer.toString(j)), types1[j]);
}
Sort[] types2 = new Sort[1]; // for y
Expr[] xs2 = new Expr[1];
types2[0] = ctx.mkIntSort();
xs2[0] = ctx.mkConst(ctx.mkSymbol("y"), types2[0]);
FuncDecl alpha_fcn = this.getFuncSymbol("alpha");
Expr[] arg0 = new Expr[] { xs1[0], xs2[0] };
Expr[] arg1 = new Expr[] { xs1[1], xs2[0] };
BoolExpr
// (= (alpha x_0 y) (alpha x_1 y))
body2 = ctx.mkEq(ctx.mkApp(alpha_fcn, arg0), ctx.mkApp(alpha_fcn, arg1)),
// forall ((y Int)) ...
bf2 = ctx.mkForall(xs2, body2, 1, null, null, null, null);
FuncDecl domain_fcn = this.getFuncSymbol("domain");
BoolExpr
// (= x_0 x_1)
eqX = ctx.mkEq(xs1[0], xs1[1]),
// (= (domain x_0) (domain x_1))
eqDo = ctx.mkEq(ctx.mkApp(domain_fcn, new Expr[] {xs1[0]}), ctx.mkApp(domain_fcn, new Expr[] {xs1[1]})),
// (and ...)
andNode = ctx.mkAnd(eqDo, bf2),
// (=> ...)
body1 = ctx.mkImplies(andNode, eqX),
// (forall ((x_0 ...) (x_1 ...))
bf1 = ctx.mkForall(xs1, body1, 1, null, null, null, null);
where getFuncSymbol is my own function to get a FuncDecl which is declared before.
Unfortunately, I have the wrong result with "let" and "a!1"
(assert (forall ((x_0 fcn_sort_2) (x_1 fcn_sort_2))
(let ((a!1 (and (= (domain_fcn_sort_2 x_0) (domain_fcn_sort_2 x_1))
(forall ((y Int))
(= (alpha_fcn_sort_2 x_0 y) (alpha_fcn_sort_2 x_1 y))))))
(=> a!1 (= x_0 x_1)))))
I found that something wrong, "let ((a!1", happens at the line
body1 = ctx.mkImplies(andNode, eqX)
Am I missing something? Thank you

let-expressions are introduced during pretty-printing in an attempt to make the output more concise. Here, it simply means that whenever the name a!1 occurs in the output, you can replace it with (and ...). Semantically, this doesn't make a difference.

Related

Having assertions inside definitions in SMT

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.

Z3 Fixedpoints: What is the meaning of formula false in model?

I'm trying to check a simple Timed Automata for reachability using Z3's fixed-point engine.
The TA I'm modeling is:
-->(x = 0 & 0 <= c <= 5) --[c > 2]-->(x = 1)
I want to verify that the state x = 1 & c = 3 is reachable. To do that I input the following into Z3:
(declare-rel T (Int Real Int Real))
(declare-rel REACH (Int Real))
(declare-var x Int)
(declare-var c Real)
(declare-var nx Int)
(declare-var nc Real)
(declare-var delay Real)
(rule (! (=> (and (= x 0) (> c 2.0)) (T x c 1 c)) :named stepint))
(rule (! (=> (and (REACH x c) (T x c nx nc)) (REACH nx nc)) :named tstep))
(rule (! (=> (and (= c 0.0) (= x 0)) (REACH x c)) :named initialstates))
(rule (! (let ((a!1 (and (>= delay 0.0) (= nc (+ c delay)) (or (not (= x 0)) (< nc 5.0)))))
(=> a!1 (T x c x nc))) :named TICK))
(query (and (REACH x c) (= x 1) (= c 3.0))
:print-certificate true)
When I run the above in Z3 on rise4fun I get back:
formula false in model: (= REACH_1_0 3.0)
formula false in model: (= REACH_0_0 1)
formula false in model: (= query!0_0_n 1)
formula false in model: (= query!0_1_n 3.0)
sat
(REACH 1 3.0)
Which indicates that x= 1 & c = 3 is reachable. What does "formula false in model mean"? Is this simply informational or is Z3 warning me about potentially poorly formed input?
The bugs appear fixed in the "opt" branch. I have not ported the fixes to the unstable branch yet. It will happen, but if impatient, use the "opt" branch.
Sorry.

How do I define for example a plus function on integers in Z3 using the .NET API?

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);

max value in set z3

I'm a new guy to work with the Z3.
Would like to know how I can calculate the maximum value of a set and two different sets.
For example:
[1, 6, 5] - The greater is 6
[1, 6, 5] e [10, 7, 2] - The greater is 6
I use the following code to set:
(declare-sort Set 0)
(declare-fun contains (Set Int) bool)
( declare-const set Set )
( declare-const distinct_set Set )
( declare-const A Int )
( declare-const B Int )
( declare-const C Int )
( assert ( = A 0 ) )
( assert ( = B 1 ) )
( assert ( = C 2 ) )
( assert ( distinct A C) )
( assert ( distinct set distinct_set ) )
(assert
(forall ((x Int))
(= (contains set x) (or (= x A) (= x C)))))
And now would like to know how can I calculate the largest value in the set (set) and the largest value in sets (set and distinct_set).
If it was for all integers was only because it was easy to do:
(define-fun max ((x Int) (y Int)) Int
(ite (< x y) y x))
But I can not leave with sets by their integers, ie, get the values ​​that have set.
Can you help me?
Thanks
Is the following encoding reasonable for your purposes? It is also available online here.
; We Enconde each set S of integers as a function S : Int -> Bool
(declare-fun S1 (Int) Bool)
; To assert that A and C are elements of S1, we just assert (S1 A) and (S1 C)
(declare-const A Int)
(declare-const C Int)
(assert (S1 A))
(assert (S1 C))
; To say that B is not an element of S1, we just assert (not (S1 B))
(declare-const B Int)
(assert (not (S1 B)))
; Now, let max_S1 be the max value in S1
(declare-const max_S1 Int)
; Then, we now that max_S1 is an element of S1, that is
(assert (S1 max_S1))
; All elements in S1 are smaller than or equal to max_S1
(assert (forall ((x Int)) (=> (S1 x) (not (>= x (+ max_S1 1))))))
; Now, let us define a set S2 and S3
(declare-fun S2 (Int) Bool)
(declare-fun S3 (Int) Bool)
; To assert that S3 is equal to the union of S1 and S2, we just assert
(assert (forall ((x Int)) (= (S3 x) (or (S1 x) (S2 x)))))
; To assert that S3 is not equal to S1 we assert
(assert (exists ((x Int)) (not (= (S3 x) (S1 x)))))
(check-sat)
; Now let max_S3 be the maximal value of S3
(declare-const max_S3 Int)
(assert (S3 max_S3))
(assert (forall ((x Int)) (=> (S3 x) (not (>= x (+ max_S3 1))))))
; the set of constraints is still satisfiable
(check-sat)
; Now, let us assert that max_S3 < max_S1.
; It should be unsat, since S3 is a super set of S1
(assert (< max_S3 max_S1))
(check-sat)

Different results between z3 binary and z3 api

I'm trying out Z3 with quantifier examples from http://rise4fun.com/Z3/tutorial/guide .
The two example works fine with the online version of Z3 ( I guess it would be Z3 4.0) .
(set-option :auto-config false) ; disable automatic self configuration
(set-option :mbqi false) ; disable model-based quantifier instantiation
(declare-fun f (Int) Int)
(declare-fun g (Int) Int)
(declare-const a Int)
(declare-const b Int)
(declare-const c Int)
(assert (forall ((x Int))
(! (= (f (g x)) x)
:pattern ((f (g x))))))
(assert (= (g a) c))
(assert (= (g b) c))
(assert (not (= a b)))
(check-sat)
and
(set-option :auto-config false) ; disable automatic self configuration
(set-option :mbqi false) ; disable model-based quantifier instantiation
(declare-fun f (Int) Int)
(declare-fun g (Int) Int)
(declare-const a Int)
(declare-const b Int)
(declare-const c Int)
(assert (forall ((x Int))
(! (= (f (g x)) x)
:pattern ((g x)))))
(assert (= (g a) c))
(assert (= (g b) c))
(assert (not (= a b)))
(check-sat)
The difference is the pattern we used for the "forall" assertion. The result should be "unknow" and "unsat".
I'm using the linux version of Z3 3.2 from http://research.microsoft.com/projects/z3/z3-3.2.tar.gz
I tried the two examples through z3 binary
./z3 -smt2 ex1.smt
./z3 -smt2 ex2.smt
The result is correct.
However, when I was using the ocaml api, the two examples are both "unknow".
I've tried:
Z3.parse_smtlib2_file ctx "ex2.smt" [||] [||] [||] [||];;
and
let mk_unary_app ctx f x = Z3.mk_app ctx f [|x|];;
let example () =
let ctx = Z3.mk_context_x [|("MBQI","false")|] in
let int = Z3.mk_int_sort ctx in
let f = Z3.mk_func_decl ctx (Z3.mk_string_symbol ctx "f") [|int|] int in
let g = Z3.mk_func_decl ctx (Z3.mk_string_symbol ctx "g") [|int|] int in
let a = Z3.mk_const ctx (Z3.mk_string_symbol ctx "a") int in
let b = Z3.mk_const ctx (Z3.mk_string_symbol ctx "b") int in
let c = Z3.mk_const ctx (Z3.mk_string_symbol ctx "c") int in
let sym = Z3.mk_int_symbol ctx 0 in
let bv = Z3.mk_bound ctx 0 int in
let pat = Z3.mk_pattern ctx [| Z3.mk_app ctx g [| bv |] |] in
let forall = Z3.mk_forall ctx 0 [| pat |] [|int|] [|sym|]
(Z3.mk_not ctx (Z3.mk_eq ctx (Z3.mk_app ctx f [|Z3.mk_app ctx g [|bv|]|]) bv)) in
Z3.assert_cnstr ctx forall;
Z3.assert_cnstr ctx (Z3.mk_eq ctx (mk_unary_app ctx g a) c);
Z3.assert_cnstr ctx (Z3.mk_eq ctx (mk_unary_app ctx g b) c);
Z3.assert_cnstr ctx (Z3.mk_not ctx (Z3.mk_eq ctx a b));
Z3.check ctx ;;
Thanks!
There is a typo in the OCaml code.
let forall = Z3.mk_forall ctx 0 [| pat |] [|int|] [|sym|]
(Z3.mk_not ctx (Z3.mk_eq ctx (Z3.mk_app ctx f [|Z3.mk_app ctx g [|bv|]|]) bv))
The problem is the Z3.mk_not. The ! in the SMT input is not a negation.
In SMT 2.0, ! is used to "attach" attributes to formulas. In the example above, the attribute is the pattern.

Resources