I need to add the following assertion
assert(x=y^2)
is it required to define a function or any syntax is available to add it directly
.Please help me.
Z3 has a built-in power operator, ^. If you're using the SMT-LIB interface it would be (assert (= x (^ y 2))). You'd probably be better off using (assert (= x (* y y))) if the power is always 2, though.
Related
Using smtlib I would like to make something like modulo using QF_UFNRA. This disables me from using mod, to_int, to_real an such things.
In the end I want to get the fractional part of z in the following code:
(set-logic QF_UFNRA)
(declare-fun z () Real)
(declare-fun z1 () Real)
(define-fun zval_1 ((x Real)) Real
x
)
(declare-fun zval (Real) Real)
(assert (= z 1.5));
(assert (=> (and (<= 0.0 z) (< z 1.0)) (= (zval z) (zval_1 z))))
(assert (=> (>= z 1.0) (= (zval z) (zval (- z 1.0)))))
(assert (= z1 (zval z)))
Of course, as I am asking this question here, implies, that it didn't work out.
Has anybody got an idea how to get the fractional part of z into z1 using logic QF_UFNRA?
This is a great question. Unfortunately, what you want to do is not possible in general if you restrict yourself to QF_UFNRA.
If you could encode such functionality, then you can decide arbitrary Diophantine equations. You would simply cast a given Diophantine equation over reals, compute the "fraction" of the real solution with this alleged method, and assert that the fraction is 0. Since reals are decidable, this would give you a decision procedure for Diophantine equations, accomplishing the impossible. (This is known as Hilbert's 10th problem.)
So, as innocent as the task looks, it is actually not doable. But that doesn't mean you cannot encode this with some extensions, and possibly have the solver successfully decide instances of it.
If you allow quantifiers and recursive functions
If you allow yourself quantifiers and recursive-functions, then you can write:
(set-logic UFNRA)
(define-fun-rec frac ((x Real)) Real (ite (< x 1) x (frac (- x 1))))
(declare-fun res () Real)
(assert (= (frac 1.5) res))
(check-sat)
(get-value (res))
To which z3 responds:
sat
((res (/ 1.0 2.0)))
Note that we used the UFNRA logic allowing quantification, which is required here implicitly due to the use of the define-fun-rec construct. (See the SMTLib manual for details.) This is essentially what you tried to encode in your question, but instead using the recursive-function-definition facilities instead of implicit encoding. There are several caveats in using recursive functions in SMTLib however: In particular, you can write functions that render your system inconsistent rather easily. See Section 4.2.3 of http://smtlib.cs.uiowa.edu/papers/smt-lib-reference-v2.5-draft.pdf for details.
If you can use QF_UFNIRA
If you move to QF_UFNIRA, i.e., allow mixing reals and integers, the encoding is easy:
(set-logic QF_UFNIRA)
(declare-fun z () Real)
(declare-fun zF () Real)
(declare-fun zI () Int)
(assert (= z (+ zF zI)))
(assert (<= 0 zF))
(assert (< zF 1))
(assert (= z 1.5))
(check-sat)
(get-value (zF zI))
z3 responds:
sat
((zF (/ 1.0 2.0))
(zI 1))
(You might have to be careful about the computation of zI when z < 0, but the idea is the same.)
Note that just because the encoding is easy doesn't mean z3 will always be able to answer the query successfully. Due to mixing of Real's and Integer's, the problem remains undecidable as discussed before. If you have other constraints on z, z3 might very well respond unknown to this encoding. In this particular case, it happens to be simple enough so z3 is able to find a model.
If you have sin and pi:
This is more of a thought experiment than a real alternative. If SMTLib allowed for sin and pi, then you can check whether sin (zI * pi) is 0, for a suitably constrained zI. Any satisfying model to this query would ensure that zI is integer. You can then use this value to extract the fractional part by subtracting zI from z.
But this is futile as SMTLib neither allows for sin nor pi. And for good reason: Decidability would be lost. Having said that, maybe some brave soul can design a logic that supported sin, pi, etc., and successfully answered your query correctly, while returning unknown when the problem becomes too hard for the solver. This is already the case for nonlinear arithmetic and the QF_UFNIRA fragment: The solver may give up in general, but the heuristics it employs might solve problems of practical interest.
Restriction to Rationals
As a theoretical aside, it turns out that if you restrict yourself to rationals only (instead of actual reals) then you can indeed write a first-order formula to recognize integers. The encoding is not for the faint of heart, however: http://math.mit.edu/~poonen/papers/ae.pdf. Furthermore, since the encoding involves quantifiers, it's probably quite unlikely that SMT solvers will do well with a formulation based on this idea.
[Incidentally, I should extend thanks to my work colleagues; this question made for a great lunch-time conversation!]
I'm currently trying to write an SMT script using define-fun-rec. I've tested with both Z3, version 4.4.2, and CVC4, version 1.4. As far as I can tell, these are the most recent versions of both, and both support the feature*. However, both do not seem to recognize the command.
(I made some changes to this based on Nikolaj's reply. It still gives the error messages.) Specifically, given:
(define-fun-rec
fac ((x Int)) Int
(
ite (<= x 1)
1
(* x (fac (- x 1)))
)
)
(assert (= (fac 4) 24))
(check-sat)
Z3 outputs:
unsupported
; define-fun-rec
(error "line 10 column 17: unknown function/constant fac")
sat
And CVC4 outputs:
(error "Parse Error: fac.smt2:1.15: expected SMT-LIBv2 command, got `define-fun-rec'.
(define-fun-rec
^
")
My best guess is that there is some sort of flag I need to set or I need to be using some specific logic, but I've had a lot of trouble finding any sort of detailed instructions or examples with define-fun-rec. Any advice would be appreciated. Thanks!
*Z3 has support: How to deal with recursive function in Z3?
CVC4 has support: http://lara.epfl.ch/~reynolds/pres-smt15.pdf
The latest version of CVC4 can be downloaded under "Development versions" (on the right hand side) of:
http://cvc4.cs.nyu.edu/downloads/
The latest development version has support for recursive function definitions. You can use the cvc4 command line option "--fmf-fun" to enable a technique that finds small models for problems involving recursive function applications, assuming definitions are admissible.
(Although, unfortunately your example with factorial also requires non-linear arithmetic, which CVC4 does not yet support.)
Don't set the logic to LIA. This is not in the LIA fragment and Z3 will use the wrong tactic to solve the problem.Just remove the set-logic line.
It helps to not use an undefined function "f" inside the definition of "fib".
I would suggest that you call the function "fac" and not "fib" since you are defining a factorial function.
Thus,
(define-fun-rec
fac ((x Int)) Int
(
ite (<= x 1)
1
(* x (fac (- x 1)))
)
)
(assert (= (fac 4) 24))
(check-sat)
z3 -version
Z3 version 4.4.2
z3 fac.smt2
sat
If you change 24 to 25 you get unsat.
I've got several questions about Z3 tactics, most of them concern simplify .
I noticed that linear inequalites after applying simplify are often negated.
For example (> x y) is transformed by simplify into (not (<= x y)). Ideally, I would want integer [in]equalities not to be negated, so that (not (<= x y)) is transformed into (<= y x). I can I ensure such a behavior?
Also, among <, <=, >, >= it would be desirable to have only one type of inequalities to be used in all integer predicates in the simplified formula, for example <=. Can this be done?
What does :som parameter of simplify do? I can see the description that says that it is used to put polynomials in som-of-monomials form, but maybe I'm not getting it right. Could you please give an example of different behavior of simplify with :som set to true and false?
Am I right that after applying simplify arithmetical expressions would always be represented in the form a1*t1+...+an*tn, where ai are constants and ti are distinct terms (variables, uninterpreted constants or function symbols)? In particular is always the case that subtraction operation doesn't appear in the result?
Is there any available description of the ctx-solver-simplify tactic? Superficially, I understand that this is an expensive algorithm because it uses the solver, but it would be interesting to learn more about the underlying algorithm so that I have an idea on how many solver calls I may expect, etc. Maybe you could give a refernce to a paper or give a brief sketch of the algorithm?
Finally, here it was mentioned that a tutorial on how to write tactics inside the Z3 code base might appear. Is there any yet?
Thank you.
Here is an example (with comments) that tries to answer questions 1-4. It is also available online here.
(declare-const x Int)
(declare-const y Int)
;; 1. and 2.
;; The simplifier will map strict inequalities (<, >) into non-strict ones (>=, <=)
;; Example: x < y ===> not x >= y
;; As suggested by you, for integer inequalities, we can also use
;; x < y ==> x <= y - 1
;; This choice was made because it is convenient for solvers implemented in Z3
;; Other normal forms can be used.
;; It is possible to map everything to a single inequality. This is a straightforward modificiation
;; in the Z3 simplifier. The relevant files are src/ast/rewriter/arith_rewriter.* and src/ast/rewriter/poly_rewriter.*
(simplify (<= x y))
(simplify (< x y))
(simplify (>= x y))
(simplify (> x y))
;; 3.
;; :som stands for sum-of-monomials. It is a normal form for polynomials.
;; It is essentially a big sum of products.
;; The simplifier applies distributivity to put a polynomial into this form.
(simplify (<= (* (+ y 2) (+ x 2)) (+ (* y y) 2)))
(simplify (<= (* (+ y 2) (+ x 2)) (+ (* y y) 2)) :som true)
;; Another relevant option is :arith-lhs. It will move all non-constant monomials to the left-hand-side.
(simplify (<= (* (+ y 2) (+ x 2)) (+ (* y y) 2)) :som true :arith-lhs true)
;; 4. Yes, you are correct.
;; The polynomials are encoded using just * and +.
(simplify (- x y))
5) ctx-solver-simplify is implemented in the file src/smt/tactic/ctx-solver-simplify.*
The code is very readable. We can add trace messages to see how it works on particular examples.
6) There is no tutorial yet on how to write tactics. However, the code base has many examples.
The directory src/tactic/core has the basic ones.
In Z3 you have to_real to obtain the Real equivalent of an Int. Is there some support to the inverse conversions, i.e., to truncation, rounding or like? In the negative case, what could be the most Z3-friendly way of defining them, if any? Many thanks to everyone will answer.
Yes, Z3 has a to_int function that converts a Real into an integer. The semantics of to_int is defined in the SMT 2.0 standard. Here is an example: http://rise4fun.com/Z3/uJ3J
(declare-fun x () Real)
(assert (= (to_int x) 2))
(assert (not (= x 2.0)))
(check-sat)
(get-model)
(declare-const x Real)
(declare-fun f (Real) Real)
(assert (= (f 1.0) 0.0))
(assert (= (* x x) (* 1.0 1.0)))
(check-sat)
(get-model)
I have two independent assertions one in non-linear arithmetic and other uninterpreted functions. Z3 gives a "model is not available" to the problem above. Is there a way to set the logic to something that can handle both at the same time? Thank you.
The new nonlinear solver is not integrated with other theories (arrays, unintepreted functions, bit-vectors) yet. In Z3 4.0, it can only be used to solve problems that contain only nonlinear arithmetic assertions. This is will change in future versions.