简体   繁体   English

Frama-C 用 "/*@ Ensure" 证明 While 循环

[英]Frama-C Prove While Loop with "/*@ ensures"

I am a newbie at Frama-C and I am trying to validate a C code.我是 Frama-C 的新手,我正在尝试验证 C 代码。 The code is very basic but somehow I can not validate it.该代码非常基本,但不知何故我无法验证它。

In summary, I am trying to prove If that function or loop has ever run.总之,我试图证明该函数或循环是否曾经运行过。 For that, I give a variable a value (4) in the beginning.为此,我在开始时给变量一个值 (4)。 In the function, I change the value to "5", and I try to ensure that the variable 5 at the end.在函数中,我将值更改为“5”,并尝试确保变量 5 在末尾。

The Code:编码:

#include <stdio.h>
int x=4;
/*@
ensures x ==5;
*/
int abs(int val){

    int accept=0;
    int count=3;
    /*@
    loop invariant 0 <= count <= \at(count, Pre);
    loop assigns accept,x,count; 
    loop variant count;
    */
    while (count !=0){
        x=5;
        accept =1;
        count--;
    }
    return x;
 }

I give the command to CLI as "frama-c-gui -wp -rte testp4.c" to start frama-c.我将命令作为“frama-c-gui -wp -rte testp4.c”给 CLI 以启动 frama-c。

As result: Frama-1结果: Frama-1

But the "*@ ensures x ≡ 5; */" is still unknown .但是 "*@ 确保 x ≡ 5; */" 仍然是未知的。

Is there anyone can help me about this ?有没有人可以帮助我解决这个问题? If I take "x=5;"如果我取"x=5;" to outside of the while loop ( before return) It validates the /*@ ensures x ==5; */到 while 循环之外(返回之前)它验证/*@ ensures x ==5; */ /*@ ensures x ==5; */

Thanks in advance to everyone who contributed!提前感谢所有做出贡献的人!

Most of the problems here are related to the use of builtin labels.这里的大多数问题都与内置标签的使用有关。 Here are the labels that we need here:这里是我们需要的标签:

  • Pre: the state in precondition Pre:前置条件中的状态
  • Post: the state in postcondition Post:后置条件中的状态
  • LoopEntry: the state when starting the loop LoopEntry:开始循环时的状态
  • Here: the state at the program point where it is used这里:使用它的程序点的状态

First things first.第一件事。 I do not known which version of Frama-C you are using but I'd suggest updating ;) .我不知道您使用的是哪个版本的 Frama-C,但我建议更新 ;) 。 You would have the following error message to prevent a mistake:您将收到以下错误消息以防止出现错误:

[kernel:annot-error] file.c:11: Warning: 
  unbound logic variable count. Ignoring loop annotation

Why?为什么? Because you are talking about count in precondition when it does not exist.因为您在谈论不存在的前提条件下count Note that in old versions of Frama-C, WP might be OK with this because the pre-state and the initialization of local variables was merged in some cases.请注意,在旧版本的 Frama-C 中,WP 可能对此没问题,因为在某些情况下合并了局部变量的预状态和初始化。

What we want is probably something like "the current value of count is somewhere between 0 and the value it had when we started the loop", thus:我们想要的可能是“ count的当前值介于 0 和我们开始循环时的值之间”,因此:

loop invariant 0 <= count <= \at(count, LoopEntry);
which is:
loop invariant 0 <= \at(count, Here) <= \at(count, LoopEntry);

Now that we have this (proven) invariant, we want to link the behavior of the loop with the postcondition (currenty, our loop invariant does not say anything about x and WP does not use the body of the loop out of it. That means that we need another invariant that is "when count does not equal to its value when starting the loop, x is 5`".现在我们有了这个(经过验证的)不变量,我们想将循环的行为与后置条件联系起来(当前,我们的循环不变量没有说明x并且 WP 没有使用循环体。这意味着我们需要另一个不变量,即“当开始循环时count不等于其值时, x为 5`”。

Thus:因此:

loop invariant count != \at(count, LoopEntry) ==> x == 5 ;

Which allows to have the program entirely proved :) .这允许完全证明该程序:)。 Final annotated program:最终注释程序:

#include <stdio.h>
int x=4;
/*@
  ensures x ==5;
*/
int abs(int val){

  int accept=0;
  int count=3;
  /*@
    loop invariant 0 <= count <= \at(count, LoopEntry);
    loop invariant count != \at(count, LoopEntry) ==> x == 5 ;
    loop assigns accept,x,count; 
    loop variant count;
  */
  while (count !=0){
    x=5;
    accept =1;
    count--;
  }
  return x;
}

Some words about why \at(count, Pre) != 0 ==> \at(x, Post) == 5 (in the comments) does not work:关于为什么\at(count, Pre) != 0 ==> \at(x, Post) == 5 (在评论中)不起作用的一些话:

  • \at(count, Pre) is the value of count in precondition of the function and \at(count, Post) is the value of count in postcondition of the function . \at(count, Pre)函数前置条件下的count值, \at(count, Post)函数后置条件下的count值。 Thus, not what we need here.因此,这里不是我们需要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM