「証明はプログラムです。それが証明する式はプログラムの型です」


37

これは哲学的な質問かもしれませんが、客観的な答えがあると思います。

Haskellに関するウィキペディアの記事を読むと、次のことがわかります。

この言語は、「証明はプログラムであり、それが証明する式はプログラムの型である」というHaskell Curryと彼の知的子孫の観察に根ざしています

今、私が尋ねているのは、これはほとんどすべてのプログラミング言語に本当に当てはまるのですか?Haskellのどの機能(または機能セット)がこのステートメントに準拠していますか?言い換えれば、この声明が言語の設計に影響した顕著な方法は何ですか?


4
「近い」投票の理由を説明したい人はいますか?

1
@Grigory Javadyan:終了することを投票しませんでしたが、それはおそらく、質問がSOの境界外のトピックであるためです。ただし、この場合、答えはHaskellが実際にどのように使用されているかについて実際的な意味合いが深いため、正当化できると思います。

2
@Grigory:この質問が実際のソリューション(コード内)の実際の問題である場合、SOのままにすることができます。閉じてプログラマーに移行することを投票しました。

9
私は少し疲れているので、それに加えてください-この質問に対する答えは、ハードCS研究への言及に満ちており、その意味でSOの90%よりも「客観的」です。さらに、sixlettervariableの基準(ソリューションにはコードが必要)は、主観的でもトピック外でもない、幅広い本物のプログラミングの質問に対してめちゃくちゃ狭いです。包含主義者/削除主義者の議論がSOに再び
現れるの

2
Programmers.SE対SO にどのようなコンテンツが含まているのかが本当に不明確であるため、これがどこで終わるかについて私はあいまいです。しかし、プログラマはいくつかの場所で「主観的な質問」のためであると説明されていると言いますが、この質問は強調されていません。私の答えは、それができるよう、私は可能性が非公式と手波状などについてですまだでも、ウィキペディアの編集者神経質参照と簡単にそれまでのバックほとんどは受け入れるだろう。
CAマッキャン

回答:


38

本質的な概念は何らかの方法で普遍的に適用されますが、そうではありませんが、有用な方法で適用されることはめったにありません。

そもそも、型理論の観点から、「動的」言語は、(とりわけ)プログラマーが見る価値の性質に関するメタデータ(これらの動的言語と呼ばれるものを含む)を含む単一の型を持つと見なされます。 「タイプ」自体(概念的には同じものではありません)。そのような証明は面白くない可能性が高いため、この概念は静的型システムを持つ言語にほとんど関連しています。

さらに、「静的型システム」と言われる多くの言語は、実行時に型の検査と変換を許可するため、このコンテキストでは実際には動的であると見なす必要があります。特に、これは、組み込み、デフォルトで「リフレクション」などをサポートする言語を意味します。たとえば、C#。

Haskellは、型が提供する情報の量に異常があります。特に、関数は引数として指定された値以外の値に依存できません。一方、可変グローバル変数を使用する言語では、どの関数でも(潜在的に)それらの値を検査し、それに応じて動作を変更できます。そう型のHaskellの関数は、A -> B小型プログラム証明とみなすことができるA含意B。他の多くの言語での同等の機能Aは、スコープ内にあるグローバルな状態が結合されていることを暗示するだけBです。

Haskellはリフレクションや動的型などをサポートしていますが、そのような機能の使用は関数の型シグネチャで示される必要があることに注意してください。同様に、グローバル状態の使用について。どちらもデフォルトでは使用できません。

ありますだけでなくHaskellで物事を破るための方法、例えば、実行時例外を許可、またはコンパイラが提供する非標準の基本操作を使用することによって、しかし、それらはそのウォン」、彼らは唯一の方法で完全に理解して使用されることを強く期待して来ますt外部コードの意味を損なう。理論的には他の言語でも同じことが言えますが、実際には他のほとんどの言語では、「チート」なしで物事を達成することはより困難であり、「チート」に眉をひそめません。そしてもちろん、真の「動的」言語では、すべてが無関係のままです。

この概念は、Haskellの場合よりもはるかに先に進むことができます。


ただし、例外は型システムに完全に統合できることに注意してください。
ガーデンヘッド

18

カリー・ハワード通信は非常に一般的なものであることは正しいです。http://en.wikipedia.org/wiki/Curry-Howard_correspondenceの歴史を少し理解しておく価値があります

もともと定式化されたように、この対応は、一方は特に直観主義的なロジックに適用され、もう一方は単純型付きラムダ計算(STLC)に適用されます。

クラシックHaskell-'98またはそれ以前のバージョンのいずれかで、STLCに非常に密接に関連しており、ほとんどの場合、Haskellの任意の表現とSTLCの対応する用語(再帰で拡張され、いくつかのプリミティブ型)。そのため、カリー・ハワードは非常に明確になりました。今日、拡張機能のおかげで、このような翻訳はややトリッキーなビジネスです。

ある意味で、質問はなぜHaskellがSTLCにそれほど単純に「脱糖」するのかということです。2つのことが思い浮かびます。

  • タイプ。また、(とりわけ)砂糖のようなラムダ計算であるSchemeとは異なり、Haskellは強く型付けされています。つまり、従来のHaskellには、定義上、STLCで適切に型付けできない用語は存在しません。
  • 純度。繰り返しになりますが、Schemeとは異なり、STLCのように、Haskellは純粋で、参照的に透過的な言語です。これは非常に重要です。副作用のある言語は、副作用のない言語に埋め込むことができます。ただし、これはプログラム全体の変換であり、単なるローカルの脱糖ではありません。したがって、直接対応するためには、純粋に機能的な言語から始める必要があります。

Haskellは、ほとんどの言語と同様に、Curry-Howard通信の直接適用に関して失敗する重要な方法もあります。Haskellは、チューリング完全な言語として、無制限の再帰の可能性、したがって終了しない可能性を含んでいます。STLCには不動点演算子がなく、チューリング完全ではなく、強く正規化されています。つまり、STLCの用語の削減は終了に失敗しません。再帰の可能性は、Curry-Howardを「cす」ことができることを意味します。たとえばlet x = x in x、タイプはforall a. a-つまり、戻ることはないので、何かを与えるふりをすることができます!これはHaskellでいつでもできるため、プログラム自体が終了しているという別の証拠がない限り、Haskellプログラムに対応する証拠を完全に「信じること」ができないことを意味します。

Haskell(特にMLファミリー)より前の関数型プログラミングの系統は、(とりわけ)物事を簡単に証明できる言語の構築に焦点を当てたCSの研究の結果であり、最初からCHに非常に気づいており、それに由来する研究です。逆に、Haskellは、ホスト言語と、CHの系統に非常に関連する型理論の開発に根ざしたAgdaやEpigramなど、開発中の多数の証明アシスタントのインスピレーションの両方として機能しました。


1
論理的な観点からは明らかに壊滅的であるが、他の多くの特性を保持する特定の方法で、非終了が証明を損なうことを強調するのは良いかもしれません。特に、をA -> B与えられた関数はA、を生成するBか、まったく生成しません。を生成することはありません。またC、どのタイプの値がB提供するか、または分岐する場合は、引き続きA提供された値のみに依存します。

@camccann-ちょっときついですが、下と「何もない」を区別しVoidます。怠azineは両方ともそれをますます複雑にしません。関数はA -> B 常に typeの値を生成しますBが、その値は期待するよりも少ない情報を持っているかもしれません。
sclv

Nitpickingは楽しいです!「何もない」と言うときは、評価を実行するという意味での価値レベルを意味しますが、ボトムは実際には抽象化としてのみ存在し、具体的なものではありません。評価される式は、bottomの値を決して「見る」ことはなく、使用しない用語(bottomの場合もあります)および使用する用語(bottom以外の値を持つ)だけを表示します。ボトムを使用しようとすると、使用が発生する前に式全体の評価が終了するため、何らかの意味で「発生しない」ことを試みます。

12

一次近似では、他のほとんどの(弱いおよび/またはユニタイプの)言語は、言語レベルの厳密な記述をサポートしていません

  • 命題(すなわち型)
  • 証明(私たちは、プリミティブおよび/またはその他のセットから命題を構築することができる方法を実証すなわちプログラム高い順構造)

および2つの厳密な関係。どちらかといえば、他のそのような言語が提供する最高の保証は

  • 入力に制限された制約が与えられ、その時点で環境内にあるものが何であれ、制限された制約を持つ値を生成できます。(従来の静的型、cf C / Java)
  • すべての構成体は同じタイプです(動的タイプ、cf ruby​​ / python)

タイプによって、私たちは命題を参照して、したがって、単にintまたはboolよりはるかに多くの情報について説明するものに注意してください。Haskellには、引数の影響のみを受ける関数の浸透文化があります - 例外はありません *。

少し厳密にするために、一般的な考え方は、(ほぼ)すべてのプログラム構成体に厳格な直観主義的アプローチを適用することによって(つまり、構成可能なものだけを証明できる)、そのようなプリミティブ構成体のセットを制限することです私たちが持っている方法

  • すべての言語プリミティブの厳密な命題
  • プリミティブを組み合わせることができる限定された一連のメカニズム

Haskellの構造は、その動作についての推論に非常に役立つ傾向があります。をA意味する証明(関数の読み取り)を構築できる場合B、これには非常に有用なプロパティがあります。

  • 常に成り立ってます(がある限りA、を構築できますB
  • この含意はにのみ依存しA、他にはも依存しません。

したがって、ローカル/グローバル不変式について効果的に推論できます。元の質問に戻るには; この考え方を最も促進するHaskellの言語機能は次のとおりです。

  • 明示的なコンストラクトへの効果の純度/セグメンテーション(効果は両方とも考慮され、入力されます!)
  • Haskellコンパイラでの型推論/チェック
  • 制御および/またはデータフローの不変式を、プログラムが証明しようとしている命題/型に埋め込む機能:(多態性、型族、GADTなどを使用)
  • 参照整合性

Haskellに固有のものはまったくありません(これらのアイデアの多くは信じられないほど古いものです)。ただし、標準ライブラリの豊富な抽象化セット(通常は型クラスにあります)、さまざまな構文レベルのシュガー化、およびプログラム設計の純度への厳格なコミットメントと組み合わせると、なんとかして両方ともなる言語になります実際のアプリケーションには十分実用的ですが、同時にほとんどの従来の言語について推論するのは簡単です。

この質問は十分に深い答えに値し、この文脈で正義をすることはできませんでした。ウィキペディア/文献でもっと読むことをお勧めします:

* NB:Haskellの不純物の例外的な部分(例外、非終端など)の一部を、引数を複雑化するだけで無視/無視しています。


4

どんな機能?型システム(静的、純粋、多態性)。良い出発点は、Wadlerの「無料の定理」です。言語の設計に顕著な効果はありますか?IOタイプ、タイプクラス。


0

クリーネ階層は証拠がプログラムされないことを私たちに示しています。

最初の再帰関係は次のいずれかです。

R1( Program , Iteration )  Program halts at Iteration.
R2( Theorem , Proof ) Proof proves a Theorem.

最初の再帰的に列挙可能な関係は次のとおりです。

(exists x) R1( Program , x )  Program Halts.
(exists x) R2( Theorem , x)   Theorem is provable.

したがって、プログラムは定理であり、プログラムが停止する反復は、定理を証明する存在する証明のようなものです。

Program = Theorem
Iteration = Proof

プログラムが仕様から正しく生成されると、仕様を満たしていることを証明できなければなりません。プログラムが仕様を満たしていることを証明できれば、それは正しいプログラム合成です。そのため、プログラムが仕様を満たしていることを証明する場合にのみ、プログラム合成を実行します。プログラムが仕様を満たすという定理は、定理が合成されるプログラムを指すという点でのプログラムです。

マーティン・ロフの誤った結論がコンピュータープログラムを生み出したことは一度もなく、人々がそれをプログラム合成方法論と信じているのは驚くべきことです。合成されるプログラムの完全な例はこれまでにありません。「タイプを入力し、そのタイプのプログラムを出力する」などの仕様は関数ではありません。このようなプログラムは複数あり、ランダムに1つを選択することは、再帰的な関数でも関数でもありません。これは、再帰関数を計算する実際のコンピュータープログラムを表さない愚かなプログラムによるプログラム合成を示す愚かな試みです。


2
どのように、質問が求めていたこの答えは「この文は、言語の設計に影響を与えている顕著な方法は何ですか?」ん
ブヨ

1
@gnat-この回答は、元の質問の根底にある仮定に対処します。 " doesn't this really apply to pretty much all the programming languages?"この回答は、その仮定が無効であると主張/示しているため、欠陥のある前提に基づく残りの質問に対処することは意味がありません。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.