有効なループの不変条件は常に無限にあります。秘訣は、アルゴリズムについて証明したいことを証明するのに十分であり、証明できることを見つけることです(通常、ループの反復回数の帰納によって)。
このアルゴリズムの正確性を証明するには、3つの部分があります。
- アルゴリズムが誤ったステップを実行することはありません。ここで、潜在的な不正な手順は、配列の境界外の配列要素にアクセスすることです。
- アルゴリズムが
YES
orを返す場合NO
、この出力は正しいです。
- アルゴリズムは入力ごとに終了します。
正確さのために、あなたはそれを証明する必要があります 1≤i≤n そして 1≤j≤n。これはあなたの不変条件の一部である方がいいです。ループ条件を考えるi<j、これを凝縮して 1≤i<j≤nループ本体への入り口。ループテストが最後に到達した場合、この条件は当てはまりませんが、次のことに気付くと役立つ場合があります。i≤j (ループ本体の内部で、 i<j、 i そして j 変更するだけ 1、これは最悪の場合、この厳密な不等式を等式に変える可能性があります)。
ときにreturn YES
実行され、A[i]+A[j]=b明らかです。したがって、この部分は証明するために特別なものを必要としません。
最後のreturn NO
ステートメントが実行されると、ループは正常に終了した(つまりi<j は偽です)、あなたはそれを証明する必要があります ∀i,∀j,A[i]+A[j]≠b。このプロパティは明らかに一般的には当てはまりませんYES
。答えがである場合、このプロパティは成り立ちません。あなたは強化する必要がありますこの特性あります。一般化する必要がある特別なケースがあります。これは、既にトラバースされている配列の一部にのみ適用されるプロパティの典型的なケースです。ループは、(x,y) 以前の値です (i,j) (すなわち 1≤x≤i そして j≤y≤n そして (x,y)≠(i,j))その後 A[x]+A[y]≠b。これは、ループ不変式で表現した方がよいでしょう。
私たちはそこで終わりましたか?結構です。通常のループ終端でわかっているのは、∀x≤i,∀y≤j,A[x]+A[y]≠b。もしあったらx>i そして y≤j、または x≤i そして y>j:できますか A[x]+A[y]≠b?それ以上の情報なしではそれを言うのは難しいです。実際、次のような場合を区別したほうがよいでしょう。A[x]+A[y]>b と場合 A[x]+A[y]<b。これらのプロパティを使用すると、配列がソートされているという事実を使用して、配列内の他の位置に関する事実を推測できます。だけで≠b、私たちが取り組むことは何もありません。どっちかわからないA[x]+A[y] いくつかのランダムのためにあります x<i そして y>j; しかし、境界で何が起こるかはわかっています。i 増加します、それは A[i]+A[j] 小さすぎる、と j 減少している、それは A[i]+A[j]大きすぎます。どのループ不変式がこれを表現できるか考えてください。以下に可能性をあげます。
このプロパティは、必要な条件を直接提供しないことに注意してください return NO
ステートメントにください。ループの最後の実行で何が起こったのかを調べる必要があります。または、いつかを詳しく調べるより強いループ不変式を証明する必要があります。A[x]+A[y]<b そしていつ A[x]+A[y]>b。
最後に、終了のために、あなたは関係する必要があります i そして jループの反復回数。ここでは、これは単純です。i または j 各ターンで移動するので、 j−i 減少する 1各ループ反復で; これを証明するためにループ不変式を使用する必要はありません。
次の不変式を取得しました。
1≤i≤j≤n∧(∀x<i,∀y<j,A[x]+A[y]≠b)∧(∀x<i,A[x]+A[j]<b)∧(∀y>j,A[i]+A[y]>b)