Cartesian Closed Category

Preview:

DESCRIPTION

Cartesian Closed Categoryを詳細を飛ばして説明してみたスライド。 参考にした本はB.C.PierceのBasic Category Theory for Computer Scientists。 ただし、CCCに関わる部分以外全て飛ばしている。

Citation preview

Cartesian Closed Categoryを駆け足で

森口

今回の発表の目的

圏(Category)の一例としてCartesian Closed Categoryを学ぶ。

圏論(Category theory)の勉強としては限定的に。

必要な内容を引っ張ってきてそれだけを。

一般に説明される構造の大半は触れない。

以下、ほとんどを日本語の用語で説明。

初出時は英語も併記。

Cartesian Closed Categoryは略称(CCC)を使用。

いい表記がみつからなかった。デカルト閉圏とかカルテシアン閉圏とか。長い。

余談:余談について

途中途中で、「余談:~~」というタイトルで 私の雑感が入る。

雑学じみていたり、どうでもいいことを言ったりする。つまり、無視して良い部分。

途中から口語になったりする。

主に私の集中力が切れたことを表す。

目次

圏論とは?

Cartesian Closed Category (CCC)とは?

単純型付きラムダ計算とは?

実際の対応関係は?

例としては?

圏論 概要 まあ、何かをする前にそれが何かをしらないと、話にならないよね。

圏論

圏(Category)という形で抽象化された体系

Category : 圏、と訳される。体系。

Category = Objects + Arrows

記号:C, D, ...

Object : 対象、と訳される。もの。

記号:A, B, C, D, ...

Arrow : 射、と訳される。morphismともいう。矢印。 対象間を結ぶ。

記号:f, g, h, ...

f : A → Bのように表記。(fはAからBへの射)

AとBをそれぞれドメイン(domain)、コドメイン(codomain)と呼ぶ。

満たさなければならない性質

射について満たさなければならない性質

全ての対象Aに対して、恒等射idA : A → Aが存在

全ての射f : A → B, g : B → Cに対して、g○f : A → Cが存在

射の合成の存在

全ての射f : A → B, g : B → C, h : C → Dに対して、h○(g○f) = (h○g)○f

射の合成の結合則

全ての射f : A → Bに対して、idB○f = f = f○idA

対象?特にないよ。

図式で表現1

f : A → Bを図式で書くと下の通り。

A

B

f

図式で表現2

g : B → Cとfを並べて書く。

A

B

f

C g

図式で表現3

h : C → Dを含むと下のようになる。

A

B

h

C g

D

f

図式で表現4

k : A → Dを追加する。

実はこれで、h○(g○f) = k = (h○g)○fである。

A

B

h

C

k D

f

g

図式の可換性

図式中で、ある始点から終点までを結ぶ射の列は、(複数経路ある場合)どの経路をたどっても合成結果が等しい。

図式が可換である(commute)という。

A

B

h

C

k D

f

g

結合則について

本来不要だが、g○fとh○gを書き加える。

ただの合成なので図式にいれられる。

わかりやすいでしょ?

A

B

h

C

k D

f

g

圏で何かを表現する

対象と射に、何か意味のあるものを割り当てる。

対象を要素、射を要素間の関係とする、など。

対象や射の性質を定義(設定)する。

e.g.) ある対象A, Bに対してf : A → Cおよびg : B → Cが唯一存在する。

この例に特に意味はない。

最終的に、対象と射の間に成立する関係によって性質を言及する。

実際にある圏

Set

対象を集合、射を(集合間の)全域関数とする圏。

恒等射は恒等関数、射の合成は関数合成、結合則は関数合成の性質。

Poset

対象を半順序集合、射を単調関数とする圏。

Cat

対象を(小さな)圏、射をFunctorとする圏。

圏の圏。Functorは圏から圏への変換と思ってくれれば。

圏論の教科書について

多くの本では、圏の各構造をボトムアップに定義していく。

実例が遠い・・・

一応途中実例は載っているが、全体がないのでピンとこない。

ここではトップダウンに、「Cartesian Closed Categoryに必要な要素を出て来た順に説明」する。

できる限り説明がネストしないように気をつける。

CARTESIAN CLOSED CATEGORY

本題。すぐ話が変わるけどね。ちなみに大文字にした覚えはないよ。

Cartesian Closed Category (CCC)

Cartesian Closedな圏(≠ある決まった圏)

終対象1が存在

二つの対象A, Bに対してA×Bが存在

積(product)

二つの対象B, Cに対してCBが存在

冪(exponential)

これらの説明は必要になるまでしません!(キリッ

余談:CCCという略称

Google先生は和洋問わず、いろいろ聞いたこともないようなものを出してくれる。

Wikipedia先生は

日本語版は残念ながら項目が少なく、Cartesian Closed Categoryはない。

そして私の愛する(してないけど)Cross-cutting concernsもない!

英語版は大量の項目があり、下の方へ行くとmathematicsのところにある。

・・・cross-cutting concernsはやっぱりない・・・

CCCの表現するもの

様々な圏がCCCだが、ここで説明するものは単純型付きラムダ計算と直観主義論理。

Curry-Howard-Lambek対応という。

前二者のラムダ計算と直観主義論理との関係だけがよく使われる。

直観主義はあまりなじみがない(特にB4には)と思われるので、単純型付きラムダ計算を元に説明していく。

幸いHaskellやってるんだし、大丈夫・・・だよね?

単純型付きラムダ計算 知ってる人は退屈な、知らない人でもすぐわかる説明。(たぶん)

単純型付きラムダ計算(最小構成)

ラムダ計算+型

xは型付きラムダ式

λx:A.MはMが型付きラムダ式であり、Aが型であるとき(かつそのときに限り)ラムダ式

(M N)はM, Nが型付きラムダ式であるとき(かつそのときに限り)型付きラムダ式

αは型(ground type)

BAはA, Bが型であるとき(かつそのときに限り)型

Haskellなどでいう A -> B

余談:矢印

A→Bと同じ意味を持つ記号はいくつかある。

今回使ったBA

主に関数型言語、ラムダ式で使われた印象がある。

あくまで個人的な意見だが。

一部の型付きラムダ計算ではλxA.Mのような書き方をしていたし、高階関数が面倒なので、使えにくかったのでは?

A⊃B

論理の世界では今も使われている。

A⇒B

どちらかといえば、メタレベルでのimplicationの印象。

余談:なぜ冪乗?

おそらく、要素数が冪乗になるから

予想だが、そう間違ってはいまい。

例)A={0,1,2}、B={0,1}に対しA→Bの数は?

答え:8つ(|B||A|)

012->0

01->0 2->1

02->0 1->1

12->0 0->1

0->0 12->1

1->0 02->1

2->0 01->1

012->1

Aの要素それぞれに対して、Bの要素数分の選択肢。

余談:「かつそのときに限り」

ラムダ式の定義に出現している言葉。

集合を一意に定めるために書く。

この文言がないと、「規則に書かれていない要素」が入りうる。

例えばλx:A.3がラムダ式と扱われる可能性がある。

文言があることで、3はラムダ式ではないので入らない。

通常は、「以下の規則を満たす最小の集合」という定義をする。

面倒だし読みにくくなるし邪魔だし。

単純型付きラムダ計算(少し拡張)

ラムダ式に組とunitを追加

(M, N)はMとNが型付きラムダ式(ry

(fst M)はMが(ry

(snd M)はMが(ry

unitは型付きラムダ式

A×BはAとBが型(ry

Unitは型

余談:型付きラムダ計算というもの

この話からわかるように、型付きラムダ計算と呼ばれるものは山のようにある。

「単純」でさえ、これに和を加えたものなどもある。

CCCは型付きラムダ計算と対応する。よって、 それだけのCCCがある。

構造以外にも、ground typeとしてintだとかboolだとか使えたりする。

型付け規則について

型が付くという関係をΓ┣ M : Aのように書く。

(変数の型)文脈Γにおいて、MはAという型が付く。

型付け規則は、線を引いた上下に関係を書く。

上には「仮定として成り立つ関係」を書く。

下には「結果として成り立つ関係」を書く。

線の横には規則の名前を書く。

下の例だと、「仮定なしに」「文脈ΓでunitがUnitに型付けられ」「その規則をUnitと呼ぶ」ことを表す。

Unit Γ┣ unit : Unit

型付け規則(1/2)

Var Γ┣ x : A

Lam Γ┣ λx:A.M : BA

Γ, x:A┣ M : B

Γ┣ (M N) : B

Γ┣ M : BA Γ┣ N : A App

Unit Γ┣ unit : Unit

x : A ∈ Γ

型付け規則(2/2)

Γ┣ (M, N) : A×B

Γ┣ M : A Γ┣ N : B Prod

Snd

Γ┣ M : A×B

Γ┣ (fst M) : A

Γ┣ (snd M) : B

Fst

Γ┣ M : A×B

余談:き?け?

型付き?型付け?

”typed”が型付き、”typing”が型付けに相当。

型をつけるラムダ計算ではなく型がくっついたラムダ計算。

規則に型がつくわけじゃなくて、型をつける規則。

ちなみに、英語の”type”は動詞。型をつける。

はいはいどうでもいいですねわろすわろす。

単純型付きラムダ計算の性質

必ずβ簡約が終了する。

逆に言えば、β簡約が終了しないラムダ式は型付きラムダ計算として書けない。

型のないラムダ計算も、型推論という形で同じ範囲の項に限定することができる。

型推論できる=型付きラムダ計算で書ける

他は・・・いや、十分か。

余談:式(プログラム)の妥当性

型付けできない型付きラムダ式というのがある。

λx:A.(x x)とか。

前のxが関数型でないため、型付け規則に合致しない。

通常のラムダ式と違い、「妥当(valid)な型付きラムダ式」という概念があることを意味している。

通常のラムダ式に、妥当でないラムダ式はない。

型は妥当であるとか妥当でないという概念を作り、それによってユーザーを助けている。

妥当でないプログラムは正しく動かない(かもしれない)からはじく(rejectする)。

CCCと単純型付きラムダ計算の 対応

ようやく話の本題。ここまでは前座。

CCCと型付きラムダ計算の対応

対象は全て型

項ではないので注意。

射は、環境の型から項の型の導出

f : A → Bは A┣ Bを証明する(ための規則の列の合成射)fを意味する。

・・・え?イミフ?

説明の順序

型付きラムダ計算を少し考え直す。

CCCの要素の定義を見ながら厳密に対応をとる。

とりあえずCCCは置いておくけど

まず型付きラムダ計算のほうから見る。

でも覚えておいてほしいこと。

CCCの対象は型と

CCCの射は型の導出Γ┣ Aと

それぞれ対応する。

というか、対応させる。これから。

型付きラムダ計算を考え直す 都合が悪ければ、本質的に等価な何かに変更すればいい。

型付け規則 Γ┣ BからA┣ Bという形へ

Bは型として、Aも型とすると若干型付け規則の形に合わない。

Aの側は「変数と型のリスト」であり、Bは「項と型」。

リストを一つの型に押し込める必要がある。

リストが駄目ならペアにすればいいじゃない。

cons=組 (積)

nil=unit (1)

文脈の変換

x1 : A1, x2 : A2, ... , xn : An

(...((unit, x1), x2), ...), xn) : (...((Unit×A1)×A2)×...×An)

これで確かに要素が一つになった。

推論の方法がやや変わる(変数の型付けに射影をとる必要あり)が、基本的には同じ。

型付け規則renewal

Var規則とLam規則が変わるのみ。他は全てΓを一つの型にすればよい。(変数の衝突に注意)

Var (L, x) : C×A┣ x : A

Proj (L, y) : C×B┣ x : A

L : C┣ x : A

Lam L : C┣ λx:A.N : BA

(L, x) : C×A┣ N : B

問題:ラムダ式は?

Q:CCCと型付きラムダ計算が対応すると言ったのに、ラムダ式と対応するものがないじゃないか。どういうこと?

A:renewalによって、実は

ラムダ式 ≡ 型の導出 が成立するようになったのだ。

ちなみに、renewal前はラムダ式のほうが細かい指示ができた。

例)λx:A.λy:A.xとλx:A.λy:A.yは導出では区別不可能。

区別できない?

どちらも、Var,Lam,Lamの順。ラムダ式は違う。

┣ λx:A.λy:A.x : (AA)A

x : A┣ λy:A.x : AA

x : A, y : A┣ x : A

Lam

Lam Var

┣ λx:A.λy:A.y : (AA)A

x : A┣ λy:A.y : AA

x : A, y : A┣ y : A

Lam

Lam Var

区別できなかったもの

以前の形式だと、唯一Varのみ「構造以外の何か」で判別する規則になっている。

リストに含まれるかどうか。リスト内の順序など全く関係ない。

他は構造を分解するだけ。Unitは分解する必要すらない。

でもUnitを使う場合必ずunitが値。

Varを使う場合、どの変数であっても(型さえ同じなら)同じように規則が使われる。

Varを使うと、ラムダ式のほうが細かく指定できる。

Var規則の変形

VarとProjに分かれた。

それぞれ「一番近い束縛変数を消去」「一番近い束縛変数が導出対象」という状態。

どちらも構造に依存し、「構造以外の何か」ではなくなっている。

簡単に言えば、VarとProjにより「今の地点から何番目の変数を参照しているか」を表す。

de Bruijn indexみたいな考えだと思えば。

区別できなかった例

上に余計なProjが入ってきている!

区別できた!

unit : Unit┣ λx:A.λy:A.y : (AA)A

(unit, x) : Unit×A┣ λy:A.y : AA

((unit, x), y) : Unit×A×A┣ y : A

Lam

Lam Var

unit : Unit┣ λx:A.λy:A.x : (AA)A

(unit, x) : Unit×A┣ λy:A.x : AA

((unit, x), y) : Unit×A×A┣ x : A

Lam

Lam Proj

(unit, x) : Unit×A┣ x : A Var

つまり

射≡型付け≡ラムダ式+環境、すなわち

射≡ラムダ式+環境 ってこと。

これで解決できたね。

規則と図式の対応 タイトルの割に、圏の構造の定義の話だったりする。

CCCの対象と型の対応

直感的には、Unitは1、組は積、関数は冪と対応

まあ、同じ記号使ったし、ね。

Ground type(αなど)はCCCの中に対応する対象があると仮定

そのようなCCCが対応する、と考える。

例:α×(βUnit)はα×(β1)と対応

まあ見たまんま。Unitが変わるくらい。

圏による終対象・積・冪の定義

規則との対応をとるに当たって必要なので、ここで説明。

圏における構造の定義は、大体次のパターン。

ある射が存在し、可換である図式がある。

積・冪もこれにもれない。

終対象はほとんど図式を使わないけれど、ね。

終対象 終わりがあるなら始まりもある。始対象という。説明しないけど。

終対象(terminal object)

全ての対象Aに対して唯一の射! : A → 1が存在。

どんなAに対しても!が射の名前。不思議だけどよくあること。

A 1 !

終対象とUnit

何かからUnitを導くのは常にUnitの規則を使えばよい。

文脈に関係なくunit : Unitと型付けられる。

あらゆる対象に!を持つことと対応する。

A 1

Unit L : A┣ unit : Unit

!

積 績と間違えられること多数。紡ぐのか、積むのか・・・

A×Bはπ1 : A×B → A, π2 : A×B → Bを伴い、 ある対象Cと射f : C → A, g : C → Bについて、 以下の図式を可換にする<f, g> : C → A×Bが 存在するものを言う。

点線の射は、他の部分から一意に導かれる射。この図

ではf, g, π1, π2から導かれる。 C

A×B B A

f g

π1 π2

<f, g>

型付けにおける積(1/2)

組を型付ける場合

さきほどの図のCが環境である。

C → A×Bという射(文脈C下で型A×B)は、 f : C → A(文脈C下で型Aがつく)と g : C → B(文脈C下で型Bがつく)の存在から導ける、と言っている。

型付けにおける積(図1)

C

A×B B A

f g

π1 π2

<f, g>

Prod L : C┣ (M, N) : A×B

L : C┣ M : A L : C┣ N : B

型付けにおける積(2/2)

組を分解する場合

C → A×Bが前提として存在、π1とπ2はやはり存在する。

合成で終了。

π1とπ2はそれぞれfstとsndに対応する。

型付けにおける積(図2)

C

A×B B A

π1○f π2○f

π1 π2

f

Snd L : C┣ M : A×B

L : C┣ (fst M) : A L : C┣ (snd M) : B Fst

L : C┣ M : A×B

余談:双対性(duality)

様々なものをひっくり返した構造(性質etc)。

圏では、非常に簡単なことに、射を逆に向けたもの

以下は余積(coproduct)と呼ばれる構造の持つ図式

co- が双対なものを表す。colimitとかcoconeとか。

例外もある。終対象の双対である始対象はinitial object。

実はこれ、一般に言う和の構造。つまり積の双対は和。

C

A+B B A

f g

ι1 ι2

[f, g]

余談:対象の一意性

実のところ、A×BとB×Aは、対象として完全に同じものである。

それぞれの射影射は全く同じ。

圏では、こういった時に「isomorphicなものを 除いて一意」という言い方をする。

簡単に言えば同等なものは本質的に同じものとする。

冪 和、積、冪とならぶはずなのに、可換じゃない。

BAは、evalBA : BA×A → Bを伴い、ある対象Cとg : C×A → Bについて、以下の図式を可換にするcurry(g) : C → BAが存在するものを言う。

f×gは、f : A → B, g : C → DのときにA×C → B×Dとなる(直感的にはfとgの積である)射。

C×A

B BA×A evalBA

curry(g)×idA g

余談:curryとeval

どちらも関数型言語のそれ。

カリー化は複数の引数をとる関数を、一つずつ引数をとって関数を返す関数に変更するもの。

A×B→CをA→B→C

eval(apply?)は関数と引数をとって適用を行うもの。

(A→B)×A→B

使用した本の表記であって、常にこの名称というわけではない。

型付けにおける冪(1/2)

関数抽象を型付ける場合

やはりCが環境である。

C → BAという射(文脈C下で型BA)は、 g : C×A → B(環境C×A下で型B)の存在から導ける、と言っている。

C×Aは環境にAという型の要素を追加したもの。

型付けにおける冪(図1)

C×A

B BA×A evalBA

curry(g)×idA g

Lam L : C┣ λx:A.N : BA

(L, x) : C×A┣ N : B

型付けにおける冪(2/2)

関数適用を型付ける場合

C → BAとC → Aが前提として存在。

積の定義からC → BA×Aが存在。

evalBA : BA×A → Bと合成することでC → Bが導ける。

型付けにおける冪(図2)

B BA×A evalBA

C┣ (M N) : B

C┣ M : BA C┣ N : A App

C

BA A

f g

<f, g>

evalBA○<f, g>

変数 CCCでは名前なんてない。つまりde Bruijn notationとほぼ等価。

最後に追加

VarとProjと対応する射

簡単に言えば、Varはπ2と、Projはπ1とそれぞれ対応する。

Projには「残りの環境から型付けする」射が必要だが。

C×A A C π1 π2

Var (L, x) : C×A┣ x : A

Projの対応

C×B B C π1 π2

Proj (L, y) : C×B┣ x : A

L : C┣ x : A

A

f f○π1

というわけで

全ての規則と対応する射の存在がわかった。

全体としては

全ての対象は型

全ての射は、ドメインが環境、コドメインがラムダ式(環境下で型が付くラムダ式に限る)の型であり、射そのものは型を付ける規則の列(ラムダ式の構造)

と対応する。

ただ、冪の内容上、頻繁に図式が離れてしまう。

例 きれいな図式を期待?――残念。

実際に圏で型付けを・・・

SKIコンビネータでもやりますか。

簡単?後悔しますよ・・・?

ラムダ式として書くと、それぞれ以下のように。

S = λf:(CB)A.λg:BA.λx:A.((f x) (g x))

((CA)BA)(CB)Aという型がつく。

K = λx:A.λy:B.x

(AB)Aという型がつく。

I = λx:A.x

AAという型がつく。

一番簡単なIから

1 AA

1×A A π2

AA×A

evalAA curry(π2)×idA

curry(π2)

あれ~・・・?

なんか変な感じがするなあ・・・

図式が離れてるせいか?

じゃあ次、K

1 (AB)A

(1×A)×B A π1 1×A

π2

AB×B

evalBA curry(π1○π2)×idA

1×A AB curry(π1○π2)

(AB)A×A

evalAAB

もう名前書くのいや・・・

なんなのcurry(curry(π1○π2))って?

ちなみに最終的な射。

Sは図だけにする。

地獄のS(1/2) 関数適用部分

1×(CB)A×BA×A C

1×(CB)A×BA

A

BA BA×A

B

1×(CB)A

(CB)A

(CB)A×A

CB

CB×B

地獄のS(2/2) 関数抽象部分

1 ((CA)BA)(CB)A

1×(CB)A

((CA)BA)(CB)A×(CB)A

(CA)BA 1×(CB)A×BA

(CA)BA×BA

CA

1×(CB)A×BA×A C

CA×A

ははは・・・

もういやです。

かんべんしてください。

と言いたくなるような内容になるのでした。

以上! 眠かったかな?