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