タイプチェッカーの正当性の証明は実際に何を証明すべきですか?


11

私は数年プログラミングをしてきましたが、理論上のCSにはあまり慣れていません。私は最近プログラミング言語を研究しようと試みており、その一環として、型チェックと推論を行っています。

私の質問は、プログラミング言語の型推論およびチェックプログラムを作成しようとして、タイプチェッカーが機能することを証明したい場合、私が探している証拠は何ですか?

平易な言葉で言えば、実行時に発生する可能性のあるコードの一部のエラーをタイプチェッカーで識別できるようにしたいと思います。Coqのようなものを使用して私の実装が正しいことを証明しようとした場合、この「正確性の証明」は何を表示しようとするのでしょうか。


おそらく、(1)実装が特定のタイピングシステム実装しているかどうか、または(2)タイピングシステムが、必要と思われるエラーを防止しているかどうかを明確にしたい場合は、彼らは異なる質問です。TTT
Martin Berger

1
@MartinBerger:ああ、私はその違いをスキップしたようです。私の実際の質問はおそらく両方を尋ねることを意味しました。コンテキストは、私が言語を構築しようとしているということであり、それのためにタイプチェッカーを書いていました。そして、人々は私に実証済みのアルゴリズムを使うように頼みました。使用していたアルゴリズムとタイプチェッカーが「正しい」ことを「証明」するのがどれほど難しいかを知りたいと思っていました。したがって、私の質問のあいまいさ。
Vivek Ghaisas 2017年

2
(1)は実際にはプログラム検証における問題であり、タイピングとはほとんど関係ありません。実装がその仕様を満たしていることを示す必要があるだけです。(2)については、最初に即時型エラーとはどういう意味かを定義します(たとえば2 + "hello"、「スタック」しているような用語)。これが形式化されたら、型の健全性の定理を証明できます。つまり、タイプ可能なプログラムが即時型エラーに発展することはありません。正式には、あなたがプログラムならばということを証明型付け可能であり、任意のためのn 以下の場合Mは走るのnになるためのステップN、その後、Nは、即時型エラーを持っていません。(1/2)MnMnNN
Martin Berger

1
これは、通常、帰納法と型判定の導出によって証明されます。(2/2)n
Martin Berger

ありがとうございました!あなたの説明に基づいて、(2)は確かに私が探していたもののようです。答えていただけませんか?(そして、多分あなたが役に立つかもしれないと思う詳細を追加してください。)私はそれを答えとして受け入れます!:)
Vivek Ghaisas 2017年

回答:


10

質問は2つの方法で解釈できます。

  • 実装が特定のタイピングシステム実装しているかどうかT
  • タイピングシステムが、あなたが考えるべきエラーを防ぐかどうか?T

前者は実際にはプログラム検証における問題であり、タイピングとはほとんど関係がありません。実装がその仕様を満たしていることを示す必要があるだけです。Andrejの回答を参照してください。

後の質問についてお話ししましょう。Andrejが言ったように、抽象的な観点から、タイピングシステムはプログラムにプロパティを強制するようです。実際には、タイピングシステムは、エラーの発生を防止しようとします。つまり、タイピング可能なプログラムは、対象となる種類のエラーを示すべきではありません。Tがあなたの考えていることをしていることを示すために、2つのことを行う必要があります。TT

  • まず、プログラムで即時入力エラーが発生することの意味を正式に定義し ます。これを定義する方法はたくさんあります-それはあなた次第です。通常、のようなプログラムを防止します 2 + "hello"。言い換えると、プログラムのサブセットを定義する必要があります。それらをBadと呼び ます。これには、タイプミスがすぐに発生するプログラムが正確に含まれています。

  • 次に、タイプ可能なプログラムがBadのプログラムに進化することは決してないことを証明する必要があります。これを形式化しましょう。あなたのタイピングの判断があるとする リコールとそれが読まれるべきであること:プログラム Mは型があるαを、環境によって与えられるように型付けされている自由変数と仮定すると、Γを。次に、証明したい定理は次のとおりです。ΓM:α.MαΓ

    定理。たびM Nその後、N 悪いですΓM:αMNN

    この定理を証明する方法は、言語の詳細、タイピングシステム、Badの選択によって異なります。

Badを定義する標準的な方法の1つは、が値でも縮小ステップM Nでもない場合、項Mには即時型エラーがあります。(この場合、Mはしばしばstuckと呼ばれます。)これは、小さなステップの操作セマンティクスでのみ機能します。定理を証明する1つの標準的な方法は、MMNM

  • M Nは一緒に暗示 Γ N αを。これを「被験者削減」と呼びます。これは通常、タイピング判断の導出と短縮の長さの同時帰納によって証明されます。ΓMαMNΓNα

  • たび その後、Mはではありません悪いです。これは通常、タイピング判断の導出に関する帰納法によっても証明されます。ΓMαM

セッションタイプなど、すべてのタイピングシステムに「サブジェクトリダクション」があるわけではないことに注意してください。この場合、より高度な証明技術が必要です。


20

それは良い質問です!型付き言語の型に何を期待するかを尋ねます。

最初に、unitypeを使用して任意のプログラミング言語を入力できることに注意してください。たとえばU、文字を1つ選択して、すべてのプログラムにタイプがあると言いUます。これはそれほど有用ではありませんが、ポイントになります。

タイプを理解するには多くの方法がありますが、プログラマーの観点からは、次のことが有用だと思います。タイプは仕様または保証と考えてください。言っても型があるAは、「我々が保証/期待/需要ということであるeがでエンコードされたプロパティを満たすAを」。多くの場合、Aはのような単純なものです。この場合、プロパティは単に「整数です」です。eeint

タイプの表現力に終わりはありません。原則として、それらは任意の種類の論理ステートメント、カテゴリ理論などを使用できます。たとえば、依存型を使用すると、「この関数はリストをリストにマッピングして、出力がソートされた入力になるように」できます。さらに先に進むことができます。私が「並行分離ロジック」の話を聞いているときは、並行プログラムが共有状態でどのように機能するかについて話すことができます。ファンシーなもの。

プログラミング言語設計における型の芸術は、表現力とシンプルさバランスをとることの 1つです。

  • より表現力豊かなタイプにより、何が起こっているのかを(自分自身とコンパイラーに)より詳細に説明できます
  • 単純な型は理解しやすく、コンパイラでより簡単に自動化できます。(人々はタイプチェックを行うために証明アシスタントとユーザーの入力を本質的に必要とするタイプを考え出します。)

すべてのプログラマーがプログラミング言語の理論で博士号を取得しているわけではないため、単純さを過小評価してはなりません。

それでは、あなたの質問に戻りましょう:あなたの型システムが良いことをどうやって知るのですか?さて、あなたのタイプのバランスが取れていることを示す定理を証明してください。定理には次の2種類があります。

  1. あなたのタイプが有用であると言う定理。プログラムにタイプがあることを知っていることは、たとえばプログラムが動かなくなることがないという保証を意味するはずです(これは安全定理です)。別の定理ファミリーは、タイプをセマンティックモデルに接続し、実際の数学を使用してプログラムについての事柄を証明できるようにします(これらは、妥当性定理などになります)。上記のユニタイプは、そのような有用な定理を持たないため、不適切です。

  2. あなたのタイプは単純であると言う定理。基本的なものは、与えられた式が与えられた型を持っているかどうかを決定できるということです。別の単純化機能は、型を推論するためのアルゴリズムを提供することです。単純化に関する他の定理は、式には最大で1つの型が含まれる、または式には主要な型(つまり、式が持つすべての型の中で「最良の」型)があるということです。

タイプは非常に一般的なメカニズムであるため、より具体的にすることは困難です。しかし、私はあなたが何を撮るべきかを見てほしいと思います。プログラミング言語設計のほとんどの側面と同様に、成功の絶対的な尺度はありません。代わりに、デザインの可能性のスペースがあり、重要なことは、スペースのどこにいるか、またはなりたい場所を理解することです。


詳しい回答ありがとうございます!しかし、私の質問への答えはまだわかりません。具体的な例として、C-十分に単純な型システムを備えた静的型付き言語を取り上げましょう。Cのタイプチェッカーを作成した場合、タイプチェッカーが「正しい」ことをどのように証明しますか?HMと言ってHaskellのタイプチェッカーを作成した場合、この答えはどのように変わりますか?「正しさ」をどのように証明しますか?
Vivek Ghaisas 2017年

1
TeTe

2.と3.を組み合わせて実行することをお勧めします。また、CompCertもご覧ください
Andrej Bauer 2017年

1
TeAeAe

e

5

「私のタイプチェッカーが機能することを証明する」とは、いくつかの異なる意味があります。これは、あなたの質問が尋ねていることの一部だと思います;)

この質問の半分は、型理論が言語に関するあらゆる特性を証明するのに十分良いことを証明しています。Andrejの答えは、この領域に非常によく取り組んでいます。質問の残りの半分は、「言語とその型システムが既に固定されている場合」、特定の型チェッカーが実際に型システムを正しく実装していることをどのように証明できるでしょうか。ここで私が見ることができる主な視点は2つあります。

1つは、特定の実装がその仕様に一致することをどのように信頼できるでしょうか。必要な保証の程度に応じて、大規模なテストスイートに満足する場合もあれば、何らかの正式な検証が必要な場合もあれば、両方の組み合わせが必要になる場合もあります。この見方の利点は、それがあなたがしている主張に境界を設定することの重要性を本当に強調しているということです:「正確に」は正確にはどういう意味ですか?チェックされるコードの部分と、想定される正しいTCBはどの部分ですか?不利な点とは、これについて考えすぎると、哲学的なうさぎの穴が1つ下がるということです。うさぎの穴を楽しんでいない場合は、「不都合」です。

2番目の視点は、正確さに関するより数学的な見方です。数学で言語を扱うとき、私たちはしばしば「理論」の「モデル」を設定し(またはその逆)、次に(a)モデルで実行できる理論で実行できるすべてのこと、および(b)理論で実行できるモデルで実行できるすべてのこと。(これらは健全性完全性です定理。どちらがどちらであるかは、構文理論から開始したのか、セマンティックモデルから開始したのかに依存します。)この考え方により、型チェックの実装は問題の型理論の特定のモデルであると考えることができます。したがって、実装で実行できることと、理論上は実行できるはずだと述べていることの間の双方向の対応を証明する必要があります。この視点の利点は、すべてのコーナーケースをカバーしたかどうか、型セーフとして受け入れる必要のあるプログラムを除外しないという意味で実装が完全であるかどうか、実装が健全であるかどうかに焦点を当てていることですタイプミスとして拒否する必要のあるプログラムを許可しないという感覚。欠点は、対応の証拠が実装自体からかなり離れている可能性が高いことです。


特に、モデルが健全であるが完全ではない場合、「この視点の一番上は、すべてのコーナーケースをカバーしたかどうかに重点を置いている」ことに同意できるかどうかはわかりません。私は別の見方を提案します。モデルを通過することは、モデルがより単純であるなど、さまざまな理由で使用する条件付き証明手法です。モデルを通過することについて、哲学的により厳格なものは何もありません。最終的には、実際の実行可能ファイルとその動作について知りたいと思っています。
Martin Berger 2017年

「モデル」と「理論」は広義の意味であると思い、レンは「健全性+完全性定理」を介して双方向の対応を確立することの重要性を強調していた。(これも重要だと思い、Andrejの投稿にコメントしました。)状況によっては、健全性の定理(または、見方によっては完全性の定理)しか証明できない場合もありますが、両方の方向性があります心に留めておくと便利な方法論的制約になります。
Noam Zeilberger 2017年

1
@NoamZeilberger「質問です」とマーティンは言いました。「言葉を非常に多くの異なる意味にできるかどうか」
Martin Berger

タイピングシステムとプログラミング言語のセマンティクスについて学んだとき、モデルは操作のセマンティクスについての証明技術に過ぎず、崇高に解放されていることに気づきました。
Martin Berger

1
健全性と完全性を介してさまざまなモデルを関連付けることは、洞察を伝達するための重要な科学的方法論です。
Martin Berger
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.