美好的一天,自动扣除和验证黑客!
为了更深入地了解WhyML究竟如何为ACSL注释的C程序提供证据,我试图手动"重现" Why3将WhyML程序转换为SMT逻辑并将其输入Z3证明器。
假设我们有以下C片段:
const int L = 3;
int a[L] = {0};
int i = 0;
while (i < L) {
a[i] = i;
i++;
}
assert (a[1] == 1);
我正在尝试将其编码为SMT逻辑,如下所示:
(set-logic AUFNIRA)
(define-sort _array () (Array Int Int))
(declare-const ar _array)
(declare-fun set_a_i (_array Int Int) _array)
(assert (forall ((ar0 _array) (i Int) (j Int))
(ite (< i j)
(= (set_a_i ar0 i j)
(set_a_i (store ar0 i i) (+ i 1) j))
(= (set_a_i ar0 i i) ar0) )))
(assert (= (select (set_a_i ar 0 3) 1) 1))
(check-sat)
Z3给出&#34;未知&#34;。
这可能是因为在指定set_a_i函数时使用了量化。但我认为没有其他方法可以指定它。
我知道以下陈述:
我几乎阅读了为WhyML,Frama-C WP插件和Z3提供的所有材料。我还阅读了几篇关于验证C代码的文章,但没有发现关于C的问题 - &gt; SMT翻译技巧。
我应该学习哪些材料才能获得这种理解?您能否提供一些见解和/或链接到描述将命令式代码翻译成多重排序的一阶逻辑的机制的文章。
我将不胜感激。谢谢!
祝你好运, 的Evgeniy。答案 0 :(得分:3)
WP 0.8 plugin manual和论文“Why3: Shepherd Your Herd of Provers”提供了如何将带注释的C代码转换为为什么逻辑的高级概述,以及如何将为什么逻辑转换为a的输入逻辑。定理证明。
如WP插件手册第1.3节所述,首先考虑Hoare的三元组:
{ P } stmt { Q }
读取:每当前提条件 P 成立时,运行 stmt 后,后置条件 Q 成立。 WP插件将最弱的前提条件视为对 stmt 的函数和后置条件,使得以下Hoare三元组成为:
{ wp ( stmt , Q )} stmt { Q }
在某种意义上,最弱的前提条件是在执行 stmt 之前必须保持的最简单的属性,以便 Q 在执行 stmt之后保持< / em>的
例如,考虑 stmt 为x = x + 1
且{ Q }为{x>}的情况。 0}。通过Hoare演算的赋值规则,我们知道{x + 1> 0} x = x + 1
{x&gt; 0}成立。 {x + 1>事实上,0}是x = x + 1
和{x>的最弱前提条件。 0}。
更一般地说,可以确定任何语句和任何后置条件的最弱前提条件。
现在假设你有一个带有前提条件 P 和后置条件 Q 注释的函数 f :
{ P } f { Q }
定义 W = wp ( f , Q )。我们根据 wp 的定义知道以下Hoare三元组持有:
{ W } f { Q }
如果我们能够证明 P ⇒ W (这是提交给定理证明者的那个),那么属性的有效性 P f 的em>和 Q 已建立。
WP插件生成为什么逻辑。正如“Why3:Shepherd Your Herd of Provers”一文中第4节所述,Why3的操作被描述为处理证明任务,这是一系列以目标结束的声明。这就是为什么逻辑被转换为特定定理证明器的输入逻辑。
对于一个具体的例子,本文概述了为什么逻辑转换为Z3。不仅输入语言不同(Z3使用SMT-LIB2语法),在Why和Z3的逻辑上存在显着差异。本文给出了Z3不支持多态或归纳谓词的例子。
为了将逻辑转换为定理证明器的输入逻辑,Why3使用一系列转换,逐步将Why逻辑转换为目标输入逻辑。 Why3使用称为驱动程序的配置文件来定义所有转换,一个输出证明者原生输入格式的漂亮打印机,以及用于解释证明器输出的正则表达式。
假设您已运行why3config
,您可以查看主目录中自动生成的.why3.conf
配置文件,以确定Why3用于特定证明的驱动程序。例如,在我的系统上,使用Z3时,Why3使用~/.opam/system/share/why3/drivers/z3_432.drv
。 z3_432.drv
导入smt-libv2.drv
驱动程序作为SMT-LIB2兼容证明器的基本驱动程序。
我知道你知道检查生成的SMT2,但我想我会提到如何为感兴趣的人做这件事。如果您将-wp-out DIR
和-wp-proof-trace
选项传递给frama-c
,那么WP将保存输出,以便在各个属性上运行证明器。然后,您可以找到感兴趣的属性的相应.err
文件。就我而言,它是main_assert_final_a_Why3_z3.err
。在文本编辑器中打开该文件,您将看到如下内容:
Call_provers: command is: /Users/dtrebbien/.opam/system/lib/why3/why3-cpulimit 10 1000 -s z3 -smt2 sat.random_seed=42 nlsat.randomize=false smt.random_seed=42 /var/folders/1v/2nkqhkgx0qnfwd75h0p3fcsc0000gn/T/why_9f8a52_main_Why3_ide-T-WP.smt2
此.smt2
文件包含向Why3生成的Z3的SMT-LIB2输入。
如果您愿意,可以运行该命令。就我而言,我看到了:
WARNING: pattern does contain any variable. WARNING: pattern does contain any variable. WARNING: pattern does contain any variable. WARNING: pattern does contain any variable. unsat why3cpulimit time : 0.020000 s
虽然略有违反直觉,但unsat
表示该财产的有效性已确定。