有没有人尝试用Z3本身证明Z3?

时间:2011-08-03 09:56:24

标签: z3 theorem-proving theorem

是否有人尝试用Z3本身证明Z3

甚至可以使用Z3证明Z3是正确的吗?

更理论上,是否可以使用X本身来证明工具X是正确的?

2 个答案:

答案 0 :(得分:27)

简短的回答是:“不,没有人试图用Z3本身证明Z3”: - )

句子“我们证明程序X是正确的”是非常误导的。 主要问题是:正确是什么意思。 在Z3的情况下,如果至少它对于不可满足的问题永远不会返回“sat”而对于可满足的问题则“不满”,则可以说Z3是正确的。 这个定义可以通过包括其他属性来改进,例如:Z3不应该崩溃; Z3 API中的函数X具有属性Y等

在我们同意我们应该证明什么之后,我们必须创建运行时的模型,编程语言语义(在Z3的情况下为C ++)等。 然后,使用工具(也称为验证器)将实际代码转换为一组公式,我们应该使用诸如Z3的定理证明器来检查。 我们需要验证器,因为Z3不“理解”C ++。 验证C编译器(VCC)就是这种工具的一个例子。 请注意,使用此方法证明Z3是正确的,因为我们的模型可能不正确,验证者可能不正确,Z3可能不正确等等,因此无法明确保证Z3确实正确。

要使用验证程序,例如VCC,我们需要使用我们要验证的属性,循环不变量等来注释程序。某些注释用于指定应该执行的代码片段。其他注释用于“帮助/指导”定理证明者。在某些情况下,注释量大于正在验证的程序。因此,该过程并非完全自动化。

另一个问题是成本,这个过程非常昂贵。这比实施Z3要费时更多。 Z3有300k行代码,其中一些代码基于非常微妙的算法和实现技巧。 另一个问题是维护,我们定期添加新功能并提高性能。这些修改会影响证明。

虽然成本可能非常高,但VCC已用于验证非常重要的代码片段,例如Microsoft Hyper-V管理程序。

理论上,任何用于编程语言X的验证者都可以用来证明自己是否也用语言X实现。 Spec#验证程序是此类工具的一个示例。 Spec#在Spec#中实现,Spec#的几个部分使用Spec#进行验证。 请注意,Spec#使用Z3并假设它是正确的。当然,这是一个很大的假设。

您可以在纸上找到有关这些问题和Z3应用程序的更多信息: http://research.microsoft.com/en-us/um/people/leonardo/ijcar10.pdf

答案 1 :(得分:2)

不,使用工具本身无法证明一个重要的工具是正确的。这基本上在Gödel's second incompleteness theorem中说明:

  

对于任何正式的有效生成的理论T,包括基本的算术真理以及关于形式可证明性的某些事实,如果T包含其自身一致性的陈述,则T是不一致的。

由于Z3包含算术,因此无法证明其自身的一致性。

因为在上面的评论中提到过:即使用户提供不变量,Gödels定理仍然适用。这不是可计算性问题。该定理指出,在一致的系统中不存在这样的证明。

但是你可以用Z3验证Z3的部分。

5年后修改

实际上,这个论证比哥德尔的不完备性定理更容易。

如果Z3只返回不可满足公式的UNSAT,那么假设Z3是正确的。

假设我们找到一个公式A,这样如果A不可满足那么Z3是正确的(我们以某种方式证明了这种关系)。

我们可以将此公式赋予Z3,但

  1. 如果Z3返回UNSAT,可能是因为Z3是正确的,或者是因为Z3中的错误。所以我们还没有验证任何内容。
  2. 如果Z3返回SAT和反模型,我们可以通过分析模型找到Z3中的错误
  3. 否则我们什么都不知道。
  4. 因此我们可以使用Z3查找Z3中的错误并提高对Z3的信心(达到极高水平),但不能正式验证它。