Iswear以前は不滅の言葉が書かれたTシャツが販売されていました。
何の部分
notわかりますか?
私の場合は、答えは…すべてです。
特に、Haskellの論文ではこのような表記法がよく見られますが、それが何を意味するのかはわかりません。私はそれがどのような数学の分野であるべきか分からない。
私はもちろんギリシャ文字のアルファベットと "∉"のような記号を認識しています(これは通常何かが集合の要素ではないことを意味します)。
その一方で、私は前に "⊢"を見たことがない( ウィキペディアはそれが "パーティション"を意味するかもしれないと主張している )。私はまた、このビンクラムの使い方に慣れていません。 (通常は分数を表しますが、が現れるはここでは当てはまりません。)
誰かが少なくともこのシンボルの海が何を意味するのか理解するために探し始めるところを私に言うことができればそれは役に立ちます。
:
はタイプありを意味します∈
は、is inを意味します。 (同様に∉
は「中にない」ことを意味します。)Γ
は通常、環境またはコンテキストを参照するために使用されます。この場合、識別子をそのタイプとペアにするタイプ注釈のセットと考えることができます。したがって、x : σ ∈ Γ
は、環境Γ
がx
のタイプがσ
であるという事実を含むことを意味します。⊢
は、provesとして読み取るか、決定します。 Γ ⊢ x : σ
は、環境Γ
がx
のタイプがσ
であることを決定することを意味します。,
は含む環境への特定の追加仮定Γ
の方法です。Γ, x : τ ⊢ e : τ'
は、環境Γ
、、x
のタイプがτ
、e
のタイプがτ'
であることを証明します。要求どおり:演算子の優先順位、最高から最低まで:
λ x . e
、∀ α . σ
、およびτ → τ'
、let x = e0 in e1
、および関数適用用の空白など、言語固有の中置演算子とmixfix演算子。:
∈
および∉
,
(左結合)⊢
この構文は、複雑に見えるかもしれませんが、実際には非常に単純です。基本的な考え方は形式的な論理に基づいています。表現全体は、上半分が仮定であり、下半分が結果であるという意味合いです。つまり、上の式が真であることを知っている場合、下の式も真であると結論付けることができます。
留意すべきもう1つのことは、一部の文字には伝統的な意味があるということです。特に、Γはあなたがいる「コンテキスト」、つまり、あなたが見た他の物のタイプを表します。したがって、Γ ⊢ ...
のようなものは、...
内のすべての式のタイプを知っている場合、「式Γ
」を意味します。
⊢
シンボルは、本質的に何かを証明できることを意味します。したがって、Γ ⊢ ...
は、「コンテキストで...
を証明できますΓ
。これらのステートメントは型判定とも呼ばれます。
留意すべきもう1つの点は、数学では、MLやScalaと同様に、x : σ
はx
の型がσ
であることを意味します。 Haskellのx :: σ
と同じように読むことができます。
したがって、これを知っていると、最初の式が理解しやすくなります。x : σ ∈ Γ
(つまり、x
が何らかのコンテキストσ
を持っていることがわかっている場合、Γ
)、Γ ⊢ x : σ
(つまり、Γ
では、x
の型はσ
です)。だから本当に、これはあなたに何か面白いことを言っているわけではありません。コンテキストの使用方法を示しているだけです。
他のルールも簡単です。たとえば、[App]
を使用します。このルールには2つの条件があります。e₀
は、あるタイプτ
からあるタイプτ'
への関数であり、e₁
はタイプτ
の値です。これで、e₀
をe₁
に適用することで、取得するタイプがわかります。うまくいけば、これは驚きではありません:)。
次のルールには、さらに新しい構文があります。特に、Γ, x : τ
は、Γ
と判断x : τ
で構成されるコンテキストを意味します。したがって、変数x
の型がτ
であり、式e
の型がτ'
であることがわかっている場合、x
を取り、e
を返す関数の型もわかります。これは、関数がどの型を取り、どの型が返すかを把握した場合の対処方法を示しているだけなので、どちらも驚くべきことではありません。
次は、let
ステートメントの処理方法を示しています。 x
の型がe₁
である限り、いくつかの式τ
の型がσ
であることがわかっている場合、let
をσ
の値にローカルにバインドするx
式e₁
の型はτ
になります。実際、これは、letステートメントを使用すると、基本的に新しいバインディングでコンテキストを拡張できることを示しています。これはまさにlet
が行うことです!
[Inst]
ルールはサブタイピングを扱います。タイプσ'
の値があり、それがσ
のサブタイプである場合(⊑
は半順序関係を表します)、その式はタイプσ
。
最後のルールは、型の一般化を扱います。余談ですが、自由変数とは、式の中のlet文やラムダによって導入されない変数です。この式は、そのコンテキストからの自由変数の値に依存するようになりました。ルールは、コンテキスト内の何かにnot "free"である変数α
がある場合、 e : σ
を知っている型の式は、any value of α
に対してその型を持つと言っても安全です。
さて、あなたはシンボルを理解したので、これらのルールで何をしますか?さて、これらのルールを使用して、さまざまな値のタイプを把握できます。これを行うには、式(たとえばf x y
)を見て、ステートメントに一致する結論(下部)を持つルールを見つけます。あなたの「目標」を見つけようとしているものを呼びましょう。この場合、e₀ e₁
で終わるルールを確認します。これを見つけたら、このルールの境界より上のすべてを証明するルールを見つける必要があります。これらは一般にサブ式のタイプに対応しているため、本質的に式の一部を再帰しています。プルーフツリーが完成するまでこれを行うだけで、式のタイプの証明が得られます。
したがって、これらのルールはすべて、式のタイプをどのように把握するかを正確に指定することです。
これで、Prologを使用したことがあるなら、これはおなじみのはずです。つまり、本質的にはPrologインタプリタのような証明ツリーを計算していることになります。 Prologが「論理プログラミング」と呼ばれる理由があります! H-M推論アルゴリズムに最初に導入された方法は、Prologに実装することであったため、これも重要です。これは実際には驚くほど単純で、何が起こっているかを明確にします。ぜひ試してみてください。
注:この説明で間違いを犯した可能性があります。誰かが指摘してくれたらそれを気に入ってくれるでしょう。私は実際に数週間でクラスでこれをカバーするので、私はその時より自信があります:P。
誰かが少なくともこのシンボルの海が何を意味するのか理解するために探し始めるところを私に言うことができれば
判断と導出による論理のスタイルについては、 " プログラミング言語の実用的な基礎 - "の第2章と第3章を参照してください。本全体は 現在Amazonで入手可能です。
帰納的定義はプログラミング言語の研究において不可欠なツールです。この章では、帰納的定義の基本的な枠組みを開発し、それらの使用例をいくつか示します。帰納的定義は、さまざまな形式の判断または表明を導出するための規則の集合で構成されます。判断は、指定された種類の1つ以上の構文オブジェクトに関するステートメントです。規則は、判決の有効性のために必要かつ十分な条件を指定し、それゆえその意味を完全に決定する。
構文オブジェクトについてのjudgement、またはassertionという概念から始めます。私たちは、次のような例を含め、さまざまな形態の判断を利用します。
判断は、1つ以上の構文上の目的語が相互に関連して性質を持つか立っていると述べます。性質または関係そのものを判定形式と呼び、オブジェクトがその性質を持っている、またはその関係にあるという判断は、その判断形式のインスタンスと呼ばれます。判定形式は述語とも呼ばれ、インスタンスを構成するオブジェクトはその主語です。 _ j _ aが成り立つと判断するためにa _ j _ と書きます。判決の主題を強調することが重要ではない場合(本文はここでは切り捨てられます)
記法は 自然な控除 から来る。
記号は 回転木戸 と呼ばれます。
6つのルールはとても簡単です。
Var
の規則はどちらかというと些細な規則です - もしidentifierのための型があなたの型環境に既に存在するのなら、その型を推論するためにはそのまま環境からそれを取り出すということです。
App
ルールは、e0
とe1
の2つの識別子があり、それらの型を推測できる場合は、アプリケーションの型e0 e1
を推測できると述べています。 e0 :: t0 -> t1
とe1 :: t0
(同じt0!)を知っていれば、規則は次のようになります。アプリケーションは正しく型付けされ、型はt1
です。
Abs
とLet
は、ラムダ抽象化とレットインの型を推測するための規則です。
Inst
規則は、あなたがより一般的でないものでタイプを置き換えることができると言います。
Hindley-Milnerは、 逐次計算 (自然な推論ではない)という形式の一連の規則であり、明示的な型宣言を行わなくてもプログラムの構成から(最も一般的な)プログラムの型を推論できます。
まず、記号について説明しましょう
それより上のものはすべて前提であり、下のものはすべて結論です( Per Martin-Löf )
この後に続くのは論理ステートメントの英語の解釈であり、その後に緩やかな言い換えと説明が続きます。
与えられた? ????の一種です。 σ、????の要素(ガンマ)、
結論を出すアサート???は????です。
別の言い方をすれば、????で、私たちは????を知っているは?なぜですか?は?で???.
これは基本的にはトートロジーです。識別子名は変数または関数です。
与えられた? ???? 0は関数型であり、???? ???? 1はa ????です。
結論を出すに関数を適用することを表明する。
規則を言い換えると、関数applicationはtype ???? 'を返すことがわかります。関数の型が????→???? 'であるためそして????型の引数を取得します。
つまり、関数が型を返すことがわかっていて、それを引数に適用すると、結果は返された型のインスタンスになります。
与えられた?そして???タイプの???アサート???型です、???? '
結論を出す無名関数をアサートします。の式を返す????→???? '型です。
再度、私達が取る機能を見るとき????そして、????という式を返します。これは、????→???? '型であることがわかります。なぜですか? (a ????)はそれを主張しています????は???? 'です。
私たちが知っていれば?は?したがって式???? ???? '型の場合は、????の関数式を返す????→???? '型です。
与えられた? ????、and ????の???? 0をアサートそして、????型の????は、????型の???? 1をアサートします。
結論を出す????型のlet
???? = ???? 0in
???? 1をアサートします。
ゆるい???なぜなら、は、であるからであり、そして、は、である。は何ですか?これは???? 1がa ????であることを表明しています。
これは、私たちがa ????という式???? 0を持っている場合を意味します。 (変数または関数である)、そして名前、????、また????、および式????の式???? 1は、その代わりに???? 0を代入することができます。 ????それが???? 1の中に現れるところはどこでも。
与えられた?アサート??? ???? 'タイプのそして???? ' ????のサブタイプです。
結論を出すアサート???は?
表現、 ????は親タイプです。という表現だから?サブタイプ???? '、そして???? ???? 'の親タイプです。
あるインスタンスが別の型のサブタイプである型の場合、それはそのスーパータイプのインスタンスでもあります。より一般的な型です。
与えられた?アサート???は何ですか? and ????は、????の自由変数の要素ではありません。
結論を出す????をアサートし、すべての引数式を入力します。を返す表現
だから一般的に、???入力されている? ????を返すすべての引数変数(????)に対しては何ですか?そして???自由変数ではありません。
これは、包含範囲にまだ束縛されていない引数(非局所的ではない変数)に対してすべての型を受け入れるようにプログラムを一般化できることを意味します。これらの束縛変数は代用可能です。
特定の仮定(自由/未定義の変数がない、既知の環境など)を考えると、次のような種類があります。
これらの規則を組み合わせることで、型注釈を必要とせずに、最も一般的な型のアサートプログラムを証明できます。
Eについて考える2つの方法があります。 1つは「式eが型σを持つ」、もう1つが「式eと型σの順序対」です。
Γを式と型のペアのセットとして実装された式のタイプに関する知識として見てください。
回転木戸⊢は、左側の知識から、右側にあるものを推測できることを意味します。
したがって、最初の規則[Var]を読むことができます。
私たちの知識Γがe:σのペアを含んでいる場合、eからタイプσを持つことをΓから推測することができます。
2番目のルール[App]は読むことができます:
Γから我々がe_0が型τ→τ 'を持つと推論することができ、そしてΓから我々がe_1が型τを持つと推論することができるなら、Γから私たちはe_0 e_1が型τ'を持つと推論することができる。
Γ` {e:σ}の代わりにΓ、e:σと書くのが一般的です。
したがって、3番目の規則[Abs]を読むことができます。
x:τで拡張されたΓから我々が、eが型τ 'を有すると推定することができるならば、Γから、λx.eが型τ→τ'を有すると推定することができる。
4番目のルール[Let]は練習問題として残されています。 :-)
5番目のルール[Inst]は読むことができます:
Γから我々がeが型σ 'を有し、σ'がσのサブタイプであると推定できる場合、Γから我々はeが型σを有すると推定することができる。
6番目と最後の規則[Gen]を読むことができます。
Γから我々がeが型σを持ち、αがΓ内の型のいずれにおいても自由型変数ではないと推定できる場合、Γから私たちはeが型∀ασを持つと推定することができる。