依存型理論と「任意の」型関数
この質問に対する私の最初の答えは、コンセプトは高く、詳細は低く、サブ質問「何が起こっているのか」に反映されました。この答えは同じですが、「任意の型関数を取得できますか?」というサブ質問に焦点を当てています。
sumとproductの代数演算の拡張機能の1つは、いわゆる「ラージオペレーター」です。これは、通常Σ
、Π
それぞれ記述されたシーケンスの合計と積(より一般的には、ドメイン上の関数の合計と積)を表します。Sigma Notationを参照してください。
だから合計
a₀ + a₁X + a₂X² + ...
書かれるかもしれない
Σ[i ∈ ℕ]aᵢXⁱ
どこa
実数のいくつかのシーケンスは、たとえば、あります。製品はのΠ
代わりにと同様に表されΣ
ます。
遠くから見ると、この種の式はの「任意」関数によく似ていX
ます。もちろん、表現可能なシリーズとそれに関連する分析機能に限定されています。これは型理論の表現の候補ですか?間違いなく!
これらの式を直接表現する型理論のクラスは、「依存型」型理論のクラス、つまり依存型の理論です。当然、用語に依存する用語があり、型関数と型の数量化を備えたHaskellのような言語では、型に依存する用語と型があります。依存する設定では、用語に応じてタイプを追加します。Haskellは依存型付き言語ではありませんが、依存型の多くの機能は、言語を少し拷問することでシミュレートできます。
カレーハワードと依存型
「カレーハワード同型」は、単純型付きラムダ計算の用語と型判定ルールが、命題の代わりに型を使用して、直観主義命題論理に適用された(Gentzenによって定式化された)自然演繹に正確に対応するという観察として誕生しました、および証明に代わる条件ですが、この2つは独立して発明/発見されました。それ以来、型理論家にとって大きなインスピレーションの源となっています。考慮すべき最も明白なことの1つは、命題論理のこの対応を述語またはより高次の論理に拡張できるかどうか、およびその方法です。依存型理論は当初、この探索の道から生まれました。
単純型付きラムダ計算のカリーハワード同型の紹介については、こちらを参照してください。例として、証明したい場合は証明して証明A ∧ B
する必要がA
ありB
ます。結合された証明は、単純に2つの証明の組み合わせです。
自然控除では:
Γ ⊢ A Γ ⊢ B
Γ ⊢ A ∧ B
そして単純に型付けされたラムダ計算では:
Γ ⊢ a : A Γ ⊢ b : B
Γ ⊢ (a, b) : A × B
∨
合計タイプ、→
関数タイプ、およびさまざまな消去規則についても、同様の対応が存在します。
証明できない(直観的には誤り)命題は、無人のタイプに対応します。
論理的な命題としての型の類比を念頭に置いて、型の世界で述語をモデル化する方法を検討し始めることができます。これが形式化された多くの方法があります(広く使用されている標準については、Martin-Löfの直観型理論の紹介を参照してください)。命題に条件をとる関数。型式に用語を含めることを許可すると、ラムダ計算スタイルでの処理がすぐに可能性として現れます。
建設的な証明のみを考慮して、何の証明を構成し∀x ∈ X.P(x)
ますか?x
対応する命題(P(x)
)の証明に条件()をとって、それを証明関数と考えることができます。したがって、型(命題)のメンバー(証明)∀x : X.P(x)
は「依存関数」であり、それぞれx
にX
型の項を与えP(x)
ます。
どう∃x ∈ X.P(x)
ですか?我々は、任意のメンバーを必要としX
、x
一緒の証明で、P(x)
。タイプ(命題)のメンバー(証明)ので∃x : X.P(x)
区別用語:「依存ペア」でありx
でX
、一緒に種類の用語とはP(x)
。
表記:使用します
∀x ∈ X...
実際のクラスのメンバに関する声明についてX
、および
∀x : X...
typeの普遍的な数量化に対応する型式の場合X
。同様に∃
。
組み合わせに関する考慮事項:積と合計
命題を伴う型のカリーハワード対応だけでなく、この問題の主要な点である代数型と数値および関数との組み合わせ対応があります。幸いにも、これは上記の依存型に拡張できます!
モジュラス表記を使用します
|A|
型の「サイズ」を表現A
し、質問で概説されている型と数の間の対応を明確にする。これは理論外の概念であることに注意してください。言語内にそのような演算子が必要であるとは主張していません。
タイプの可能な(完全に削減された、正規の)メンバーを数えましょう
∀x : X.P(x)
これは、型の項x
から型の項への依存関数X
の型P(x)
です。そのような各関数は、のすべての項に対してX
出力を持たなければならず、この出力は特定のタイプでなければなりません。それぞれの場合x
でX
、それから、これは与え|P(x)|
出力の「選択肢」を。
パンチラインは
|∀x : X.P(x)| = Π[x : X]|P(x)|
もちろん、これはの場合X
はあまり意味がありませんがIO ()
、代数型に適用できます。
同様に、タイプの用語
∃x : X.P(x)
はとのペアのタイプであるため、のいずれかが与えられる(x, p)
とp : P(x)
、の任意のメンバーと適切なペアを構築し、「選択肢」を与えることができます。x
X
P(x)
|P(x)|
したがって、
|∃x : X.P(x)| = Σ[x : X]|P(x)|
同じ警告で。
これは、記号Π
とを使用する理論の依存型の一般的な表記を正当化します。Σ
実際、多くの理論は、上記の対応により、「すべて」と「製品」と「あり」と「合計」の区別を曖昧にします。
間近です!
ベクトル:従属タプルを表す
次のような数値式をエンコードできますか
Σ[n ∈ ℕ]Xⁿ
型式として?
結構です。Xⁿ
Haskellのように式の意味を非公式に検討することはできますX
が、は型とn
自然数ですが、これは表記法の乱用です。これは数値を含む型式です。明らかに有効な式ではありません。
一方、図の依存型では、数値を含む型がまさにポイントです。実際、依存タプルまたは「ベクター」は、依存型がリストアクセスなどの操作に実用的な型レベルの安全性を提供する方法の非常に一般的に引用される例です。ベクトルは、長さに関する型レベルの情報を含む単なるリストです。正確には、のような型式の後に何があるかXⁿ
です。
この回答の期間中、
Vec X n
-type値のlength- n
vectorのX
タイプです。
技術的n
には、実際の自然数ではなく、自然数のシステムでの表現です。我々は(自然数を表すことができNat
、ゼロ(としてペアノのスタイルで)0
)、またはその後継(S
のために別の自然数の)、そしてn ∈ ℕ
私が書く˻n˼
に用語を意味するようにNat
表しているがn
。たとえば˻3˼
ですS (S (S 0))
。
次に、
|Vec X ˻n˼| = |X|ⁿ
どれでもn ∈ ℕ
。
NATタイプ:タイプへのℕ用語の昇格
これで、次のような式をエンコードできます
Σ[n ∈ ℕ]Xⁿ
タイプとして。この特定の式はX
、質問で特定されているように、もちろんのリストのタイプに同型のタイプを生成します。(それだけでなく、カテゴリ理論の観点から、タイプ関数-ファンクタである- X
上記のタイプを採用することは、当然リストファンクタと同型です。)
「任意の」関数のパズルの最後のピースは、エンコードする方法です。
f : ℕ → ℕ
のような表現
Σ[n ∈ ℕ]f(n)Xⁿ
べき級数に任意の係数を適用できるようにします。
代数型と数値の対応はすでに理解しているため、型から数値へ、型関数から数値関数へのマッピングが可能です。他の方法で行くこともできます!-自然数を取ると、依存型があるかどうかに関係なく、明らかにその数の項メンバーを持つ定義可能な代数型があります。型理論の外でこれを帰納法によって簡単に証明できます。システム内で、自然数から型にマッピングする方法が必要です。
満足のいく実現は、依存型があると、帰納法による証明と再帰による構築が密接に類似することになります-実際、それらは多くの理論で非常に同じものです。誘導によって、ニーズを満たす型が存在することを証明できるので、それらを構築できないのでしょうか。
用語レベルでタイプを表す方法はいくつかあります。ここでは*
、型のユニバースについて、架空のHaskellish表記を使用します。それ自体は通常、従属設定の型と見なされます。1
同様に、ℕ
依存型理論と同じように、少なくとも '-除去'を表記する方法もたくさんあります。ハスケリッシュのパターンマッチング表記法を使用します。
私たちは、マッピングを必要とするα
からNat
に*
プロパティを使用して、
∀n ∈ ℕ.|α ˻n˼| = n.
次の疑似定義で十分です。
data Zero -- empty type
data Successor a = Z | Suc a -- Successor ≅ Maybe
α : Nat -> *
α 0 = Zero
α (S n) = Successor (α n)
したがって、のアクションはα
後続のの動作をS
ミラーリングし、一種の準同型になります。Successor
型のメンバーの数に「1」を追加する型関数です。つまり、サイズが定義さ|Successor a| = 1 + |a|
れているすべてのa
場合です。
たとえばα ˻4˼
(つまりα (S (S (S (S 0))))
)は、
Successor (Successor (Successor (Successor Zero)))
このタイプの条件は
Z
Suc Z
Suc (Suc Z)
Suc (Suc (Suc Z))
正確に4つの要素を提供します|α ˻4˼| = 4
。
同様に、についてはn ∈ ℕ
、
|α ˻n˼| = n
要求に応じ。
- 多くの理論では、のメンバーは
*
タイプの単なる代表である必要があり、操作はタイプの用語から*
関連するタイプへの明示的なマッピングとして提供されます。他の理論では、リテラルタイプ自体を用語レベルのエンティティにすることができます。
「任意」の機能?
完全に一般的なパワーシリーズをタイプとして表現するための装置が用意されました。
シリーズ
Σ[n ∈ ℕ]f(n)Xⁿ
タイプになります
∃n : Nat.α (˻f˼ n) × (Vec X n)
どこ˻f˼ : Nat → Nat
機能の言語内のいくつかの適切な表現ですf
。これは次のように見ることができます。
|∃n : Nat.α (˻f˼ n) × (Vec X n)|
= Σ[n : Nat]|α (˻f˼ n) × (Vec X n)| (property of ∃ types)
= Σ[n ∈ ℕ]|α (˻f˼ ˻n˼) × (Vec X ˻n˼)| (switching Nat for ℕ)
= Σ[n ∈ ℕ]|α ˻f(n)˼ × (Vec X ˻n˼)| (applying ˻f˼ to ˻n˼)
= Σ[n ∈ ℕ]|α ˻f(n)˼||Vec X ˻n˼| (splitting product)
= Σ[n ∈ ℕ]f(n)|X|ⁿ (properties of α and Vec)
これはどれだけ「恣意的」なのでしょうか?この方法による整数係数だけでなく、自然数にも制限されます。それとは別に、依存型のチューリング完全言語がf
与えられれば、何でもかまいませんが、自然数係数で任意の分析関数を表すことができます。
私はこれと、このList X ≅ 1/(1 - X)
ような否定的で非整数的な「型」がこの文脈で持つ可能性のある疑問やどのような意味を持つ可能性があるかなどとの相互作用を調査していません。
うまくいけば、この答えは、任意の型関数でどこまで行けるかを調査するのに役立つでしょう。