Z3 : strange behavior with non linear arithmetic

孤者浪人 提交于 2019-12-10 19:24:19

问题


I am just starting to use Z3 (v4.4.0), and I wanted to try one of the tutorial examples :

(declare-const a Int)
(assert (> (* a a) 3))
(check-sat)
(get-model)

(echo "Z3 will fail in the next example...")
(declare-const b Real)
(declare-const c Real)
(assert (= (+ (* b b b) (* b c)) 3.0))
(check-sat)

As said, the second example fails with "unknown", and by increasing the verbose level (to 3) I think I understand why : some problem with the simplifying process, then the tactic fails. In order to have a better idea of the problem (and a shorter output), I decided to remove the first part of the code to test only the failed part :

(echo "Z3 will fail in the next example...")
(declare-const b Real)
(declare-const c Real)
(assert (= (+ (* b b b) (* b c)) 3.0))
(check-sat)

But magically, now I get "sat". I am not sure about how Z3 chooses its tactic when it is about non linear arithmetic, but can the problem be from Z3 choosing a tactic for the first formula that is useless for the second one ?

Thanks in advance


回答1:


The second encoding is not equivalent to the first, hence the different behavior. The second encoding does not include the constraint (assert (> (* a a) 3)), so Z3 can find it is satisfiable that b^3 + b*c = 3 for some choice of reals b and c. However, when it has the constraint that a^2 > 3 for some integer a, it fails to find it's satisfiable, even though the two assertions are independent from one another.

For this problem, it's essentially that Z3 by default will not use the nonlinear real arithmetic solver (which is complete) when it encounters reals mixed with integers. Here's an example of how to force it using qfnra-nlsat (rise4fun link: http://rise4fun.com/Z3/KDRP ):

(declare-const a Int)
;(assert (> (* a a) 3))
;(check-sat)
;(get-model)

(echo "Z3 will fail in the next example...")
(declare-const b Real)
(declare-const c Real)
(push)
(assert (and (> (* a a) 3) (= (+ (* b b b) (* b c)) 3.0)))
(check-sat)
(check-sat-using qfnra-nlsat) ; force using nonlinear solver for nonlinear real arithimetic (coerce integers to reals)
(get-model)
(pop)
(assert (= (+ (* b b b) (* b c)) 3.0))
(check-sat)
(get-model)

Likewise, if you just change (declare-const a Int) to (declare-const a Real), it will by default pick the correct solver that can handle this. So yes, in essence this has to do with what solver is getting picked, which is determined in part by the sorts of the underlying terms.

Related Q/A: Combining nonlinear Real with linear Int



来源:https://stackoverflow.com/questions/32460549/z3-strange-behavior-with-non-linear-arithmetic

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!