4

我有这个 C 代码:

while(p->next)   p = p->next;

我想证明,不管列表有多长,当这个循环结束时,p->nextequalsNULL和 EIP 指的是这个循环之后的下一条指令。

但我不能。有谁知道如何证明Isabelle/HOL中的循环?

4

1 回答 1

11

Michael Norrish 的C ParserAutoCorres允许您将 C 代码导入 Isabelle/HOL 以进行进一步推理的一组工具(免责声明:我是后者的作者)。

使用 AutoCorres,我可以解析以下 C 文件:

struct node {
    struct node *next;
    int data;
};

struct node * traverse_list(struct node *list)
{
    while (list)
        list = list->next;
    return list;
}

使用以下命令进入伊莎贝尔:

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

这是一个部分正确性定理,它在某种程度上说明了您的要求。(特别是,它声明如果函数终止,并且如果它没有出错,则后置条件为真)。

要获得更完整的证明,您需要在上面添加更多内容:

  1. 您需要知道该列表是有效的;例如,中间节点不指向无效地址(例如,未对齐的地址),并且列表不形成循环(意味着 while 循环永远不会终止)。

  2. 您还需要证明终止。这与上面的第二个条件有关,但您可能仍需要就为什么它为真提出一个论据。(一种典型的方法是说列表的长度总是减少,因此循环最终会终止)。

AutoCorres 不指导指令指针的概念(通常这些概念仅存在于汇编级别),但终止证明将是类似的。

AutoCorres 提供了一些用于推理链表的基本库DataStructures.thy,这将是一个很好的起点。

于 2013-11-05T07:55:37.160 回答