大まかに言えば、あなたは正しいです。ループ不変条件は、「ループの各反復の直前と直後に真である条件」です。ただし、この定義では、問題のコードのループ不変条件は文字通り無数にあり、それらのほとんどは特に重要ではありません。たとえば、i < 101、i < 102、i < 103、... はすべて、特定のコードのループ不変条件です。
ただし、通常、ループ不変条件を見つけるためだけにループ不変条件を見つけることには関心がありません。代わりに、プログラムが正しいことを証明することに関心があり、プログラムが正しいことを証明したい場合は、適切に選択されたループ不変条件が非常に役立つことがわかります。
たとえば、問題のコードはバブル ソート アルゴリズムの内側のループであり、その目的は配列を "よりソート" することです。したがって、このコードが完全に正しいことを証明するには、次の 3 つのことを証明する必要があります。
(1) 実行がコードの最後に到達すると、配列はコードの先頭の配列の順列になります。(2) 実行がコードの最後に到達すると、配列内の反転の数はゼロであるか、コードの開始時の配列内の反転の数よりも少なくなります (この条件は、外側のバブルソートアルゴリズムのループが終了します)。(3) コードが終了します。
(1) を証明するには、3 つの実行パスを考慮する必要があります (パス 2 を検討する場合、ループ不変条件が重要な役割を果たします)。
(PATH 1) 実行がコードの先頭から始まり、ループの先頭に初めて到達したときに何が起こるかを考えてみてください。この実行パスでは配列に対して何も行われないため、配列はコードの先頭にある配列の順列です。
(PATH 2) 次に、実行がループの先頭から開始され、ループを一巡して、ループの先頭に戻るとどうなるかを考えてみましょう。a[i] <= a[i+1] の場合、スワップは発生せず、したがって、配列はコードの先頭で配列の順列のままです (何も行われないため)。または、a[i] > a[i+1] の場合、スワップが発生します。ただし、コードの先頭では、配列は依然として配列の順列です (スワップは順列の一種であるため)。したがって、実行がループの先頭に到達するたびに、配列はコードの先頭にある配列の順列になります。「配列はコードの先頭にある配列の順列である」というステートメントは、コードが正しいことを証明するために必要な、適切に選択されたループ不変条件であることに注意してください。
(パス 3) 最後に、実行がループの先頭から開始され、ループに入らずにコードの最後まで実行されるとどうなるかを考えてみましょう。この実行パスでは配列に対して何も行われないため、配列はコードの先頭にある配列の順列です。
これらの 3 つのパスは、実行がコードの先頭からコードの末尾まで進む可能性のあるすべての方法をカバーしているため、(1) コードの末尾の配列は先頭の配列の順列であることが証明されました。コードの。