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