終了を部分的な正確さに減らすのはどれくらい難しいですか?


14

プログラムの検証に精通している場合は、背景の前に質問を読むことをお勧めします。プログラムの検証に慣れていない場合でも、この質問に答えることはできますが、背景を最初に読むことをお勧めします。

バックグラウンド

部分的な正確性の確認は決定できないとしばしば言われます。議論のために、フロイドのスタイルでこの声明を正確にする1つの非常に特定の方法を選んでみましょう-ホア。フローグラフは区別付き有向グラフである初期のノードのすべてのノードが到達可能であるから。プログラムは、そのノードでコマンドです流れ図です。コマンドには3つのタイプがあります(1)前提条件 q、(2)アサーション qをアサート、(3)割り当てはv:= eです。ここで、qはfol(1次論理)式、eはfol項、vは変数です。

我々は、プログラムがあると言う部分正しい各ノード注釈を付ける方法がある場合、XとA前提条件A(X)と事後条件のB(x)のように、(1)は、最初のノードの前提条件が有効である、(2){ a(x) } x { b(x) }はすべてのコマンドxに適用され、(3)(b(x)はa(y)を意味ます)はxからyまでのすべてのエッジに有効です。ここで、Hoareトリプルは次のように定義されます。

  • { p } assert q { r }は、(pが(q and r)を意味する)が有効であることを意味します
  • { p } は、 q { r }が((pおよびq)がrを暗示する)が有効であることを意味すると仮定する
  • { P } V:= E { R((つまり}手段PEの代わりにVが)を意味し、Rは)有効です

この部分的な正しさを確認することが決定できない理由について、手で波打った議論があります:a(x)b(x)を入力したら、いくつかのfol式が有効であるかどうかを確認する必要があります。

部分的に正確に終了をエンコードする一般的な方法は、「前回実行されてから終了に向かって進行した」と本質的に言う特別なアサーションを追加することです。これらの進行アサーションは、フローグラフ上のすべての無限ウォーク(初期ノードから開始)に無限に多くの進行アサーションが含まれるように配置する必要があります。具体的には、進行アサーションの形式 常にassert u < vで、ここでuvは正の整数であり、割り当てu:= fが先行し、その後に割り当てv:= uが続くとしましょう。ここでfバリアント関数uは現在の値、vは以前の値です。ここで、「正の整数」について説明し、それらを比較するため、folよりも少し多く使用できることを確認する必要があります。Peano算術が使用可能であるとしましょう。(この選択については強く感じません。都合が良ければ無視してください。)もちろん、fはプログラムで言及されている他の関数や定数を使用するかもしれません。(プログラムの最初に仮定を追加することは、非論理公理を導入することと同等であることに注意してください。)

これで、進行状況のアサーションがあるプログラムがまだ部分的に正しい場合、元のプログラムが終了することがわかります。

質問

終了プログラムを考えると、進行状況の表明のためのバリアント関数を思いつくのは難しいと感じています。しかし、どのくらい難しいですか?(上記の大きな背景があっても、見方によっては、この質問を未解決または未定義のままにしておくことを知っています。)

別の言い方をすれば、終了を部分的な正確さまで減らす問題を形式化し、その複雑さについて何かを述べているリファレンスを探しています。もちろん、これをすべて行う回答は歓迎されます。


これを理解しているかどうか確認してみましょう。あなたが求めているものは、とりわけ、完全な再帰関数を計算し、関数が全体であることのステートメントの証明を出力するプログラムを取得するアルゴリズムを提供します(バリアント関数の形で、それらが適切であることの証明)?それは私にはひどく計算できないように思えます。
アンドレイバウアー

Andrej、それは私にも計算できないように聞こえます。私が求めているのは、それが計算不可能であることの証明です。
ラドゥグリゴール

回答:


7

これに答える1つの方法は、決定可能であることが知られている部分的正確性および終了クエリのクラスの決定問題の計算の複雑さを考慮することです。多面体ドメインを使用した抽象解釈は、必要な注釈が線形不等式の結合である場合に言及する部分的正確性注釈を推測できます。抽象事後条件の計算は、変数の数において指数関数的です。その後、不動点を見つけるオーバーヘッドがあります。この詳細については、Cousotの初期の論文と、直接試してみたい場合はエプロンライブラリを参照してください。

バリアント関数が線形である場合、バリアント関数の検索は決定可能です。これの複雑さの完全な特徴を見つけることはできませんでしたが、Tiwariによる「線形プログラムの終了」には、複雑さについて説明するセクションがあります。PodelskiとRybalchenkoによる「線形ランキング関数の合成のための完全な方法」も参照してください。また、Byron Cookは、終了引数の構築を支援するために抽象解釈を活用する作業を行っています。たとえば、「ランク付け抽象化」および「不変性分析からの分散分析」を参照してください。これらは、部分的な正確さと終了との関係についてのさらなる洞察を与えるかもしれません。

リンク:


1
回答を編集してリンクをアクティブにすることを気にしないでください。
アンドレイバウアー

4

必要な非終了から部分的な正確性への明らかな削減、すなわち:

Pは、初期状態で起動したときに満たす終了したことがないφ IFF { φ } P {偽}が有効です。

これは別の非回答であることを認識しています。その利点は、上記のものよりも短いことです。


3

グラフに事前条件と事後条件、つまり最も弱いリベラルな事前条件セマンティクスを設定するための標準テクノロジがあります。これは、仕様を満たすか、満たさないかのどちらかで最も弱い事前条件を与える述語変換セマンティクスの形式です-終了。これは本質的に、そのような言語の部分的な正確さの完全な理論であり、実際、完全な正確さです。

終了と部分的な正確さのどちらがハードワークがどこにあるかを決定するチョークとチーズです。しかし、プログラム言語と仕様言語の両方について、言語設計の問題に部分的な正確さが絡み合っていますが、終了の難易度は明確です:終了を証明するために使用される理論には、終了するアルゴリズムがありますが、相対的な終了は証明されていませんその理論に。たとえば、純粋な多相ラムダ計算の計算は終了する必要がありますが、ペアノ算術はこれを証明できません。

私の印象では、Patrick Cousotによって開拓された抽象解釈の研究は、この分野で最もダイナミックでしたが、専門家であるふりはしていません。


バリアント関数を推測することの複雑さについて質問しようとしていました。はっきりしないでごめんなさい!好奇心として、Rustan Leinoは昨晩(パブで)サンプルを思いつきました。仕事に適した場所に着いたら、もう一度確認する必要があります:)
ラドゥグリゴール

@Radu:自動終了証明に関する作業が行われましたが、Prologについてはいくつかの素晴らしい作業が行われています。時間を見つけたら、参考文献を掘り下げることができます。
チャールズスチュワート
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.