Frama-C 不验证来自 https://frama-c.com/html/acsl.html 的归零数组示例

Frama-C does not verify zeroing-array example from https://frama-c.com/html/acsl.html

seems to work only for fixed-length arrays, however the similar code below from https://frama-c.com/html/acsl.html中的例子好像没有通过。一旦我将代码更改为包含要求 && n == 42(或任何其他正整数),它就会通过。

失败时显示 [wp] [Alt-Ergo 2.4.1] Goal typed_set_to_0_loop_invariant_established : Timeout (Qed:1ms) (1') (cached)

/*@
  requires \valid(a+(0..n-1));

  assigns  a[0..n-1];

  ensures

  \forall integer i;
    0 <= i < n ==> a[i] == 0;
*/
void set_to_0(int* a, int n){
  int i;

  /*@
    loop invariant 0 <= i <= n;
    loop invariant
    \forall integer j;
      0 <= j < i ==> a[j] == 0;
    loop assigns i, a[0..n-1];
    loop variant n-i;
  */
  for(i = 0; i < n; ++i)
    a[i] = 0;
}

关于如何进行的任何提示/预期的 behaviour/flags 是什么?

实际上,如果 n 严格为负,则 loop invariant 0 <= i <= n 不成立。循环不变量必须在您第一次到达循环时保持不变(这就是“已建立”部分的意思,与“保留”部分相反,在“保留”部分中,您必须检查它是否在任何循环步骤结束时保持不变,假设它是在上述步骤开始时为真),即使您最终根本没有进入循环(如果 n<0 显然就是这种情况)。因此,您必须在函数的合同中添加一个 requires n >=0;

编辑 我忘了提到另一种解决方案当然是 ni unsigned(或者甚至更好 #include <stddef.h> 并使用 size_t):这样,您可以保证得到一个正数,而不必再写 requires)