【发布时间】:2013-10-04 01:15:29
【问题描述】:
我无法证明 2 个循环不变量:
loop invariant \forall integer i; 0 <= i < (\at(n, Pre) - n) ==> ((char*)m2)[i] == \at(((char*)m1)[i], Pre);
loop invariant \forall integer i; 0 <= i < (\at(n, Pre) - n) ==> ((char*)m1)[i] == \at(((char*)m2)[i], Pre);
我猜 \at 不像我预期的那样适用于数组。
ACSL by Example(第 68 页,swap_ranges)中有一个类似的函数,它使用了这个,但是,如前所述,他们无法用 WP 插件证明这个特定的函数。我在我的机器上试过了,确实不能证明同样的不变量。
完整代码
/*
* memswap()
*
* Swaps the contents of two nonoverlapping memory areas.
* This really could be done faster...
*/
#include "string.h"
/*@
requires n >= 1;
requires \valid(((char*)m1)+(0..n-1));
requires \valid(((char*)m2)+(0..n-1));
requires \separated(((char*)m1)+(0..n-1), ((char*)m2)+(0..n-1));
assigns ((char*)m1)[0..n-1];
assigns ((char*)m2)[0..n-1];
ensures \forall integer i; 0 <= i < n ==> ((char*)m1)[i] == \old(((char*)m2)[i]);
ensures \forall integer i; 0 <= i < n ==> ((char*)m2)[i] == \old(((char*)m1)[i]);
@*/
void memswap(void *m1, void *m2, size_t n)
{
char *p = m1;
char *q = m2;
char tmp;
/*@
loop invariant 0 <= n <= \at(n, Pre);
loop invariant p == m1+(\at(n, Pre) - n);
loop invariant q == m2+(\at(n, Pre) - n);
loop invariant (char*)m1 <= p <= (char*)m1+\at(n, Pre);
loop invariant (char*)m2 <= q <= (char*)m2+\at(n, Pre);
loop invariant \forall integer i; 0 <= i < (\at(n, Pre) - n) ==> ((char*)m2)[i] == \at(((char*)m1)[i], Pre);
loop invariant \forall integer i; 0 <= i < (\at(n, Pre) - n) ==> ((char*)m1)[i] == \at(((char*)m2)[i], Pre);
loop assigns n, tmp, ((char*)m1)[0..\at(n,Pre)-1], ((char*)um2)[0..\at(n, Pre)-1], p, q;
loop variant n;
@*/
while (/*n--*/ n) {
tmp = *p;
*p = *q;
*q = tmp;
p++;
q++;
n--; // inserted code
}
}
编辑
我正在使用 Frama-C Oxygen 版本并尝试使用 alt-ergo(0.94) 和 cvc3(2.4.1) 进行自动证明
frama-c 的输出:
cvc3:
[wp] [Cvc3] Goal store_memswap_loop_inv_7_established : Valid
[wp] [Cvc3] Goal store_memswap_loop_inv_6_established : Valid
[wp] [Cvc3] Goal store_memswap_loop_inv_7_preserved : Unknown
[wp] [Cvc3] Goal store_memswap_loop_inv_6_preserved : Unknown
alt-ergo:
[wp] [Alt-Ergo] Goal store_memswap_loop_inv_7_established : Valid
[wp] [Alt-Ergo] Goal store_memswap_loop_inv_6_established : Valid
[wp] [Alt-Ergo] Goal store_memswap_loop_inv_7_preserved : Timeout
[wp] [Alt-Ergo] Goal store_memswap_loop_inv_6_preserved : Timeout
【问题讨论】:
-
你好克里斯蒂亚诺,关于你的问题的一些句法评论(我无法回答自己):1)“它不能证明”是没有意义的。您应该说明您尝试过的证明。我们是在讨论无法证明的——错误的——义务的产生,还是你安装的自动证明器的弱点?这些是完全不同的讨论。 2) 说你在谈论哪个版本的 Frama-C 也没有什么坏处。 3)我不知道ACSL-by-example示例中的注释,但是您示例中的注释是错误的,因此您不应该期望它们被证明
-
等等,其实 3) 是答案的开始,我将在下面展开。
-
正如你所指出的,我添加了更多信息。
标签: c static-analysis design-by-contract frama-c loop-invariant