问题
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 bysimplify
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 ofsimplify
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 forma1*t1+...+an*tn
, whereai
are constants andti
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.
回答1:
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.
来源:https://stackoverflow.com/questions/15876712/adjusting-simplify-tactic-in-z3