2

デフォルトのロジック ラベル LoopEntry と LoopCurrent を使用しようとすると、問題が発生します。これは、私が使用するさまざまな証明者 (alt-ergo、coq、cvc3、z3) が証明できない簡単な例です。

/*@ requires n > 0;*/
void f(int n){
    int i = 0;
    /*@ loop invariant \at(i,LoopEntry) == 0;
      @ loop invariant \at(i,LoopCurrent) >= \at(i,LoopEntry);
      @ loop invariant 0 <= i <= n;
      @ loop assigns i;
      @ loop variant n-i;
    */
    while(i < n){
        i++;
    }
}

特に、1 番目と 2 番目の不変条件は証明されていません (他は問題ありません)。ここで、i の宣言/定義の後にラベル「label」を追加してこの単純な例を変更し、そのラベルを参照して、ここで LoopCurrent を変更すると (このスニペットが得られます:

/*@ requires n > 0;*/
void f(int n){
    int i = 0;
    label : ;
    /*@ loop assigns i;
      @ loop invariant \at(i,label) == 0;
      @ loop invariant \at(i,Here) >= \at(i,label);
      @ loop invariant 0 <= i <= n;
      @ loop variant n-i;
    */
    while(i < n){
        i++;
    }
}

)

これですべてが証明されました。

Acsl のデフォルト ロジック ラベルに関するドキュメントは非常に理解しやすく、最初の例が 2 番目の例として証明されることを期待していました。問題がどこから来るのか説明していただけますか?

ロー

PS1 : ループ句で Pre が使用される場合、Pre は何を参照しますか? 最初のループ反復または前の反復の前の状態??

PS2 : Frama-C Fluorine を使用していますが、マイナー アップデートごとにアップグレードしていない可能性があります。

4

1 に答える 1