Say I have
t1<x and x<t2
is it possible to hide variable x so that
t1<t2
in Z3?
You can use quantifier elimination for doing that. Here is an example:
(declare-const t1 Int)
(declare-const t2 Int)
(elim-quantifiers (exists ((x Int)) (and (< t1 x) (< x t2))))
You can try this example online at: http://rise4fun.com/Z3/kp0X
Possible solution using Redlog of Reduce:
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.
In fact, does the SMT-LIB standard have a rational (not just real) sort? Going by its website, it does not.
If x is a rational and we have a constraint x^2 = 2, then we should get back ``unsatisfiable''. The closest I could get to encoding that constraint is the following:
;;(set-logic QF_NRA) ;; intentionally commented out
(declare-const x Real)
(assert (= (* x x) 2.0))
(check-sat)
(get-model)
for which z3 returns a solution, as there is a solution (irrational) in the reals. I do understand that z3 has its own rational library, which it uses, for instance, when solving QF_LRA constraints using an adaptation of the Simplex algorithm. On a related note, is there an SMT solver that supports rationals at the input level?
I'm sure it's possible to define a Rational sort using two integers as suggested by Nikolaj -- I would be interested to see that. It might be easier to just use the Real sort, and any time you want a rational, assert that it's equal to the ratio of two Ints. For example:
(set-option :pp.decimal true)
(declare-const x Real)
(declare-const p Int)
(declare-const q Int)
(assert (> q 0))
(assert (= x (/ p q)))
(assert (= x 0.5))
(check-sat)
(get-value (x p q))
This quickly comes back with
sat
((x 0.5)
(p 1)
(q 2))
What might be the reason for timeout for the following program in z3.
http://rise4fun.com/Z3/pbEOw
(declare-const a Int)
(declare-const a2 Int)
(declare-const b Int)
(assert (> b 0))
(assert (>= a a2))
(assert (< (div a b) (div a2 b)))
(check-sat)
(get-model)
The second operand of the division operator is a variable.
This makes the constraints non-linear and the search for satisfying interpretations of non-linear constraints is in general not terminating (it is also undecidable in general).
I would like to know what is the difference between following 2 statements -
Statement 1
(define-fun max_integ ((x Int) (y Int)) Int
(ite (< x y) y x))
Statement 2
(declare-fun max_integ ((Int)(Int)) Int)
(assert (forall ((x Int) (y Int)) (= (max_integ x y) (if (< x y) y x))))
I observed that when I use Statement1, my z3 constraints give me a result in 0.03 seconds. Whereas when I used Statement2, it does not finish in 2 minutes and I terminate the solver.
I would like also to know how achieve it using C-API.
Thanks !
Statement 1 is a macro. Z3 will replace every occurrence of max_integ with the ite expression. It does that during parsing time. In the second statement, by default, Z3 will not eliminate max_integ, and to be able to return sat it has to build an interpretation for the uninterpreted symbol max_integ that will satisfy the quantifier for all x and y.
Z3 has an option called :macro-finder, it will detect quantifiers that are essentially encoding macros, and will eliminate them. Here is an example (also available online here):
(set-option :macro-finder true)
(declare-fun max_integ ((Int)(Int)) Int)
(assert (forall ((x Int) (y Int)) (= (max_integ x y) (if (< x y) y x))))
(check-sat)
(get-model)
That being said, we can easily simulate macros in a programmatic API by writing a function that given Z3 expressions return a new Z3 expression. Here in an example using the Python API (also available online here):
def max(a, b):
# The function If builds a Z3 if-then-else expression
return If(a >= b, a, b)
x, y = Ints('x y')
solve(x == max(x, y), y == max(x, y), x > 0)
Yet another option is to use the C API: Z3_substitute_vars. The idea is to an expression containing free variables. Free variables are created using the API Z3_mk_bound. Each variable represents an argument. Then, we use Z3_substitute_vars to replace the variables with other expressions.
Basically, I want to ask Z3 to give me an arbitrary integer whose value is greater than 10. So I write the following statements:
(declare-const x (Int))
(assert (forall ((i Int)) (> i 10)))
(check-sat)
(get-value(x))
How can I apply this quantifier to my model? I know you can write (assert (> x 10)) to achieve this. But I mean I want a quantifier in my model so every time I declare an integer constant whose value is guaranteed to be over 10. So I don't have to insert statement (assert (> x 10)) for every integer constant that I declared.
When you use (assert (forall ((i Int)) (> i 10))), i is a bounded variable and the quantified formula is equivalent to a truth value, which is false in this case.
I think you want to define a macro using quantifiers:
(declare-fun greaterThan10 (Int) Bool)
(assert (forall ((i Int)) (= (greaterThan10 i) (> i 10))))
And you can use them to avoid code repetition:
(declare-const x (Int))
(declare-const y (Int))
(assert (greaterThan10 x))
(assert (greaterThan10 y))
(check-sat)
It is essentially the way to define macros using uninterpreted functions when you're working with Z3 API. Note that you have to set (set-option :macro-finder true) in order that Z3 replaces universal quantifiers with bodies of those functions.
However, if you're working with the textual interface, the macro define-fun in SMT-LIB v2 is an easier way to do what you want:
(define-fun greaterThan10 ((i Int)) Bool
(> i 10))