Z3:非线性算术的奇怪行为

时间:2015-09-08 14:35:20

标签: z3 solver smt sat

我刚刚开始使用Z3(v4.4.0),我想尝试一个教程示例:

(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)

如上所述,第二个例子以" unknown"失败,并且通过增加详细级别(到3)我认为我理解为什么:简化过程出现问题,然后策略失败。 为了更好地了解问题(以及更短的输出),我决定删除代码的第一部分以仅测试失败的部分:

(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)

但神奇的是,现在我得到了#34;坐着#34;我不确定Z3在关于非线性算术时如何选择它的策略,但问题可能来自Z3选择第一个对第二个公式无效的公式的策略?

提前致谢

1 个答案:

答案 0 :(得分:3)

第二种编码不等同于第一次编码,因此行为不同。第二种编码不包括约束(assert (> (* a a) 3)),因此对于某些实数b和c的选择,Z3可以发现b ^ 3 + b * c = 3是可满足的。然而,当它具有a ^ 2> 1的约束时。 3对于某个整数a,即使这两个断言彼此独立,也无法找到它是否可以满足。

对于这个问题,基本上Z3默认情况下在遇到与整数混合的实数时不会使用非线性实数算术求解器(完成)。以下是使用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)

同样,如果您只是将(declare-const a Int)更改为(declare-const a Real),默认情况下会选择可以处理此问题的正确解算器。所以是的,从本质上讲,这与求解的求解器有关,这部分取决于各种基本术语。

相关问答:Combining nonlinear Real with linear Int