Coq 在使用可验证的C语言添加到链表时,找出适当的循环不变量

Coq 在使用可验证的C语言添加到链表时,找出适当的循环不变量,coq,verifiable-c,Coq,Verifiable C,我正在研究beta第5版软件基础模块,它涵盖了可验证的C语言。我在研究最后一部分,它涉及到哈希映射上的操作(需要在链表上进行操作) 我有点被body\u incr\u list卡住了 正在验证的代码: void incr_list (struct cell **r0, char *s) { struct cell *p, **r; for(r=r0; ; r=&p->next) { p = *r; if (!p) { *r = new_cell(s,1,N

我正在研究beta第5版软件基础模块,它涵盖了可验证的C语言。我在研究最后一部分,它涉及到哈希映射上的操作(需要在链表上进行操作)

我有点被
body\u incr\u list
卡住了

正在验证的代码:

void incr_list (struct cell **r0, char *s) {
  struct cell *p, **r;
  for(r=r0; ; r=&p->next) {
    p = *r;
    if (!p) { *r = new_cell(s,1,NULL); return; }
    if (strcmp(p->key, s)==0) {p->count++; return;}
  }
}
这做了一些新的事情…一个指针指针,事实上p在循环中是空的,但是如果它循环,则保证有一个值。模块给出的规格为:

Definition incr_list_spec : ident × funspec :=
 DECLARE _incr_list
 WITH r0: val, al: list (list byte × Z), s: val,
      sigma : list byte, gv: globals
 PRE [ _r0 OF tptr (tptr tcell), _s OF tptr tschar ]
    PROP (list_get sigma al < Int.max_unsigned)
    LOCAL (temp _r0 r0; temp _s s; gvars gv)
    SEP (listboxrep al r0; cstring Ews sigma s; mem_mgr gv)
 POST [ tvoid ]
      PROP ( ) LOCAL ()
      SEP (listboxrep (list_incr sigma al) r0;
           cstring Ews sigma s; mem_mgr gv).
有了这一点,我能够取得一些基本进展,但我在处理以下方面遇到了困难:

    if (!p) { *r = new_cell(s,1,NULL); return; }
原因是,现在在SEP子句中,我有
listboxrep al'r0'
,但为了让它通过这一行

    p = *r;
我需要在Ews(tptr tcell)pR0'*listrep al'p将其展开为
数据。同样,这不是一个大问题,但是在p为null并创建新单元格的情况下(
*r=new_cell(s,1,null);return;
),我得到了一个证明目标,我不知道它是否可以解决

这是因为Ews(tptr tcell)pR0'的
数据被转换为Ews(tptr tcell)vret r0'的
数据,但我们仍然只有
listrep al'p
,而不是
listrep al'vret
。虽然在这种情况下,al'很可能是[],这意味着我们有
listrep[]p
,但我不确定用它可以做什么。如果我坚持到底,我最终会得到以下结果:

(list_cell sigma 1 (Vint (Int.repr 0)) vret *
 data_at Ews (tptr tcell) vret r0' *
 ((EX p : val, data_at Ews (tptr tcell) p r0' * (!! (p = nullval) && emp)) -*
  (ALL sigma0 : list byte,
   (EX y : val, list_cell sigma0 1 y nullval * (!! (y = nullval) && emp)) -*
   listboxrep (list_incr sigma0 al) r0)))%logic
|-- listboxrep (list_incr sigma al) r0
这让我相信我的不变量是不正确的…例如,如果我通过咀嚼来设置p

EX p : val, data_at Ews (tptr tcell) p r0' * (!! (p = nullval) && emp)
当然,它必须是空值。但我们拥有的价值是Ews(tptr tcell)vret r0'的数据


所以我不知道。我很确定我需要改进我的不变量,但不确定如何改进!非常感谢您的指点。

让我们重点关注您提议的不变量的SEP条款:

SEP (
 listboxrep al' r0';
 cstring Ews sigma s;
 mem_mgr gv;
 listboxrep al' r0' -* (ALL sigma:list byte, listrep (list_incr sigma []) nullval -* listboxrep (list_incr sigma al) r0)
)).
首先,表达式
listrep(list_incr sigma[])nullval
相当于
(list_incr sigma[]=nil&&emp)
,因此您可能会问自己,这就是您的意思吗


其次,想想你的魔杖,
listboxrep al'r0'-*…
。您的SEP的第一条说,“现在我有
listboxrep al'r0'
”。魔杖的表情是:“我可以用list
al'
准确地填充
r0'
孔。但是list incr将修改孔的内容。因此,您不希望在(的左侧)中准确地填充
al'
魔杖,你想要一些普遍量化的列表值,你可以稍后填写。

谢谢你的指点,Appel教授。我会尝试看看这些技巧是否能取得一些进展。可验证的C很复杂,但它非常酷,这个软件基础模块非常有启发性!
SEP (
 listboxrep al' r0';
 cstring Ews sigma s;
 mem_mgr gv;
 listboxrep al' r0' -* (ALL sigma:list byte, listrep (list_incr sigma []) nullval -* listboxrep (list_incr sigma al) r0)
)).