Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Z3 Java API defining a function

Tags:

java

z3

smt

I need your help defining a function with the Z3 Java API. I try to solve something like this (which is working fine with the z3.exe process):

(declare-fun a () Real)
(declare-fun b () Real)
(declare-fun c () Bool)

(define-fun max2 ((x Real) (y Real)) Real (ite (<= x y) y x))

(assert (and (>= a 0.0) (<= a 100.0)))
(assert (or (= (max2 (+ 100.0 (* (- 1.0) a)) (/ 1.0 1000.0)) 0.0) c (not (= b 0.0))))

(check-sat-using (then simplify bit-blast qfnra))
(get-model)

The result of this smt-file is:

sat
(model
  (define-fun a () Real
    1.0)
  (define-fun c () Bool
    false)
  (define-fun b () Real
    1.0)
)

The problem now is: There is no option, to define a function with the java API. In another post (Equivalent of define-fun in Z3 API), i noticed to use the following statement in the java API:

(declare-fun max2 (Real Real) Real)
(assert (forall ((y Real) (x Real)) (= (max2 y x) (ite (<= x y) y x))))

So i replaced (define-fun max2 ((x Real) (y Real)) Real (ite (<= x y) y x)) in my smt-file and started the z3.exe process again. The result was the following:

unknown
(model
  (define-fun b () Real
    0.0)
)

So, as you can see, there is no satisfiable result any more. Translating this in java, will get the same result UNKNOWN.

Any ideas, what i can do?

like image 787
ConcolicAndy Avatar asked May 11 '15 15:05

ConcolicAndy


People also ask

What does Z3 do in Python?

For convenience the Python front-end to Z3 contains some shorthand functions. The function solvesets up a solver, adds assertions, checks satisfiability, and prints a model if one is available. Propositional logic is an important, but smaller subset of formulas handled by Z3.

How to specify the optimization objective of Z3?

The main approach for specifying an optimization objective is through functions that specify whether to find solutions that maximizeor minimizevalues of an arithmetical (in the case of Z3, the term has to a lineararithmetic term) or bit-vector term $t$.

What is the main point of reference for Z3?

The main point of reference for Z3 is the GitHub repository https://​github.​com/​z3prover/​z3 There is an interactive tutorial using the SMT-LIB2 front-end on

What does define-fun do in Z3?

Z3 will expand every occurrence of my-div during parsing time. The command define-fun may be used to make the input file simpler and easier to read, but internally it does not really help Z3. In the current API, there is no support for creating macros.


2 Answers

There is no equivalent to function definitions because they aren't necessary, just like the define-fun macro. The equivalent thing to do in the API is to build an expression for the function and then for every application of the function, just substitute the argument values for the input values, e.g., by using Expr.Substitute.

Like Leo mentioned in the post you cited, the use of quantifiers is possible for this purpose, but the solver will often just give up and return unknown because it thinks the formula is too hard to solve. We can get around that by using the macro finder (see cited post), which will recognize exactly this kind of macro.

like image 123
Christoph Wintersteiger Avatar answered Oct 11 '22 19:10

Christoph Wintersteiger


How about declaring a function like this:

private static RealExpr max2(Context ctx, ArithExpr x, ArithExpr y) 
        throws Z3Exception {
    return (RealExpr) ctx.mkITE(ctx.mkLe(x, y), y, x);
}

And probably use it like this:

Context ctx = new Context();

ArithExpr a = (ArithExpr) ctx.mkConst(ctx.mkSymbol("a"), ctx.getRealSort());
ArithExpr b = (ArithExpr) ctx.mkConst(ctx.mkSymbol("b"), ctx.getRealSort());
BoolExpr c = (BoolExpr) ctx.mkConst(ctx.mkSymbol("c"), ctx.getBoolSort());

Goal g = ctx.mkGoal(true, true, false);
g.add(ctx.mkAnd(ctx.mkGe(a, ctx.mkReal(0)), ctx.mkLe(a, ctx.mkReal(100))));
g.add(ctx.mkOr(
    ctx.mkEq(
        max2(ctx, 
            ctx.mkAdd(ctx.mkReal(100), ctx.mkMul(ctx.mkReal(-1), a)), 
            ctx.mkDiv(ctx.mkReal(1), ctx.mkReal(1000))), 
        ctx.mkReal(0)),
    c,
    (ctx.mkNot(ctx.mkEq(b, ctx.mkReal(0))))));
like image 35
dejvuth Avatar answered Oct 11 '22 17:10

dejvuth