我试图使用Why3的Z3后端来检索模型,然后可以使用这些模型导出在程序中显示错误的测试用例。但是,对于任何Why3目标,Z3版本4.3.2似乎无法回答sat
。看起来,Why3使用的一些公理定义以某种方式混淆了Z3。例如,以下示例(这是Why3生成的一小部分)
(declare-fun abs1 (Int) Int)
;; abs_def
(assert
(forall ((x Int)) (ite (<= 0 x) (= (abs1 x) x) (= (abs1 x) (- x)))))
(check-sat)
使用以下命令行生成timeout
:
z3 -smt2 model.partial=true file.smt2 -T:10
另一方面,将定义更改为
(declare-fun abs1 (Int) Int)
;; abs_def
(assert
(forall ((x Int)) (=> (<= 0 x) (= (abs1 x) x))))
(assert
(forall ((x Int)) (=> (> 0 x) (= (abs1 x) (- x)))))
会给我一个模型(看起来很合理)
(model
(define-fun abs1 ((x!1 Int)) Int
(ite (>= x!1 0) x!1 (* (- 1) x!1)))
)
但如果我尝试添加原始Why3文件中存在的下一个公理,即
;; Abs_pos
(assert (forall ((x Int)) (<= 0 (abs1 x))))
再次Z3回答timeout
。
Z3配置中是否缺少某些内容?此外,在以前版本的Why3中,有一个选项MODEL_ON_TIMEOUT
,它允许在这种情况下检索模型。即使不能保证这是一个真正的模型,因为Z3无法完成检查,实际上这些模型通常包含我需要的所有信息。但是,我还没有在4.3.2中找到类似的选项。它还存在吗?
更新最后一个公理Abs_pos
是错误的(我在发布此处之前玩了一下Why3的输出并最终粘贴了错误版本的问题)。现在已经修复了。
答案 0 :(得分:0)
附加公理
(断言(不是(forall((x Int))(&lt; = 0(abs1 x)))))
使问题不可满足,因为abs1总是返回一个非负整数,并且使用附加公理,你需要为某些x存在abs1的负结果。 Z3的Web版本按预期返回不满,请参阅here。