How to make z3 recognize equivalence of certain arithmetic expressions? - z3

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

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

unknown when using a integer division in z3 smt2

I am trying to find a solution for the function penta(n) = (n * (3n -1)) / 2 and where penta (z) = penta (a) + penta(b) for all number positives. That works until the integer division (div) is part ofthe definition, but when it is added in the definition I either got a timeout or an unknown.
I would expect to get 8 , 7 , 4. Any idea on what I did wrongly?
(declare-const a Int)
(declare-const b Int)
(declare-const z Int)
(define-fun penta ((n Int)) Int (div (* (- (* 3 n ) 1) n) 2) )
(assert (= (penta z) (+ (penta a) (penta b)) ))
(assert (> a 1))
(assert (> b 1))
(assert (> z 1))
(check-sat)
(get-model)
I am using the version on the http://rise4fun.com/Z3 website and the version 4.1 (x64).
The main issue is that the problem uses integer multiplication between two non-numeric arguments. There are no decision procedures for general Diophantine problems so Z3 does a best effort, which does not favor model enumeration.
When you don't use integer division, Z3 will try a partial heuristic based on
converting the problem into finite domain bit-vectors to find models. It invokes
this heuristic by performing a syntactic check on the formulas. THe syntactic check fails when you use the operator (div .. 2).
You can encode (div x 2) so the heuristic picks up the problem
by introducing fresh variables and bounding them:
(declare-const penta_z Int)
(declare-const penta_a Int)
(declare-const penta_b Int)
(assert (or (= (* 2 penta_z) (penta z)) (= (+ 1 (* 2 penta_z)) (penta z))))
(assert (or (= (* 2 penta_a) (penta a)) (= (+ 1 (* 2 penta_a)) (penta a))))
(assert (or (= (* 2 penta_b) (penta b)) (= (+ 1 (* 2 penta_b)) (penta b))))
(assert (= penta_z (+ penta_a penta_b) ))
(assert (> a 1))
(assert (> b 1))
(assert (> z 1))
(assert (>= penta_z 0))
(assert (<= penta_z 100))
You can also directly encode your problem using bit-vectors although this starts getting error prone because you have to deal with how to handle overflows.

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.

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