我再次对一个简单的验证工作感到困惑,这一次是在使用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" );
}
答案 0 :(得分:5)
这让我困惑了一段时间,但在尝试了Coq证明之后,我发现你无法证明found
行为的原因仅仅是......它是不是正确。也就是说,len > INT_MAX
和item
在数组的INT_MAX
个第一个单元格中找不到但稍后出现在某个地方,结果将被视为int
负。
从技术上讲,这是实现定义的,如C99,6.3.1.3§3中所述:
否则,新类型已签名且值无法表示 它;结果是实现定义的还是 实现定义的信号被提出。
如果在命令行中添加选项-warn-signed-downcast
,您将看到一个新的RTE生成的断言,但未证明:
/*@ assert rte: signed_downcast: i ≤ 2147483647; */
然后在假设所述断言成立的情况下证明了found
行为的后置条件。