how to simplify the result of hiding variable using z3? - z3

I wish to hide some variables and get the simplified results.
I wish to hide c1, c2 and d as follows:
(declare-const v1 Real)
(declare-const v2 Real)
(elim-quantifiers (exists ((c1 Real) (c2 Real)(d Real))
(and (<= c1 10.0) (>= c2 5.0) (>= d 0.0)
(= v1 (+ c1 d))
(= v2 (+ c2 d)))))
However the result seems complex, in fact, the result should be v2>=5.0 & v1<= v2+5.0, I used to use (apply ctx-solver-simplify) the code is
(declare-const v1 Real)
(declare-const v2 Real)
(assert (elim-quantifiers (exists ((c1 Real) (c2 Real)(d Real))
(and (<= c1 10.0) (>= c2 5.0) (>= d 0.0)
(= v1 (+ c1 d))
(= v2 (+ c2 d))))))
(apply ctx-solver-simplify)
However, when I add apply ....There is and error,the script can not work. could someone help me to fix it?

You can use then tactic to apply quantifier elimination to the formula and apply context simplification to all sub-goals produced:
(declare-const v1 Real)
(declare-const v2 Real)
(assert (exists ((c1 Real) (c2 Real)(d Real))
(and (<= c1 10.0) (>= c2 5.0) (>= d 0.0)
(= v1 (+ c1 d))
(= v2 (+ c2 d)))))
(apply (then qe ctx-solver-simplify))
The result is v2 >= 5.0 and v1 - v2 <= 5.0 which is quite close to what you want.

Related

Z3; Simplify with if-then-else

Is there a way to simplify the following expression to "6 < var"?
According to Z3, these expressions are equivalent but simplification does not produce the latter.
I have tried the three parameters since they seem to be related to if-then-else but this also did not help.
(declare-fun var () Int)
(simplify
(exists ((bx Int))
(and
(exists ((byX Int))
(ite (> bx 5) (= byX 0) (&& (> bx 2) (= byX (+ byX 4)))))
(= bx (+ var 1))
(> var 6)
)
)
:push_ite_arith true
:pull_cheap_ite true
:ite_extra_rules true
)
(assert
(not
(iff
(exists ((bx Int))
(and
(exists ((by Int))
(ite (> bx 5) (= by 0) (&& (> bx 2) (= by (+ by 4)))))
(= bx (+ var 1))
(> var 6)
)
)
(< 6 var)
)
)
)
(check-sat)
Not in general, no.
Z3's simplifications and what you would consider "simple" are typically not the same, and it works more or less as a black-box. It won't produce output like what you would get from a symbolic math package or alike: The simplifications are more geared towards making the input "simpler" for further solving; not for "presenting it back to the user" purpose.
You can find many similar questions on stack-overflow, see: https://stackoverflow.com/search?q=%5Bz3%5D+simplify and in particular this answer from Leo: simplification in Z3

Why does Z3 give no response on the following input?

I originally posted the question as shown below the dotted line, but since then I have an even simpler example:
(declare-fun f (Int) Int)
(assert (= (f 10) 1))
(check-sat)
(get-model)
produces an interpretation for f as expected. However change the constant to anything but 10, and Z3 just spins the arrowhead a couple of times but then prints nothing!
--------------------------------------- original question -----------------------------
I tried Z3 on the following input and the arrowhead turns a few times and stops but Z3 prints or says nothing. Why?
(declare-fun f (Int Int) Int)
(assert (>= (f 1 1) 1))
(assert (>= (f 1 2) 2))
(assert (>= (f 2 1) 2))
(assert (>= (f 2 2) 2))
(assert (= (f 1 1) 1))
(assert (= (f 2 2) 2))
(assert (or (= (f 1 2) 1) (= (f 1 2) 2)))
(assert (or (= (f 2 1) 1) (= (f 2 1) 2)))
(check-sat)
(get-model)
I feel like I'm missing something really obvious..
I am obtaining (using iZ3, Z3 unstable branch)
sat
(model
(define-fun f ((x!1 Int) (x!2 Int)) Int
(ite (and (= x!1 1) (= x!2 1)) 1
(ite (and (= x!1 2) (= x!2 2)) 2
(ite (and (= x!1 1) (= x!2 2)) 2
(ite (and (= x!1 2) (= x!2 1)) 2 2)))))
)
Run this example online here
I presume you're using Z3 on rise4fun? The version running there may be a little out of date. We have to manually update the binary there. If it doesn't reply, it's either because it times out, or because there was some other problem (e.g., segfault). It's quite possible that the version on rise4fun exhibits some bug that's already been fixed in other version of Z3 (e.g., unstable, iZ3, etc).

mysterious 'unknown' from Z3

I'm writing a proofchecker for a novel program logic, dealing with weak memory. Z3 does the heavy lifting: I translate all my checks into ASTs and throw them at Z3 using the ML binding. (But, see below, I've checked that Z3 online, via rise4fun, gives the same answer). Here's the implication I would like to check, pretty-printed so I can understand the operator nesting, with the names slightly simplified so it's easy to see what they are:
r1=1
=> y=1
/\ x=1
/\ xnew=x
/\ ynew=2
=> xnew=x
/\ ynew=y
\/ Exists(r1)
r1=1
=> y=1
/\ x=1
/\ xnew=x
/\ ynew=2
This translates into ASTs nicely (type declarations not shown, but see below for actual Z3 input):
(let ((a1 (and (=> (= r1 1) (and (= y 1) (= x 1)))
(= xnew x)
(= ynew 2)))
(a2 (exists ((r1 Int))
(and (=> (= r1 1) (and (= y 1) (= x 1)))
(= xnew x)
(= ynew 2)))))
(=> a1 (or
(and (= xnew x) (= ynew y)) a2)))
So that's all fine. But Z3 says 'unknown'. Oddly, this is the only one of many thousands of queries in all my tests which gives this result. So I investigated with the online version of Z3, via the rise4fun tutorial, which accepted this input
(declare-const r1 Int)
(declare-const y Int)
(declare-const x Int)
(declare-const xnew Int)
(declare-const ynew Int)
(define-fun a1 () Bool
(and (=> (= r1 1) (and (= y 1) (= x 1)))
(= xnew x)
(= ynew 2))
)
(define-fun a2 () Bool
(exists ((r1 Int))
(and (=> (= r1 1) (and (= y 1) (= x 1)))
(= xnew x)
(= ynew 2)))
)
(define-fun conjecture () Bool
(=> a1 (or (and (= xnew x) (= ynew y)) a2))
)
(assert (not conjecture))
(check-sat)
and said 'unknown'.
Am I making a simple error, or is this a bug, or what?
This seems to be a bug in the master branch and in the executable used online.
The behavior does not reproduce in the latest unstable branch.

How to make z3 recognize equivalence of certain arithmetic expressions?

I have a pretty simple problem, I'm mentioning the relevant part here:
;; All variables are declared to be of type Real
(assert (and (<= 1.0 var1-r) (< var1-r 4.0)))
;;following defines var1-r
(assert (= var1-r (+ a b)))
;;following defines var1-e
(assert (=> (and (<= 1.0 var1-r) (< var1-r 2.0)) (= var1-e 8388608.0)))
(assert (=> (and (<= 2.0 var1-r) (< var1-r 4.0)) (= var1-e 4194304.0)))
;;following defines var1
(assert (= var1 (/ (foo (* var1-r var1-e)) var1-e)))
;;Similarly for var2-r, var2-e, var2
(assert (and (<= 1.0 var2-r) (< var2-r 4.0)))
(assert (= var2-r (+ b a)))
(assert (=> (and (<= 1.0 var2-r) (< var2-r 2.0)) (= var2-e 8388608.0)))
(assert (=> (and (<= 2.0 var2-r) (< var2-r 4.0)) (= var2-e 4194304.0)))
(assert (= var2 (/ (foo (* var2-r var2-e)) var2-e)))
Here, foo() is a simple interpreted function, eg., foo (x) = (to_real (to_int x))
Note that var1 and var2 are equal. Reason: var1-r and var2-r are equal (commutativity of Reals) and consequently var2-e and var1-e are equal, leading to var1 and var2 being equal. However, I am not able to prove unsatisfiability of (not (= var1 var2)) using z3. In fact, the same is true if var2-r is defined as (+ a b). [Note that var1 and var2 being equal is actually also independent of the definition of foo()].
Please look at here. I am obtaining
unsat

Calculating Absolute Value in Z3

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)

Resources