Python Z3位矢量的符号高低提取

Python Z3位矢量的符号高低提取,python,z3,z3py,Python,Z3,Z3py,我一直在尝试使用Z3证明某些SIMD矢量化,但我在尝试对有条件地在位或通道上移动的SIMD操作建模时遇到了一个问题(例如英特尔\u mm\u shuffle\u epi8) 当我尝试将符号high和low与Extract一起使用时出现问题,这似乎不受支持: assert a.sort() == BitVecSort(128) assert b.sort() == BitVecSort(128) Extract( Extract(i+3,i,b)*8+7, Extract(i+3,i,b)*8,

我一直在尝试使用Z3证明某些SIMD矢量化,但我在尝试对有条件地在位或通道上移动的SIMD操作建模时遇到了一个问题(例如英特尔
\u mm\u shuffle\u epi8

当我尝试将符号
high
low
Extract
一起使用时出现问题,这似乎不受支持:

assert a.sort() == BitVecSort(128)
assert b.sort() == BitVecSort(128)
Extract( Extract(i+3,i,b)*8+7, Extract(i+3,i,b)*8, a)
导致

z3.z3types.Z3Exception: Symbolic expressions cannot be cast to concrete Boolean values.
问题似乎有两个方面:

Z3似乎不支持符号大小的位向量

>>> a = Int('a')
>>> b = BitVec('b', a)
ctypes.ArgumentError: argument 2: <class 'TypeError'>: wrong type
>a=Int('a')
>>>b=比特向量('b',a)
ctypes.ArgumentError:参数2::错误类型
这会很整洁,但唉。因此,
Extract
需要能够知道其返回值的精确
BitVec
排序,并要求
high
low
都是具体的,尽管看起来唯一的实际要求应该是
simplify(high-low)
产生具体的值


这样做的正确方法是什么?

是的,高/低需要是常数,以便静态地知道结果类型。
您可以使用移位和/或掩码来执行您想要的操作,不过您需要为输出确定最大大小。

是的,高/低需要是常量,以便静态地知道结果类型。
您可以使用移位和/或掩码来执行您想要的操作,但需要为输出确定最大大小。

SMTLib位向量逻辑仅为具体的位大小定义。这不仅仅是一个疏忽:这是逻辑的一个基本限制:没有决策程序可以决定可能涉及符号大小的位向量公式的正确性,因为位向量公式的真实性可以根据大小而改变。经典的例子是:

x <= 7
同样,如果
x
的宽度为2位,则为真;如果宽度为3位,则为假。因此,SMTLib要求所有位向量大小在指定时间都是具体的。请注意,您可以编写适用于任意位大小的高级程序,但一旦渲染并发送到解算器,所有位向量大小都必须是已知的具体常量

关于
摘录
的问题。你说得对,严格地说,最后一段的具体性就足够了。但是z3py是SMTLib之上的一个薄层,它没有做这样的简化。“具体性”要求源自对相应SMTLib功能的类似限制:

请参见此处:注意,由于这个原因,甚至逻辑本身也被称为“FixedSizeBitVectors”,而不仅仅是“位向量”

然而,提取固定大小的数据块并不困难,只需按
lo
右移,然后屏蔽/提取所需的比特数:

 ((_ extract 7 0) (bvlshr x lo))
如果块大小不是恒定的,那么再次进入符号位向量大小的世界,SMTLib出于我上面提到的原因避免了这种情况。(这也是为什么
extract
将具体整数作为参数,并使用有趣的SMTLib符号来表示参数是具体值的原因。)


如果您确实需要使用“符号”字号,那么最好的办法是编写程序,并通过确保每种情况下的字号都是具体的来分别证明每个感兴趣的“符号”字号。(基本上是针对您感兴趣的所有大小进行大小写分割。)

SMTLib位向量逻辑仅针对具体的位大小定义。这不仅仅是一个疏忽:这是逻辑的一个基本限制:没有决策程序可以决定可能涉及符号大小的位向量公式的正确性,因为位向量公式的真实性可以根据大小而改变。经典的例子是:

x <= 7
同样,如果
x
的宽度为2位,则为真;如果宽度为3位,则为假。因此,SMTLib要求所有位向量大小在指定时间都是具体的。请注意,您可以编写适用于任意位大小的高级程序,但一旦渲染并发送到解算器,所有位向量大小都必须是已知的具体常量

关于
摘录
的问题。你说得对,严格地说,最后一段的具体性就足够了。但是z3py是SMTLib之上的一个薄层,它没有做这样的简化。“具体性”要求源自对相应SMTLib功能的类似限制:

请参见此处:注意,由于这个原因,甚至逻辑本身也被称为“FixedSizeBitVectors”,而不仅仅是“位向量”

然而,提取固定大小的数据块并不困难,只需按
lo
右移,然后屏蔽/提取所需的比特数:

 ((_ extract 7 0) (bvlshr x lo))
如果块大小不是恒定的,那么再次进入符号位向量大小的世界,SMTLib出于我上面提到的原因避免了这种情况。(这也是为什么
extract
将具体整数作为参数,并使用有趣的SMTLib符号来表示参数是具体值的原因。)

如果您确实需要使用“符号”字号,那么最好的办法是编写程序,并通过确保每种情况下的字号都是具体的来分别证明每个感兴趣的“符号”字号。(基本上是针对您感兴趣的所有尺寸的案例分割。)