Simplifying uninterpreted functions in Z3 - z3

Is there any way to apply simplifications to uninterpreted functions defined in z3, rather than the goals and subgoals ?
I have the following z3 code :
(declare-fun f (Bool Bool) Bool)
(assert (forall ((b1 Bool) (b2 Bool))
(implies b2 (f b1 b2))))
(assert (exists ((b1 Bool) (b2 Bool))
(not (f b1 b2))))
(check-sat)
(get-model)
And I get the following output:
sat
(model
(define-fun b1!1 () Bool
false)
(define-fun b2!0 () Bool
false)
(define-fun k!7 ((x!1 Bool)) Bool
false)
(define-fun f!8 ((x!1 Bool) (x!2 Bool)) Bool
(ite (and (= x!1 false) (= x!2 true)) true
false))
(define-fun k!6 ((x!1 Bool)) Bool
(ite (= x!1 false) false
true))
(define-fun f ((x!1 Bool) (x!2 Bool)) Bool
(f!8 (k!7 x!1) (k!6 x!2)))
)
It turns out that by applying rewrite rules to the definition of f, we can get that
f is equal to the second argument (x!2) by the following derivation:
(f!8 (k!7 x!1) (k!6 x!2))
= (f!8 false (k!6 x!2))
= (f!8 false x!2)
=(x!2)
Is there any way to get z3 to produce the following definition automatically ?
(define-fun f ((x!1 Bool) (x!2 Bool)) Bool
(x!2))
Thanks for your help.
Regards,
Oswaldo.

One option is to ask Z3 to evaluate the expression (f x y) where x and y are fresh Boolean constants. The eval command will evaluated (f x y) in the current model, and will produce y in your example. Here is the complete example (also available online here):
(declare-fun f (Bool Bool) Bool)
; x and y are free Boolean constants that will be used to create the expression (f x y)
(declare-const x Bool)
(declare-const y Bool)
(assert (forall ((b1 Bool) (b2 Bool))
(implies b2 (f b1 b2))))
(assert (exists ((b1 Bool) (b2 Bool))
(not (f b1 b2))))
(check-sat)
(eval (f x y))

Related

Z3 tactic for conjunction elimination in formulas with quantifiers

Is there a Z3 tactic that rewrites the goal (say, one assertion with quantifiers and uninterpreted functions) into a set of conjunction-free formulas? For example, the following formula:
(declare-fun P (Int) Bool)
(declare-fun Q (Int Int) Bool)
(declare-fun R (Int Int) Bool)
(assert (forall ((x Int)) (!
(or
(P x)
(forall ((x Int) (y Int)) (!
(and
(Q x y)
(R x y))
:pattern ((Q x y)) )) )
:pattern ((P x)))))
Should be rewritten to
(declare-fun P (Int) Bool)
(declare-fun Q (Int Int) Bool)
(declare-fun R (Int Int) Bool)
(assert (forall ((x Int)) (!
(or
(P x)
(forall ((x Int) (y Int)) (!
(Q x y)
:pattern ((Q x y)))))
:pattern ((P x)))))
(assert (forall ((x Int)) (!
(or
(P x)
(forall ((x Int) (y Int)) (!
(R x y)
:pattern ((Q x y)))))
:pattern ((P x)))))
You can obtain a list of tactics via (help-tactic). Searching for "conjunction" yields a few hits, including tactic simplify with option elim_and, which removes all conjunctions from your example.
Rewriting the quantifiers is a different matter. I've tried a few tactics that sound potentially related, but none had any useful effects.
; (help-tactic)
(declare-fun P (Int) Bool)
(declare-fun Q (Int Int) Bool)
(declare-fun R (Int Int) Bool)
(assert (forall ((x Int)) (!
(or
(P x)
(forall ((x Int) (y Int)) (!
(and
(Q x y)
(R x y))
:pattern ((Q x y)) )) )
:pattern ((P x)))))
; (apply (try-for qe-light 5000)) ; no effect
; (apply (try-for qe_rec 5000)) ; appears to fail
; (apply (try-for qe2 5000)) ; appears to fail
(apply
(then
distribute-forall ; no effect
(using-params simplify :elim_and true)
))
;;; RESULT:
; (forall ((x Int))
; (! (let ((a!1 (forall ((x!1 Int) (y Int))
; (! (not (or (not (Q x!1 y)) (not (R x!1 y))))
; :pattern ((Q x!1 y))))))
; (or (P x) a!1))
; :pattern ((P x))))

Z3 Solver outputting the satisfying model?

In Z3, if the input script is written in SMTLib format, is it possible to output the model (value assignments satisfying the model)? The get-model returns an interpretation satisfying the constraints. Is there any way to extract the concrete values from these interpretations. I am aware that we can use the python/C++ API to get model values.
You probably want to use get-value, here's a minimal example (rise4fun link: http://rise4fun.com/Z3/wR81 ):
(declare-fun x () Int)
(declare-fun y () Int)
(declare-fun z () Int)
(assert (>= (* 2 x) (+ y z)))
(declare-fun f (Int) Int)
(declare-fun g (Int Int) Int)
(assert (< (f x) (g x x)))
(assert (> (f y) (g x x)))
(check-sat) ; sat
(get-model) ; returns:
; (model
; (define-fun z () Int
; 0)
; (define-fun y () Int
; (- 38))
; (define-fun x () Int
; 0)
; (define-fun g ((x!1 Int) (x!2 Int)) Int
; (ite (and (= x!1 0) (= x!2 0)) 0
; 0))
; (define-fun f ((x!1 Int)) Int
; (ite (= x!1 0) (- 1)
; (ite (= x!1 (- 38)) 1
; (- 1))))
;)
(get-value (x)) ; returns ((x 0))
(get-value ((f x))) ; returns (((f x) (- 1)))
You'd potentially then have to parse this depending on what you're trying to do, etc.
For more details, check out the SMT-LIB standard:
http://smtlib.cs.uiowa.edu/language.shtml
The latest version is: http://smtlib.cs.uiowa.edu/papers/smt-lib-reference-v2.0-r12.09.09.pdf
You can see some examples of get-value on page 39 / figure 3.5.

How to obtain a non-trivial model of an idempotent quasigroup using Z3

I am trying to obtain a non-trivial model of an idempotent quasigroup using Z3 with the following code
(set-logic AUFNIRA)
(set-option :macro-finder true)
(set-option :mbqi true)
(set-option :pull-nested-quantifiers true)
(declare-sort S 0)
(declare-fun prod (S S) S)
(declare-fun left (S S) S)
(declare-fun right (S S) S)
(assert (forall ((x S) (y S))
(= (prod (left x y) y) x)))
(assert (forall ((x S) (y S))
(= (prod x (right x y) ) y)))
(assert (forall ((x S) (y S))
(= (left (prod x y) y ) x)))
(assert (forall ((x S) (y S))
(= (right x (prod x y)) y)))
(assert (forall ((x S)) (= (prod x x) x) ))
(check-sat)
(get-model)
but I am obtaining only a trivial model:
sat
(model
;; universe for S:
;; S!val!0
;; -----------
;; definitions for universe elements:
(declare-fun S!val!0 () S)
;; cardinality constraint:
(forall ((x S)) (= x S!val!0))
;; -----------
(define-fun elem!3 () S
S!val!0)
(define-fun elem!2 () S
S!val!0)
(define-fun elem!0 () S
S!val!0)
(define-fun elem!1 () S
S!val!0)
(define-fun left ((x!1 S) (x!2 S)) S
S!val!0)
(define-fun right ((x!1 S) (x!2 S)) S
S!val!0)
(define-fun prod ((x!1 S) (x!2 S)) S
x!1)
)
Run this example online here
Please let me know how we can obtain a non-trivial model. Many thanks.
If I understand right, you want to find more than one sat model for the original assertions.
I have a dull solution here. You can define another set of functions in the same way as prod, left and right, which are named prod2, left2 and right2. Add assertions for them similarly. Then, you want prod2 to differ from prod.
Like this:
(assert (exists ((x S) (y S)) (not (= (prod x y) (prod2 x y)))))
or maybe expression meaning or(prod != prod2, left != left2, right != right2) will be more proper.
I took a little attempt to run that online, but returned 'time out'. I think you have to do it on your machine.
This may be not a best answer, but best regards!

Defining injective functions in Z3

My goal is to define an injective function f: Int -> Term, where Term is some new sort. Having referred to the definition of the injective function, I wrote the following:
(declare-sort Term)
(declare-fun f (Int) Term)
(assert (forall ((x Int) (y Int))
(=> (= (f x) (f y)) (= x y))))
(check-sat)
This causes a timeout. I suspect that this is because the solver tries to validate the assertion for all values in the Int domain, which is infinite.
I also checked that the model described above works for some custom sort instead of Int:
(declare-sort Term)
(declare-sort A)
(declare-fun f (A) Term)
(assert (forall ((x A) (y A))
(=> (= (f x) (f y)) (= x y))))
(declare-const x A)
(declare-const y A)
(assert (and (not (= x y)) (= (f x) (f y))))
(check-sat)
(get-model)
The first question is how to implement the same model for Int sort instead of A. Can solver do this?
I also found the injective function example in the tutorial in multi-patterns section. I don't quite get why :pattern annotation is helpful. So the second question is why :pattern is used and what does it brings to this example particularly.
I am trying this
(declare-sort Term)
(declare-const x Int)
(declare-const y Int)
(declare-fun f (Int) Term)
(define-fun biyect () Bool
(=> (= (f x) (f y)) (= x y)))
(assert (not biyect))
(check-sat)
(get-model)
and I am obtaining this
sat
(model
;; universe for Term:
;; Term!val!0
;; -----------
;; definitions for universe elements:
(declare-fun Term!val!0 () Term)
;; cardinality constraint:
(forall ((x Term)) (= x Term!val !0))
;; -----------
(define-fun y () Int
1)
(define-fun x () Int
0)
(define-fun f ((x!1 Int)) Term
(ite (= x!1 0) Term!val!0
(ite (= x!1 1) Term!val!0
Term!val!0)))
)
What do you think about this
(declare-sort Term)
(declare-fun f (Int) Term)
(define-fun biyect () Bool
(forall ((x Int) (y Int))
(=> (= (f x) (f y)) (= x y))))
(assert (not biyect))
(check-sat)
(get-model)
and the output is
sat
(model
;; universe for Term:
;; Term!val!0
;; -----------
;; definitions for universe elements:
(declare-fun Term!val!0 () Term)
;; cardinality constraint:
(forall ((x Term)) (= x Term!val!0))
;; -----------
(define-fun x!1 () Int 0)
(define-fun y!0 () Int 1)
(define-fun f ((x!1 Int)) Term
(ite (= x!1 0) Term!val!0
(ite (= x!1 1) Term!val!0
Term!val!0)))
)

Program satisfiability using Z3

How to check satisfiability of a program using Z3? For example:
Boolean x, y
while(x is False) {
x = x or y
y = x & y
}
y = x or y
You can represent programs as a set of Horn clauses. For your program you can represent it as follows:
(set-logic HORN)
(set-option :fixedpoint.engine bmc)
(declare-fun L0 (Bool Bool) Bool)
(declare-fun L1 (Bool Bool) Bool)
(declare-fun L2 (Bool Bool) Bool)
(declare-fun L3 (Bool Bool) Bool)
(assert (forall ((x Bool) (y Bool)) (L0 x y))) ; all values of x,y are possible at L0
(assert (forall ((x Bool) (y Bool)) (=> (L0 x y) (L1 x y)))) ; from L0 move to L1 without changing x, y
(assert (forall ((x Bool) (y Bool) (x1 Bool) (y1 Bool))
(=> (and (not x) (L1 x y) (= x1 (or x y)) (= y1 (and x1 y))) (L1 x1 y1)))); assignment in while loop
(assert (forall ((x Bool) (y Bool)) (=> (and x (L1 x y)) (L2 x y)))) ; exit while loop
(assert (forall ((x Bool) (y Bool)) (=> (L2 x y) (L3 x (or x y))))) ; assignment after while loop
(assert (forall ((x Bool) (y Bool)) (=> (L3 true true) false))) ; say x = true, y = true is unreachable.
(check-sat)
I have added a last assertion to make a reachability statement.
I have also instructed Z3 to use a BMC engine to unfold the Horn clauses using
bounded model checking. Other engines are available as well, for the example the PDR/IC3
engine (set-option :fixedpoint.engine pdr), does not unfold transition relations.
Now the meaning of reachability vs. satisfiability
is going to be different for Horn clauses, as compared to a conjunction of the unfolded
transition relation:
the above clauses are UNSAT.
This does in fact correspond to a feasible path from L0 to (L3 true true).
If you change the last statement to (L3 true false), you get the answer "sat"
(The BMC problem is UNSAT). While BMC itself would not terminate on with such a loop,
it turns out that the last transition and loop exit condition are enough to prune out
the possibility of (L3 true false) so Z3 solves this problem by pre-processing the horn clauses.
You can of course also write down the transition relation for the program statements you have and unfold this directly yourself into a logical formula that you check satisfiability of.

Resources