回答:
インバリアントは、変数よりも「概念的」です。一般に、それは常に真であるプログラム状態のプロパティです。不変式が保持されることを保証する関数またはメソッドは、不変式を維持すると言われています。
たとえば、二分探索木には、すべてのノードについて、ノードの左の子のキーがノード自体のキーよりも小さいという不変式がある場合があります。このツリーに対して正しく記述された挿入関数は、その不変を維持します。
あなたが言うことができるように、それはあなたが変数に格納できるものの一種ではありません:それはより多くの文の程度プログラム。プログラムがどのような不変条件を維持する必要があるかを把握し、コードを見直して、それらの不変条件が実際に維持されていることを確認することにより、コードの論理エラーを回避できます。
ウィキペディアの魔法:不変(コンピューターサイエンス)
コンピュータサイエンスでは、trueの場合、特定の操作シーケンス全体を通してtrueのままであるという述語は、そのシーケンスに対して(不変)と呼ばれます。
この行が述べるように:
コンピュータサイエンスでは、trueの場合、特定の操作シーケンス全体を通してtrueのままであるという述語は、そのシーケンスに対して(不変)と呼ばれます。
これをよりよく理解するには、C ++のこの例が役立ちます。
いくつかの値を取得し、as count
と呼ばれる変数にそれらの合計数を取得し、それらをas と呼ばれる変数に追加する必要があるシナリオを考えますsum
// invariant:
// we have read count grades so far, and
// sum is the sum of the first count grades
上記のコードは次のようになります、
int count=0;
double sum=0,x=0;
while (cin >> x) {
++count;
sum+=x;
}
上記のコードは何をしますか?
1)から入力を読み取り、cin
それらを入れますx
2)読み取りに成功した後、インクリメントcount
してsum = sum + x
3)読み取りが停止するまで1-2を繰り返します(例:ctrl + D)
不変条件は常に Trueでなければなりません。したがって、最初はこれだけでコードを開始します
while(cin>>x){
}
このループは、標準入力からデータを読み取り、xに格納します。まあ、良い。しかし、不変は、私たちの最初の部分ので偽となり不変が続く(または真の保持)されませんでした。
// we have read count grades so far, and
シンプル!増分カウント。
だから++count;
良いでしょう!コードは次のようになります。
while(cin>>x){
++count;
}
今でも、不変条件(TRUEでなければならない概念)はFalse です。これは、不変条件の2番目の部分を満たさなかったためです。
// sum is the sum of the first count grades
それで、今何をすべきか?
()に追加x
しsum
て保存すると、次回
は新しい値がxに読み込まれます。sum
sum+=x
cin>>x
コードは次のようになります。
while(cin>>x){
++count;
sum+=x;
}
// invariant:
// we have read count grades so far, and
// sum is the sum of the first count grades
コード:
while(cin>>x){
++count;
sum+=x;
}
ああ!これで、ループ不変条件は常に Trueになり、コードは正常に機能します。
上記の例は、Andrew-koeningとBarbara-Eによる書籍Accelerated C ++ から取得および変更されました。
ADTインバリアントは、データフィールド(インスタンス変数)間の関係を指定します。これは、インスタンスメソッドの実行の前後に常にtrueでなければなりません。
不変条件の優れた例と、それが重要な理由は、Java Concurrency in Practiceの本にあります。
Java中心ですが、この例では、提供された整数の係数の計算を担当するいくつかのコードについて説明しています。サンプルコードは、提供された最後の数値と、パフォーマンスを改善するために計算された要因をキャッシュしようとします。このシナリオでは、コード例で考慮されなかった不変条件があり、コードが並行シナリオで競合状態の影響を受けやすくなっています。
ここでのすべての答えは素晴らしいですが、私はその問題にもっと光を当てることができると感じました:
言語の観点から不変とは、決して変わらないものを意味します。概念は実際には数学から来ていますが、誘導と組み合わせると、これは人気のある証明手法の1つです。
ここに証明があります。初期状態にある不変式を見つけることができ、この不変式が状態に適用された[法的]変換に関係なく持続する場合、特定の状態にこれがない場合に証明できます。したがって、初期状態に適用される変換のシーケンスに関係なく、不変になることはありません。
これで、以前の考え方(これも帰納法と組み合わせる)により、コンピューターソフトウェアのロジックを述語することが可能になります。実行がループで実行される場合に特に重要です。ループでは、不変条件を使用して、特定のループが特定の結果をもたらすか、またはプログラムの状態を特定の方法で変更しないことを証明できます。
ループロジックを述語するために不変が使用される場合、その呼び出されたループ不変です。ループの外側で使用できますが、多くの可能性や無限の可能性があるため、ループの場合は非常に重要です。
コンピューターソフトウェアのロジックである「述語」という言葉を使用していること、および証明していないことに注意してください。数学では不変量を証明として使用できますが、ソフトウェアを実行すると多くの抽象化の上で実行されるため、コンピュータソフトウェアを実行しても期待どおりの結果が得られるとは証明できないため、証明できません。期待される結果が得られることを確認します(たとえば、ハードウェアの抽象化を考えてください)。
最後に、ソフトウェアロジックを理論的かつ厳密に予測することは、医療や軍事などの重要度の高いアプリケーションでのみ重要です。インバリアントは、デバッグ時に一般的なプログラマを支援するために引き続き使用できます。これは、特定の場所のどこにあるかを知るために使用できます。プログラムは、特定の不変条件を維持できなかったために失敗しました。