我在Z3的最新(不稳定分支)版本上使用内置插值功能。它适用于包含整数的SMT2公式。但是,对于以下SMT2程序,它会抛出iz3proof_itp::proof_error
和随后的iz3translate::unsupported error
(见下文) -
(set-option :produce-models true)
(set-logic QF_AUFBV)
(declare-fun a () (_ BitVec 32))
(declare-fun b () (_ BitVec 32))
(declare-fun x1 () (_ BitVec 32))
(declare-fun x2 () (_ BitVec 32))
(declare-fun x3 () (_ BitVec 32))
(declare-fun y1 () (_ BitVec 32))
(declare-fun y2 () (_ BitVec 32))
(compute-interpolant
(= a (_ bv0 32))
(= b (bvneg (_ bv2 32)))
(= x1 (_ bv1 32))
(= y1 (_ bv0 32))
(= x2 (bvadd x1 a))
(= x3 (bvadd x2 b))
(= y2 (bvadd y1 a))
(bvsge x3 (_ bv0 32))
)
我在rise4fun上的在线版本上尝试过,它运行良好。因此,经过一些调试后,我发现错误是从文件find_congruence_position
中的函数iz3proof_itp.cpp
内部引发的。
所以我对函数进行了以下简单(可能是危险的)更改,以便至少处理proof_error -
在第2431行更改if(x == arg(arg(con,0),i) && (y == arg(arg(con,1),i))
到if((x == arg(arg(con,0),i) && (y == arg(arg(con,1),i))) || (y == arg(arg(con,0),i) && (x == arg(arg(con,1),i))))
我简单地说,或者复制x和y互换的条件 - 我发现x和y有时会互换它们的值,可能是由于一些证明技术。
这确实解决了这个问题,我发现使用相等和不相等,以及bvadd或bvneg与BitVecs同时计算插值工作。例如,以下文件有效 -
(set-option :produce-models true)
(set-logic QF_AUFBV)
(declare-fun a () (_ BitVec 32))
(declare-fun b () (_ BitVec 32))
(compute-interpolant
(= a (_ bv0 32))
(= b (bvadd a (_ bv1 32)))
(= b (_ bv0 32))
)
但后来我尝试使用关系运算符,比如bvsgt或bvsge,并且它抛出了一个新的错误 -
terminate called after throwing an instance of 'iz3translation::unsupported'
我仔细研究了一下,发现引起问题的表达是 -
(not ((_ bit2bool 2) x2))
- 为其分配了PR_TH_LEMMA类型和UNKNOWN_THEORY类型。似乎没有人支持这种行动。
由于在线版本正常运行,我想知道是否可以获得该版本。我在StackOverflow上阅读了之前的问题和答案,我有点困惑。有人说不支持BitVec理论(尽管这些帖子都很旧),但那么在线版本是如何工作的呢?或者我做错了什么?任何帮助都非常感谢。
答案 0 :(得分:0)
实际上,不支持位向量运算的插值。有趣的是,它适用于网络版。然而,那个版本很老了,我认为它早于Z3的源代码版本。我可以想到它运作的两个可能原因:
1)内插Z3的版本使用" foci"证明者作为备份。每当它遇到一部分不能理解的证据时,它就会将该部分打包为引理并使用焦点进行重新编写。当前版本不使用foci(源代码中不可用的第三方工具),完全依赖于Z3生成的证明。
2)旧版本可能以不同的方式进行钻孔。如果所有非局部证明步骤都是纯粹的命题(仅使用分辨率规则),那么很容易计算插值。
据我所知,从高效位向量求解器(使用所有已知的预处理技巧)计算插值是一个悬而未决的问题。