math::category

34
2009-11-21 Math::Category id:hiratara

Upload: masahiro-honma

Post on 07-May-2015

1.198 views

Category:

Technology


0 download

DESCRIPTION

Perlを使って圏論概念をシミュレーション。

TRANSCRIPT

Page 1: Math::Category

2009-11-21

Math::Categoryid:hiratara

Page 2: Math::Category

Math::Category とは?(1)

✤ Perlによる圏の計算のシミュレーション

✤ 射、関手、自然変換を実装

✤ 米田埋込関手の実装

✤ モナド、クライスリ射の実装

Page 3: Math::Category

Math::Category とは?(2)

✤ 射は関数を仮定していない

✤ dom, cod, comp を適切に実装

✤ 関手、自然変換は関数と仮定

✤ 小さなHom集合しか扱えない。実用上は十分

✤ 実用、速度は無視。圏論の言葉をなるべく忠実に翻訳

Page 4: Math::Category

圏の実装(1)

✤ 圏は射のみで表現

✤ 対象は、恒等射として射で現せる

✤ Morphism は、以下のメソッドを持つinterface

✤ source: domの対象を表す恒等Morphismを返す

✤ target: codの対象を表す恒等Morphismを返す

✤ composition: 射の合成

Page 5: Math::Category

圏の実装(2)

✤ 圏の性質は、ユーザの責任となる

✤ targetやsourceが本当に恒等射か

✤ composition の結合則

✤ 圏の全体の管理もユーザの責任

✤ 圏の全ての射を得ることはできない

✤ インスタンス化した射が圏のどの部分かは気にしない

Page 6: Math::Category

圏の例(1): SimpleMorphism

✤ 2つの対象間に最大で1個しか射がない圏の表現。主にテスト用。

✤ simple_morph ‘1’ => ‘2’; のように射を記述

✤ source は simple_morph ‘1’ => ‘1’

✤ target は simple_morph ‘2’ => ‘2’

✤ (simple_morph ‘2’ => ‘3’) . (simple_morph ‘1’ => ‘2’)= (simple_morph ‘1’ => ‘3’)

‘3’

‘2’

‘1’

Page 7: Math::Category

圏の例(2): SubroutineMorphism(1)

✤ Perlの関数の圏

✤ Perlは型がないので、引数となれる任意の値の集合を対象と考える

✤ 型のある言語であれば、型を対象とすべき

✤ sub_morph { $_[0] * 2 } と関数的に定義

✤ sourceとtargetは同じで、 sub_morph { @_ } (恒等関数)

✤ 対象となる集合にあわせて、臨機応変に制限して考える(ズル)

文字列

undef

print

Page 8: Math::Category

圏の例(2): SubroutineMorphism(2)

✤ 合成 $sub2 . $sub1 は、「$sub1 、 $sub2」 の順に実行とする

✤ 実装でも、合成せずにサブルーチンをリストとして持っている

✤ スタックオーバフローとならないようにするため

✤ 副作用は・・・あってもいいんじゃないか?

Page 9: Math::Category

副作用はあっていいの?(1)

✤ f . ( g . h ) も (f . g) . h も f をやって g をやって h をやる

✤ 同じ意味。結合則が成り立っている

✤ idは副作用があってはいけない(当たり前)

✤ ただし、いい性質の圏ではないかも

✤ f×g: x → ( f(x), g(x) ) は副作用があると積にならない

怪しい議論!

Page 10: Math::Category

A × BA B

C

f

πA πB

g( f, g )

副作用はあっていいの?(2)

(f,g)にはfとgの副作用が入り可換にならない。

A×Bと射影πAとπBをとる( f, g ): f, gの順に実行して2値にする

結果が外部環境に依存する場合、(f,g)と(g,f)の結果が異なる。

怪しい議論!

Page 11: Math::Category

圏の例(3): 圏の積、双対圏

✤ 圏の積: bi_morph $morph1, $morph2;

✤ sourceやtarget、合成はそれぞれの射のもの

✤ 双対圏: op $morph;

✤ sourceとtargeが逆。合成も逆。

✤ op op $morph; は $morph になる

(A1, A2)(f, g)

(B1, B2)B

f

A

Page 12: Math::Category

関手の実装(1)

✤ Functor クラス

✤ 実体は、単なるサブルーチンのラッパー

✤ Morphismを引数とし、Morphismを返す関数

✤ 射関数だけで表現。対象関数はない(対象は恒等射で表しているため、射関数に含まれる)

Page 13: Math::Category

関手の実装(2)

✤ 関手は、 functor { ... }; と普通の無名関数風に定義する

✤ どの圏からどの圏の関手か、は定義する人が意識する(Morphismの型で判断してもOK)

✤ 恒等射、結合則の保存は、定義する人の責任

✤ ピリオドによって合成できる ( $functor2 . $functor1 )

Page 14: Math::Category

関手の例(1): $BI_FUNCTOR

✤ Hom(-, -) の実装

✤ C^op × C から Sets への関手

✤ C^op × C は、双対射と圏の積を利用して表現

✤ Sets は SubroutineMorphism で表現(副作用のないものを集めた部分圏をSetsと見なせる)

Page 15: Math::Category

自然変換の実装(1)

✤ NaturalTransformation クラス

✤ 実体は単なるサブルーチンのラッパー

✤ 恒等射を引数にとり、対応する成分(Morphism)を返す

Page 16: Math::Category

自然変換の実装(2)

✤ 自然変換は nat { }; と定義する

✤ どの関手間の対応かは、定義する人が意識する

✤ 自然性を満たすかは、定義した人の責任

✤ 引数(恒等射)のチェックは、定義する人が実装するかどうかによる

✤ 一般的には難しい

Page 17: Math::Category

自然変換の実装(3)

✤ 結合の定義

✤ $nat2 . $nat1 自然変換同士の垂直結合

✤ $funct . $nat 関手と自然変換の水平結合

✤ $nat . $funct 自然変換と関手の水平結合

Page 18: Math::Category

✤ 関手圏の実装

✤ functor_morph nat { my $id = shift; ... 略 ... return $sum_morph};

✤ sourceやtargetは、各コンポーネントのsourceやtargetを集めたもの

圏の例(4): FunctorMorphism

G

F

τ

Page 19: Math::Category

関手の例(2): $YONEDA_EMBEDDING

✤ 米田埋込の定義

✤ C^op から 関手圏 Sets^C への関手

✤ 自然変換 Hom(g, -) を返せばいいらしいので、盲目的に定義

Page 20: Math::Category

米田埋込の利用: CPS変換(1)

✤ 例えば、 uc を CPS変換

my $shout = uc "Sheaf, Category, and Topos";print qq("$shout!"\n);

cps_uc sub { print qq("$_[0]!"\n); }, "Sheaf, Category, and Topos";

Page 21: Math::Category

米田埋込の利用: CPS変換(2)

my $fun_morph = $YONEDA_EMBEDDING->( op sub_morph { uc shift } );my $cps_uc = $fun_morph->( sub_morph { @_ } );

$cps_uc->( sub_morph { print qq("$_[0]!"\n); })->( "Sheaf, Category, and Topos" );

文字列

文字列

Hom(文字列, -)

Hom(文字列, -)

uc $fun_morph

Hom(文字列, undef)

Hom(文字列, undef)

$cps_uc

print

$cps_uc->(print)

元の双対圏 関手圏 Setsの圏

Page 22: Math::Category

Monadの実装(1)

✤ 自己関手functorと自然変換etaとmuをフィールドに持つオブジェクト

✤ eta: I → T, mu: TT → T の自然変換

✤ モナド則は開発者が遵守する

✤ Haskellと違い、クライスリトリプルではなくほんとのMonad

✤ モナド則も違うよ

Page 23: Math::Category

Monadの実装(2)

✤ モナド則1. 単位元$monad->mu . (funct_nat $monad->functor, $monad->eta)$monad->mu . (nat_funct $monad->eta, $monad->functor)のどちらもT → Tの恒等変換

✤ モナド則2. 結合則$monad->mu . (funct_nat $monad->functor, $monad->mu)$monad->mu . (nat_funct $monad->mu, $monad->functor)が等しい(どちらも TTT → T の自然変換)

Page 24: Math::Category

Monadの例(1): $LIST_MONAD

✤ 多値の関数を許したのでちょっと面倒くさい

✤ 関手の対象関数は、引数集合を、[v1_1, v1_2, v1_3], [v2_1, v2_2], [v3_1, v3_2, v3_3, v3_4]と、引数となりうる多値を複数持つような集合に移すもの。

✤ 射関数はmap、eta は [] で包むだけ、 mu は concat

Page 25: Math::Category

Monadの例(2): $STATE_MONAD

✤ これも多値を許したので面倒

✤ 対象関数は、引数の集合を、sub { my @states = @_; .. 略 .. return ¥@values, ¥@new_states }という形式の1値の値が集まる集合に移す

✤ functor, eta, mu は Haskell のそれと同じ定義 (ソース見るべし)

Page 26: Math::Category

Monadの例(3): Maybeモナド

✤ Maybeモナド。元の値にnothing 値を加えたもの

✤ リファレンス(ポインタ)をとって、null 値を追加することで実装

✤ Listモナドとほとんど同じ実装だなあ・・・

Page 27: Math::Category

圏の例(5): KleisliMorphism

✤ モナド m、射f: a -> m b、恒等射b にて表現

a b c

m b

m m b m m cm m a

m a m cf g

m gμ c

η cη bη a

Page 28: Math::Category

圏の例(5): KleisliMorphism

✤ モナド m、射f: a -> m b、恒等射b にて表現

a b c

m b

m m b m m cm m a

m a m cf g

m gμ c

η cη bη a

Page 29: Math::Category

Kleisli圏の利用例: Maybeモナド(1)

✤ 以下の関数を組み合わせてHTMLから分数を得たいget_number: HTMLから該当箇所を得る(<span>3/10</span>)cut_tag: タグを落とす (3/10)parse_number: 数字を得る (3, 10)div: 数値に直す (0.3)

✤ 右のコードではNG

*parse_rate = ¥&{ (wrap \&div) . (wrap \&parse_number) . (wrap \&cut_tag) . (wrap \&get_number)};

Page 30: Math::Category

Kleisli圏の利用例: Maybeモナド(2)

✤ エラー処理

Page 31: Math::Category

Kleisli圏の利用例: Maybeモナド(2)

✤ エラー処理

sub parse_rate { my $html = shift; my $number_str = get_number($html); if( $number_str ){ my $no_tag = cut_tag( $number_str ); if( $no_tag ){ my ($n1, $n2) = parse_number( $no_tag ); if( $n1 ){ my $ret = div( $n1, $n2 ); if( $ret ){ return $ret; } } } }

return undef;}

Page 32: Math::Category

Kleisli圏の利用例: Maybeモナド(2)

✤ MaybeモナドによるKleisli射だと、そのまま結合できる

Page 33: Math::Category

Kleisli圏の利用例: Maybeモナド(2)

✤ MaybeモナドによるKleisli射だと、そのまま結合できる

sub parse_rate { my $kleisli_morphism = $div . $parse_number . $cut_tag . $get_number; return eval_maybe $kleisli_morphism, @_;};

Page 34: Math::Category

まとめと課題

✤ 当たり前だけど、圏論の概念を実装すれば、理論通りに動く

✤ 課題

✤ 数学概念を持ち込むためにラップしまくってるので遅い

✤ いまいちいい用途が見つからない(笑)

✤ 今は実装を膨らませて、可能性を見ていきたい