Z3:提取存在模型值

Z3:提取存在模型值,z3,smt,theorem-proving,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) )

我在玩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 (x))
(get-value (x!0))
在每一种情况下,Z3都正确地抱怨没有这样的常数。显然,Z3拥有这些信息,这可以从对
(检查sat)
呼叫的响应中得到证明。有没有办法通过
get value
或其他机制自动访问存在值


谢谢..

在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。 维基百科上有一个条目

话虽如此,我从未为你所描述的问题找到满意的解决方案。 例如,公式可能有许多同名的不同存在变量。 因此,如何以不含糊的方式引用
get value
命令中的每个实例尚不清楚

此限制的一个可能解决方法是“手动”应用skolemization步骤,或者至少对您想要知道值的变量应用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函数可用于获取每个
y
x
值。 上面的例子变成:

(declare-fun sx ((_ BitVec 16)) (_ BitVec 16))
(assert (forall ((y (_ BitVec 16))) (bvuge y (sx y))))
(check-sat)
(get-model)

在本例中,
sx
是fresh函数。Z3生产的模型将为
sx
指定解释。在版本3.0中,解释是标识函数。此函数可用于获取每个
y
x

谢谢莱昂纳多。。如果存在主义先于普遍性,那么这是一个特别好的技巧,在这种情况下,skolemization是微不足道的。在嵌套/交替量词的一般情况下,更好的解决方案可能是用户以某种明确的方式“标记”它们,类似于ACL2中的提示。我想,由用户来确保节点被唯一地标记。类似于(伪SMT-Lib2语法):
存在((x(\uBitvec 16):model\u name“x”)…
这可能会破坏纯粹的SMT-Lib兼容性,但考虑到Z3是如何推动边界的,这可能是一个很好的折衷方案。感谢您的建议。我会考虑Z3未来版本的可能性。但是,用户将无法控制Z3生成的skolem函数符号的签名。Z3在skolemization之前执行了许多简化,skolemization步骤试图最小化对通用变量的依赖性。我用一个例子更新了我的答案,说明了如何提取嵌套在通用量词中的存在变量。