Z3应该能够验证这个程序吗?

时间:2016-05-09 13:38:32

标签: z3 smt

我是Z3的初学者。最近,我一直在使用z3来验证一些问题。这是我尝试过的一个问题:(x< 0& y< 0)暗示x / y> = 0,下面是我写的程序:

(declare-const x Int)
(declare-const y Int)
(define-fun assumption() Bool
  (and (< x 0) (< y 0))
)

(define-fun predicate() Bool
  (<= 0 (div x y))
)

(assert (not (=> assumption predicate)))

(check-sat)

当我使用'z3 -smt2 filename'来验证这个程序时,它可以工作并返回不满。但是,当我稍后将程序修改为:

(declare-const x Int)
(declare-const y Int)
(define-fun assumption() Bool
  (and (< x 0) (< y 0))
)

(define-fun predicate() Bool
  (<= 0 (div (* -1 x) (* -1 y)))
)

(assert (not (=> assumption predicate)))

(check-sat)

当我将'x / y'更改为(-1 * x)/( - 1 * y)时,这导致z3超时,并且我需要在那里添加-1。我很困惑为什么会发生这种情况以及为什么乘以常数会使这个问题变得更加复杂。

有人可以帮助弄清楚为什么会这样吗?

谢谢!

2 个答案:

答案 0 :(得分:1)

对非线性算术的支持非常有限,例如除数是变量的除法。 因此,Z3将尽最大努力,但绝不能确保通过非线性算术运算为每个公式做出决策。因此,例如,您可以将丢番图方程式输入Z3,但不要指望它提供饱和/不饱和答案。 而不是尝试一些无限的搜索,Z3可能更愿意放弃并返回未知。

答案 1 :(得分:0)

(注意:这只是一个评论而不是一个答案。我必须这样做,因为我没有足够的声誉来添加评论。)

以下是Z3 guide关于整数除法,模数和提醒运算符的引用:

  

Z3还支持除法,整数除法,模数和余数运算符。在内部,它们都映射到乘法。

(declare-const a Int)
(declare-const r1 Int)
(declare-const r2 Int)
(declare-const r3 Int)
(declare-const r4 Int)
(declare-const r5 Int)
(declare-const r6 Int)
(assert (= a 10))
(assert (= r1 (div a 4))) ; integer division
(assert (= r2 (mod a 4))) ; mod
(assert (= r3 (rem a 4))) ; remainder
(assert (= r4 (div a (- 4)))) ; integer division
(assert (= r5 (mod a (- 4)))) ; mod
(assert (= r6 (rem a (- 4)))) ; remainder
(declare-const b Real)
(declare-const c Real)
(assert (>= b (/ c 3.0)))
(assert (>= c 20.0))
(check-sat)
(get-model)
  

在Z3中,允许除以零,但未指定结果。分工不是部分功能。实际上,在Z3中,所有函数都是完全的,尽管在某些情况下结果可能没有指定,例如除以零。

当参数为负时,不清楚是什么行为。换句话说,这些操作的乘法映射不明确。