Z3:提取存在模型值

时间:2011-08-24 17:33:06

标签: z3 smt theorem-proving

我正在玩Z3的QBVF求解器,并想知道是否有可能从存在主义断言中提取值。也就是说,让我说我有以下内容:

(assert (exists ((x (_ BitVec 16))) (forall ((y (_ BitVec 16))) (bvuge y x))))

这基本上表示存在“最小”16位无符号值。然后,我可以说:

(check-sat)
(get-model)

Z3-3.0愉快地回应:

sat
(model  (define-fun x!0 () (_ BitVec 16)
#x0000)
)

这真的很酷。但我想做的是能够通过get-value提取该模型的各个部分。不出所料,以下似乎都不起作用

(get-value (x))
(get-value (x!0))

在每种情况下,Z3都正确地抱怨没有这样的常数。显然,Z3具有该信息,如对(check-sat)电话的响应所证明的那样。有没有办法通过get-value或其他一些机制自动访问存在价值?

谢谢..

1 个答案:

答案 0 :(得分:3)

在Z3中,get-value仅允许用户引用“全局”声明。 存在变量x是一个本地声明。因此,无法使用get-value访问它。 默认情况下,Z3使用称为“skolemization”的过程消除了存在变量。 我们的想法是用新常量和函数符号替换存在变量。 例如,公式

exists x. forall y. exists z. P(x, y, z)

转换为

forall y. P(x!1, y, z!1(y))

请注意,z成为一个函数,因为z的选择可能取决于y。 维基百科在skolem normal form

上有一个条目

话虽如此,我从来没有找到一个令人满意的解决方案来解决你所描述的问题。 例如,公式可能具有许多具有相同名称的不同存在变量。 因此,不清楚如何以非模糊的方式引用get-value命令中的每个实例。

此限制的一种可能的解决方法是“手动”应用skolemization步骤,或至少应用于您想要知道值的变量。 例如,

(assert (exists ((x (_ BitVec 16))) (forall ((y (_ BitVec 16))) (bvuge y x))))

写成:

(declare-const x (_ BitVec 16))
(assert (forall ((y (_ BitVec 16))) (bvuge y x)))
(check-sat)
(get-value x)

如果存在变量嵌套在通用量词中,例如:

(assert (forall ((y (_ BitVec 16))) (exists ((x (_ BitVec 16))) (bvuge y x))))
(check-sat)
(get-model)

可以使用新的skolem函数来获取每个x的{​​{1}}值。 上面的例子变成:

y

在此示例中,(declare-fun sx ((_ BitVec 16)) (_ BitVec 16)) (assert (forall ((y (_ BitVec 16))) (bvuge y (sx y)))) (check-sat) (get-model) 是新功能。由Z3制作的模型将为sx指定解释。在3.0版中,解释是身份功能。此函数可用于获取每个sx的{​​{1}}值。