在 Z3 中创建可变宽度掩码约束

Creating a variable width mask constraint in Z3

我想在一个 Bitvector (X) 上创建一个约束,将另一个 Bitvector 屏蔽到它的 n 最低有效位。我希望这尽可能高效。到目前为止我所尝试的是将第二个位向量表示为:1<<n - 1,其中 n 是另一个位向量。这给了我两个问题:

有什么更有效的方法来解决这个问题或解决宽度问题吗?

不太清楚您要做什么,发布实际代码总是更有帮助。但是,根据您的描述,您可以简单地先向左移动,然后再向右移动。这将从底部推出 0,然后将它们放下;确保 bit-vector 还剩下 least-most n 位。您移动的数量应等于 bitsize - n,其中 bitsize 是您的 bit-vector 的长度,n 是您要保留的 least-significant 位。假设您正在处理 64 位向量,它看起来像:

(declare-const n (_ BitVec 64))
(declare-const x (_ BitVec 64))
(define-fun amnt () (_ BitVec 64) (bvsub #x0000000000000040 n))
(define-fun maskedX () (_ BitVec 64) (bvlshr (bvshl x amnt) amnt))

(常量 #x0000000000000040 是将 SMT-lib 中的 64 写成 64 位 bit-vector 常量的方式。)请注意,这隐含地假设 n 最多64:如果这不是真的,那么减法将 wrap-around 并且你会得到一个不同的约束。我假设您的系统中已经有一个约束,表明 n 最多是您正在处理的 bit-vector 大小。

关于效率:确实没有明显的方法可以使 bit-vector 这样的约束变快或变慢:这实际上取决于您周围有哪些其他约束。因此,在不了解您的问题的任何其他信息的情况下,不可能认为这是否是实现您想要的目标的最佳方法。当存在符号值时,在 SMTLib 中考虑 "speed" 通常没有帮助,影响求解器效率的因素太多了。

关于类型:SMTLib 基于一个非常简单的 first-order 类型系统。所以,是的:几乎所有 bit-vector 操作都必须与参数具有完全相同的大小。这是设计使然:Variable-length bit-vector 在逻辑中根本不可用,因为它会使它变得无用,因为公式的可满足性将取决于您将它们实例化到的实际 bit-sizes。

如果这没有帮助,我建议您发布一个实际的代码片段,说明您正在尝试做的事情以及您 运行 遇到的问题。例子越具体越好