在Z3py中,为什么简化将分裂转换为未解释的功能?

时间:2013-07-12 22:37:34

标签: z3 division z3py

TL; DR:使用Z3_OP_BSDIV时,位向量分割节点从Z3_OP_UNINTERPRETED更改为simplify。如何从未解释的操作中判断除法操作?

说明:

以下会话显示了位向量除法被解释,但是,在使用simplify()之后,它被解释。看看下面的变量d会发生什么。

>>> x, y = BitVecs('x y', 32)
>>> n = x/y
>>> n.decl().kind()
1031L
>>> d = simplify(x/y)
>>> d.decl().kind()
2051L

我们可以看到手动声明的未解释函数和UDiv也具有相同的类型。

>>> foo = Function('foo', BitVecSort(32), BitVecSort(32), BitVecSort(32))
>>> u = foo(x, y)
>>> u.decl().kind()
2051L
>>> d1 = simplify(UDiv(x,y))
>>> d1.decl().kind()
2051L

然而,它似乎并没有影响解决:解算器似乎仍然将操作解释为实际划分。

>>> prove(d != 400)
counterexample
[y = 1, x = 400]

我正在尝试按类型处理节点,但是这个似乎对它的类型“撒谎” - 有没有办法知道它真的被解释了,即使它kind是{{1} }?这是一个错误吗?

1 个答案:

答案 0 :(得分:1)

这不一定是个错误。当分母为零时,bvudiv / bvsdiv运算符的结果是未定义的(参见QF_BV logic definition)。因此,可以认为“x / y”的结果是未定义的,并且如果没有其他约束,则保证用未解释的函数替换。因此,位向量公式的简化器必须考虑到未解释的函数可能以简化的方式出现。