I am trying to do this in SMT-LIB, running z3 -smt2 script.smt2 on the script containing these expressions:
(set-logic AUFLIA)
(declare-fun a () Int)
(declare-fun b () Int)
(declare-fun c () Int)
(declare-fun d () Int)
(declare-fun e () Int)
(declare-fun f () Int)
(declare-fun x () Int)
(declare-fun c () Int)
(declare-fun addition (Int Int) Int)
(assert (= x c))
(assert (= c (addition a b)))
(assert (= f (addition d e)))
(check-sat)
I want to get a unification for these variables. For example, I expect to be able to unify the variables by assigning x=f, a=d and b=e.
Is it even possible to do this in z3 or SMT-LIB?
Or should I be using some other language to do this (maybe give a recommendation is this is what you think?)
Related
Suppose I have a Sort T and I declare an array indexed by T, what is the sort of mapping over it?
e.g
(declare-datatypes ()
((T ....))) ; some index, may be finite or infinite (as in Int)
(declare-const a (Array T Int))
(declare-const b (Array Int Int))
(define-fun foo ((x Int)) Int)
(define-fun bar ((y Int)) Bool)
What is the sort of mapping foo on a? And the sort of mapping foo on b? Is there any way to mess up with the indexes type and obtain from an array indexed by T an array indexed by another sort, say e.g. Int?
Usual sort-matching rules apply. That is, to map a function f : A -> B on an array, the array must have its range type A, and it'll turn it into a B, preserving the type of its domain.
Regarding your example: Regardless of what your T is, you'll simply have Array T Int as the final sort if you map foo, and Array T Bool as the result if you map bar. The following script type-checks without any issues:
(declare-datatypes ((T 0)) ((i Int)))
(declare-const a (Array T Int))
(declare-const b (Array Int Int))
(declare-fun foo (Int) Int)
(declare-fun bar (Int) Bool)
(define-fun e1 () (Array T Int) ((_ map foo) a))
(define-fun e2 () (Array T Bool) ((_ map bar) a))
(define-fun e3 () (Array Int Int) ((_ map foo) b))
(define-fun e4 () (Array Int Bool) ((_ map bar) b))
Note that you cannot change the type of the domain (which is what you mean by index I presume) by mapping a function over an array. It only changes the range type.
I have the following example of quantifiers elimination using z3py below. However I would like to rewrite it using SMTLIB syntax (code below python code). Somehow I did not get the same output like what I got from python which are formulas. I wonder if anyone could point me out the problem.
from z3 import *
a, five = Ints('a five')
cmp = Bool('cmp')
j = Goal()
j.add(Exists([five, cmp], And(five == a,
cmp == (five < 1000),
False == cmp)))
t = Tactic('qe')
print(t(j)) # output [[1000 <= a]]
(declare-fun five () Int)
(declare-fun a () Int)
(declare-fun cmp () Bool)
(assert (exists ((five Int) (cmp Bool)) (and (= five a)
(= cmp (< five 1000))
(= cmp false) )))
(apply (then qe smt))
output
(goals
(goal
:precision precise :depth 1)
)
I asked the question too quickly. After more searching (Quantifier Elimination - More questions), I found a solution below.
(declare-fun five () Int)
(declare-fun a () Int)
(declare-fun cmp () Bool)
(assert (exists ((five Int) (cmp Bool)) (and (= five a)
(= cmp (< five 1000))
(= cmp false) )))
(apply (using-params qe :qe-nonlinear true))
I have a problem with the generation of model values through get-value.
If I try to get the value of an array, I will get a value
containing internal z3 constants which are not printed. I know that
get-model would print those constants but I would like to stick
to using get-value.
Here is an example (I tried it on rise4fun):
(declare-const b (Array Int Int))
(declare-const a (Array Int Int))
(assert (= (store a 1 2) b))
(check-sat)
(get-value (b a))
returns:
sat ((b (_ as-array k!1)) (a (_ as-array k!0)))
The output with get-model is the following:
sat (model (define-fun b () (Array Int Int) (_ as-array k!1)) (define-fun a () (Array Int Int) (_ as-array k!0)) (define-fun k!0 ((x!1 Int)) Int 0) (define-fun k!1 ((x!1 Int)) Int (ite (= x!1 1) 2 0)) )
It contains the value of k!0 and k!1. Is it possible to substitute these in the values for a and b ?
This is a limitation with Z3's modeling of arrays.
get-value isn't guaranteed to give meaningful results for arrays.
I have some confusion of using universal quantifier and declare-const without using forall
(set-option :mbqi true)
(declare-fun f (Int Int) Int)
(declare-const a Int)
(declare-const b Int)
(assert (forall ((x Int)) (>= (f x x) (+ x a))))
I can write like this:
(declare-const x Int)
(assert (>= (f x x) (+ x a))))
with Z3 will explore all the possible values of type Int in this two cases. So what's the difference?
Can I really use the declare-const to eliminate the forall quantifier?
No, the statements are different. Constants in Z3 are nullary (0 arity) functions, so (declare-const a Int) is just syntactic sugar for (declare-fun a () Int), so these two statements are identical. Your second statement (assert (>= (f x x) (+ x a)))) implicitly asserts existence of x, instead of for all x as in your first statement (assert (forall ((x Int)) (>= (f x x) (+ x a)))). To be clear, note that in your second statement, only a single assignment for x needs to satisfy the assertion, not all possible assignments (also note the difference in the function f, and see this Z3#rise script: http://rise4fun.com/Z3/4cif ).
Here's the text of that script:
(set-option :mbqi true)
(declare-fun f (Int Int) Int)
(declare-const a Int)
(declare-fun af () Int)
(declare-const b Int)
(declare-fun bf () Int)
(push)
(declare-const x Int)
(assert (>= (f x x) (+ x a)))
(check-sat) ; note the explicit model value for x: this only checks a single value of x, not all of them
(get-model)
(pop)
(push)
(assert (forall ((x Int)) (>= (f x x) (+ x a))))
(check-sat)
(get-model) ; no model for x since any model must satisfy assertion
(pop)
Also, here's an example from the Z3 SMT guide ( http://rise4fun.com/z3/tutorial/guide from under the section "Uninterpreted functions and constants"):
(declare-fun f (Int) Int)
(declare-fun a () Int) ; a is a constant
(declare-const b Int) ; syntax sugar for (declare-fun b () Int)
(assert (> a 20))
(assert (> b a))
(assert (= (f 10) 1))
(check-sat)
(get-model)
You can eliminate a top-level exists with a declare-const. Maybe this is the source of your confusion? The following two are equivalent:
(assert (exists ((x Int)) (> x 0)))
(check-sat)
and
(declare-fun x () Int)
(assert (> x 0))
(check-sat)
Note that this only applies to top-level existential quantifiers. If you have nested quantification of both universals (forall) and existentials (exists), then you can do skolemization to float the existentials to the top level. This process is more involved but rather straightforward from a logical point of view.
There is no general way of floating universal quantifiers to the top-level in this way, at least not in classical logic as embodied by SMT-Lib.
How do I get the maximum of a formula using smt-lib2?
I want something like this:
(declare-fun x () Int)
(declare-fun y () Int)
(declare-fun z () Int)
(assert (= x 2))
(assert (= y 4))
(assert (= z (max x y))
(check-sat)
(get-model)
(exit)
Of course, 'max' is unknown to smtlibv2.
So, how can this be done?
In Z3, you can easily define a macro max and use it for getting maximum of two values:
(define-fun max ((x Int) (y Int)) Int
(ite (< x y) y x))
There is another trick to model max using uninterpreted functions, which will be helpful to use with Z3 API:
(declare-fun max (Int Int) Int)
(assert (forall ((x Int) (y Int))
(= (max x y) (ite (< x y) y x))))
Note that you have to set (set-option :macro-finder true), so Z3 is able to replace universal quantifiers with body of the function when checking satisfiability.
You've got abs, and per basic math max(a,b) = (a+b+abs(a-b))/2