我有这个C代码:
while(p->next) p = p->next;
我想证明无论列表有多长,当此循环结束时,p->next
等于NULL
,EIP指的是此循环后的下一条指令。
但我不能。有谁知道如何在 Isabelle / HOL 中证明循环?
答案 0 :(得分:9)
一组工具(免责声明:我是后者的作者)允许您将C代码导入Isabelle / HOL以进一步推理是Michael Norrish的C Parser和AutoCorres。
使用AutoCorres,我可以解析以下C文件:
struct node {
struct node *next;
int data;
};
struct node * traverse_list(struct node *list)
{
while (list)
list = list->next;
return list;
}
使用命令进入Isabelle:
theory List
imports AutoCorres
begin
install_C_file "list.c"
autocorres [ts_rules = nondet] "list.c"
然后我们可以证明一个Hoare三元组,它表明,对于任何输入状态,函数的返回值将是NULL
:
lemma "⦃ λs. True ⦄ traverse_list' l ⦃ λrv s. rv = NULL ⦄"
(* Unfold the function definition. *)
apply (unfold traverse_list'_def)
(* Add an invariant to the while loop. *)
apply (subst whileLoop_add_inv [where I="λnext s. True"])
(* Run a VCG, and solve the conditions using the simplified. *)
apply wp
apply simp
done
这是一个部分正确性定理,有点陈述你所要求的。 (特别是,它声明如果函数终止,如果它没有错,则后置条件为真。)
要获得更完整的证明,您需要在上面添加更多内容:
您需要知道该列表有效;例如,中间节点不指向无效地址(例如,未对齐的地址),并且列表不形成循环(意味着while循环永远不会终止)。
您还需要证明终止。这与上面的第二个条件有关,但您可能仍需要对其为何成立进行论证。 (一种典型的方法是说列表的长度总是减少,因此循环最终会终止)。
AutoCorres不指示指令指针的概念(通常这些概念仅存在于汇编级别),但终止证明类似。
AutoCorres提供了一些基本库来推理DataStructures.thy
中的链接列表,这将是一个很好的起点。