2

假设我们有以下 C 注释代码:

#define L  3
int a[L] = {0};
/*@ requires \valid(a+(0..(L - 1)));
    ensures \forall int j; 0 <= j < L ==> (a[j] == j); */
int main() {
        int i = 0;
        /*@ loop assigns i, a[0..(i-1)];
            loop invariant inv1: 0 <= i <= L;
            loop invariant inv2:
                        \forall int k; 0 <= k < i ==> a[k] == k; 
        */
        while (i < L) {
          a[i] = i;
          i++;
        }
        /*@ assert final_progress:
               \forall int k; 0 < k < L ==> a[k] == a[k-1] + 1; 
            assert final_c: 
               a[2] == a[1] - 1; */
        return 0;
}

尽管 final_progress 语句已被证明,为什么 Alt-Ergo/Z3 会为 final_c 断言产生“未知”或超时?对于这种明显(从用户的角度)无效的陈述,我肯定希望看到“无效”。

$ frama-c -wp -wp-rte -wp-prover z3 test2.c
..
[wp] [z3] Goal typed_main_assert_final_c : Unknown (455ms)

$ frama-c -wp -wp-rte -wp-prover alt-ergo test2.c 
..
[wp] [Alt-Ergo] Goal typed_main_assert_final_c : Timeout
4

1 回答 1

1

WP 插件不支持将属性(前置条件、后置条件、用户断言)标记为无效。如WP 插件手册2.2 节所述,状态为以下之一:

  1. 没试过图标— 没有尝试证明。
  2. 未知图标— 该属性尚未经过验证。

    此状态表示无法找到证明。这可能是因为该属性实际上是无效的。

  3. 在假设下有效图标— 该属性有效但具有依赖关系。

    如果 WP 插件能够在假设一个或多个属性完全有效的情况下证明该属性,您将看到此状态应用于属性。

  4. 肯定有效的图标— 该属性及其所有依赖项完全有效。

虽然 WP 插件不支持将属性标记为无效,但您可以使用\false在函数末尾断言的技巧:

#define L  3
int a[L] = {0};
/*@ requires \valid(a+(0..(L - 1)));
    ensures \forall int j; 0 <= j < L ==> (a[j] == j); */
int main()
{
    int i = 0;
    /*@ loop assigns i, a[0..(i-1)];
        loop invariant inv1: 0 <= i <= L;
        loop invariant inv2: \forall int k; 0 <= k < i ==> a[k] == k; 
    */
    while (i < L) {
        a[i] = i;
        i++;
    }
    //@ assert final_progress: \forall int k; 0 < k < L ==> a[k] == a[k-1] + 1;
    //@ assert final_c: a[2] == a[1] - 1;
    //@ assert false: \false;
    return 0;
}

在此代码上运行 WP 插件会导致:

...
[wp] [Alt-Ergo] 目标 typed_main_assert_false :有效 (114ms) (97)
...

如果 WP 插件标记assert \false为有效(在 GUI 中它将显示为有效但具有依赖关系),那么您就知道存在无效属性。

于 2015-07-21T11:00:21.897 回答