圏に圏を対応させる関数や関手にも、その入力と出力があります。であるなら、通常の関数同様にプロファイル(入出力の仕様)を書けます。幾つかの具体例に対して、実際のプロファイルを書いてみましょう。明示的にプロファイルを書くことは、オーバーロードの弊害を軽減させる効果があります。$`\newcommand{\cat}[1]{\mathcal{#1}}
\newcommand{\mrm}[1]{\mathrm{#1}}
\newcommand{\mbf}[1]{\mathbf{#1}}
%\newcommand{\msc}[1]{\mathscr{#1}}
%\newcommand{\id}{\mathrm{id}}
%\newcommand{\op}{\mathrm{op}}
\newcommand{\In}{\text{ in }}
%\newcommand{\Imp}{\Longrightarrow} % for meta prop
\newcommand{\hyp}{ \text{-} }
%\newcommand{\twoto}{\Rightarrow }
%
%
\newcommand{\T}[1]{\text{#1} }
`$
内容:
- 大規模関数と関手
- モノ射達の集合/圏を作る関数 Mono
- 部分圏達の集合を作る関数 Subcat
- アロー圏を作る関数 Arr
- アロー圏を作る関手 Arr
- 可換四角形達の圏を作る3引数の関数 CSq
- おわりに
大規模関数と関手
大規模関数〈large-scale function〉は、大きい関数〈large function〉と同義語です。つまり、域または余域(両方かも知れない)が小さくないかも知れない関数です。
例えば、$`F`$ が $`\mbf{Set}\to \mbf{Set}`$ という関手のとき、その対象パート〈object part〉は次のような大規模関数です。
$`\quad F_\mrm{obj} : |\mbf{Set}| \to |\mbf{Set}| \In \mbf{SET}`$
関手は、関数の組み合わせとして表現できます。ここでは、対象パートとホムパート〈hom part〉の組み合わせで表現することにします。大きい圏のあいだの関手の対象パート/ホムパートは大規模関数〈大きい関数〉になります。
大規模関数といえども関数なので、そのプロファイル宣言は通常の関数〈小さい関数〉と同じです。例えば:
$`\quad f:A \to B \In \mbf{SET}`$
この記事では、上記のような単純なケースだけではなくて、もっと複雑なケースまで扱います。それは:
- 関数の引数が複数ある。
- 関数の引数の型が、それより前の引数達に依存する。
- 関数の戻り値の型が引数達に依存する。
- 省略可能な引数がある。
モノ射達の集合/圏を作る関数 Mono
$`\cat{C}`$ が圏のとき、$`\cat{C}`$ のモノ射〈monomorphism | monic morphism〉の全体を $`\mrm{Mono}(\cat{C})`$ と書くことにします。'$`\mrm{Mono}(\cat{C})`$' という書き方で、'$`\mrm{Mono}`$' は関数記号〈関数名〉で、'$`\cat{C}`$' が引数です。ということは、1引数〈1変数〉の関数 $`\mrm{Mono}`$ が存在します。そのプロファイル宣言は:
$`\quad \mrm{Mono}: |\mbf{Cat}| \to |\mbf{Set}| \In \mbf{SET}`$
これは、引数として小さい圏だけを考える場合です。$`\mrm{Mono}(\mbf{Set})`$ なども考えるなら、もっと大規模な関数になります。
$`\quad \mrm{Mono}: |\mbf{CAT}| \to |\mbf{SET}| \In \mathbb{SET}`$
念の為、$`\mrm{Mono}`$ の定義を書いておくと:
$`\text{For }\cat{C} \in |\mbf{CAT}|\\
\quad \mrm{Mono}(\cat{C}) := \{f\in \mrm{Mor}(\cat{C})\mid f \text{ is monic} \}
`$
さて、関数のプロファイル宣言の構文を少し変えて、次のように書くことにします。
$`\T{function }\mrm{Mono}: (\cat{C}\in |\mbf{CAT}|) \to |\mbf{SET}| \T{ end}`$
変更点は:
- 関数のプロファイル宣言であることを強調するために、先頭にキーワード $`\T{function}`$ を置く。
- プロファイル宣言の末尾〈終端〉にキーワード $`\T{end}`$ を置く。ただし、終端が明らかなら $`\T{end}`$ は省略してよい。
- 引き数変数〈仮引数名〉を付ける。これは、依存性の記述に必要だから。依存性がないときは引き数変数は不要だが、今回は構文〈書式〉の統一性から(不要でも)付けておく。(面倒なので、省略可能なほうが良さそうだけど。)
- 引数変数と引数の型を囲む丸括弧は必須。括弧の種類で省略可能性(後述)を示すので。
- 当該の関数が所属する圏($`\mbf{Set}`$ 、$`\mbf{SET}`$ 、$`\mathbb{SET}`$ など)は明示しない。できるだけ、所属する集合圏(のサイズ)に依存しない汎用的〈多相的〉なプロファイルを書く。
新しい宣言構文で、もうひとつ別な関数を宣言してみます。
$`\T{function }\mrm{Mono}: (\cat{C}\in |\mbf{CAT}|) \to |\mbf{CAT}| \T{ end}`$
別な関数ですが名前は同じです。つまり、オーバーロードしています。“名前も同じでプロファイルも同じだが別な関数”はさすがに困りますが、二番目に定義した $`\mrm{Mono}`$ のプロファイルは最初に定義した $`\mrm{Mono}`$ のプロファイルと違います。二番目の $`\mrm{Mono}`$ は、単なる集合ではなくて圏を返します。
二番目の $`\mrm{Mono}`$ の値〈戻り値〉である圏は次のように定義されます。
- $`|\mrm{Mono}(\cat{C})| := |\cat{C}|`$
- $`\mrm{Mor}(\mrm{Mono}(\cat{C}) ) := \mrm{Mono}(\cat{C})`$
- (以下省略)
上記箇条書き2番目の定義は、字面だけみると循環論法ですが、'$`:=`$' の右に出現する $`\mrm{Mono}(\cat{C})`$ は、最初の定義による $`\mrm{Mono}(\cat{C})`$ なので、モノ射達の集合です。
オーバーロードは諸悪の根源ですが、「避けることができない」「使わざるをえない」という意味で必要悪です。暗黙にオーバーロードされるよりは、明示的に宣言されたオーバーロードのほうがずっとマシです。オーバーロードを使うときは、明示的に宣言しましょう。そうすれば、弊害が軽減されます。
部分圏達の集合を作る関数 Subcat
圏 $`\cat{C}`$ に対して、その部分圏〈subcategory〉の全体を $`\mrm{Subcat}(\cat{C})`$ と書くことにします。もうわかりますね、$`\mrm{Subcat}`$ は関数です。引数を小さい圏に限るなら、関数 $`\mrm{Subcat}`$ のプロファイルは次のように宣言できます。
$`\T{function }\mrm{Subcat} : (\cat{C}\in |\mbf{Cat}|) \to |\mbf{Set}| \T{ end}`$
しかし、$`\mrm{Subcat}(C)`$ は単なる集合ではなくて、要素が圏である集合です。ベキ集合 $`\mrm{Pow}(\hyp)`$ を使って次のように書けないでしょうか。
$`\T{function }\mrm{Subcat} : (\cat{C}\in |\mbf{Cat}|) \to \mrm{Pow}(|\mbf{Cat}|) \T{ end}`$
ウーム、だいぶあやしい/あやうい。$`|\mbf{Cat}|`$ は大きい集合〈真のクラス〉なので、そのベキ集合を取ることは通常禁止されています。階層化されたグロタンディーク宇宙達を使って合理化〈正当化〉できなくもないですが、サイズを縮めたい。以下にサイズ縮小法を書きますが、サイズ問題が気にならないなら無視してください*1。
小さい部分集合だけからなるベキ集合(むしろベキクラス)を $`\mrm{SmallPow}(\hyp)`$ とします。無条件の $`\mrm{Pow}(\hyp)`$ よりは $`\mrm{SmallPow}(\hyp)`$ のほうが不安感は少ないのでコッチを使います。
$`\T{function }\mrm{Subcat} : (\cat{C}\in |\mbf{Cat}|) \to \mrm{SmallPow}(|\mbf{Cat}|) \T{ end}`$
$`\mrm{SmallPow}`$ の small は、背後にある宇宙と集合圏に相対的な“小ささ”だと解釈すれば、次のような書き方も許容されます。
$`\T{function }\mrm{Subcat} : (\cat{C}\in |\mbf{CAT}|) \to \mrm{SmallPow}(|\mbf{CAT}|) \T{ end}`$
前節の $`\mrm{Mono}`$ に関して次のことが言えます。
$`\T{For }\cat{C} \in |\mbf{CAT}|\\
\quad \mrm{Mono}(\cat{C}) \in \mrm{Subcat}(\cat{C})\\
\quad \mrm{Subcat}(\cat{C}) \in \mrm{SmallPow}(|\mbf{CAT}|)
`$
なんか別な工夫(今は思いつかない)で、$`\mrm{Subcat}(\hyp)`$ を“安全に”使える関数として定義できるかも知れません。とりあえず今は、「使っても大丈夫だろう」と楽観的に考えておきます。
アロー圏を作る関数 Arr
圏 $`\cat{C}`$ のアロー圏(「アロー圏 = バンドルの圏」参照)を $`\mrm{Arr}(\cat{C})`$ と書きます。$`\mrm{Arr}`$ は関数です。圏を引数に受け取って、圏を返します。このことは、次のように書けます。
$`\T{function } \mrm{Arr} : (\cat{C}\in |\mrm{Cat}|) \to |\mrm{Cat}| \T{ end}`$
アロー圏とバンドル達の圏と可換四角形達の圏は同じです。この事実は次のように書けます。
$`\quad \mrm{Arr} = \mrm{Bun} = \mrm{CSq}`$
もちろんここで、
- $`\mrm{Arr}(\cat{C})`$ は、“$`\cat{C}`$ のアロー圏”
- $`\mrm{Bun}(\cat{C})`$ は、“$`\cat{C}`$ のバンドル達の圏”
- $`\mrm{CSq}(\cat{C})`$ は、“$`\cat{C}`$ の可換四角形達の圏”
複数の名前が同じひとつの概念を指しています。ひとつの名前が複数の概念を指すのがオーバーロードでしたから、いわば逆オーバーロード現象が起きています。
アロー圏を作る関手 Arr
アロー圏を構成する関数を関手に拡張することも出来ます。そのときは、プロファイル宣言は次のように記述します。名前は前節の関数と同じです(オーバーロードしてます)。
$`\T{functor }\mrm{Arr} : {_1 \mbf{Cat}} \to {_1 \mbf{Cat}} \T{ end}`$
先頭の $`\T{functor}`$ により、単なる関数ではなくて関手であることを明示します。関手に引数変数を付けるのは(特別な約束をしないと)困難なので、引数変数は付けてません。$`{_1 \mbf{Cat}}`$ は、“圏達の2-圏”ではなくて“圏達の1-圏”であることを示しています。
関手は関数の組み合わせで表現できるので、関数達にブレークダウンしたプロファイル宣言が書けます。次のように書くことにします。
$`\T{functor }\mrm{Arr} \T{ consists-of} \\
\quad \T{function }\mrm{Arr}_\mrm{obj} : (\cat{C}\in |{_1 \mbf{Cat}}|)
\to |{_1 \mbf{Cat}}| \T{ end}\\
\T{and}\\
\quad \T{function }\mrm{Arr}_\mrm{hom} : (\cat{C}\in |{_1 \mbf{Cat}}|), (\cat{D}\in |{_1 \mbf{Cat}}|) \\
\quad \to \mrm{Map}(
{_1 \mbf{Cat}}(\cat{C}, \cat{D}) , \;
{_1 \mbf{Cat}}(\mrm{Arr}_\mrm{obj}(\cat{C}), \mrm{Arr}_\mrm{obj}(\cat{D}) )
) \\
\quad \T{ end}\\
\T{end}
`$
このプロファイルを分析してみましょう。
関手 $`\mrm{Arr}`$ は2つの関数 $`\mrm{Arr}_\mrm{obj}`$ と $`\mrm{Arr}_\mrm{hom}`$ に分解されます。関数 $`\mrm{Arr}_\mrm{obj}`$ は前節の関数 $`\mrm{Arr}`$ と同じ関数です。
関数 $`\mrm{Arr}_\mrm{hom}`$ に2つの引数 $`\cat{C}`$ と $`\cat{D}`$ を渡すと、その値は次のようです。
$`\quad \mrm{Arr}_\mrm{hom}(\cat{C}, \cat{D}) \in
\mrm{Map}(
{_1 \mbf{Cat}}(\cat{C}, \cat{D}) , \;
{_1 \mbf{Cat}}(\mrm{Arr}_\mrm{obj}(\cat{C}), \mrm{Arr}_\mrm{obj}(\cat{D}) )
)
`$
値 $`\mrm{Arr}_\mrm{hom}(\cat{C}, \cat{D})`$ が関数なので、そのプロファイルを書けます。
$`\T{function }\mrm{Arr}_\mrm{hom}(\cat{C}, \cat{D}) :
(F \in {_1 \mbf{Cat}}(\cat{C}, \cat{D}) ) \to
{_1 \mbf{Cat}}(\mrm{Arr}_\mrm{obj}(\cat{C}), \mrm{Arr}_\mrm{obj}(\cat{D}) )
`$
関数 $`\mrm{Arr}_\mrm{hom}(\cat{C}, \cat{D})`$ に引数 $`F`$ を渡すと、その値は次のようです。
$`\quad \mrm{Arr}_\mrm{hom}(\cat{C}, \cat{D})(F) \in
{_1 \mbf{Cat}}(\mrm{Arr}_\mrm{obj}(\cat{C}), \mrm{Arr}_\mrm{obj}(\cat{D}) )
`$
値 $`\mrm{Arr}_\mrm{hom}(\cat{C}, \cat{D})(F)`$ が関手なので、そのプロファイルを書けます。
$`\T{functor }\mrm{Arr}_\mrm{hom}(\cat{C}, \cat{D})(F) :
\mrm{Arr}_\mrm{obj}(\cat{C}) \to \mrm{Arr}_\mrm{obj}(\cat{D})
\T{ end}
`$
関手は関数の組み合わせで表現できるので、関数達にブレークダウンしたプロファイル宣言が書けます。記述を多少簡潔にするために、let代入文で一時的名前を導入しています*2。
$`\T{let }\cat{C'} := \mrm{Arr}_\mrm{obj}(\cat{C})\\
\T{let }\cat{D'} := \mrm{Arr}_\mrm{obj}(\cat{D})\\
\T{functor }\mrm{Arr}_\mrm{hom}(\cat{C}, \cat{D})(F) \T{ consists-of} \\
\quad \T{function }{\mrm{Arr}_\mrm{hom}(\cat{C}, \cat{D})(F)}_\mrm{obj} : (f \in |\cat{C'}|)
\to |\cat{D'} |
\T{ end}\\
\T{and}\\
\quad \T{function }{\mrm{Arr}_\mrm{hom}(\cat{C}, \cat{D})(F)}_\mrm{hom} : (f\in |{\cat{C'}}|), (g \in |{\cat{C'}}|) \\
\quad \to
\mrm{Map}(\cat{C'}(f, g), \;
\cat{D'}({\mrm{Arr}_\mrm{hom}(\cat{C}, \cat{D})(F)}_\mrm{obj}(f),
{\mrm{Arr}_\mrm{hom}(\cat{C}, \cat{D})(F)}_\mrm{obj}(g) )
)\\
\quad \T{ end}\\
\T{end}
`$
このようにプロファイル宣言を分解していき、分解結果の末端の関数に具体的な定義を割り当てていきます。関数の定義は形式的でなくても(例えば、自然言語ベースの説明でも)いいですが、宣言は形式的に明示的に書いておいたほうがよいと思います。事情がハッキリするので。
可換四角形達の圏を作る3引数の関数 CSq
圏 $`\cat{C}`$ に対して、そのアロー圏 $`\mrm{Arr}(\cat{C})`$ と、可換四角形達の圏 $`\mrm{CSq}(\cat{C})`$ は同じものです。つまり、$`\mrm{Arr} = \mrm{CSq}`$ 。
可換四角形達の圏という概念を精密化します。圏 $`\cat{C}`$ の部分圏 $`\cat{D},\cat{E}`$ も指定して、次のような可換四角形を考えるのです。
$`\quad \xymatrix{
\cdot \ar[r]^p \ar[d]_f
&\cdot \ar[d]^g
\\
\cdot \ar[r]_q
&\cdot
}\\
\quad \T{commutative }\In \cat{C}\\
\quad \T{where }\\
\quad f, g \in \mrm{Mor}(\cat{D})\\
\quad p, q \in \mrm{Mor}(\cat{E})
`$
関数 $`\mrm{CSq}`$ は3つの引数を持つことになります。そのプロファイル宣言は:
$`\T{function }\mrm{CSq} :
(\cat{C} \in |\mbf{Cat}|),
(\cat{D} \in \mrm{Subcat}(\cat{C}) ),
(\cat{E} \in \mrm{Subcat}(\cat{C}) )\\
\quad \to
|\mbf{Cat}|\\
\T{end}p
`$
例えば、$`\mrm{CSq}(\cat{C}, \cat{C}, \mrm{Mono}(\cat{C}))`$ は正しい関数呼び出しで、戻り値として(上記のレイアウトで)横方向の射がモノ射である可換四角形達の圏が返ります。
省略可能引数を導入しましょう。省略可能引数は波括弧で囲みます。イコール記号の後に、省略時値を書きます。次は、第2、第3引数を省略可能とした $`\mrm{CSq}`$ のプロファイル宣言です。
$`\T{function }\mrm{CSq} : \\
\quad (\cat{C} \in |\mbf{Cat}|),\\
\quad \{\cat{D} \in \mrm{Subcat}(\cat{C}) = \cat{C} \},\\
\quad \{\cat{E} \in \mrm{Subcat}(\cat{C}) = \cat{C} \}\\
\quad \to
|\mbf{Cat}|\\
\T{end}
`$
次のように引数を省略した呼び出しが可能となります。
- $`\mrm{CSq}(\cat{C})`$
- $`\mrm{CSq}(\cat{C}, \mrm{Mono}(\cat{C}) )`$
- $`\mrm{CSq}(\cat{C}, , \mrm{Mono}(\cat{C}) )`$
それぞれ、省略した引数を補うと:
- $`\mrm{CSq}(\cat{C}, \cat{C}, \cat{C})`$
- $`\mrm{CSq}(\cat{C}, \mrm{Mono}(\cat{C}),\cat{C} )`$
- $`\mrm{CSq}(\cat{C}, \cat{C}, \mrm{Mono}(\cat{C}) )`$
省略時の値は、文脈・環境や他の引数値から推論〈計算〉することもあります。場合により、この推論〈計算〉は複雑なものになり得ます。
今回は、$`\mrm{CSq}`$ という名前の3引数関数を定義しました。省略可能引数の働きにより、1引数関数としても使えます。相変わらず $`\mrm{CSq}(\cat{C}) = \mrm{Arr}(\cat{C})`$ は成立します。しかし、名前 $`\mrm{Arr}`$ の3引数関数は定義してないので、呼び出し
$`\quad \mrm{Arr}(\cat{C}, \mrm{Mono}(\cat{C}), \cat{C})`$
は有効ではありません。
おわりに
関数名/関数記号のオーバーロードや省略可能引数を多用すると、関数呼び出し形式が有効〈OK〉か無効〈NG〉か? その関数呼び出し形式が何を意味するのか? などがワケワカラナクなります。暗黙にやられると、たまったものではありません。オーバーロードや省略可能引数は便利なので禁止はしませんが、明示的なプロファイル宣言により導入することをオススメします。明示的な宣言があれば、オーバーロード解決や省略された値の補完のときにヒントになります。
実際に使われる関数のなかには、今回紹介した事例より複雑な関数呼び出し形式を使うものもあります。また、関数呼び出し形式に特殊な構文を使う場合もあります。それらについては、また具体例で紹介する機会があるでしょう。