ホーア論理(フロイド・ホーア論理またはホーア規則とも呼ばれる)は、コンピュータプログラムの正しさについて厳密に推論するための論理規則のセットを持つ形式体系である。これは、1969 年にイギリスのコンピュータ科学者であり論理学者でもあるトニー・ホーアによって提案され、その後ホーアや他の研究者によって改良された。[ 1 ]元々のアイデアは、フローチャート用の同様のシステムを発表したロバート・W・フロイドの研究に端を発している。[ 2 ]
ホア論理の中心となるのはホアトリプルです。トリプルは、コードの実行によって計算の状態がどのように変化するかを記述します。ホアトリプルは次の形式をとります。
どこそして主張とはコマンドです。[注1 ]は前提条件と呼ばれ、事後条件:事前条件が満たされると、コマンドを実行することで事後条件が確立されます。アサーションは述語論理における式です。
ホア論理は、単純な命令型プログラミング言語のすべての構成要素に対する公理と推論規則を提供する。ホアの原著論文における単純な言語の規則に加えて、その後、ホア自身や他の多くの研究者によって、他の言語構成要素に対する規則が開発されてきた。並行処理、手続き、ジャンプ、ポインタに関する規則などがある。
標準的なホーア論理を用いると、部分的な正しさしか証明できない。完全な正しさにはさらに停止条件が必要であり、これは個別に、またはWhileルールの拡張版を用いて証明できる。[ 3 ]したがって、ホーアトリプルの直感的な解釈は「Whenever」である。執行前に国家が保持する、 それからその後保持される、または終了しません。後者の場合、「後」は存在しないのでどのような文でも構いません。実際、選択することができます。偽りであることを表現する終了しません。
本稿および本記事の残りの部分における「終了」とは、計算が最終的に完了するというより広い意味で用いられており、無限ループが存在しないことを意味します。ただし、実装上の制限違反(例えば、ゼロ除算)によってプログラムが途中で停止しないことを意味するものではありません。ホアは1969年の論文で、実装上の制限違反がないことも含む、より狭い意味での終了を用い、より広い意味での終了の方が、アサーションが実装に依存しないという理由で好ましいと述べています。
上記の公理と規則のもう1つの欠点は、プログラムが正常に終了することの証明の根拠を与えていないことです。終了しない原因は無限ループかもしれませんし、実装定義の制限(例えば、数値オペランドの範囲、ストレージのサイズ、オペレーティングシステムの時間制限など)に違反している可能性もあります。したがって、「「」は「プログラムが正常に終了し、その結果の特性が記述される場合」と解釈されるべきである。非終了型プログラムの「結果」を予測するために公理を使用できないように公理を修正することは比較的容易ですが、公理の実際の使用は、コンピュータのサイズと速度、数値の範囲、オーバーフロー手法の選択など、多くの実装依存機能に関する知識に依存することになります。無限ループの回避の証明とは別に、プログラムの「条件付き」正しさを証明し、実装制限違反の結果としてプログラムの実行を中止せざるを得なかった場合に、実装が警告を発するようにする方がおそらく良いでしょう。
—ホア1969、578-579頁
空文ルールは、 skip文はプログラムの状態を変更しないと主張しており、したがってskip文の前に真であったことは、その後も真であり続ける。[注2 ]
代入公理は、代入後、代入の右辺に対して以前は真であった述語は、変数に対しても真となることを述べている。形式的には、変数x が自由変数であることを示す主張をPとする。すると、次のようになる。
どここれは、 xの各自由出現が式Eに置き換えられた主張Pを表します。
割り当て公理スキームは、これは、 Pの割り当て後の真理値と同等である。したがって、代入前に真であれば、代入公理により、代入後にはPが真となる。逆に、偽(つまり代入文の前に P が true であれば、その後はPは false でなければならない。
有効なトリプルの例としては、以下のようなものがあります。
式によって変更されないすべての前提条件は、事後条件に引き継ぐことができます。最初の例では、それは事実を変えない、したがって、両方のステートメントが事後条件に現れる可能性があります。形式的には、この結果は、 Pが (である公理図式を適用することによって得られます。そして) となり、いる (そして)は、与えられた前提条件に単純化できる。。
代入公理のスキームは、前提条件を見つけるには、まず事後条件を取り、代入式の左辺のすべての出現箇所を右辺に置き換えることと同等です。この誤った考え方に従って逆算しようとしないように注意してください。このルールは次のような意味不明な例につながる。
一見魅力的に見えるもう一つの誤ったルールは; それは次のような意味不明な例につながります。
与えられた事後条件P が事前条件を一意に決定する一方で、しかし、その逆は必ずしも真ではありません。例えば:
これらは、代入公理スキームの有効なインスタンスである。
Hoare が提案した代入公理は、複数の名前が同じ格納値を参照する可能性がある場合には適用されません。たとえば、
xとyが同じ変数を参照している場合(エイリアシング)、これは誤りですが、代入公理スキームの適切なインスタンスです(両方ともそしている)
ホアの合成規則は、逐次実行されるプログラムSとTに適用され、S はTより先に実行され、次のように記述されます。( Qは中間条件と呼ばれる): [ 4 ]
例えば、割り当て公理の次の2つの例を考えてみましょう。
そして
順序付け規則により、次の結論が得られる。
別の例を右側の枠内に示します。
条件ルールでは、then 部分とelse部分に共通する事後条件Q は、 if...endif文全体の事後条件でもあると規定されています。 [ 5 ] then部分とelse部分では、それぞれ否定されていない条件 B と否定された条件Bを事前条件Pに追加できます。条件Bは副作用があってはなりません。次のセクションで例を示します。
この規則はホアの原著には含まれていなかった。[ 1 ] しかし、声明以来
ワンタイムループ構造と同じ効果を持つ
条件付きルールは、他のホーアルールから導き出すことができる。同様に、forループ、do...untilループ、switch、break、continueなどの他の派生プログラム構造のルールも、プログラム変換によってホーアの原論文のルールに還元することができる。
このルールは前提条件を強化することを可能にするおよび/または事後条件を弱める例えば、 then部分とelse部分で文字通り同一の事後条件を実現するために使用されます。
例えば、
条件ルールを適用する必要があり、それは証明する必要がある
当時の部分については、
その他部分について。
しかし、 then部分の割り当てルールでは、P を次のように選択する必要があります。; ルールの適用により、
前提条件を強化するために結果ルールが必要である割り当てルールから取得条件付きルールに必要です。
同様に、else の部分では、代入ルールは次のようになります。
したがって、結果ルールを適用する必要があるそしているそしてそれぞれ、前提条件を再び強化する。非公式には、結果ルールの効果は、else部分で使用される代入規則はその情報を必要としないため、 else部分の開始時点では が既知です。
ここでPはループ不変量であり、ループ本体Sによって保持されるべきものです。ループが終了した後も、この不変量P は依然として有効であり、さらにループを終了させる原因となったに違いない。条件ルールと同様に、Bは副作用を持ってはならない。
例えば、
whileルールでは証明する必要がある
これは割り当てルールによって容易に得られる。最後に、事後条件簡略化できる。
別の例として、while ルールを使用すると、任意の数aの正確な平方根xを計算する次の奇妙なプログラムを形式的に検証できます。ただし、xは整数変数であり、aは平方数ではありません。
Pが真である状態でwhileルールを適用した後、証明すべきことは
これはスキップルールと結果ルールから導かれる。
実際、この奇妙なプログラムは部分的に正しい。もしプログラムが終了した場合、xには(偶然にも) aの平方根の値が含まれていたことは確実である。それ以外の場合は終了しないため、完全に正しいとは言えない。
上記の通常のwhile文を次の文に置き換えると、ホーア計算を用いて、完全な正しさ(つまり、終了性)と部分的な正しさの両方を証明することができます。一般的に、ここではプログラムの正しさに関する異なる概念を示すために、波括弧の代わりに角括弧が使用されます。
この規則では、ループ不変条件を維持することに加えて、ループ変種と呼ばれる式tによって終了性も証明します。この式 t の値は、各反復中に、あるドメイン集合D上の整礎関係<に関して厳密に減少します。 <は整礎であるため、Dの要素の厳密に減少する連鎖は有限の長さしか持ち得ません。したがって、t は永遠に減少し続けることはできません。(例えば、通常の順序<は正の整数に対して整礎です。)しかし、整数に対してはどちらも正の実数にも適用されない(これらの集合はすべて数学的な意味でのものであり、計算的な意味ではない。特に、これらはすべて無限集合である。)
ループ不変量Pが与えられた場合、条件B はtがDの最小要素ではないことを意味しなければならない。そうでなければ、本体S はt をこれ以上減らすことができないため、つまり規則の前提が偽となるからである。(これは完全な正しさを表すさまざまな表記法の 1 つである。) [注 3 ]
前節の最初の例に戻ると、完全な正当性の証明は次のようになる。
完全な正しさのためのwhileルールは、例えばDが通常の順序の非負整数であり、式tが すると今度は証明する必要がある
非公式に言えば、距離がはループサイクルごとに減少するが、常に非負の値を保つ。このプロセスは有限のサイクル数しか継続できない。
前述の証明目標は以下のように簡略化できます。
これは以下のように証明できる。
前のセクションの 2 番目の例では、当然ながら、空のループ本体によって減少する式tは見つからないため、終了性を証明することはできません。
ホーア論理の入門を含む教科書