使用Frama-C验证线性搜索

时间:2016-01-06 03:34:51

标签: verification frama-c

我再次对一个简单的验证工作感到困惑,这一次是在使用WP插件的Frama-C(Sodium)中,因为我无法让Jessie在uni工作站上工作(在由admin安装的过程中)工作人员/团队。)我一直在阅读'ACSL by example'和手册。虽然我认为这个例子很简单,但很快就能正确行事。在使用Dafny和Whiley验证相同的算法后,我可能会变得有点污点。

2,3,4,5 // I don't care about the commas  

和我在尝试验证时得到的输出是:

#include <stdio.h>
// A linear search over a sorted array looking for a given element.

/*@ requires len > 0;
  @ requires \valid( ls+ ( 0..(len - 1) ) );
  @ requires \forall size_t k; 0 <= k < (len - 1) ==> ls[k] <= ls[k + 1];
  @ assigns \nothing;
  @ behavior found:
  @   assumes \exists size_t k; 0 <= k < len && ls[k] == item;
  @   ensures \result >= 0;
  @ behavior nfound:
  @   assumes \forall size_t k; 0 <= k < len ==> ls[k] != item;
  @   ensures \result == -1;
  @ complete behaviors found, nfound;
  @ disjoint behaviors found, nfound;
  */
int search( int ls[], const size_t len, int item )
{
  size_t i = 0;

  /*@ loop invariant 0 <= i <= len;
    @ loop invariant \forall size_t k; 0 <= k < i ==> ls[k] != item;
    @ loop assigns i;
    @ loop variant len - i;
    */
  while ( i < len )
  {
    if ( ls[i] == item )
      return i;
    ++i;
  }
  return -1;
}

int main()
{
  int src[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
  if ( search( src, 10, 5 ) >= 0 ) printf( "found item" );
  else printf( "no item found" );
}

1 个答案:

答案 0 :(得分:5)

这让我困惑了一段时间,但在尝试了Coq证明之后,我发现你无法证明found行为的原因仅仅是......它是不是正确。也就是说,len > INT_MAXitem在数组的INT_MAX个第一个单元格中找不到但稍后出现在某个地方,结果将被视为int负。

从技术上讲,这是实现定义的,如C99,6.3.1.3§3中所述:

  

否则,新类型已签名且值无法表示   它;结果是实现定义的还是   实现定义的信号被提出。

如果在命令行中添加选项-warn-signed-downcast,您将看到一个新的RTE生成的断言,但未证明:

     /*@ assert rte: signed_downcast: i ≤ 2147483647; */

然后在假设所述断言成立的情况下证明了found行为的后置条件。