『プログラマーのための圏論』第3章 圏のさまざま
『プログラマーのための圏論』第3章「圏のさまざま」を読みます。
この章では、対象と射の選び方を変えながら、さまざまな圏を見ていきます。本の順番に沿って内容を整理しつつ、読んでいて気になった「自由とは何か」「普遍性は何が嬉しいのか」「射が等しいとはどういうことか」といった疑問も、その都度掘り下げます。
# 圏の定義
以降の基準になる圏の定義を正確にしておく。
圏
ただし、合成と恒等射は次の法則を満たすものとする。
- 結合律
- 単位律
「=」って何?
圏論が、すべての圏に共通する新しい等号の意味を定めるわけではない。射は各Hom集合の元なので、圏の定義では集合の元に対する通常の等号が使われている (と解釈する) 。
つまり、その等号が具体的に何を意味するかは、扱っている圏によって異なります。
の射なら、写像として等しいこと - 自由圏の射なら、パスを構成する辺の列が等しいこと
- 前順序集合から作った細い圏なら、同じ始点と終点を持つ射は高々一つなので、始点と終点がそれぞれ等しい2つの射は等しい
さらに遡ると、集合論の背景にある?一階述語論理に行き着く。
(等号つき) 一階述語論理では、
として解釈されます。また、証明体系では反射律や代入原理によって同一性の振る舞いを形式化する。
二階述語論理を使って
のように「すべての性質を共有すること」として「=」を表したくなるが、通常の数学の基礎として二階述語論理を採用すると、妥当な式を機械的に列挙できないことや、ゲーテルの完全性定理が成立しないことなど、別の難しさが出てくるらしい。
可換性を考えられる!
圏論において、可換図式は、異なる経路で射を合成した結果が等しいことを表す。
つまり「図式が可換である」という概念は、射の合成に加えて、その二つの合成結果を比較する「=」から自然に誘導される。
自由圏の普遍性でも、
という等式によって、三角形の二つの経路が同じ写像になることを表している。
同値関係を等号の代わりにできるか
オリジナルの「等しさ」を同値関係
そこで商集合を作り、同値な元を同じ同値類へまとめることで、元同士の
# 3.1 対象がない場合
対象がなければ、合成できない射や恒等射を持たない対象も存在しない。そのため、圏の公理に反する例はなく、対象が0個の場合も圏として認められる。
# 3.2 有向グラフ
有向グラフの頂点を対象、辺を射と考えると、圏に似た図が得られるが、一般にはそのままでは圏にならない。
合成について閉じていないためである。
そこで、辺だけでなくパスを射にする。
有向グラフ
- 対象:
の頂点 - 射:
上の有限長の有向パス - 合成:パスの連結
- 恒等射:各頂点における長さ0の空パス
パスの連結は結合的である。また、空パスを前後に連結しても元のパスは変わらない。したがって、圏の結合律と単位律が成り立つ。
グラフに閉路がある場合、その閉路を何度でもたどれるので、元のグラフが有限でも自由圏の射は無限個になることがある。
自由って何?
ここでいう「自由」は、
元の辺の間に、圏の公理から必要になるもの以外の関係を課さない
という意味らしい。
# 自由圏は普遍性によって特徴づけられるらしいので、その話がしたい!
を、頂点を同じ対象へ、辺を長さ1のパスへ送る自然なグラフ準同型とする。
このとき、任意の圏
に対して、
がただ一つ存在する。(自由圏の普遍性)
圏
ただし、恒等射と射の合成を保存する。
つまり関手とは、圏の「対象・射・合成」という構造を壊さずに、別の圏へ写すものである。
以上の性質が成り立ち、これは自由圏の定義と同値である。
直感的には、グラフの頂点と辺を別の圏でどう解釈するかを決めれば、その解釈はパス全体を扱う関手へ一意に拡張できる、という主張である。
非空なパス
とするしかない。空パスは恒等射へ送る必要がある。そのため、この延長は存在するだけでなく一意になる。
普遍性の嬉しさって?
普遍性の嬉しさは、おおざっぱに次のように整理できそう。
- 対象を具体的な構成ではなく性質によって特徴づけられる
- 構成時の選択に依存しない、同型を除く一意性が得られる
- 生成元のような小さなデータから、目的の射を一意に構成できる
- 一意性を使って、二つの射が等しいことを示せる
- 対象ごとの構成を、射の対応を含む関手へ昇格できる
自由圏の場合、グラフの辺に対する解釈だけを与えれば、任意のパスに対する解釈を一つずつ手作業で定義する必要がない。普遍性が、その拡張の存在と一意性を保証してくれる。
# 3.3 順序
前順序集合
- 対象:
の元 のとき: から への射が一つ存在する のとき: から への射は存在しない
順序の公理は、そのまま圏の公理に対応する。
| 順序の性質 | 圏における対応 |
|---|---|
| 反射律 |
恒等射 |
| 推移律 |
射の合成 |
前順序集合から作った圏では、任意の2対象間の射は高々一つしかない。このような圏を細い圏という。
したがって、
は空集合または単集合である。特に、反射律によって、
は単集合になる。
前順序集合では、
が成り立っても、
半順序集合では、さらに反対称律
を要求する。そのため、両方向に射が存在するなら、二つの対象は同じ対象である。
# 3.4 集合としてのモノイド
モノイドは、集合
の組で、次を満たすものである。
- 結合法則
- 単位元
の存在
群とは異なり、各元に対する逆元の存在は要求しない。
モノイドの例には、次のようなものがある。
- 自然数と加算:単位元は
- 文字列と連結:単位元は空文字列
"" - リストと連結:単位元は空リスト
[]
# Haskellでのモノイド
現在のHaskellでは、Monoid はSemigroupを前提にして定義されている。
class Semigroup m => Monoid m where
mempty :: m
Semigroup側の (<>) が結合的な二項演算、mempty が単位元に対応する。
文字列を例にした古い形式の定義は、次のようなイメージである。
instance Monoid String where
mempty = ""
mappend = (++)
ただし、型クラスの定義そのものは、演算が本当に結合律や単位律を満たすことまでは表現しない。それらの法則を守るのは、インスタンスを実装するプログラマの責任である。
結合律も単位律も保証してくれてもいいのに...
そういえばHaskellって二項演算の記号がめちゃ多いイメージある。
(<>):半群の結合演算(++):リストの連結(+):加算(==):等値比較(.):関数合成($):関数適用(<$>):関手のfmap(<*>):Applicativeの適用(>>=):Monadのbind
# C++でのモノイド
C++では、Conceptsを使って、モノイド "らしい" インターフェースを次のように表現できる。
template<typename T>
struct mempty;
template<typename T>
T mappend(T, T) = delete;
template<typename M>
concept Monoid = requires (M m) {
{ mempty<M>::value() } -> std::same_as<M>;
{ mappend(m, m) } -> std::same_as<M>;
};
文字列に対しては、例えば次の実装を与える。
template<>
struct mempty<std::string> {
static std::string value() { return ""; }
};
template<>
std::string mappend(std::string s1, std::string s2) {
return s1 + s2;
}
これも「適切な型の単位元と二項演算が存在する」ことは確認できるが、結合法則と単位律までは保証しない。
Haskellでは、次の二つの書き方を考えられる。
mappend = (++)
mappend s1 s2 = (++) s1 s2
プログラムとしては同じ結果になるが、数学的には別の解釈ができると言っている。
- 前者:二つの関数、つまり
の射そのものが等しい - 後者:すべての引数に対して同じ結果を返すという、外延的な等しさを示している
(冒頭の「=」とは...?につながる)
# 3.5 圏としてのモノイド
ただ一つの対象
という自己射である。
この自己射全体を集合
逆に、任意のモノイドから、ただ一つの対象を持つ圏を作れる。
| 集合としてのモノイド | 一対象圏 |
|---|---|
| 元 |
射 |
| 二項演算 | 射の合成 |
| 単位元 | 恒等射 |
| 結合法則 | 合成の結合律 |
なぜモノイドの話を?
モノイドをわざわざ一対象圏として捉えることに、どのような利点があるのか。
白状すると、現時点では私にはわからなかった。
ので、お茶を濁すために周辺の話を2つほど。
- モノイド準同型は、一対象圏同士の関手として扱える
モノイド準同型
準同型が積と単位元を保つという条件は、関手が射の合成と恒等射を保つという条件にそのまま対応する。逆に、一対象圏同士の関手からはモノイド準同型が得られる。
- モノイド作用は、一対象圏としてのモノイド
から集合の圏 への関手として扱える
この関手は、唯一の対象
は、
モノイド作用
# 3.6 課題
# 1. 以下から自由圏を生成せよ。
- 一つの頂点を持ち、辺のないグラフ

- 1つのノードと1つの(有向)辺を持つグラフ(ヒント:この辺は自身と合成できる)

- 2つのノードと、それらの間の(有向)辺を1つ持つグラフ

- 1つのノードと、アルファベットa, b, c … zでマークされた26個の(有向)辺を持つグラフ

厳密には、
- アルファベットを
とする - ここで
とし、空語 が恒等射 に対応する
- ここで
- 射
の合成はパスの連結、すなわち語の連結である。 - 先に
、続いて をたどるとき、 と定める - この合成は結合的であり、
- 空語
は当然 を満たすため、
- 先に
は自由モノイド を一対象圏とみなしたものに等しい
# 2. 以下はどんな順序だろうか?
- 複数の集合を要素とする集合と、その上の包含関係。なお、AがBに包含されるとは、Aの全要素がBの要素でもあることを指す。
- C++の型の集合とその上の部分型関係。なお、
T1がT2の部分型であるとは、T2へのポインターを期待する関数にT1をコンパイルエラーを発生させずに渡せることを指す。- 半順序?
- 追いきれていないが、あり得る場合とその組み合わせを網羅的に見ればよさそう
- 半順序?
# 3. Boolが2つの値TrueとFalseの集合であることを踏まえて、それが2つの演算子&& (AND) と|| (OR) のそれぞれについて(集合論的)モノイドをなすことを示せ。
いいよ。
# 4. AND演算子を伴うBoolモノイドを圏として表せ。射と合成の規則を列挙せよ。

# 5. モジュロ3加算をモノイドの圏として表せ。

# まとめ
この章に登場した圏を並べると、次のようになる。
| 圏 | 対象 | 射 | 合成 | 恒等射 |
|---|---|---|---|---|
| 空圏 | なし | なし | — | — |
| 自由圏 | グラフの頂点 | 有向パス | パスの連結 | 空パス |
| 前順序の圏 | 集合の元 | 推移律 | 反射律 | |
| モノイドの圏 | ただ一つの対象 | モノイドの元 | 二項演算 | 単位元 |
圏の定義そのものは、対象・射・合成・恒等射と二つの法則だけである。しかし具体例を追っていくと、有向グラフ、順序、モノイドを同じ言葉で捉えられるだけでなく、自由な構成、普遍性、等号の意味にまで疑問が広がった。
第3章は「圏にはいろいろな具体例がある」という紹介であると同時に、圏論が異なる構造の共通部分をどのように取り出すのかを見せる章だったように思う。