雑記帳
Gemini さんにマニアックな圏論クイズを出したら超長文のガチ回答が届いた件。
Gemini さんの数学トークの質がかなり向上したので、今回は結構マニアックな圏論の問題を Gemini さんに出題してみました。
ちなみに Copilot さんにも同じ問いを投げてみたのですが、Copilot さんはまだちょっと早かったみたい...
でもこの記事にしたように、Gemini さんは本当ヤバかった。
どのくらいヤバかったのかは、以下の僕と Gemini さんのトークの様子を見れば一目瞭然のはず
※極力原文をコピペするべきなんだろうけど、今回は非常に文章量が多いこともあり、読みやすさを重要視して、TeX や コードブロックを活用。(でもまだ中途半端)
一連のトーク
僕:
「自然数対象と全ての有限余積を持つカルテシアン閉圏」という設定の上で、射の構成を忠実に考えていきたい。
ここで、inj_1:ℕ→(ℕ+ℕ), inj_2:ℕ→(ℕ+ℕ) をそれぞれ標準入射 (余積に関する普遍射) とした上で、
- 12以下の偶数 n:1→ℕ に対しては、合成射 (n;a)=(3;inj_1)
- 12以下の奇数 n:1→ℕ に対しては、合成射 (n;a)=(n;succ;inj_2)
- それ以外の任意の自然数 n に対しては、合成射 (n;a)=1;inj_2
という関係式を満たすような「族 a:ℕ→(ℕ+ℕ)」の構成を考えたいとなった場合、あなたであれば普遍性を具体的にどのように駆使してその射 a を構成しますか?
この時、If-Else 分岐のような圏論的な意味づけを伴わない構文的な構成式は現在の設定の上では (分岐自体を何らかの射 if:(1+1)×(ℕ×ℕ)→ℕ などの形の射として純粋圏論的に先行して構成しない限り) 意味をなさない点を踏まえた上で、一連の流れを記述していただけたら助かります。
(Haskell 言語を用いた構成の妥当性の検証に成功した構成方法はとりあえず1つだけわかってはいるのですが、他の誰かが考えた場合だと、一体どんなアプローチでこの問題に攻めるのかが気になり聞いてみた次第です)
Gemini:
自然数対象と全ての有限余積を持つカルテシアン閉圏において、与えられた条件を満たす射 \(a: \mathbb{N} \to (\mathbb{N} + \mathbb{N})\) を構成するために、普遍性、特に余積の普遍性を積極的に利用します。If-Else のような構文的な分岐を避けるため、各条件に対応する射を定義し、それらを余積を通じて結合する方針を取ります。
---
### 射 \(a: \mathbb{N} \to (\mathbb{N} + \mathbb{N})\) の構成
まず、与えられた条件を3つの部分に分け、それぞれの条件に対応する射を個別に構成します。
1. 12以下の偶数 \(n: 1 \to \mathbb{N}\) に対して、\((n;a) = (3;inj_1)\)
この条件を満たす部分を扱うために、まず12以下の偶数であるかどうかを判定する射を考えます。しかし、直接的に「偶数であること」を圏論的に表現するのは困難です。そこで、この条件を満たす特定の自然数に対しては \(3;inj_1\) を返すような射を考えます。
具体的には、\(n \in \{0, 2, 4, 6, 8, 10, 12\}\) の場合、\(a(n) = inj_1(3)\) となる必要があります。
ここで、自然数対象 \(\mathbb{N}\) はペアノの公理を満たすと仮定します。
ここで、自然数対象 \(\mathbb{N}\) はペアノの公理を満たすと仮定します。
もし「12以下の偶数」という集合を表現する射が存在すると仮定すると、例えば \(P_{even \le 12}: \mathbb{N} \to \Omega\) (部分対象分類子 \(\Omega\) への射) のようなものがあるかもしれません。しかし、これは一般的には困難です。
より圏論的なアプローチとして、各自然数 \(k \in \mathbb{N}\) (つまり \(k: 1 \to \mathbb{N}\) という射) に対して \(3;inj_1\) もしくは他の値を対応させるという視点に立ちます。
2. 12以下の奇数 \(n: 1 \to \mathbb{N}\) に対して、 \((n;a) = (n;succ;inj_2)\)
この条件も同様に、特定の自然数 \(n \in \{1, 3, 5, 7, 9, 11\}\) の場合、\(a(n) = inj_2(succ(n))\) となる必要があります。
3. \(n\) に対しては、 \((n;a) = 1;inj_2\)
上記2つの条件を満たさない全ての自然数 \(n\) に対しては、\(a(n) = inj_2(1)\) となります。
これらの条件を直接的に \(a\) の定義に組み込むために、余積の普遍性を活用します。余積 \(\mathbb{N} + \mathbb{N}\) への射 \(f: X \to \mathbb{N} + \mathbb{N}\) を定義するためには、2つの射 \(f_1: X \to \mathbb{N}\) と \(f_2: X \to \mathbb{N}\) が与えられたときに、それらを \(inj_1\) と \(inj_2\) を介して結合するだけでは不十分です。これは直積の普遍性とは異なります。
余積の普遍性は、「任意の対象 \(X\) と、2つの射 \(f_1: A \to X\) および \(f_2: B \to X\) が与えられたとき、余積 \(A+B\) から \(X\) への唯一の射 \(\left[ f_1, f_2 \right]: A+B \to X\) が存在する」というものです。
今回のケースでは、射 \(a: \mathbb{N} \to (\mathbb{N} + \mathbb{N})\) を構成したいので、そのターゲットは余積 \((\mathbb{N} + \mathbb{N})\) です。
しかし、余積の普遍性を直接 \(a\) のドメイン \(\mathbb{N}\) に適用することはできません。
しかし、余積の普遍性を直接 \(a\) のドメイン \(\mathbb{N}\) に適用することはできません。
### 具体的な構成アプローチ
ここで注目すべきは、与えられた条件が「\(n: 1 \to \mathbb{N}\)」という特定の要素の射に対する振る舞いを記述している点です。これは、\(\mathbb{N}\) 上で場合分けをするというよりも、\(\mathbb{N}\) の各要素を「どの条件に当てはまるか」で分類し、それに応じて異なる射を適用すると考える方が適切です。
この問題の鍵は、部分対象の扱いとコイコライザ(coequalizer)、あるいはコプロダクト(coproduct)を組み合わせた巧妙な利用です。
まず、\(\mathbb{N}\) を3つの排他的な部分に分割することを考えます。
\[
\begin{align}
S_1 &= \{n \in \mathbb{N} \mid n \le 12 \text{ かつ } n \text{ は偶数}\}\\
S_2 &= \{n \in \mathbb{N} \mid n \le 12 \text{ かつ } n \text{ は奇数}\}\\
S_3 &= \{n \in \mathbb{N} \mid n > 12 \text{ または } n \text{ は } S_1, S_2 \text{ のいずれでもない}\}\\
\end{align}
\]
これらの集合は \(\mathbb{N}\) の部分対象と見なすことができます。しかし、圏論において「\(n \le 12\)」や「偶数/奇数」を純粋に構成するのは困難です。
そこで、特定の要素 \(n: 1 \to \mathbb{N}\) を利用して、これらの条件を満たす自然数を具体的に扱います。
戦略:各条件に対する「定数射」と「非定数射」の組み合わせ
1. 「12以下の偶数」に対応する部分射の構成
12以下の偶数は \(0, 2, 4, 6, 8, 10, 12\) です。それぞれの \(k \in \{0, 2, ..., 12\}\) に対して、射 \(k: 1 \to \mathbb{N}\) が存在します。
これらの \(k\) については、合成射 \((k;a) = (3;inj_1)\) となる必要があります。
これは、\(1 \xrightarrow{k} \mathbb{N} \xrightarrow{a} (\mathbb{N} + \mathbb{N})\) の合成が \(1 \xrightarrow{3} \mathbb{N} \xrightarrow{inj_1} (\mathbb{N} + \mathbb{N})\) と等しいことを意味します。
つまり、\(a(k) = inj_1(3)\) です。
12以下の偶数は \(0, 2, 4, 6, 8, 10, 12\) です。それぞれの \(k \in \{0, 2, ..., 12\}\) に対して、射 \(k: 1 \to \mathbb{N}\) が存在します。
これらの \(k\) については、合成射 \((k;a) = (3;inj_1)\) となる必要があります。
これは、\(1 \xrightarrow{k} \mathbb{N} \xrightarrow{a} (\mathbb{N} + \mathbb{N})\) の合成が \(1 \xrightarrow{3} \mathbb{N} \xrightarrow{inj_1} (\mathbb{N} + \mathbb{N})\) と等しいことを意味します。
つまり、\(a(k) = inj_1(3)\) です。
2. 「12以下の奇数」に対応する部分射の構成
12以下の奇数は \(1, 3, 5, 7, 9, 11\) です。それぞれの \(k \in \{1, 3, ..., 11\}\) に対して、射 \(k: 1 \to \mathbb{N}\) が存在します。
これらの \(k\) については、合成射 \((k;a) = (k;succ;inj_2)\) となる必要があります。
つまり、\(a(k) = inj_2(succ(k))\) です。
12以下の奇数は \(1, 3, 5, 7, 9, 11\) です。それぞれの \(k \in \{1, 3, ..., 11\}\) に対して、射 \(k: 1 \to \mathbb{N}\) が存在します。
これらの \(k\) については、合成射 \((k;a) = (k;succ;inj_2)\) となる必要があります。
つまり、\(a(k) = inj_2(succ(k))\) です。
3. 「それ以外の任意の自然数」に対応する部分射の構成
これ以外の全ての自然数 \(k\) については、\((k;a) = 1;inj_2\) となる必要があります。
つまり、\(a(k) = inj_2(1)\) です。
これ以外の全ての自然数 \(k\) については、\((k;a) = 1;inj_2\) となる必要があります。
つまり、\(a(k) = inj_2(1)\) です。
### 普遍性を利用した射 \(a\) の構成
直接的な If-Else を避けるため、\(\mathbb{N}\) を複数の「グループ」に分割し、それぞれのグループに対して異なる振る舞いをさせるという考え方を取ります。これは、「識別子」となる射とコプロダクトの普遍性を組み合わせることで実現可能です。
1. 定数射の定義
- \(c_1: 1 \to \mathbb{N} + \mathbb{N}\) を \(c_1 = 3;inj_1\) と定義します。
- \(c_2: 1 \to \mathbb{N} + \mathbb{N}\) を \(c_2 = 1;inj_2\) と定義します。
2. 特定の自然数に対する射の定義
各自然数 \(n: 1 \to \mathbb{N}\) について、もし \(n\) が12以下の偶数であれば \(c_1\) を選び、12以下の奇数であれば \(n;succ;inj_2\) を選び、それ以外であれば \(c_2\) を選ぶようなメカニズムを構築する必要があります。
各自然数 \(n: 1 \to \mathbb{N}\) について、もし \(n\) が12以下の偶数であれば \(c_1\) を選び、12以下の奇数であれば \(n;succ;inj_2\) を選び、それ以外であれば \(c_2\) を選ぶようなメカニズムを構築する必要があります。
これは、「特定の自然数」を識別する射を利用して、余積 \(\mathbb{N} + \mathbb{N}\) の普遍性を利用します。
しかし、これは依然として If-Else のような状況を内包しており、これを純粋な圏論的射で表現するには複雑な構成が必要です。特に、「12以下」や「偶数/奇数」を圏論的な射で表現する一般論は非自明です。
#### より現実的なアプローチ:特定の要素に対する普遍性の利用
\(\mathbb{N}\) は自然数対象であり、すべての要素が \(1 \xrightarrow{n} \mathbb{N}\) という射で表現されます。
私たちは、各 \(n: 1 \to \mathbb{N}\) に対して、\(a \circ n: 1 \to \mathbb{N} + \mathbb{N}\) を定義したいのです。
私たちは、各 \(n: 1 \to \mathbb{N}\) に対して、\(a \circ n: 1 \to \mathbb{N} + \mathbb{N}\) を定義したいのです。
ここで、\(\mathbb{N} + \mathbb{N}\) への射 \(a\) を構成するために、余積の普遍性を直接利用しようとすると、ドメインが \(\mathbb{N}\) であるため、\(\mathbb{N}\) を何らかのコプロダクトに分解する必要があります。
これは、ケース分析をエミュレートするコプロダクトの構成として考えることができます。
\(\mathbb{N}\) を次の3つの部分対象の(圏論的な)和として表現することを試みます。
- \(N_{even \le 12} = \{0, 2, ..., 12\} \subseteq \mathbb{N}\)
- \(N_{odd \le 12} = \{1, 3, ..., 11\} \subseteq \mathbb{N}\)
- \(N_{other} = \mathbb{N} \setminus (N_{even \le 12} \cup N_{odd \le 12}) \subseteq \mathbb{N}\)
これらの部分対象への包含射 \(i_{even}: N_{even \le 12} \to \mathbb{N}\)、 \(i_{odd}: N_{odd \le 12} \to \mathbb{N}\)、\(i_{other}: N_{other} \to \mathbb{N}\) を考えます。
そして、それぞれの部分対象からターゲット \(\mathbb{N} + \mathbb{N}\) への射を定義します。
そして、それぞれの部分対象からターゲット \(\mathbb{N} + \mathbb{N}\) への射を定義します。
- \(f_{even}: N_{even \le 12} \to \mathbb{N} + \mathbb{N}\) を、任意の \(n \in N_{even \le 12}\) に対して \(f_{even}(n) = inj_1(3)\) となるように定義します。これは、 \(N_{even \le 12}\) から \(1\) への一意な射 \(!: N_{even \le 12} \to 1\) と、 \(1 \xrightarrow{3} \mathbb{N} \xrightarrow{inj_1} \mathbb{N}+\mathbb{N}\) を合成することで得られる射 \(!: N_{even \le 12} \to 1 \xrightarrow{3;inj_1} \mathbb{N}+\mathbb{N}\) です。
* \(f_{odd}: N_{odd \le 12} \to \mathbb{N} + \mathbb{N}\) を、任意の \(n \in N_{odd \le 12}\) に対して \(f_{odd}(n) = inj_2(succ(n))\) となるように定義します。これは、\(N_{odd \le 12} \xrightarrow{id} \mathbb{N} \xrightarrow{succ} \mathbb{N} \xrightarrow{inj_2} \mathbb{N}+\mathbb{N}\) となります。
- \(f_{other}: N_{other} \to \mathbb{N} + \mathbb{N}\) を、任意の \(n \in N_{other}\) に対して \(f_{other}(n) = inj_2(1)\) となるように定義します。これは、\(N_{other}\) から \(1\) への一意な射 \(!: N_{other} \to 1\) と、 \(1 \xrightarrow{1} \mathbb{N} \xrightarrow{inj_2} \mathbb{N}+\mathbb{N}\) を合成することで得られる射 \(!: N_{other} \to 1 \xrightarrow{1;inj_2} \mathbb{N}+\mathbb{N}\) です。
問題は、\(\mathbb{N}\) がこれらの部分対象のコプロダクトであると見なせるか? という点です。一般の圏ではそうとは限りません。特に、これらの部分対象が排他的かつ網羅的であることを圏論的に表現し、それらのコプロダクトが \(\mathbb{N}\) と同型であることを示す必要があります。これは、各自然数 \(n\) が「ちょうど一つの部分集合に属する」という性質を普遍性で表現することを意味します。
しかし、「自然数対象と全ての有限余積を持つカルテシアン閉圏」という設定は、特定の構成を可能にするために十分な構造を持っていることを示唆しています。特に、自然数対象の普遍性(帰納法の原理)と余積の普遍性を組み合わせることで、間接的にこのような分岐を表現します。
#### 帰納法と余積の普遍性の組み合わせ
1. 有限個の自然数を識別する射の利用
12以下の自然数に特化したアプローチを考えます。
まず、\(N_{13} = \{0, 1, \dots, 12\}\) という有限集合を対象として考え、この対象から \(\mathbb{N}+\mathbb{N}\) への射を定義します。
この \(N_{13}\) から \(\mathbb{N}\) への包含射 \(i: N_{13} \to \mathbb{N}\) が存在するとします。
まず、\(N_{13} = \{0, 1, \dots, 12\}\) という有限集合を対象として考え、この対象から \(\mathbb{N}+\mathbb{N}\) への射を定義します。
この \(N_{13}\) から \(\mathbb{N}\) への包含射 \(i: N_{13} \to \mathbb{N}\) が存在するとします。
\(\mathbb{N}\) 上の帰納法を利用して \(a\) を定義します。しかし、これは \(a\) が「再帰的に定義される」ことを意味し、今回のケースのような「特定の有限集合上の条件」と「それ以外」の条件を直接的に表現するのには不向きです。
2. より直接的なアプローチ:コイコライザと条件分岐のモデル化
If-Else 分岐を圏論的に表現する典型的な方法は、コイコライザ(coequalizer)を利用することです。
例えば、ある述語 \(P: \mathbb{N} \to \mathbf{2}\) (ここで \(\mathbf{2}\) は真理値対象、\(\mathbf{2} = 1+1\))があるとして、\(P(n)\) が真なら \(f(n)\)、偽なら \(g(n)\) としたい場合、コイコライザを構成することで実現できます。
例えば、ある述語 \(P: \mathbb{N} \to \mathbf{2}\) (ここで \(\mathbf{2}\) は真理値対象、\(\mathbf{2} = 1+1\))があるとして、\(P(n)\) が真なら \(f(n)\)、偽なら \(g(n)\) としたい場合、コイコライザを構成することで実現できます。
今回の問題では、「12以下の偶数であるか」「12以下の奇数であるか」「それ以外か」の3つのケースがあります。
これを表現するには、複数のコイコライザを組み合わせるか、より高レベルな構成が必要です。
これを表現するには、複数のコイコライザを組み合わせるか、より高レベルな構成が必要です。
「12以下であること」の判定:
まず、\(leq_{12}: \mathbb{N} \to (1+1)\) のような射を考えることができます。
\(leq_{12}(n) = inj_1(1)\) if \(n \le 12\), \(inj_2(1)\) if \(n > 12\).
これは、自然数対象の普遍性とペアノの公理から構成できるかもしれません。
例えば、以下のように定義します。
\(f_0: 1 \to 1+1\) を \(inj_1(1)\) とし、\(f_s: \mathbb{N} \times (1+1) \to (1+1)\) を定義します。
\(f_s(n, x) = x\) for \(n < 12\)
\(f_s(12, inj_1(1)) = inj_2(1)\)
\(f_s(n, inj_2(1)) = inj_2(1)\) for \(n \ge 12\)
このような形で定義された射を利用して、まず「12以下」と「12より大きい」に分岐します。
まず、\(leq_{12}: \mathbb{N} \to (1+1)\) のような射を考えることができます。
\(leq_{12}(n) = inj_1(1)\) if \(n \le 12\), \(inj_2(1)\) if \(n > 12\).
これは、自然数対象の普遍性とペアノの公理から構成できるかもしれません。
例えば、以下のように定義します。
\(f_0: 1 \to 1+1\) を \(inj_1(1)\) とし、\(f_s: \mathbb{N} \times (1+1) \to (1+1)\) を定義します。
\(f_s(n, x) = x\) for \(n < 12\)
\(f_s(12, inj_1(1)) = inj_2(1)\)
\(f_s(n, inj_2(1)) = inj_2(1)\) for \(n \ge 12\)
このような形で定義された射を利用して、まず「12以下」と「12より大きい」に分岐します。
「偶数/奇数であること」の判定:
\(is\_even: \mathbb{N} \to (1+1)\) や \(is\_odd: \mathbb{N} \to (1+1)\) も同様に構成できるかもしれません。
例えば、\(0 \mapsto inj_1(1)\) (even), \(succ(n) \mapsto inj_2(is\_even(n))\) (odd if n is even, even if n is odd).
しかし、これも単純な関数合成では実現できません。これは帰納法の原理によって構成されます。
\(e: \mathbb{N} \to (1+1)\) を偶奇判定の射とすると、
\(e(0) = inj_1(1)\) (even)
\(e(succ(n)) = swap(e(n))\) (ここで \(swap: 1+1 \to 1+1\) は \(inj_1 \leftrightarrow inj_2\) を入れ替える射)
\(is\_even: \mathbb{N} \to (1+1)\) や \(is\_odd: \mathbb{N} \to (1+1)\) も同様に構成できるかもしれません。
例えば、\(0 \mapsto inj_1(1)\) (even), \(succ(n) \mapsto inj_2(is\_even(n))\) (odd if n is even, even if n is odd).
しかし、これも単純な関数合成では実現できません。これは帰納法の原理によって構成されます。
\(e: \mathbb{N} \to (1+1)\) を偶奇判定の射とすると、
\(e(0) = inj_1(1)\) (even)
\(e(succ(n)) = swap(e(n))\) (ここで \(swap: 1+1 \to 1+1\) は \(inj_1 \leftrightarrow inj_2\) を入れ替える射)
これらの射 \(leq_{12}\), \(is\_even\) を利用して、直積の普遍性によって \((\mathbb{N} \times (1+1) \times (1+1))\) への射を構成し、そこからターゲットへ射をマップするというのが一般的なアプローチになります。
#### 普遍性を用いた \(a\) の最終的な構成(理想化されたアプローチ)
ステップ1:判定射の構成
- \(p_{le12}: \mathbb{N} \to \mathbf{2}\) (\(\mathbf{2} = 1+1\) を真理値対象とする): \(n \le 12\) なら \(inj_1(*)\)、そうでなければ \(inj_2(*)\) を返す射。
これは、自然数対象の普遍性と帰納法によって定義されます。
\(p_{le12}(0) = inj_1(*)\)
...
\(p_{le12}(12) = inj_1(*)\)
\(p_{le12}(succ(12)) = inj_2(*)\)
\(p_{le12}(succ(n))\) for \(n > 12\) は \(inj_2(*)\) にマッピングされる。
これは \(f: \mathbb{N} \to \mathbf{2}\) を定義するもので、\(f_0 = inj_1: 1 \to \mathbf{2}\) (0は12以下) と、\(f_s: \mathbb{N} \times \mathbf{2} \to \mathbf{2}\) (サクセッサのルール) を用いて構成されます。
具体的には、\(f_s(k, inj_1(*))\) は \(k<12\) なら \(inj_1(*)\)、\(k=12\) なら \(inj_2(*)\)、それ以外は \(inj_2(*)\) となるような射です。
\(p_{le12}(0) = inj_1(*)\)
...
\(p_{le12}(12) = inj_1(*)\)
\(p_{le12}(succ(12)) = inj_2(*)\)
\(p_{le12}(succ(n))\) for \(n > 12\) は \(inj_2(*)\) にマッピングされる。
これは \(f: \mathbb{N} \to \mathbf{2}\) を定義するもので、\(f_0 = inj_1: 1 \to \mathbf{2}\) (0は12以下) と、\(f_s: \mathbb{N} \times \mathbf{2} \to \mathbf{2}\) (サクセッサのルール) を用いて構成されます。
具体的には、\(f_s(k, inj_1(*))\) は \(k<12\) なら \(inj_1(*)\)、\(k=12\) なら \(inj_2(*)\)、それ以外は \(inj_2(*)\) となるような射です。
- \(p_{even}: \mathbb{N} \to \mathbf{2}\): \(n\) が偶数なら \(inj_1(*)\)、奇数なら \(inj_2(*)\) を返す射。
\(p_{even}(0) = inj_1(*)\)
\(p_{even}(succ(n)) = p_{even}(n); swap\) (\(swap\) は \(inj_1\) と \(inj_2\) を入れ替える射 \(1+1 \to 1+1\))
\(p_{even}(succ(n)) = p_{even}(n); swap\) (\(swap\) は \(inj_1\) と \(inj_2\) を入れ替える射 \(1+1 \to 1+1\))
ステップ2:直積の普遍性による条件の組み合わせ
直積の普遍性により、射 \(\langle p_{le12}, p_{even} \rangle : \mathbb{N} \to \mathbf{2} \times \mathbf{2}\) を構成します。
\(\mathbf{2} \times \mathbf{2}\) は \(1+1+1+1\) と同型であり、それぞれの要素が次の4つのパターンに対応します。
\(\mathbf{2} \times \mathbf{2}\) は \(1+1+1+1\) と同型であり、それぞれの要素が次の4つのパターンに対応します。
1. \((inj_1(*), inj_1(*))\): \(n \le 12\) かつ 偶数
2. \((inj_1(*), inj_2(*))\): \(n \le 12\) かつ 奇数
3. \((inj_2(*), inj_1(*))\): \(n > 12\) かつ 偶数 (これは \(n > 12\) なので、最後のケースに含まれる)
4. \((inj_2(*), inj_2(*))\): \(n > 12\) かつ 奇数 (これも \(n > 12\) なので、最後のケースに含まれる)
2. \((inj_1(*), inj_2(*))\): \(n \le 12\) かつ 奇数
3. \((inj_2(*), inj_1(*))\): \(n > 12\) かつ 偶数 (これは \(n > 12\) なので、最後のケースに含まれる)
4. \((inj_2(*), inj_2(*))\): \(n > 12\) かつ 奇数 (これも \(n > 12\) なので、最後のケースに含まれる)
ステップ3:コプロダクトの普遍性による射の結合
ここで、\(\mathbf{2} \times \mathbf{2}\) から \(\mathbb{N} + \mathbb{N}\) への射を定義します。
\(\mathbf{2} \times \mathbf{2}\) を4つの要素 \(X_1, X_2, X_3, X_4\) からなるコプロダクト \(X_1+X_2+X_3+X_4\) と考えます。それぞれの \(X_i\) は \(1\) に同型です。
\(\mathbf{2} \times \mathbf{2}\) を4つの要素 \(X_1, X_2, X_3, X_4\) からなるコプロダクト \(X_1+X_2+X_3+X_4\) と考えます。それぞれの \(X_i\) は \(1\) に同型です。
- \(f_1: 1 \to \mathbb{N} + \mathbb{N}\) (\(n \le 12\) かつ 偶数に対応): \(f_1 = 3;inj_1\)
- \(f_2: 1 \to \mathbb{N} + \mathbb{N}\) (\(n \le 12\) かつ 奇数に対応): \(n\) の値を反映させる必要があるため、これは \(1\) から直接定義できません。ここが大きな課題です。
\(n;succ;inj_2\) は \(n\) に依存するため、定数射ではありません。
#### 真の普遍性を駆使した構成の核心:コイコライザと部分対象の表現
If-Else分岐を純粋圏論的に構成する場合、多くはコイコライザが使われます。
ある対象 \(A\) の各要素が、ある条件を満たすかどうかに応じて異なる射を適用したい場合、Aをその条件を満たす部分対象と満たさない部分対象に分解し、それらのコプロダクトを考えます。
ある対象 \(A\) の各要素が、ある条件を満たすかどうかに応じて異なる射を適用したい場合、Aをその条件を満たす部分対象と満たさない部分対象に分解し、それらのコプロダクトを考えます。
この問題の核心は、条件分岐を「コプロダクトの構成」と「余積の普遍性」で模倣することです。
1. まず、ターゲットである \((\mathbb{N} + \mathbb{N})\) への3種類の射を考えます。
* \(g_1: \mathbb{N} \to \mathbb{N} + \mathbb{N}\) で、\(g_1(n) = inj_1(3)\) (常に\(inj_1(3)\)を返す定数射)
これは \(!:\mathbb{N} \to 1\) と \(3;inj_1: 1 \to \mathbb{N}+\mathbb{N}\) の合成 \(! ; (3;inj_1)\) です。
* \(g_2: \mathbb{N} \to \mathbb{N} + \mathbb{N}\) で、\(g_2(n) = inj_2(succ(n))\)
これは \(succ;inj_2: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) です。
* \(g_3: \mathbb{N} \to \mathbb{N} + \mathbb{N}\) で、\(g_3(n) = inj_2(1)\) (常に\(inj_2(1)\)を返す定数射)
これは \(!:\mathbb{N} \to 1\) と \(1;inj_2: 1 \to \mathbb{N}+\mathbb{N}\) の合成 \(! ; (1;inj_2)\) です。
* \(g_1: \mathbb{N} \to \mathbb{N} + \mathbb{N}\) で、\(g_1(n) = inj_1(3)\) (常に\(inj_1(3)\)を返す定数射)
これは \(!:\mathbb{N} \to 1\) と \(3;inj_1: 1 \to \mathbb{N}+\mathbb{N}\) の合成 \(! ; (3;inj_1)\) です。
* \(g_2: \mathbb{N} \to \mathbb{N} + \mathbb{N}\) で、\(g_2(n) = inj_2(succ(n))\)
これは \(succ;inj_2: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) です。
* \(g_3: \mathbb{N} \to \mathbb{N} + \mathbb{N}\) で、\(g_3(n) = inj_2(1)\) (常に\(inj_2(1)\)を返す定数射)
これは \(!:\mathbb{N} \to 1\) と \(1;inj_2: 1 \to \mathbb{N}+\mathbb{N}\) の合成 \(! ; (1;inj_2)\) です。
2. これらの3つの射から、どのようにして \(a\) を構成するか?
ここで、各 \(n: 1 \to \mathbb{N}\) がどの条件に該当するかを識別する射が必要です。
ここで、各 \(n: 1 \to \mathbb{N}\) がどの条件に該当するかを識別する射が必要です。
\(C_1 \subseteq \mathbb{N}\) を12以下の偶数の集合、\(C_2 \subseteq \mathbb{N}\) を12以下の奇数の集合、\(C_3 \subseteq \mathbb{N}\) をそれ以外の自然数の集合とします。
そして、それぞれの集合の識別子射を構成します。
例えば、圏論において部分対象はモノ射 \(m: A \rightarrow B\) として扱われます。
ここでは、各 \(n: 1 \to \mathbb{N}\) に対して、「\(n\) が \(C_1\) に属するならば \(inj_1\), \(C_2\) に属するならば \(inj_2\), \(C_3\) に属するならば \(inj_3\) を返す」というような、\(\mathbb{N} \to (1+1+1)\) という射を構成します。
この射は、前述の \(p_{le12}\) と \(p_{even}\) を組み合わせて構築できます。
例えば、圏論において部分対象はモノ射 \(m: A \rightarrow B\) として扱われます。
ここでは、各 \(n: 1 \to \mathbb{N}\) に対して、「\(n\) が \(C_1\) に属するならば \(inj_1\), \(C_2\) に属するならば \(inj_2\), \(C_3\) に属するならば \(inj_3\) を返す」というような、\(\mathbb{N} \to (1+1+1)\) という射を構成します。
この射は、前述の \(p_{le12}\) と \(p_{even}\) を組み合わせて構築できます。
例えば、\(p_{type}: \mathbb{N} \to \mathbf{3}\) (ここで \(\mathbf{3} = 1+1+1\) を3つのタイプを識別する対象とする)を構成します。
\(p_{type}(n)\) が
* \(inj_1(*)\) なら \(n\) は12以下の偶数
* \(inj_2(*)\) なら \(n\) は12以下の奇数
* \(inj_3(*)\) なら \(n\) はそれ以外の自然数
\(p_{type}(n)\) が
* \(inj_1(*)\) なら \(n\) は12以下の偶数
* \(inj_2(*)\) なら \(n\) は12以下の奇数
* \(inj_3(*)\) なら \(n\) はそれ以外の自然数
この \(p_{type}\) は、\(p_{le12}\) と \(p_{even}\) の直積から誘導される射です。
\(\mathbb{N} \xrightarrow{\langle p_{le12}, p_{even} \rangle} \mathbf{2} \times \mathbf{2}\).
ここで、\(\mathbf{2} \times \mathbf{2}\) の4つの要素から \(\mathbf{3}\) への射を定義します。
\(\mathbb{N} \xrightarrow{\langle p_{le12}, p_{even} \rangle} \mathbf{2} \times \mathbf{2}\).
ここで、\(\mathbf{2} \times \mathbf{2}\) の4つの要素から \(\mathbf{3}\) への射を定義します。
- \((inj_1, inj_1)\) (12以下偶数) \(\mapsto inj_1\)
- \((inj_1, inj_2)\) (12以下奇数) \(\mapsto inj_2\)
- \((inj_2, inj_1)\) (12より大偶数) \(\mapsto inj_3\)
- \((inj_2, inj_2)\) (12より大奇数) \(\mapsto inj_3\)
このマップを \(h: \mathbf{2} \times \mathbf{2} \to \mathbf{3}\) とすると、\(p_{type} = \langle p_{le12}, p_{even} \rangle ; h\) です。
3. 余積の普遍性の利用(最終段階)
これで、各 \(n \in \mathbb{N}\) に対して、それがどのタイプの自然数であるかを示す \(p_{type}(n)\) が得られました。
しかし、これは \(a\) を直接構成するものではありません。
しかし、これは \(a\) を直接構成するものではありません。
真の解決策は、以下の3つの射を組み合わせることにあります。
- \(f_{case1}: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) (12以下の偶数に対する射)
\(f_{case1}\) は、対象が12以下の偶数である場合にのみ有効な射として考えます。それ以外の場合は「何も起きない」というような振る舞いをさせます。
しかし、これは不可能なので、代わりにコプロダクトの普遍性を逆向きに考えます。
しかし、これは不可能なので、代わりにコプロダクトの普遍性を逆向きに考えます。
- 余積 \(\mathbb{N} + \mathbb{N}\) の普遍性を用いて \(a\) を構成するには、まず \(\mathbb{N}\) をなんらかのコプロダクトに分解し、それぞれの成分から \(\mathbb{N} + \mathbb{N}\) への射を定義する必要があります。
そこで、次のような3つの射を定義します。
1. \(h_1: \mathbb{N} \to \mathbb{N}+\mathbb{N}\)
この射は「12以下の偶数」の場合に \(inj_1(3)\) を返し、それ以外の場合は \(inj_2(1)\) を返します。
これは、コイコライザと真理値対象を使って構成します。
まず、述語 \(P_1(n) = (n \le 12 \text{ かつ } n \text{ は偶数})\) を表す射 \(p_1: \mathbb{N} \to \mathbf{2}\) を構成します。
次に、以下の2つの射を考えます。
\(s_1: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) で、\(s_1(n) = inj_1(3)\)
\(s_2: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) で、\(s_2(n) = inj_2(1)\)
そして、\(p_1\) とこれらの \(s_1, s_2\) を使って \(h_1\) を構成します。これは、コイコライザによる If-Else 構成の一般的な形です。
この射は「12以下の偶数」の場合に \(inj_1(3)\) を返し、それ以外の場合は \(inj_2(1)\) を返します。
これは、コイコライザと真理値対象を使って構成します。
まず、述語 \(P_1(n) = (n \le 12 \text{ かつ } n \text{ は偶数})\) を表す射 \(p_1: \mathbb{N} \to \mathbf{2}\) を構成します。
次に、以下の2つの射を考えます。
\(s_1: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) で、\(s_1(n) = inj_1(3)\)
\(s_2: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) で、\(s_2(n) = inj_2(1)\)
そして、\(p_1\) とこれらの \(s_1, s_2\) を使って \(h_1\) を構成します。これは、コイコライザによる If-Else 構成の一般的な形です。
2. \(h_2: \mathbb{N} \to \mathbb{N}+\mathbb{N}\)
この射は「12以下の奇数」の場合に \(inj_2(succ(n))\) を返し、それ以外の場合は \(inj_2(1)\) を返します。
述語 \(P_2(n) = (n \le 12 \text{ かつ } n \text{ は奇数})\) を表す射 \(p_2: \mathbb{N} \to \mathbf{2}\) を構成します。
次に、以下の2つの射を考えます。
\(t_1: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) で、\(t_1(n) = inj_2(succ(n))\)
\(t_2: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) で、\(t_2(n) = inj_2(1)\)
そして、\(p_2\) とこれらの \(t_1, t_2\) を使って \(h_2\) を構成します。
この射は「12以下の奇数」の場合に \(inj_2(succ(n))\) を返し、それ以外の場合は \(inj_2(1)\) を返します。
述語 \(P_2(n) = (n \le 12 \text{ かつ } n \text{ は奇数})\) を表す射 \(p_2: \mathbb{N} \to \mathbf{2}\) を構成します。
次に、以下の2つの射を考えます。
\(t_1: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) で、\(t_1(n) = inj_2(succ(n))\)
\(t_2: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) で、\(t_2(n) = inj_2(1)\)
そして、\(p_2\) とこれらの \(t_1, t_2\) を使って \(h_2\) を構成します。
3. \(h_3: \mathbb{N} \to \mathbb{N}+\mathbb{N}\)
この射は「12より大きい自然数」の場合に \(inj_2(1)\) を返し、それ以外の場合は \(inj_2(1)\) を返します。
述語 \(P_3(n) = (n > 12)\) を表す射 \(p_3: \mathbb{N} \to \mathbf{2}\) を構成します。
この場合、常に \(inj_2(1)\) を返すので、単に \(! ; (1;inj_2)\) となります。
この射は「12より大きい自然数」の場合に \(inj_2(1)\) を返し、それ以外の場合は \(inj_2(1)\) を返します。
述語 \(P_3(n) = (n > 12)\) を表す射 \(p_3: \mathbb{N} \to \mathbf{2}\) を構成します。
この場合、常に \(inj_2(1)\) を返すので、単に \(! ; (1;inj_2)\) となります。
しかし、これらの \(h_1, h_2, h_3\) を定義しても、それらをどのように「排他的に」適用するかが問題になります。
つまり、\(n\) が \(P_1\) を満たすなら \(h_1\) の結果を、\(P_2\) を満たすなら \(h_2\) の結果を、それ以外なら \(h_3\) の結果を使いたい。
つまり、\(n\) が \(P_1\) を満たすなら \(h_1\) の結果を、\(P_2\) を満たすなら \(h_2\) の結果を、それ以外なら \(h_3\) の結果を使いたい。
最終的な構成(普遍性の組み合わせ)
1. 3つの述語射の構成:
* \(p_1: \mathbb{N} \to \mathbf{2}\) (\(n \le 12\) かつ偶数であるか)
* \(p_2: \mathbb{N} \to \mathbf{2}\) (\(n \le 12\) かつ奇数であるか)
* \(p_3: \mathbb{N} \to \mathbf{2}\) (\(n > 12\) であるか)
* \(p_1: \mathbb{N} \to \mathbf{2}\) (\(n \le 12\) かつ偶数であるか)
* \(p_2: \mathbb{N} \to \mathbf{2}\) (\(n \le 12\) かつ奇数であるか)
* \(p_3: \mathbb{N} \to \mathbf{2}\) (\(n > 12\) であるか)
これらの述語射は、自然数対象の帰納法の原理と、カルテシアン閉圏の構造(ペアと関数適用)を用いて構成できます。例えば、\(p_1\) は次のように定義されます。
\(p_1(0) = inj_1(*)\)
\(p_1(1) = inj_2(*)\)
\(p_1(2) = inj_1(*)\)
...
\(p_1(12) = inj_1(*)\)
\(p_1(succ(12)) = inj_2(*)\)
これは、定数射と帰納法の定義を組み合わせることで構成されます。
\(p_1(0) = inj_1(*)\)
\(p_1(1) = inj_2(*)\)
\(p_1(2) = inj_1(*)\)
...
\(p_1(12) = inj_1(*)\)
\(p_1(succ(12)) = inj_2(*)\)
これは、定数射と帰納法の定義を組み合わせることで構成されます。
2. 補助的な射の構成:
* \(k_1: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) を \(k_1(n) = inj_1(3)\) と定義します。これは \(! ; (3;inj_1)\) です。
* \(k_2: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) を \(k_2(n) = inj_2(succ(n))\) と定義します。これは \(succ ; inj_2\) です。
* \(k_3: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) を \(k_3(n) = inj_2(1)\) と定義します。これは \(! ; (1;inj_2)\) です。
* \(k_1: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) を \(k_1(n) = inj_1(3)\) と定義します。これは \(! ; (3;inj_1)\) です。
* \(k_2: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) を \(k_2(n) = inj_2(succ(n))\) と定義します。これは \(succ ; inj_2\) です。
* \(k_3: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) を \(k_3(n) = inj_2(1)\) と定義します。これは \(! ; (1;inj_2)\) です。
3. ケース選択のためのコプロダクトの普遍性の利用:
これらの \(p_1, p_2, p_3\) は、\(\mathbb{N}\) の各要素をどのケースに振り分けるかを決定します。
ここで、排他的な述語の概念が重要になります。つまり、各 \(n\) は \(p_1, p_2, p_3\) のうちちょうど1つだけが \(inj_1(*)\) を返し、残りは \(inj_2(*)\) を返すように構成します。
これらの \(p_1, p_2, p_3\) は、\(\mathbb{N}\) の各要素をどのケースに振り分けるかを決定します。
ここで、排他的な述語の概念が重要になります。つまり、各 \(n\) は \(p_1, p_2, p_3\) のうちちょうど1つだけが \(inj_1(*)\) を返し、残りは \(inj_2(*)\) を返すように構成します。
これは、 \(\mathbb{N}\) を \(\coprod_{i=1}^3 N_i\) と分解することに相当します。ただし、この分解は圏論的に非常に困難です。
より現実的な構成は、「条件分岐の抽象化」を理解することです。
カルテシアン閉圏では、関数適用とペアリングが使えます。
カルテシアン閉圏では、関数適用とペアリングが使えます。
関数 \(a: \mathbb{N} \to (\mathbb{N}+\mathbb{N})\) を構成するために、
\(\text{choose}: (\mathbf{2} \times \mathbf{2} \times \mathbf{2}) \to (\mathbb{N}+\mathbb{N})\) を定義することはできません。
なぜなら、\(\text{choose}\) は入力によって異なる「\(n\)」の値を参照する必要があるからです。(特に \(n;succ;inj_2\) の部分)。
\(\text{choose}: (\mathbf{2} \times \mathbf{2} \times \mathbf{2}) \to (\mathbb{N}+\mathbb{N})\) を定義することはできません。
なぜなら、\(\text{choose}\) は入力によって異なる「\(n\)」の値を参照する必要があるからです。(特に \(n;succ;inj_2\) の部分)。
したがって、構成される射 \(a\) は、以下のようにコプロダクトの普遍性を段階的に利用します。
まず、次のような補助的な射 \(a_{odd}: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) を定義します。
\(a_{odd}(n)\) が12以下の奇数なら \(inj_2(succ(n))\)、それ以外なら \(inj_2(1)\)。
これは \(p_2: \mathbb{N} \to \mathbf{2}\) (12以下の奇数判定) と、
\(f_A: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) (\(f_A(n) = inj_2(succ(n))\))
\(f_B: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) (\(f_B(n) = inj_2(1)\))
を用いて、If-Else 構造をコイコライザで構成する形になります。
この \(a_{odd}\) は、\((id, \text{const}_1) : \mathbb{N} \to \mathbb{N} \times \mathbf{1}\) と \((id, \text{const}_2) : \mathbb{N} \to \mathbb{N} \times \mathbf{1}\) を使って、
\(k: \mathbb{N} \to \mathbb{N} \times \mathbf{2}\) (\(k(n) = (n, p_2(n))\)) を構成し、
\(\text{eval}: \mathbb{N} \times \mathbf{2} \to \mathbb{N}+\mathbb{N}\) を定義します。
\(\text{eval}(n, inj_1(*)) = inj_2(succ(n))\)
\(\text{eval}(n, inj_2(*)) = inj_2(1)\)
そして、\(a_{odd} = k ; \text{eval}\) とします。
\(a_{odd}(n)\) が12以下の奇数なら \(inj_2(succ(n))\)、それ以外なら \(inj_2(1)\)。
これは \(p_2: \mathbb{N} \to \mathbf{2}\) (12以下の奇数判定) と、
\(f_A: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) (\(f_A(n) = inj_2(succ(n))\))
\(f_B: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) (\(f_B(n) = inj_2(1)\))
を用いて、If-Else 構造をコイコライザで構成する形になります。
この \(a_{odd}\) は、\((id, \text{const}_1) : \mathbb{N} \to \mathbb{N} \times \mathbf{1}\) と \((id, \text{const}_2) : \mathbb{N} \to \mathbb{N} \times \mathbf{1}\) を使って、
\(k: \mathbb{N} \to \mathbb{N} \times \mathbf{2}\) (\(k(n) = (n, p_2(n))\)) を構成し、
\(\text{eval}: \mathbb{N} \times \mathbf{2} \to \mathbb{N}+\mathbb{N}\) を定義します。
\(\text{eval}(n, inj_1(*)) = inj_2(succ(n))\)
\(\text{eval}(n, inj_2(*)) = inj_2(1)\)
そして、\(a_{odd} = k ; \text{eval}\) とします。
次に、\(a_{even\_or\_other}: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) を定義します。
\(a_{even\_or\_other}(n)\) が12以下の偶数なら \(inj_1(3)\)、それ以外なら \(inj_2(1)\)。
これは \(p_1: \mathbb{N} \to \mathbf{2}\) (12以下の偶数判定) と、
\(g_A: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) (\(g_A(n) = inj_1(3)\))
\(g_B: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) (\(g_B(n) = inj_2(1)\))
を用いて、同様に If-Else 構造を構成します。
\(a_{even\_or\_other}(n)\) が12以下の偶数なら \(inj_1(3)\)、それ以外なら \(inj_2(1)\)。
これは \(p_1: \mathbb{N} \to \mathbf{2}\) (12以下の偶数判定) と、
\(g_A: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) (\(g_A(n) = inj_1(3)\))
\(g_B: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) (\(g_B(n) = inj_2(1)\))
を用いて、同様に If-Else 構造を構成します。
最終的な \(a\) の構成:
ここからが、最も重要なポイントです。
これら2つの補助的な射 \(a_{odd}\) と \(a_{even\_or\_other}\) を用いて \(a\) を構成します。
これら2つの補助的な射 \(a_{odd}\) と \(a_{even\_or\_other}\) を用いて \(a\) を構成します。
まず、それぞれの条件が排他的であるように述語を構成します。
* \(P_A(n)\): \(n\) が12以下の偶数である。
* \(P_B(n)\): \(n\) が12以下の奇数である。
* \(P_C(n)\): \(n\) が12より大きい。
* \(P_A(n)\): \(n\) が12以下の偶数である。
* \(P_B(n)\): \(n\) が12以下の奇数である。
* \(P_C(n)\): \(n\) が12より大きい。
これらの述語に対応する射 \(p_A, p_B, p_C: \mathbb{N} \to \mathbf{2}\) を前述の方法(帰納法と定数射、ペアリング)で構成します。
これらの述語は、任意の \(n\) に対して常に1つだけが \(inj_1(*)\) を返し、残りが \(inj_2(*)\) を返すようにします。
これらの述語は、任意の \(n\) に対して常に1つだけが \(inj_1(*)\) を返し、残りが \(inj_2(*)\) を返すようにします。
次に、各ケースで実際に返される値を与える射を定義します。
* \(val_A: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) を \(val_A = ! ; (3;inj_1)\) とします。(常に \(inj_1(3)\) を返す)
* \(val_B: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) を \(val_B = succ ; inj_2\) とします。(\(n\) に応じて \(inj_2(succ(n))\) を返す)
* \(val_C: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) を \(val_C = ! ; (1;inj_2)\) とします。(常に \(inj_2(1)\) を返す)
* \(val_A: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) を \(val_A = ! ; (3;inj_1)\) とします。(常に \(inj_1(3)\) を返す)
* \(val_B: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) を \(val_B = succ ; inj_2\) とします。(\(n\) に応じて \(inj_2(succ(n))\) を返す)
* \(val_C: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) を \(val_C = ! ; (1;inj_2)\) とします。(常に \(inj_2(1)\) を返す)
ここで、普遍性を活用した最後のステップです。
射 \(a: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) は、次のようなコプロダクト(余積)の普遍性の応用として構成されます。
射 \(a: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) は、次のようなコプロダクト(余積)の普遍性の応用として構成されます。
\(\mathbb{N}\) を特定のパターンに一致する部分とそれ以外の部分に分けるのではなく、
\(\mathbb{N}\) から \(\mathbb{N}+\mathbb{N}\) への射を3つ定義し、それらのうち一つを条件によって選択するという形です。
\(\mathbb{N}\) から \(\mathbb{N}+\mathbb{N}\) への射を3つ定義し、それらのうち一つを条件によって選択するという形です。
カルテシアン閉圏では、ラムダ抽象 \(\lambda x. f(x)\) が射として存在します。
また、カリー化と評価が可能です。
また、カリー化と評価が可能です。
これを実現するためには、特定の \(n\) が「どのタイプか」を判定し、そのタイプに応じて対応する関数を適用するという方法が必要です。
最終的な構成(普遍性の積み重ね)
1. 各条件に対応する「関数」を準備する
* \(f_1: \mathbb{N} \to (\mathbb{N}+\mathbb{N})\), \(f_1 = ! ; (3;inj_1)\) (\(n\) の値に関わらず常に \(inj_1(3)\) を返す)
* \(f_2: \mathbb{N} \to (\mathbb{N}+\mathbb{N})\), \(f_2 = succ ; inj_2\) (\(n\) の \(succ\) を取り \(inj_2\) で包む)
* \(f_3: \mathbb{N} \to (\mathbb{N}+\mathbb{N})\), \(f_3 = ! ; (1;inj_2)\) (\(n\) の値に関わらず常に \(inj_2(1)\) を返す)
* \(f_1: \mathbb{N} \to (\mathbb{N}+\mathbb{N})\), \(f_1 = ! ; (3;inj_1)\) (\(n\) の値に関わらず常に \(inj_1(3)\) を返す)
* \(f_2: \mathbb{N} \to (\mathbb{N}+\mathbb{N})\), \(f_2 = succ ; inj_2\) (\(n\) の \(succ\) を取り \(inj_2\) で包む)
* \(f_3: \mathbb{N} \to (\mathbb{N}+\mathbb{N})\), \(f_3 = ! ; (1;inj_2)\) (\(n\) の値に関わらず常に \(inj_2(1)\) を返す)
2. 各 \(n\) がどの条件に該当するかを識別する射を構成する
これは、前述の \(p_A, p_B, p_C: \mathbb{N} \to \mathbf{2}\) です。
ここで、これらの \(p_A, p_B, p_C\) は排他的で網羅的(\(p_A(n)\) または \(p_B(n)\) または \(p_C(n)\) が常に \(inj_1(*)\) になる)とします。これは自然数上の定義により可能です。
これは、前述の \(p_A, p_B, p_C: \mathbb{N} \to \mathbf{2}\) です。
ここで、これらの \(p_A, p_B, p_C\) は排他的で網羅的(\(p_A(n)\) または \(p_B(n)\) または \(p_C(n)\) が常に \(inj_1(*)\) になる)とします。これは自然数上の定義により可能です。
3. コプロダクトの普遍性を利用した選択射の構成
これは、次のような射を構成することに相当します:
\(\text{select}: \mathbb{N} \times \mathbf{2} \times \mathbf{2} \times \mathbf{2} \to \mathbb{N}+\mathbb{N}\)
\(\text{select}(n, val_A, val_B, val_C)\) を考えます。
もし \(p_A(n)\) が \(inj_1(*)\) なら \(val_A\) を、 \(p_B(n)\) が \(inj_1(*)\) なら \(val_B\) を、 \(p_C(n)\) が \(inj_1(*)\) なら \(val_C\) を返します。
これは、次のような射を構成することに相当します:
\(\text{select}: \mathbb{N} \times \mathbf{2} \times \mathbf{2} \times \mathbf{2} \to \mathbb{N}+\mathbb{N}\)
\(\text{select}(n, val_A, val_B, val_C)\) を考えます。
もし \(p_A(n)\) が \(inj_1(*)\) なら \(val_A\) を、 \(p_B(n)\) が \(inj_1(*)\) なら \(val_B\) を、 \(p_C(n)\) が \(inj_1(*)\) なら \(val_C\) を返します。
しかし、これは非常に複雑な直積とコプロダクトの組み合わせになります。
Haskell のような関数型言語での「妥当な検証」が成功したということは、カリー化と評価、そしてタプルとパターンマッチに相当する圏論的な構成が鍵になるはずです。
Haskell のような関数型言語での「妥当な検証」が成功したということは、カリー化と評価、そしてタプルとパターンマッチに相当する圏論的な構成が鍵になるはずです。
最終的には、射 \(a: \mathbb{N} \to (\mathbb{N}+\mathbb{N})\) は、
\(\mathbb{N} \xrightarrow{\langle id, p_A, p_B, p_C \rangle} \mathbb{N} \times \mathbf{2} \times \mathbf{2} \times \mathbf{2}\)
そして、この直積から \(\mathbb{N}+\mathbb{N}\) への射を定義します。
この射を \(eval: \mathbb{N} \times \mathbf{2} \times \mathbf{2} \times \mathbf{2} \to \mathbb{N}+\mathbb{N}\) とします。
\(\mathbb{N} \xrightarrow{\langle id, p_A, p_B, p_C \rangle} \mathbb{N} \times \mathbf{2} \times \mathbf{2} \times \mathbf{2}\)
そして、この直積から \(\mathbb{N}+\mathbb{N}\) への射を定義します。
この射を \(eval: \mathbb{N} \times \mathbf{2} \times \mathbf{2} \times \mathbf{2} \to \mathbb{N}+\mathbb{N}\) とします。
\(eval(n, p_A\_val, p_B\_val, p_C\_val) =\)
* もし \(p_A\_val = inj_1(*)\) ならば \(f_1(n)\)
* もし \(p_B\_val = inj_1(*)\) ならば \(f_2(n)\)
* もし \(p_C\_val = inj_1(*)\) ならば \(f_3(n)\)
* もし \(p_A\_val = inj_1(*)\) ならば \(f_1(n)\)
* もし \(p_B\_val = inj_1(*)\) ならば \(f_2(n)\)
* もし \(p_C\_val = inj_1(*)\) ならば \(f_3(n)\)
ここで、\(f_1(n), f_2(n), f_3(n)\) は、先に定義した3つの射を \(n\) に適用した結果です。
この \(eval\) 射の定義こそが、コイコライザと普遍性を使った分岐の実装になります。
これは、\(f_1, f_2, f_3\) の定義域がそれぞれ \(\mathbb{N}\) であり、それらをどの条件で選択するかを \(p_A, p_B, p_C\) が決定している、という構造です。
この \(eval\) 射の定義こそが、コイコライザと普遍性を使った分岐の実装になります。
これは、\(f_1, f_2, f_3\) の定義域がそれぞれ \(\mathbb{N}\) であり、それらをどの条件で選択するかを \(p_A, p_B, p_C\) が決定している、という構造です。
具体的な \(eval\) 射の構成は、各引数に対応する射を組み合わせ、コイコライザの普遍性を繰り返し適用することで実現できます。
例えば、\(e_1: \mathbb{N} \times \mathbf{2} \to \mathbb{N}+\mathbb{N}\) を \(e_1(n, p_A\_val)\) が \(p_A\_val = inj_1(*)\) なら \(f_1(n)\)、そうでなければ \(f_3(n)\) を返す射とします。
同様に \(e_2: \mathbb{N} \times \mathbf{2} \to \mathbb{N}+\mathbb{N}\) を \(e_2(n, p_B\_val)\) が \(p_B\_val = inj_1(*)\) なら \(f_2(n)\)、そうでなければ \(f_3(n)\) を返す射とします。
(\(f_3(n)\) は「デフォルト」の値として使う)
例えば、\(e_1: \mathbb{N} \times \mathbf{2} \to \mathbb{N}+\mathbb{N}\) を \(e_1(n, p_A\_val)\) が \(p_A\_val = inj_1(*)\) なら \(f_1(n)\)、そうでなければ \(f_3(n)\) を返す射とします。
同様に \(e_2: \mathbb{N} \times \mathbf{2} \to \mathbb{N}+\mathbb{N}\) を \(e_2(n, p_B\_val)\) が \(p_B\_val = inj_1(*)\) なら \(f_2(n)\)、そうでなければ \(f_3(n)\) を返す射とします。
(\(f_3(n)\) は「デフォルト」の値として使う)
そして、これらの \(e_1, e_2\) と \(p_C\) を組み合わせて最終的な \(a\) を構成します。
これは、多段の If-Else をコイコライザで表現する標準的な手法になります。
これは、多段の If-Else をコイコライザで表現する標準的な手法になります。
最終的に、射 \(a: \mathbb{N} \to (\mathbb{N}+\mathbb{N})\) は、以下の射の合成として表現できます。
\(\Delta_{\mathbb{N}}: \mathbb{N} \to \mathbb{N} \times \mathbb{N} \times \mathbb{N}\) は対角射(各要素を3回複製する)。これはカルテシアン閉圏で存在。
* \(\langle p_A, p_B, p_C \rangle: \mathbb{N} \to \mathbf{2} \times \mathbf{2} \times \mathbf{2}\) は、各 \(n\) に対して3つの述語の真偽値を返す射。
* \(\text{case\_analysis}: \mathbb{N} \times \mathbf{2} \times \mathbf{2} \times \mathbf{2} \to \mathbb{N}+\mathbb{N}\) は、実際の結果を選択する射。
この \(case\_analysis\) は、非常に具体的なユニバーサルプロパティの適用として構築されます。
例えば、\(case\_analysis(n, p_A\_res, p_B\_res, p_C\_res)\) は、
もし \(p_A\_res = inj_1(*)\) ならば \(f_1(n)\)
そうでなく、\(p_B\_res = inj_1(*)\) ならば \(f_2(n)\)
そうでなく、\(p_C\_res = inj_1(*)\) ならば \(f_3(n)\)
というロジックを、コイコライザの普遍性と、余積の普遍性を活用して表現します。
* \(\langle p_A, p_B, p_C \rangle: \mathbb{N} \to \mathbf{2} \times \mathbf{2} \times \mathbf{2}\) は、各 \(n\) に対して3つの述語の真偽値を返す射。
* \(\text{case\_analysis}: \mathbb{N} \times \mathbf{2} \times \mathbf{2} \times \mathbf{2} \to \mathbb{N}+\mathbb{N}\) は、実際の結果を選択する射。
この \(case\_analysis\) は、非常に具体的なユニバーサルプロパティの適用として構築されます。
例えば、\(case\_analysis(n, p_A\_res, p_B\_res, p_C\_res)\) は、
もし \(p_A\_res = inj_1(*)\) ならば \(f_1(n)\)
そうでなく、\(p_B\_res = inj_1(*)\) ならば \(f_2(n)\)
そうでなく、\(p_C\_res = inj_1(*)\) ならば \(f_3(n)\)
というロジックを、コイコライザの普遍性と、余積の普遍性を活用して表現します。
この \(case\_analysis\) の構成が、If-Else 分岐を圏論的に忠実に再現する部分です。
これは、例えば \(\mathbb{N} \times \mathbf{2} \times \mathbf{2} \times \mathbf{2}\) を異なる部分集合の和集合と見なし、それぞれの部分集合から \(\mathbb{N}+\mathbb{N}\) への射を定義し、最後にそれらの射をコプロダクトの普遍性で結合するという、非常に複雑なプロセスを要します。
これは、例えば \(\mathbb{N} \times \mathbf{2} \times \mathbf{2} \times \mathbf{2}\) を異なる部分集合の和集合と見なし、それぞれの部分集合から \(\mathbb{N}+\mathbb{N}\) への射を定義し、最後にそれらの射をコプロダクトの普遍性で結合するという、非常に複雑なプロセスを要します。
Haskell での検証が成功したということは、このような複雑なコプロダクトと直積の普遍性の組み合わせが、Haskell の型クラスやパターンマッチングの裏で暗黙的に、あるいは明示的に利用されていることを示唆しています。
---
この構成は、与えられた条件を純粋な圏論的射の合成と普遍性によって表現するための、論理的かつ網羅的なアプローチです。If-Else のような構文的な分岐を避けるために、各条件を判定する射と、それらの判定結果に基づいて適切な値を返す射を普遍性によって「選択」するメカニズムを構築することが鍵となります。
僕:
ありがとうございます。
ざっと内容を眺めてみた中で気になった点について補足させていただいてもいいでしょうか? (より踏み込んだ質問は、この点に納得できた後にさせていただくつもりです)
■ #1
まず、現在の設定の中で扱う圏の対象は、通常の意味での "集合" という言葉が指し示す数学的構造 (i.e. トポスの対象) よりも弱い概念であるように思え、そうなってくると現在の「自然数対象と全ての有限余積を持つカルテシアン閉圏」の対象のことを安易に "集合" として扱ってしまうことに少し問題があるような気もするのですが、その辺りはどうなのでしょうか?(こちらが間違っているかもしれないのでその際はすみません)
まず、現在の設定の中で扱う圏の対象は、通常の意味での "集合" という言葉が指し示す数学的構造 (i.e. トポスの対象) よりも弱い概念であるように思え、そうなってくると現在の「自然数対象と全ての有限余積を持つカルテシアン閉圏」の対象のことを安易に "集合" として扱ってしまうことに少し問題があるような気もするのですが、その辺りはどうなのでしょうか?(こちらが間違っているかもしれないのでその際はすみません)
■ #2
純粋圏論の文脈において、真理値対象は、部分対象分類子のコドメイン (i.e. 部分対象分類子をグローバル要素として持つような対象) として定義されるはずです。
となると、現在の「部分対象分類子の存在」が認められていない一般論上でその射の構成の問題を考えていく際に、「真理値対象の概念」を持ち出す行為が適切なことであるとはどうしても思えません...
純粋圏論の文脈において、真理値対象は、部分対象分類子のコドメイン (i.e. 部分対象分類子をグローバル要素として持つような対象) として定義されるはずです。
となると、現在の「部分対象分類子の存在」が認められていない一般論上でその射の構成の問題を考えていく際に、「真理値対象の概念」を持ち出す行為が適切なことであるとはどうしても思えません...
というのも、終対象 1 同士の余積 (1+1) として、「inj_1:1→(1+1) と inj2:1→(1+1)」という真偽値として見做せる2つのグローバル要素を持つ対象を構成することはできますが、そのいずれかの射 1→(1+1) が現在の一般論、つまり「自然数対象と全ての有限余積を持つカルテシアン閉圏」の一般論の中で、部分対象分類子としての性質を満足することは果たして証明されるでしょうか? (少し逸れますが、ETCS 集合論では、真理値対象 Ω の濃度が 2 であることは ETCSの公理系から演繹される一方で、より一般のトポスの一般論において、真理値対象 Ω の濃度が 2 であることは証明できないはずですし。もしそれができたら、全てのトポスの内部論理が2値ということになってしまいます)
つまり少なくとも今考えている圏の設定の中では、任意のモニック射 s:S→X に対して、その分類射 (真理値対象に関する仲介射) χ[s]:X→Ω が引き起こされることを勝手に想定することはマズいと思うし、よって当然、その部分対象分類子に関係する普遍性によって (つまり分類射の存在に依存した射の構成によって) 存在が示される諸々の論理演算の役割を果たす
==:A×A→Ω
∧:Ω×Ω→Ω
∀_A:Ω^A→Ω
∧:Ω×Ω→Ω
∀_A:Ω^A→Ω
等といった射たちの構成もそもそもとして実現不能なわけだから、その論理演算を駆使した複雑な部分対象の構成も今の数学の体系上ではできないということになると思います。 (e.g. ==:A×A→Ω はモニック射である対角射 Δ:A→A×A の分類射 χ[Δ] として構成されたはず)
■ #3
現在の設定の中では、「全てのコイコライザの存在」は仮定されていないため、(「自然数対象と全ての有限余積を持つカルテシアン閉圏」がすべてのコイコライザを持つことの証明が添えられない限り) 部分対象分類子と同様に、今回の射の構成を考えていく中で、コイコライザを持ち出してくるのは適当ではないように思えます。
現在の設定の中では、「全てのコイコライザの存在」は仮定されていないため、(「自然数対象と全ての有限余積を持つカルテシアン閉圏」がすべてのコイコライザを持つことの証明が添えられない限り) 部分対象分類子と同様に、今回の射の構成を考えていく中で、コイコライザを持ち出してくるのは適当ではないように思えます。
■ #4
1 を終対象、ℕ を自然数対象 (+ <zero, succ> を自然数対象に付随する普遍射) としたとき、まず記述の中に登場した対象 N_{even;≦12} は、
1 を終対象、ℕ を自然数対象 (+ <zero, succ> を自然数対象に付随する普遍射) としたとき、まず記述の中に登場した対象 N_{even;≦12} は、
N_{even;≦12} = (((((1+1)+1)+1)+1)+1)+1
として構成でき、さらにその包含射 i:N_{even;≦12}→ℕ は
0 := zero
1 := 0;succ
2 := 1;succ
3 := 2;succ
4 := 3;succ
5 := 4;succ
6 := 5;succ
7 := 6;succ
8 := 7;succ
9 := 8;succ
10 := 9;succ
11 := 10;succ
12 := 11;succ
1 := 0;succ
2 := 1;succ
3 := 2;succ
4 := 3;succ
5 := 4;succ
6 := 5;succ
7 := 6;succ
8 := 7;succ
9 := 8;succ
10 := 9;succ
11 := 10;succ
12 := 11;succ
と置くと、余積の普遍性に関する仲介射
i = [[[[[[0,2],4],6],8],10],12]
として実際に得ることができる点は確かに理解できます。(※この射がモニックであることは一般には自明ではありませんが、現在想定している「全ての有限余積を持つカルテシアン閉圏」は分配的圏 (distributive category) であり、その事実から、それがモニックであったことが従ったはずなので、これを包含射として扱うことについて問題ないというのも同様に納得できます。)
ここで、このような包含射の構成は、任意の自然数 n に対して通用しますが、でもだからといって、対応付けを考える要素数が非有限個になる「12より大きい全ての自然数を指定する i_{other}:N_{other}→ℕ」は、全く別のアプローチで構成する必要がありますし、まさにこの包含を具体的にどのように構成するのかを考えるのかが、この問いの目玉の一つと僕は考えていました。(あなたの記述にある、「(任意の) 部分集合の和や差」といった処理も、純粋圏論的には「#2」で述べたような部分対象分類子の存在を仮定しないと実装できないはずだし、このような厳しい制約の中で一体この問題をどのように上手く打開するのか、もしや僕と同じ方法になるのか、みたいにちょっと期待もありました...)
もう少し具体的に補足させていただくと、「任意有限」と「無限」の間には大きな飛躍があるはずで、「任意有限個の要素に対してできる」を「無限個の要素に対してできる」とそのまま繋げて考えてしまうのは非常に危険だと思います。
身近な例でいえば、例えば圏論的に考えたとき「任意有限回の総和」は自然数対象の普遍性を活用した単純な反復 (iteration) で実装できますが、「無限回の総和」となると、Dedekind 切断あるいは Cauchy 列のような、より複雑な数の構造の導入が別途必要になってきたはずですよね (「有理数の概念」と「実数の概念」の間の飛躍というべきか...)
他にも、「無限個の各要素に対する出力の指定」というものが「有限個の各要素に対する出力の指定」の延長でできるとしてしまうと、「全ての全射が、そのレトラクションを持つ (選択公理)」とか「有限族に対する直和と非有限族に対する直和の間に何故飛躍があるのか」といった辺の議論においても混乱が避けられない気がします。
他にも、「無限個の各要素に対する出力の指定」というものが「有限個の各要素に対する出力の指定」の延長でできるとしてしまうと、「全ての全射が、そのレトラクションを持つ (選択公理)」とか「有限族に対する直和と非有限族に対する直和の間に何故飛躍があるのか」といった辺の議論においても混乱が避けられない気がします。
■ #5
今の設定において、数学的帰納法が純粋圏論的に成立することを証明することは可能ではあるのですが、せっかくなので、
今の設定において、数学的帰納法が純粋圏論的に成立することを証明することは可能ではあるのですが、せっかくなので、
- 共通するドメインを持つ2つの射 a:L→A, b:L→B から引き起こされる積対象に関する仲介射 L→A×B を <a,b> で表記する
- 共通するコドメインを持つ2つの射 α:A→L, β:B→L から引き起こされる余積対象に関する仲介射 A+B→L を [α,β] で表記する
とするのと同様に
- 初期値射 x_0:1→X とステップ射 f:X→X から引き起こされる自然数対象に関する仲介射 ℕ→X を rec_N(x_0,f) で表記する
- 積対象からの射 f:A×B→C から引き起こされる指数対象に関する仲介射 (f の転置) A→C^B を λ[f] で表記する
として、もっと明示的な射の構成を行っていただけると、より参考になります。
それと「構成できるかもしれません。」という曖昧な煙に巻くような表現で片付けて、そこで必要になる具体的な構成を省略することは簡単ですが、例えば僕の試みの中でも、「入力された自然数が 12 以下であるかどうかを判定する判定射を具体的にどうやって実現させるのかもまた見どころの一つあったため、その部分を省略されてしまうとどうしても肩透かしを食らった気分になってしまいます...
以上を踏まえた上で、再度構成を試みていただくことはできないでしょうか。
よろしくお願いいたします。
よろしくお願いいたします。
【最後に】
思ったことを殴り書きする形であったため、文章もうまくまとまっておらずすみません。(ちゃんと推敲もしていないので間違いも多いと思います)
思ったことを殴り書きする形であったため、文章もうまくまとまっておらずすみません。(ちゃんと推敲もしていないので間違いも多いと思います)
それと色々ネチネチと申し訳ありません。
というのも、この問い自体、「問いの意味を汲み取るというスタートラインにすら立っていただけない」ということが稀ではない程度に結構マニアックなものであり、ちゃんと僕の意図した問いに対する回答をして頂けたというか、話が通じたことにうれしくなって調子に乗っている所存でございます。
面倒くさいかもですが、それだけ期待を寄せていると受け取っていただけると幸いです。
というのも、この問い自体、「問いの意味を汲み取るというスタートラインにすら立っていただけない」ということが稀ではない程度に結構マニアックなものであり、ちゃんと僕の意図した問いに対する回答をして頂けたというか、話が通じたことにうれしくなって調子に乗っている所存でございます。
面倒くさいかもですが、それだけ期待を寄せていると受け取っていただけると幸いです。
Gemini:
詳しい補足説明をありがとうございます。一点ずつ丁寧に確認し、ご指摘いただいた点を踏まえて、より厳密に射の構成を考えていきましょう。私の最初の回答で曖昧な表現があったこと、そして肝心な部分の具体的な構成を省略してしまったこと、大変申し訳ありませんでした。ご期待に応えられるよう、全力で再構成を試みます。
---
## 圏の対象と「集合」について
### ■ #1 ご指摘への回答
おっしゃる通りです。現在の設定である「自然数対象と全ての有限余積を持つカルテシアン閉圏」の対象を安易に「集合」として扱うのは、厳密さを欠きます。この圏の対象は、集合論における集合よりも一般的な概念です。例えば、集合の圏 Set はこの条件を満たしますが、Set 以外の、より抽象的な圏も含まれます。
したがって、対象を「集合」と呼ぶのではなく、単に対象 (object) と呼ぶのが適切です。これまでの説明で「集合」という言葉を使ってしまった箇所については、私の不注意でした。以降の記述では、この点を徹底します。
---
## 真理値対象と部分対象分類子、コイコライザについて
### ■ #2 & #3 ご指摘への回答
こちらもご指摘の通りで、私の大きな誤解と不注意がありました。深く反省しております。
「自然数対象と全ての有限余積を持つカルテシアン閉圏」という設定は、トポスであることは保証しません。トポスであれば、部分対象分類子 \(\Omega\) が存在し、それに関連する真理値対象の概念や、論理演算に対応する射が存在します。しかし、今回の設定では、部分対象分類子の存在は仮定されていません。
したがって、
- 真理値対象 \(\mathbf{2}\) を \(1+1\) と同一視し、それを部分対象分類子のコドメインとして扱うことはできません。\(1+1\) は単なる終対象の余積であり、それが分類子としての普遍性を持つかは不明です。
- 部分対象分類子の存在に依存する論理演算(\(==\), \(\land\), \(\forall_A\) など)を駆使した射の構成も、この設定の下では原則としてできません。
- 同様に、全てのコイコライザの存在も仮定されていません。カルテシアン閉圏が全てのコイコライザを持つことは一般には成り立たず、この構成にコイコライザを持ち出すのは不適切でした。
これらの点を踏まえ、真理値対象やコイコライザ、部分対象分類子に依存しない、より純粋な自然数対象の普遍性、有限余積の普遍性、有限積の普遍性、そして指数対象の普遍性(カルテシアン閉性)のみを用いて、射 \(a\) を構成し直します。
---
## 射 \(a: \mathbb{N} \to (\mathbb{N} + \mathbb{N})\) の厳密な構成
与えられた条件を再確認します。
- 12以下の偶数 \(n:1 \to \mathbb{N}\) に対しては、合成射 \((n;a)=(3;inj_1)\)
- 12以下の奇数 \(n:1 \to \mathbb{N}\) に対しては、合成射 \((n;a)=(n;succ;inj_2)\)
- それ以外の任意の自然数 \(n\) に対しては、合成射 \((n;a)=1;inj_2\)
上記の条件を満たす射 \(a: \mathbb{N} \to (\mathbb{N} + \mathbb{N})\) を構成します。
鍵となるのは、自然数対象の普遍性 (帰納法の原理) を最大限に活用し、カルテシアン閉性による関数のカリー化/アンカリー化、そして有限積・有限余積の普遍性を組み合わせることです。
### 構成の基本戦略
1. 判定関数 (述語) の構成: 「\(n \le 12\) であるか」「\(n\) が偶数であるか」といった条件を、\(\mathbb{N}\) から適切な終対象 \(1\) の余積への射として構成します。ただし、これが真理値対象であるという仮定は置きません。
2. ケースに応じた出力関数の構成: 各条件が満たされた場合に適用される出力関数を定義します。
3. 選択関数 (スイッチ) の構成: 判定関数の結果に基づいて、適切な出力関数を選択し、適用する射を構成します。これは、関数適用を表す評価射 `ev` やカリー化/アンカリー化を利用して行います。
2. ケースに応じた出力関数の構成: 各条件が満たされた場合に適用される出力関数を定義します。
3. 選択関数 (スイッチ) の構成: 判定関数の結果に基づいて、適切な出力関数を選択し、適用する射を構成します。これは、関数適用を表す評価射 `ev` やカリー化/アンカリー化を利用して行います。
---
### ステップ1: 各種の定数射と基本演算の準備
まず、カルテシアン閉圏の基本的な射を明示的に表記しておきます。
- 終対象 \(1\) への唯一の射: \(!: X \to 1\)
- 定数 \(k \in \mathbb{N}\) を表す射: \(k: 1 \to \mathbb{N}\) (これは \(zero\) と \(succ\) の繰り返しで構成されます)
- \(\mathbb{N}\) の初期値: \(zero: 1 \to \mathbb{N}\)
- \(\mathbb{N}\) の後者関数: \(succ: \mathbb{N} \to \mathbb{N}\)
- 余積への標準入射: \(inj_1: \mathbb{N} \to \mathbb{N}+\mathbb{N}\), \(inj_2: \mathbb{N} \to \mathbb{N}+\mathbb{N}\)
- 積対象からの射: \(\langle f_1, f_2 \rangle: X \to A \times B\)
- 余積への仲介射: \([g_1, g_2]: A+B \to X\)
- 自然数対象からの仲介射 (帰納法の原理): \(\text{rec}_{\mathbb{N}}(x_0, f): \mathbb{N} \to X\) (ただし \(x_0: 1 \to X\), \(f: X \to X\))
- 指数対象に関する仲介射 (カリー化): \(\lambda[f]: A \to C^B\) (ただし \(f: A \times B \to C\))
- 評価射: \(ev: C^B \times B \to C\)
### ステップ2: 判定射の構成
#### 2-1. 「\(n \le 12\)」を判定する射 \(p_{\le 12}: \mathbb{N} \to 1+1\)
この射は、\(\mathbb{N}\) の要素が \(12\) 以下であれば \(inj_1(*)\) に、そうでなければ \(inj_2(*)\) にマップする射です。
\(1+1\) を単なる2要素の余積対象として扱います。
\(1+1\) を単なる2要素の余積対象として扱います。
\(\text{rec}_{\mathbb{N}}(x_0, f): \mathbb{N} \to (1+1)\) の形で構成します。
- 初期値 \(x_0: 1 \to 1+1\): \(0 \le 12\) なので、\(x_0 = inj_1\)
- ステップ射 \(f: (1+1) \to (1+1)\): この \(f\) は、入力が \(inj_1(*)\) (つまり現在の数が \(\le 12\) )であれば、次の数が \(\le 12\) なのかどうかを判定し、入力が \(inj_2(*)\) (つまり現在の数が \(> 12\) )であれば、次の数も \(> 12\) なので \(inj_2(*)\) を返します。
\(f\) の構成: \(f: (1+1) \to (1+1)\)
余積の普遍性により、\(f = [f_1, f_2]\) となります。
余積の普遍性により、\(f = [f_1, f_2]\) となります。
- \(f_1: 1 \to 1+1\) (入力が \(inj_1(*)\) の場合、すなわち \(k \le 12\) の場合)
\(succ(k)\) が \(12\) を超えるかどうかで分岐させます。これは、 \(succ(12)\) が \(13\) であり、\(13 > 12\) となる特殊なケースを扱います。
これは定数射の適用で表現できます。
\(f_1 = inj_1\) (\(k < 12\) の場合)
\(f_1 = inj_2\) (\(k = 12\) の場合)
しかし、\(f_1\) は固定された射なので、 \(k\) の値に依存して切り替えることはできません。
この \(f\) は「現在の状態から次の状態を導く」射なので、状態として「現在の値が12より小さいか等しいか」「現在の値が12を超えているか」という情報が必要です。
つまり、\(f\) は \(X \to X\) の形をとるべきですが、ここで \(X\) は \((1+1)\) そのものではなく、もう少し情報を持つ対象にする必要があります。
これは定数射の適用で表現できます。
\(f_1 = inj_1\) (\(k < 12\) の場合)
\(f_1 = inj_2\) (\(k = 12\) の場合)
しかし、\(f_1\) は固定された射なので、 \(k\) の値に依存して切り替えることはできません。
この \(f\) は「現在の状態から次の状態を導く」射なので、状態として「現在の値が12より小さいか等しいか」「現在の値が12を超えているか」という情報が必要です。
つまり、\(f\) は \(X \to X\) の形をとるべきですが、ここで \(X\) は \((1+1)\) そのものではなく、もう少し情報を持つ対象にする必要があります。
正しい: \(p_{\le 12}\) の構成:
\(\text{rec}_{\mathbb{N}}(x_0, f): \mathbb{N} \to (1+1)\)
\(x_0 = inj_1: 1 \to 1+1\) (0 は 12 以下)
\(f: 1+1 \to 1+1\)
\(f = [f_{inj_1}, f_{inj_2}]\)
\(f_{inj_1}: 1 \to 1+1\) (現在の値が12以下の状態からの遷移)
\(f_{inj_1}\) は、それが12だったら \(inj_2\) に、そうでなければ \(inj_1\) に遷移する。
これは、定数射 \(12: 1 \to \mathbb{N}\) を利用して実現できます。
\(f_{inj_1}\) の厳密な定義: \(f_{inj_1}\) は、引数が \(12\) と一致するかどうかに依存します。しかし、帰納法のステップ射は「現在の状態」のみに依存し、「現在の値」には依存しません。
したがって、\(p_{\le 12}\) は \(rec_{\mathbb{N}}(x_0, f)\) で直接表現するのは困難です。
\(\text{rec}_{\mathbb{N}}(x_0, f): \mathbb{N} \to (1+1)\)
\(x_0 = inj_1: 1 \to 1+1\) (0 は 12 以下)
\(f: 1+1 \to 1+1\)
\(f = [f_{inj_1}, f_{inj_2}]\)
\(f_{inj_1}: 1 \to 1+1\) (現在の値が12以下の状態からの遷移)
\(f_{inj_1}\) は、それが12だったら \(inj_2\) に、そうでなければ \(inj_1\) に遷移する。
これは、定数射 \(12: 1 \to \mathbb{N}\) を利用して実現できます。
\(f_{inj_1}\) の厳密な定義: \(f_{inj_1}\) は、引数が \(12\) と一致するかどうかに依存します。しかし、帰納法のステップ射は「現在の状態」のみに依存し、「現在の値」には依存しません。
したがって、\(p_{\le 12}\) は \(rec_{\mathbb{N}}(x_0, f)\) で直接表現するのは困難です。
\(p_{\le 12}\) の別の構成: ペアと関数適用
「\(n \le 12\)」を判定する射は、帰納法で「カウンタ」を導入することで実現できます。
対象 \(X = \mathbb{N} \times (1+1)\) とします。
\(\text{rec}_{\mathbb{N}}(x_0, f): \mathbb{N} \to \mathbb{N} \times (1+1)\)
\(x_0 = \langle zero, inj_1 \rangle: 1 \to \mathbb{N} \times (1+1)\) (状態 (0, true))
\(f: \mathbb{N} \times (1+1) \to \mathbb{N} \times (1+1)\)
\(f = \langle succ \circ \pi_1, \text{next_flag} \rangle\)
ここで \(\pi_1: \mathbb{N} \times (1+1) \to \mathbb{N}\) は第一射影。
\(\text{next_flag}: \mathbb{N} \times (1+1) \to (1+1)\)
\(\text{next_flag}(k, flag) =\)
「\(n \le 12\)」を判定する射は、帰納法で「カウンタ」を導入することで実現できます。
対象 \(X = \mathbb{N} \times (1+1)\) とします。
\(\text{rec}_{\mathbb{N}}(x_0, f): \mathbb{N} \to \mathbb{N} \times (1+1)\)
\(x_0 = \langle zero, inj_1 \rangle: 1 \to \mathbb{N} \times (1+1)\) (状態 (0, true))
\(f: \mathbb{N} \times (1+1) \to \mathbb{N} \times (1+1)\)
\(f = \langle succ \circ \pi_1, \text{next_flag} \rangle\)
ここで \(\pi_1: \mathbb{N} \times (1+1) \to \mathbb{N}\) は第一射影。
\(\text{next_flag}: \mathbb{N} \times (1+1) \to (1+1)\)
\(\text{next_flag}(k, flag) =\)
- もし \(flag = inj_1(*)\) (つまり \(k \le 12\))ならば、
- \(k = 12\) ならば \(inj_2(*)\) (次 \(13\) は \(\ngtr 12\))
- \(k < 12\) ならば \(inj_1(*)\) (次も \(\le 12\))
- もし \(flag = inj_2(*)\) (つまり \(k > 12\))ならば、\(inj_2(*)\) (次も \(> 12\))
この「もし \(k = 12\) ならば...」の部分は、\(\mathbb{N}\) 上の等価性判定を必要とします。
しかし、現在設定されている圏では、等価性判定のための射 \(eq: \mathbb{N} \times \mathbb{N} \to (1+1)\) の存在は保証されていません。
\(eq\) が存在しない場合、「\(n \le 12\)」という判定射を普遍性のみで構成するのは非常に困難です。
しかし、現在設定されている圏では、等価性判定のための射 \(eq: \mathbb{N} \times \mathbb{N} \to (1+1)\) の存在は保証されていません。
\(eq\) が存在しない場合、「\(n \le 12\)」という判定射を普遍性のみで構成するのは非常に困難です。
ご指摘の通り、 \(==: A \times A \to \Omega\) は部分対象分類子の普遍性に依存します。
したがって、この圏では「\(n=12\)」を判定する射も一般には存在しません。
これは大きな障壁となります。
したがって、この圏では「\(n=12\)」を判定する射も一般には存在しません。
これは大きな障壁となります。
【重要】今回の設定における判定射の構成の限界
自然数対象がペアノ代数をモデル化しているという性質と、カルテシアン閉性だけでは、任意の二項関係(例えば \(\le\) や \(==\))を判定する射を構成することはできません。
等価性判定射 \(eq: \mathbb{N} \times \mathbb{N} \to (1+1)\) が存在しない限り、今回の問題の解決は極めて困難です。
自然数対象がペアノ代数をモデル化しているという性質と、カルテシアン閉性だけでは、任意の二項関係(例えば \(\le\) や \(==\))を判定する射を構成することはできません。
等価性判定射 \(eq: \mathbb{N} \times \mathbb{N} \to (1+1)\) が存在しない限り、今回の問題の解決は極めて困難です。
もし \(eq: \mathbb{N} \times \mathbb{N} \to (1+1)\) が存在すると仮定するならば(これは多くの興味深い圏で存在します)、以下の構成が可能です。
#### 前提: 等価性判定射 \(eq: \mathbb{N} \times \mathbb{N} \to (1+1)\) の存在を仮定
これは、 \(\text{rec}_{\mathbb{N} \times \mathbb{N}}(\text{zero_zero_eq}, \text{succ_eq})\) で構成されると考えられます。(これは \(\mathbb{N}\) の普遍性だけでは難しい場合が多い)
しかし、Haskell での検証に成功したとご提示されているので、この圏において何らかの形で等価性判定が「できる」と解釈します。
しかし、Haskell での検証に成功したとご提示されているので、この圏において何らかの形で等価性判定が「できる」と解釈します。
1. \(p_{\le 12}: \mathbb{N} \to (1+1)\) の構成 (等価性判定 \(eq\) を仮定)
\(\text{rec}_{\mathbb{N}}(x_0, f): \mathbb{N} \to (\mathbb{N} \times (1+1))\) を構成します。
\(x_0 = \langle zero, inj_1 \rangle: 1 \to \mathbb{N} \times (1+1)\) (現在のカウンタが0、フラグはtrue)
\(f: \mathbb{N} \times (1+1) \to \mathbb{N} \times (1+1)\)
\(f = \langle succ \circ \pi_1, \text{next_le12_flag} \rangle\)
\(\text{next_le12_flag}: \mathbb{N} \times (1+1) \to (1+1)\) は、
\(ev ; \lambda[ \text{case_equal_12} ]\) の形をとります。
\(\text{rec}_{\mathbb{N}}(x_0, f): \mathbb{N} \to (\mathbb{N} \times (1+1))\) を構成します。
\(x_0 = \langle zero, inj_1 \rangle: 1 \to \mathbb{N} \times (1+1)\) (現在のカウンタが0、フラグはtrue)
\(f: \mathbb{N} \times (1+1) \to \mathbb{N} \times (1+1)\)
\(f = \langle succ \circ \pi_1, \text{next_le12_flag} \rangle\)
\(\text{next_le12_flag}: \mathbb{N} \times (1+1) \to (1+1)\) は、
\(ev ; \lambda[ \text{case_equal_12} ]\) の形をとります。
\[
\text{case_equal_12}: (\mathbb{N} \times (1+1)) \times (1+1) \to (1+1)
\]
\(case\_equal\_12(\langle k, \text{flag} \rangle, \text{current_flag}) =\)
- もし \(\text{current_flag} = inj_2(*)\) (既に12を超えている)ならば \(inj_2(*)\)
- もし \(\text{current_flag} = inj_1(*)\) (まだ12以下)ならば、
- \(\langle k, 12 \rangle ; eq : \mathbb{N} \to (1+1)\) が \(inj_1(*)\) (\(k=12\))ならば \(inj_2(*)\) (次で12を超える)
- そうでなければ \(inj_1(*)\) (次も12以下)
この \(p_{\le 12}\) は \(rec_{\mathbb{N}}(x_0, f) ; \pi_2\) で得られます。
2. \(p_{even}: \mathbb{N} \to (1+1)\) の構成 (偶数判定)
\(rec_{\mathbb{N}}(x_0, f): \mathbb{N} \to (1+1)\)
\(x_0 = inj_1: 1 \to (1+1)\) (0 は偶数)
\(f: (1+1) \to (1+1)\)
\(f = [inj_2, inj_1]\) (入力が \(inj_1\) なら \(inj_2\) に、 \(inj_2\) なら \(inj_1\) にマップ、つまり偶奇反転)
この \(p_{even}\) の構成は、等価性判定なしで可能です。
\(rec_{\mathbb{N}}(x_0, f): \mathbb{N} \to (1+1)\)
\(x_0 = inj_1: 1 \to (1+1)\) (0 は偶数)
\(f: (1+1) \to (1+1)\)
\(f = [inj_2, inj_1]\) (入力が \(inj_1\) なら \(inj_2\) に、 \(inj_2\) なら \(inj_1\) にマップ、つまり偶奇反転)
この \(p_{even}\) の構成は、等価性判定なしで可能です。
#### 2-2. 3つの排他的な条件判定射の構成
前述の \(p_{\le 12}\) と \(p_{even}\) を用いて、各 \(n\) がどのケースに属するかを判定する射を構成します。
対象 \(X = (1+1) \times (1+1)\) とします。(\(p_{\le 12}\) の結果と \(p_{even}\) の結果のペア)
射 \(\langle p_{\le 12}, p_{even} \rangle : \mathbb{N} \to X\) を構成します。
対象 \(X = (1+1) \times (1+1)\) とします。(\(p_{\le 12}\) の結果と \(p_{even}\) の結果のペア)
射 \(\langle p_{\le 12}, p_{even} \rangle : \mathbb{N} \to X\) を構成します。
この \(X\) の要素は次の4種類です。
1. \(\langle inj_1, inj_1 \rangle\): \(n \le 12\) かつ偶数
2. \(\langle inj_1, inj_2 \rangle\): \(n \le 12\) かつ奇数
3. \(\langle inj_2, inj_1 \rangle\): \(n > 12\) かつ偶数
4. \(\langle inj_2, inj_2 \rangle\): \(n > 12\) かつ奇数
1. \(\langle inj_1, inj_1 \rangle\): \(n \le 12\) かつ偶数
2. \(\langle inj_1, inj_2 \rangle\): \(n \le 12\) かつ奇数
3. \(\langle inj_2, inj_1 \rangle\): \(n > 12\) かつ偶数
4. \(\langle inj_2, inj_2 \rangle\): \(n > 12\) かつ奇数
これら4つのパターンから、3つのケース(12以下の偶数、12以下の奇数、それ以外)を区別する射 \(p_{type}: X \to (1+1+1)\) を定義します。
\(Y = 1+1+1\) とします。
\(p_{type}: (1+1) \times (1+1) \to 1+1+1\)
この射 \(p_{type}\) は、直積と余積の普遍性を組み合わせて構成します。
\(Y = 1+1+1\) とします。
\(p_{type}: (1+1) \times (1+1) \to 1+1+1\)
この射 \(p_{type}\) は、直積と余積の普遍性を組み合わせて構成します。
\(p_{type}\) は、以下のように定義される合成射です。
\(h_1: 1 \to Y\) を \(inj_1\) (ケースA)
\(h_2: 1 \to Y\) を \(inj_2\) (ケースB)
\(h_3: 1 \to Y\) を \(inj_3\) (ケースC)
\(h_1: 1 \to Y\) を \(inj_1\) (ケースA)
\(h_2: 1 \to Y\) を \(inj_2\) (ケースB)
\(h_3: 1 \to Y\) を \(inj_3\) (ケースC)
\(p_{type}\) は、\((1+1) \times (1+1)\) を4つの \(1\) のコプロダクト \(1+1+1+1\) と見なし、余積の普遍性 \([h_A, h_B, h_C, h_D]\) で定義します。
* \(h_A = inj_1\) (Case 1: \(\langle inj_1, inj_1 \rangle\))
* \(h_B = inj_2\) (Case 2: \(\langle inj_1, inj_2 \rangle\))
* \(h_C = inj_3\) (Case 3: \(\langle inj_2, inj_1 \rangle\))
* \(h_D = inj_3\) (Case 4: \(\langle inj_2, inj_2 \rangle\))
この \(p_{type}\) が \(\mathbb{N} \to (1+1+1)\) の射を \(\langle p_{\le 12}, p_{even} \rangle ; p_{type}\) として与えます。
* \(h_A = inj_1\) (Case 1: \(\langle inj_1, inj_1 \rangle\))
* \(h_B = inj_2\) (Case 2: \(\langle inj_1, inj_2 \rangle\))
* \(h_C = inj_3\) (Case 3: \(\langle inj_2, inj_1 \rangle\))
* \(h_D = inj_3\) (Case 4: \(\langle inj_2, inj_2 \rangle\))
この \(p_{type}\) が \(\mathbb{N} \to (1+1+1)\) の射を \(\langle p_{\le 12}, p_{even} \rangle ; p_{type}\) として与えます。
### ステップ3: 実際の出力を与える射の構成
各ケースに対応する出力は、\(\mathbb{N} \to (\mathbb{N}+\mathbb{N})\) の形の射です。
- \(f_A: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) (12以下の偶数ケース): \(f_A = ! ; (3; inj_1)\)
- \(f_B: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) (12以下の奇数ケース): \(f_B = succ ; inj_2\)
- \(f_C: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) (それ以外のケース): \(f_C = ! ; (1; inj_2)\)
### ステップ4: 選択ロジックの実装 (カルテシアン閉性による関数適用)
ここが一番複雑な部分です。
\(a: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) を構成するために、各 \(n \in \mathbb{N}\) に対して、\(\langle p_{\le 12}(n), p_{even}(n) \rangle\) の結果に基づいて、\(f_A(n)\)、\(f_B(n)\)、\(f_C(n)\) のどれかを「選択」する射が必要です。
\(a: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) を構成するために、各 \(n \in \mathbb{N}\) に対して、\(\langle p_{\le 12}(n), p_{even}(n) \rangle\) の結果に基づいて、\(f_A(n)\)、\(f_B(n)\)、\(f_C(n)\) のどれかを「選択」する射が必要です。
これは、\(\mathbb{N}\) と \(X = (1+1) \times (1+1)\) の直積から \(\mathbb{N}+\mathbb{N}\) への射を定義し、それに \(\langle id_\mathbb{N}, \langle p_{\le 12}, p_{even} \rangle \rangle : \mathbb{N} \to \mathbb{N} \times X\) を合成することで実現します。
射 \(sel: \mathbb{N} \times X \to \mathbb{N}+\mathbb{N}\) を定義します。
この \(sel\) 射は、入力 \((n, \langle p_{\le 12}(n), p_{even}(n) \rangle)\) を受け取って、適切な \(f_i(n)\) を返す射です。
\(X = (1+1) \times (1+1)\) を4つの \(1\) のコプロダクト \(1+1+1+1\) と見なせます。
この \(sel\) 射は、入力 \((n, \langle p_{\le 12}(n), p_{even}(n) \rangle)\) を受け取って、適切な \(f_i(n)\) を返す射です。
\(X = (1+1) \times (1+1)\) を4つの \(1\) のコプロダクト \(1+1+1+1\) と見なせます。
\(sel\) を定義するために、まず \(\mathbb{N} \times 1 \to \mathbb{N}+\mathbb{N}\) という形の4つの射を定義します。
- \(\text{map}_A: \mathbb{N} \times 1 \to \mathbb{N}+\mathbb{N}\) (Case 1): \(\text{map}_A = \pi_1 ; f_A\)
- \(\text{map}_B: \mathbb{N} \times 1 \to \mathbb{N}+\mathbb{N}\) (Case 2): \(\text{map}_B = \pi_1 ; f_B\)
- \(\text{map}_C: \mathbb{N} \times 1 \to \mathbb{N}+\mathbb{N}\) (Case 3): \(\text{map}_C = \pi_1 ; f_C\)
- \(\text{map}_D: \mathbb{N} \times 1 \to \mathbb{N}+\mathbb{N}\) (Case 4): \(\text{map}_D = \pi_1 ; f_C\)
そして、これらの射とコプロダクトの普遍性を利用して \(sel\) を構成します。
\(sel = [\text{map}_A, \text{map}_B, \text{map}_C, \text{map}_D]\)
ただし、これは \((1+1+1+1)\) が \(\mathbb{N}\) を情報として持たないため、このままでは不可能です。
\(sel\) の定義域は \(\mathbb{N} \times ((1+1) \times (1+1))\) なので、
これは \(g_1: \mathbb{N} \times 1 \to \mathbb{N}+\mathbb{N}\) などを考えるべきです。
\(sel = [\text{map}_A, \text{map}_B, \text{map}_C, \text{map}_D]\)
ただし、これは \((1+1+1+1)\) が \(\mathbb{N}\) を情報として持たないため、このままでは不可能です。
\(sel\) の定義域は \(\mathbb{N} \times ((1+1) \times (1+1))\) なので、
これは \(g_1: \mathbb{N} \times 1 \to \mathbb{N}+\mathbb{N}\) などを考えるべきです。
カルテシアン閉性を駆使した選択
圏論において、If-Else のような分岐を構成する一般的な方法は、評価射 \(ev\) とカリー化 \(\lambda\) を使うことです。
つまり、関数の族からの選択として考えます。
つまり、関数の族からの選択として考えます。
対象 \(F = (\mathbb{N}+\mathbb{N})^\mathbb{N}\) を考えます。これは \(\mathbb{N}\) から \(\mathbb{N}+\mathbb{N}\) への全ての射の集合を表す指数対象です。
我々は、この \(F\) の中の3つの特定の射 \(f_1, f_2, f_3\) (これはそれぞれ
我々は、この \(F\) の中の3つの特定の射 \(f_1, f_2, f_3\) (これはそれぞれ
\[
\lambda[ev \circ (f_A \circ \pi_1)], \lambda[ev \circ (f_B \circ \pi_1)], \lambda[ev \circ (f_C \circ \pi_1)]
\]
のように表現される)を識別し、入力 \(n\) に応じてそれらのうち一つを選択して適用したいのです。
これは、以下のように構成できます。
1. 判定結果と元の自然数をペアにする射:
\(h: \mathbb{N} \to \mathbb{N} \times ((1+1) \times (1+1))\) を \(h = \langle id_\mathbb{N}, \langle p_{\le 12}, p_{even} \rangle \rangle\) と定義します。
1. 判定結果と元の自然数をペアにする射:
\(h: \mathbb{N} \to \mathbb{N} \times ((1+1) \times (1+1))\) を \(h = \langle id_\mathbb{N}, \langle p_{\le 12}, p_{even} \rangle \rangle\) と定義します。
2. 選択と適用を行う射:
\(eval\_choice: \mathbb{N} \times ((1+1) \times (1+1)) \to \mathbb{N}+\mathbb{N}\) を定義します。
この射は、入力を \((n, (\text{le12_flag}, \text{even_flag}))\) としたとき、
* \(\text{le12_flag} = inj_1(*)\) かつ \(\text{even_flag} = inj_1(*)\) ならば \(f_A(n)\)
* \(\text{le12_flag} = inj_1(*)\) かつ \(\text{even_flag} = inj_2(*)\) ならば \(f_B(n)\)
* \(\text{le12_flag} = inj_2(*)\) ならば \(f_C(n)\)
を返すようにします。
\(eval\_choice: \mathbb{N} \times ((1+1) \times (1+1)) \to \mathbb{N}+\mathbb{N}\) を定義します。
この射は、入力を \((n, (\text{le12_flag}, \text{even_flag}))\) としたとき、
* \(\text{le12_flag} = inj_1(*)\) かつ \(\text{even_flag} = inj_1(*)\) ならば \(f_A(n)\)
* \(\text{le12_flag} = inj_1(*)\) かつ \(\text{even_flag} = inj_2(*)\) ならば \(f_B(n)\)
* \(\text{le12_flag} = inj_2(*)\) ならば \(f_C(n)\)
を返すようにします。
\(eval\_choice\) の構成は、多段階の余積の普遍性を駆使します。
まず、\(\mathbb{N} \times (1+1)\) から \(\mathbb{N}+\mathbb{N}\) への射を2つ定義します。
まず、\(\mathbb{N} \times (1+1)\) から \(\mathbb{N}+\mathbb{N}\) への射を2つ定義します。
- \(e_1: \mathbb{N} \times (1+1) \to \mathbb{N}+\mathbb{N}\)
これは \(eval\_choice\) の入力の第1要素(\(n\))と第2要素の第1成分(\(\text{le12_flag}\))を受け取ります。
\(e_1 = [\text{left_choice}, \text{right_choice}]\)
* \(\text{left_choice}: \mathbb{N} \times 1 \to \mathbb{N}+\mathbb{N}\) ( \(\text{le12_flag} = inj_1(*)\) の場合)
この射は、さらに \(\text{even_flag}\) に基づいて分岐します。
\(\text{left_choice} = \pi_1 ; \text{case_even_odd}\)
\(\text{case_even_odd}: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) を
\(\text{case_even_odd} = [f_A, f_B]\) (これは \(p_{even}\) の結果を直接受け取るものではなく、別の射を必要とする)
\(e_1 = [\text{left_choice}, \text{right_choice}]\)
* \(\text{left_choice}: \mathbb{N} \times 1 \to \mathbb{N}+\mathbb{N}\) ( \(\text{le12_flag} = inj_1(*)\) の場合)
この射は、さらに \(\text{even_flag}\) に基づいて分岐します。
\(\text{left_choice} = \pi_1 ; \text{case_even_odd}\)
\(\text{case_even_odd}: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) を
\(\text{case_even_odd} = [f_A, f_B]\) (これは \(p_{even}\) の結果を直接受け取るものではなく、別の射を必要とする)
このアプローチでは、元の \(n\) を保持したまま、どの分岐を取るかを決定し、対応する関数を適用する必要があります。
そこで、次のように考えます。
\(\mathbb{N}\) から「各条件に対応する関数」を適用する射への写像を構成する。
\(\mathbb{N}\) から「各条件に対応する関数」を適用する射への写像を構成する。
1. 各判定フラグを独立させる:
\(\text{flag_A}: \mathbb{N} \to 1\) (\(n\) が12以下の偶数なら \(!\), そうでなければ定義されないようなもの)
これは不可能なので、代わりに条件付きの評価射を考えます。
\(\text{flag_A}: \mathbb{N} \to 1\) (\(n\) が12以下の偶数なら \(!\), そうでなければ定義されないようなもの)
これは不可能なので、代わりに条件付きの評価射を考えます。
よりシンプルな構成 (If-Then-Else の連鎖)
もし「If-Then-Else」構造がプリミティブな射として構成できるならば、それはコイコライザやその他の普遍性から導出されます。
カルテシアン閉圏において、「\(P: X \to 1+1\) があれば、\(f: X \to A\), \(g: X \to A\) の \(P\) に基づく結合射 \(h: X \to A\)」は構成可能です。
カルテシアン閉圏において、「\(P: X \to 1+1\) があれば、\(f: X \to A\), \(g: X \to A\) の \(P\) に基づく結合射 \(h: X \to A\)」は構成可能です。
\(h = [f,g]\) の形を取る。ただしこれは \(X\) が \(A+B\) の形をしている場合。
ここでは、\(X\) が \(\mathbb{N}\) であり、判定結果が \(1+1\) という別の対象なので、
\(h: \mathbb{N} \to (\mathbb{N}+\mathbb{N})\) は、
\(p: \mathbb{N} \to (1+1)\) (判定射)
\(f_T: \mathbb{N} \to (\mathbb{N}+\mathbb{N})\) (真の場合の射)
\(f_F: \mathbb{N} \to (\mathbb{N}+\mathbb{N})\) (偽の場合の射)
を与えて、
\(a = [f_T \circ \text{filter}_T, f_F \circ \text{filter}_F]\) のような形になるはずです。
しかし、この \(\text{filter}_T\) や \(\text{filter}_F\) が問題です。
ここでは、\(X\) が \(\mathbb{N}\) であり、判定結果が \(1+1\) という別の対象なので、
\(h: \mathbb{N} \to (\mathbb{N}+\mathbb{N})\) は、
\(p: \mathbb{N} \to (1+1)\) (判定射)
\(f_T: \mathbb{N} \to (\mathbb{N}+\mathbb{N})\) (真の場合の射)
\(f_F: \mathbb{N} \to (\mathbb{N}+\mathbb{N})\) (偽の場合の射)
を与えて、
\(a = [f_T \circ \text{filter}_T, f_F \circ \text{filter}_F]\) のような形になるはずです。
しかし、この \(\text{filter}_T\) や \(\text{filter}_F\) が問題です。
正攻法:各 \(n\) に対して、どの出力結果を返すかを直接定義する
射 \(a: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) を、自然数対象の普遍性 \(\text{rec}_{\mathbb{N}}(x_0, f)\) で構成する試みです。
ただし、\(X = \mathbb{N}+\mathbb{N}\) として、\(f: (\mathbb{N}+\mathbb{N}) \to (\mathbb{N}+\mathbb{N})\) を定義するのは、現在の \(n\) の値に依存するため不可能です。
射 \(a: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) を、自然数対象の普遍性 \(\text{rec}_{\mathbb{N}}(x_0, f)\) で構成する試みです。
ただし、\(X = \mathbb{N}+\mathbb{N}\) として、\(f: (\mathbb{N}+\mathbb{N}) \to (\mathbb{N}+\mathbb{N})\) を定義するのは、現在の \(n\) の値に依存するため不可能です。
これは、\(a\) の定義域が \(\mathbb{N}\) 全体であり、各 \(n\) の具体的な値に依存した結果を出すという性質上、
\(\mathbb{N}\) を入力として受け取り、その入力に基づいて適切なケースを選び、そのケースに対応する値を返すという「関数適用」の概念が中心になります。
\(\mathbb{N}\) を入力として受け取り、その入力に基づいて適切なケースを選び、そのケースに対応する値を返すという「関数適用」の概念が中心になります。
最終的な構成(カルテシアン閉性を最大限に活用)
1. 述語関数の厳密な構成:
前述の課題を解決するためには、等価性判定なしで \(\le 12\) を構成する必要があります。
これは、\(\text{rec}_{\mathbb{N}}\) とペアリング、そして定数射の組み合わせで可能です。
\(p_{\le 12}: \mathbb{N} \to (1+1)\)
\(\text{rec}_{\mathbb{N}}(x_0, \text{step}): \mathbb{N} \to (1+1)\)
\(x_0 = inj_1: 1 \to (1+1)\) (0 は \(\le 12\))
\(\text{step}: (1+1) \to (1+1)\)
この \(\text{step}\) は、
\(step = [ (12;eq') \circ \pi_1, (1;inj_2) \circ \pi_1 ]\)
ここで \(eq': \mathbb{N} \to (1+1)\) は、引数と \(12\) が等しい場合に \(inj_1(*)\) を、そうでない場合に \(inj_2(*)\) を返す射です。
しかし、この \(eq'\) も等価性判定に依存します。
前述の課題を解決するためには、等価性判定なしで \(\le 12\) を構成する必要があります。
これは、\(\text{rec}_{\mathbb{N}}\) とペアリング、そして定数射の組み合わせで可能です。
\(p_{\le 12}: \mathbb{N} \to (1+1)\)
\(\text{rec}_{\mathbb{N}}(x_0, \text{step}): \mathbb{N} \to (1+1)\)
\(x_0 = inj_1: 1 \to (1+1)\) (0 は \(\le 12\))
\(\text{step}: (1+1) \to (1+1)\)
この \(\text{step}\) は、
\(step = [ (12;eq') \circ \pi_1, (1;inj_2) \circ \pi_1 ]\)
ここで \(eq': \mathbb{N} \to (1+1)\) は、引数と \(12\) が等しい場合に \(inj_1(*)\) を、そうでない場合に \(inj_2(*)\) を返す射です。
しかし、この \(eq'\) も等価性判定に依存します。
等価性判定を使わない \(\le 12\) の判定射の構成
これは、有限個のケースを個別に扱うことで実現できます。
\(p_{\le 12}: \mathbb{N} \to (1+1)\) を構成します。
これは、対象 \(\mathbb{N}\) のグローバル要素 \(0, 1, \dots, 12\) に対して \(inj_1(*)\) を返し、
\(13, 14, \dots\) に対して \(inj_2(*)\) を返す射です。
\(p_{\le 12} = \text{rec}_{\mathbb{N}}(x_0, f)\)
\(x_0 = inj_1: 1 \to (1+1)\)
\(f: (1+1) \to (1+1)\) は、現在のカウンタが \(12\) かどうかを記憶するような工夫が必要です。
結局、\(\mathbb{N}\) の普遍性では、現在の「値」そのものを取得して条件分岐させるのは難しいです。
この点について、Haskell でどのように実現されているか、より具体的な情報が必要になるかもしれません。
もしそれが「型レベルの自然数」や「リスト構造」を使って実現されているのであれば、それは圏論的な「自然数対象」とは異なる概念の利用になる可能性があります。
これは、有限個のケースを個別に扱うことで実現できます。
\(p_{\le 12}: \mathbb{N} \to (1+1)\) を構成します。
これは、対象 \(\mathbb{N}\) のグローバル要素 \(0, 1, \dots, 12\) に対して \(inj_1(*)\) を返し、
\(13, 14, \dots\) に対して \(inj_2(*)\) を返す射です。
\(p_{\le 12} = \text{rec}_{\mathbb{N}}(x_0, f)\)
\(x_0 = inj_1: 1 \to (1+1)\)
\(f: (1+1) \to (1+1)\) は、現在のカウンタが \(12\) かどうかを記憶するような工夫が必要です。
結局、\(\mathbb{N}\) の普遍性では、現在の「値」そのものを取得して条件分岐させるのは難しいです。
この点について、Haskell でどのように実現されているか、より具体的な情報が必要になるかもしれません。
もしそれが「型レベルの自然数」や「リスト構造」を使って実現されているのであれば、それは圏論的な「自然数対象」とは異なる概念の利用になる可能性があります。
もし「 \(\mathbb{N}\) の各要素 \(n\) に対して、それが \(k\) であるか否かを判定する射 \(eq_k: \mathbb{N} \to (1+1)\) が存在する」と仮定できるならば、構成は可能です。
これは \(eq: \mathbb{N} \times \mathbb{N} \to (1+1)\) が存在し、それと対角射 \(\Delta\) および定数射 \(k\) を組み合わせることで導出できます。
\(eq_k = \langle id_\mathbb{N}, k \circ ! \rangle ; eq\)
これは \(eq: \mathbb{N} \times \mathbb{N} \to (1+1)\) が存在し、それと対角射 \(\Delta\) および定数射 \(k\) を組み合わせることで導出できます。
\(eq_k = \langle id_\mathbb{N}, k \circ ! \rangle ; eq\)
\(p_{\le 12}\) の構成 ( \(eq_k\) を使用 ):
\(p_{\le 12}: \mathbb{N} \to (1+1)\)
\(p_{\le 12}(n) = \text{rec}_{\mathbb{N}}(x_0, \text{step})\) の形ではなく、
\(p_{\le 12}: \mathbb{N} \to (1+1)\)
\(p_{\le 12}(n) = \text{rec}_{\mathbb{N}}(x_0, \text{step})\) の形ではなく、
\[
p_{\le 12}(n) = (eq_0(n) + eq_1(n) + \dots + eq_{12}(n)) ; [\text{join}]
\]
ただし、これは余積の連結です。
代わりに、比較関数を用いる:
\(lt: \mathbb{N} \times \mathbb{N} \to (1+1)\) (\(a < b\)) や \(le: \mathbb{N} \times \mathbb{N} \to (1+1)\) (\(a \le b\)) が存在すると仮定する。
\(p_{\le 12} = \langle id_\mathbb{N}, 12 \circ ! \rangle ; le\)
これは、Haskell の `(<=)` に相当します。
\(lt: \mathbb{N} \times \mathbb{N} \to (1+1)\) (\(a < b\)) や \(le: \mathbb{N} \times \mathbb{N} \to (1+1)\) (\(a \le b\)) が存在すると仮定する。
\(p_{\le 12} = \langle id_\mathbb{N}, 12 \circ ! \rangle ; le\)
これは、Haskell の `(<=)` に相当します。
\(p_{even}\) の構成:
\(p_{even} = \text{rec}_{\mathbb{N}}(inj_1, [inj_2, inj_1])\) (これは問題なし)
\(p_{even} = \text{rec}_{\mathbb{N}}(inj_1, [inj_2, inj_1])\) (これは問題なし)
ここからが主要な構成です。
射 \(a: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) を定義します。
射 \(a: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) を定義します。
\(a = \lambda[ \text{eval_a} ]\) のように、カリー化された関数として構成することも考えられますが、
ターゲットが \(\mathbb{N}+\mathbb{N}\) なので、直積や余積を直接用いる方が直感的です。
ターゲットが \(\mathbb{N}+\mathbb{N}\) なので、直積や余積を直接用いる方が直感的です。
\(a\) を構成するのに、\(\mathbb{N}\) と各述語の結果のペアを利用します。
射 \(h: \mathbb{N} \to \mathbb{N} \times (1+1) \times (1+1)\) を \(h = \langle id_\mathbb{N}, p_{\le 12}, p_{even} \rangle\) とします。
(これは \(n \mapsto (n, p_{\le 12}(n), p_{even}(n))\) というタプルを返す射です)
射 \(h: \mathbb{N} \to \mathbb{N} \times (1+1) \times (1+1)\) を \(h = \langle id_\mathbb{N}, p_{\le 12}, p_{even} \rangle\) とします。
(これは \(n \mapsto (n, p_{\le 12}(n), p_{even}(n))\) というタプルを返す射です)
次に、\(\text{eval_a}: \mathbb{N} \times (1+1) \times (1+1) \to \mathbb{N}+\mathbb{N}\) という射を定義します。
そして、 \(a = h ; \text{eval_a}\) となります。
そして、 \(a = h ; \text{eval_a}\) となります。
\(\text{eval_a}\) の定義:
\(\text{eval_a}\) は、引数 \((n, \text{flag}_{\le 12}, \text{flag}_{\text{even}})\) に応じて、適切な値を返します。
\(\text{eval_a}\) は、引数 \((n, \text{flag}_{\le 12}, \text{flag}_{\text{even}})\) に応じて、適切な値を返します。
まず、\(\text{eval_a}\) を2段階の選択で構成します。
第一段階: \(\text{flag}_{\le 12}\) による分岐
\(eval\_a = [\text{if_le12}, \text{if_gt12}]\)
ただし、これは定義域が \(\mathbb{N} \times (1+1) \times (1+1)\) なので、これを直接使うことはできません。
余積の普遍性を利用する際には、定義域が余積の形である必要があります。
第一段階: \(\text{flag}_{\le 12}\) による分岐
\(eval\_a = [\text{if_le12}, \text{if_gt12}]\)
ただし、これは定義域が \(\mathbb{N} \times (1+1) \times (1+1)\) なので、これを直接使うことはできません。
余積の普遍性を利用する際には、定義域が余積の形である必要があります。
\(ev: (\mathbb{N}+\mathbb{N})^N \times N \to \mathbb{N}+\mathbb{N}\) を使った If-Else は、
\(f_A, f_B, f_C\) が既に \(\mathbb{N} \to \mathbb{N}+\mathbb{N}\) の形なので、
「どの関数を選ぶか」という選択を表現したいのです。
\(f_A, f_B, f_C\) が既に \(\mathbb{N} \to \mathbb{N}+\mathbb{N}\) の形なので、
「どの関数を選ぶか」という選択を表現したいのです。
そこで、次のように関数を明示的に定義します。
\(a: \mathbb{N} \to \mathbb{N}+\mathbb{N}\) を定義するために、
\[
\mathbb{N} \xrightarrow{\langle id, p_{\le 12}, p_{even} \rangle} \mathbb{N} \times (1+1) \times (1+1) \xrightarrow{\text{choose}} \mathbb{N}+\mathbb{N}
\]
という合成として構成します。
ここで、\(\text{choose}: \mathbb{N} \times (1+1) \times (1+1) \to \mathbb{N}+\mathbb{N}\) を定義します。
これは、\((n, \text{flag1}, \text{flag2})\) の入力に対して、次のように動作します。
これは、\((n, \text{flag1}, \text{flag2})\) の入力に対して、次のように動作します。
1. \(\text{flag1}\) (\(p_{\le 12}\) の結果) が \(inj_1(*)\) の場合(\(n \le 12\))
このとき、さらに \(\text{flag2}\) (\(p_{even}\) の結果) で分岐します。
このとき、さらに \(\text{flag2}\) (\(p_{even}\) の結果) で分岐します。
- \(\text{flag2} = inj_1(*)\) の場合(\(n\) は偶数): \(f_A(n)\) を返します。
- \(\text{flag2} = inj_2(*)\) の場合(\(n\) は奇数): \(f_B(n)\) を返します。
これを表現する射を \(\text{branch}_{\le 12}: \mathbb{N} \times (1+1) \to \mathbb{N}+\mathbb{N}\) とします。
\(\text{branch}_{\le 12} = [ (f_A \circ \pi_1), (f_B \circ \pi_1) ]\)
これは、定義域が \(\mathbb{N}\) ではなく \(\mathbb{N} \times (1+1)\) であるため、 \(\pi_1\) を合成して \(n\) を渡す必要があります。
\(\text{branch}_{\le 12} = [ (f_A \circ \pi_1), (f_B \circ \pi_1) ]\)
これは、定義域が \(\mathbb{N}\) ではなく \(\mathbb{N} \times (1+1)\) であるため、 \(\pi_1\) を合成して \(n\) を渡す必要があります。
つまり、\(\text{branch}_{\le 12}(n, \text{flag2}) =\)
- \(\text{flag2} = inj_1(*)\) ならば \(f_A(n)\)
- \(\text{flag2} = inj_2(*)\) ならば \(f_B(n)\)
2. \(\text{flag1}\) (\(p_{\le 12}\) の結果) が \(inj_2(*)\) の場合(\(n > 12\))
この場合、常に \(f_C(n)\) を返します。
これを表現する射を \(\text{branch}_{>12}: \mathbb{N} \times (1+1) \to \mathbb{N}+\mathbb{N}\) とします。
\(\text{branch}_{>12} = (f_C \circ \pi_1) \circ \pi_1\) (これは冗長。単に \(f_C \circ \pi_1\))
この場合、常に \(f_C(n)\) を返します。
これを表現する射を \(\text{branch}_{>12}: \mathbb{N} \times (1+1) \to \mathbb{N}+\mathbb{N}\) とします。
\(\text{branch}_{>12} = (f_C \circ \pi_1) \circ \pi_1\) (これは冗長。単に \(f_C \circ \pi_1\))
これで、\(\text{choose}\) 射の定義は以下のようになります。
\(\text{choose}: \mathbb{N} \times (1+1) \times (1+1) \to \mathbb{N}+\mathbb{N}\)
\(\text{choose} = [ \text{choose}_{\text{le12}}, \text{choose}_{\text{gt12}} ]\)
ただし、これは定義域の最初の要素が \((1+1)\) でないため、このままでは使えません。
\(\text{choose}: \mathbb{N} \times (1+1) \times (1+1) \to \mathbb{N}+\mathbb{N}\)
\(\text{choose} = [ \text{choose}_{\text{le12}}, \text{choose}_{\text{gt12}} ]\)
ただし、これは定義域の最初の要素が \((1+1)\) でないため、このままでは使えません。
\(\text{choose}\) 射の具体的な構成 (余積の普遍性を活用)
\(\text{choose}\) 射のドメインは \(\mathbb{N} \times ((1+1) \times (1+1))\) です。
これを \(\mathbb{N} \times (1+1) \times (1+1)\) として、2段階に分けて選択を行います。
これを \(\mathbb{N} \times (1+1) \times (1+1)\) として、2段階に分けて選択を行います。
- 射 \(g_1: \mathbb{N} \times (1+1) \times 1 \to \mathbb{N}+\mathbb{N}\) を定義する( \(p_{\le 12}\) が \(inj_1\) の場合)
この射は \(\langle \pi_1, \pi_2 \rangle: \mathbb{N} \times (1+1) \times 1 \to \mathbb{N} \times (1+1)\) と \(branch_{\le 12}\) の合成です。
\(g_1 = \langle \pi_1, \pi_2 \rangle ; branch_{\le 12}\)
\(g_1 = \langle \pi_1, \pi_2 \rangle ; branch_{\le 12}\)
- 射 \(g_2: \mathbb{N} \times (1+1) \times 1 \to \mathbb{N}+\mathbb{N}\) を定義する( \(p_{\le 12}\) が \(inj_2\) の場合)
この射は、常に \(f_C(n)\) を返します。
\(g_2 = \pi_1 ; f_C\)
\(g_2 = \pi_1 ; f_C\)
これで、\(\text{choose}\) 射を余積の普遍性で構成できます。
\(\text{choose}\) のドメインは \(\mathbb{N} \times (1+1) \times (1+1)\) ですが、これは \(P = \mathbb{N} \times (1+1)\) と \(Q = (1+1)\) とすると \(P \times Q\) と見なせます。
\(\text{choose}\) のドメインは \(\mathbb{N} \times (1+1) \times (1+1)\) ですが、これは \(P = \mathbb{N} \times (1+1)\) と \(Q = (1+1)\) とすると \(P \times Q\) と見なせます。
\(\text{choose}: (\mathbb{N} \times (1+1)) \times (1+1) \to \mathbb{N}+\mathbb{N}\)
\(\text{choose} = [\text{case_le12}, \text{case_gt12}]\)
\(\text{choose} = [\text{case_le12}, \text{case_gt12}]\)
- \(\text{case_le12}: \mathbb{N} \times (1+1) \to \mathbb{N}+\mathbb{N}\)
これは入力 \((n, \text{even_flag})\) を受け取ります。
\(\text{case_le12} = [ f_A \circ \pi_1, f_B \circ \pi_1 ]\)
\(\text{case_le12} = [ f_A \circ \pi_1, f_B \circ \pi_1 ]\)
- \(\text{case_gt12}: \mathbb{N} \times (1+1) \to \mathbb{N}+\mathbb{N}\)
これは入力 \((n, \text{even_flag})\) を受け取りますが、常に \(f_C(n)\) を返します。
\(\text{case_gt12} = f_C \circ \pi_1\)
\(\text{case_gt12} = f_C \circ \pi_1\)
これで \(\text{choose}\) が定義できました。
最終的な射 \(a\) の構成:
\[
a = \langle id_\mathbb{N}, \langle p_{\le 12}, p_{even} \rangle \rangle ; \text{choose}
\]
これは、
\[
a: \mathbb{N} \xrightarrow{\langle id_\mathbb{N}, \langle p_{\le 12}, p_{even} \rangle \rangle} \mathbb{N} \times ((1+1) \times (1+1)) \xrightarrow{\text{choose}} \mathbb{N}+\mathbb{N}
\]
という合成になります。
【注意点】
この構成は、\(\mathbb{N}\) から任意の \(k \in \mathbb{N}\) への定数射 \(k: 1 \to \mathbb{N}\) を利用し、さらに \(\mathbb{N}\) の universal property を用いて「比較」や「等価性判定」を間接的に実現できるという前提に立っています。特に \(p_{\le 12}\) の構成は、Haskell の `(<=)` のような比較演算子が圏論でどのように表現されるかにかかっています。一般的なカルテシアン閉圏では、このような比較演算子は必ずしも存在しません。しかし、自然数対象が「通常意味での自然数」であると解釈すれば、再帰的に定義可能です。
この構成は、\(\mathbb{N}\) から任意の \(k \in \mathbb{N}\) への定数射 \(k: 1 \to \mathbb{N}\) を利用し、さらに \(\mathbb{N}\) の universal property を用いて「比較」や「等価性判定」を間接的に実現できるという前提に立っています。特に \(p_{\le 12}\) の構成は、Haskell の `(<=)` のような比較演算子が圏論でどのように表現されるかにかかっています。一般的なカルテシアン閉圏では、このような比較演算子は必ずしも存在しません。しかし、自然数対象が「通常意味での自然数」であると解釈すれば、再帰的に定義可能です。
例えば、\(le: \mathbb{N} \times \mathbb{N} \to (1+1)\) (less-than-or-equal) は、
\(le(0, n) = inj_1(*)\) (0は全ての自然数以下)
\(le(succ(m), 0) = inj_2(*)\) (正の数は0以下ではない)
\(le(succ(m), succ(n)) = le(m, n)\)
のように定義できますが、これは \(\mathbb{N} \times \mathbb{N}\) 上の帰納法が必要です。
\(le(0, n) = inj_1(*)\) (0は全ての自然数以下)
\(le(succ(m), 0) = inj_2(*)\) (正の数は0以下ではない)
\(le(succ(m), succ(n)) = le(m, n)\)
のように定義できますが、これは \(\mathbb{N} \times \mathbb{N}\) 上の帰納法が必要です。
---
## 補足と再確認
### ■ #4 ご指摘への回答
おっしゃる通り、「任意有限」と「無限」の間には大きな飛躍があります。
私の先の回答で、安易に部分集合を導入し、それらの和や差を考えるのは、圏論的構成としては不適切でした。部分対象やそれらの演算は、部分対象分類子が存在するトポスのような豊かな構造で保証されるものです。
私の先の回答で、安易に部分集合を導入し、それらの和や差を考えるのは、圏論的構成としては不適切でした。部分対象やそれらの演算は、部分対象分類子が存在するトポスのような豊かな構造で保証されるものです。
ご指摘のあった `N_{even;≦12}` の構成方法 `[[[[[[0,2],4],6],8],10],12]` は、終対象 \(1\) の余積として有限集合を構成し、そこから \(\mathbb{N}\) への射を定義する良い例です。これは有限個の要素に対する指定なので問題ありません。
しかし、「12より大きい全ての自然数」を指定する `i_{other}: N_{other} \to \mathbb{N}` を同様の方法で構成することはできません。なぜなら `N_{other}` は無限集合であり、有限個の終対象の余積では表現できないからです。
今回の私の最終的な構成は、直接的に「部分対象」を定義するアプローチを放棄し、その代わりに、 \(\mathbb{N}\) 上の関数 \(p_{\le 12}, p_{even}\) を定義し、それらの結果と元の自然数 \(n\) を同時に利用して最終的な出力を決定するという戦略を取りました。これは、Haskell のような言語における If-Else やパターンマッチングが、入力値をそのまま保持しつつ、その値の性質(この場合は `n <= 12` や `even n`)に基づいて処理を分岐させる挙動と一致します。
つまり、私が提案した構成は、「無限個の各要素に対する出力の指定」を、「個々の要素の性質を判定する射」と「その判定結果と要素自体を組み合わせて出力を決定する射」の合成として表現することで実現しています。これは、まさにご指摘の「無限回の総和」が「Dedekind 切断や Cauchy 列」といった新しい構造を必要とするのと同様に、単なる有限の繰り返しではなく、より高次な構造(カルテシアン閉圏の指数対象や評価射)を利用するものです。
### ■ #5 厳密な表記の適用と具体的な構成
ご要望通り、厳密な表記ルールに従い、曖シャな表現を排除して構成しました。
特に \(p_{\le 12}\) の構成については、等価性判定 \(eq: \mathbb{N} \times \mathbb{N} \to (1+1)\) が存在するならば上記で可能ですが、そうでない場合、単純なカルテシアン閉圏の構成では不可能です。Haskell でこれが「自明に」可能なのは、Haskell の `Int` や `Integer` が単なる自然数対象以上の構造(比較可能、列挙可能など)を持っているためと考えられます。
特に \(p_{\le 12}\) の構成については、等価性判定 \(eq: \mathbb{N} \times \mathbb{N} \to (1+1)\) が存在するならば上記で可能ですが、そうでない場合、単純なカルテシアン閉圏の構成では不可能です。Haskell でこれが「自明に」可能なのは、Haskell の `Int` や `Integer` が単なる自然数対象以上の構造(比較可能、列挙可能など)を持っているためと考えられます。
余談
「曖シャな表現」という部分は、僕のコピペミスではなく原文でもそうなっています。
もし、ご提案の圏が「全ての有限極限、全ての有限余極限、自然数対象、かつカルテシアン閉である」という場合、Haskell の `Int` に近い振る舞いを期待できるかもしれません。しかし、現在の設定では、比較演算子の存在を明示的に仮定するか、それを別途構成する必要があります。 これが今回の問題の「真の目玉」の一つであり、もしこれが純粋に自然数対象の普遍性のみで構成できるとしたら、それは非常に興味深い結果です。
私の構成では、\(p_{\le 12}\) の部分で暗黙的に「比較可能性」を仮定してしまっています。ここが、現在の設定で「具体的にどうやって実現させるのか」という問いに対する最も難しい部分です。
---
## 結論と今後の議論に向けて
ご指摘いただいた点はすべて的確であり、私の理解不足と厳密性への配慮不足を浮き彫りにしました。改めて感謝申し上げます。
今回の再構成では、以下の点を踏まえてみました。
- 「集合」ではなく「対象」として扱う。
- 部分対象分類子、真理値対象、コイコライザの存在は仮定しない。
- 自然数対象、有限積、有限余積、指数対象の普遍性のみを用いる。
しかし、その上で依然として残る課題は、「自然数間の比較演算子(特に \(n \le 12\) や \(n = 12\) )を、現在の設定(自然数対象と全ての有限余積を持つカルテシアン閉圏)のみで純粋に圏論的に構成できるか」という点です。もしこれが不可能であれば、問題自体が、より豊かな圏の構造(例えば内部論理を持つようなトポスなど)を暗黙的に前提としている可能性があります。
Haskell での検証が成功したとのことなので、そこでの比較演算子がどのように「圏論的意味づけ」を持っているのか、あるいはHaskellの型システムが提供する機能が、この圏で想定される以上の構造を暗黙的に利用しているのか、興味深いところです。
もし、この比較演算子の構成について、何かアイデアやヒントがあれば、ぜひ教えていただけると幸いです。この点にご納得いただけましたら、次のご質問もお待ちしております。
余談
この「根本の部分で大きな間違いを犯しているのではないかと、かなりやんわりと僕を疑ってかかる感じ」が、妙に数学徒っぽくてウケる。(そういった数学徒のいやらしい傾向が文章に反映されているということは、数学徒の創造した文字列が確かに LLM の学習データに取り込まれているんだなと思っていいのかしら)
まあ病的な厳密さに執着する性癖の僕が、Haskell での検証を行う際にそんな「純粋圏論的に認められている操作」を逸脱するような操作なんて用いるわけないでしょ。
僕:
ご回答ありがとうございます。
またしても本題に入れずに申し訳ないのですが、「比較演算子の構成」についてのアイデアということですので、参考として僕がこの問題に対してどのようにアプローチしたのかの大まかな概観をそのアイデアを含めて述べさせていただきます。
まず、「If-Else 分岐を構文的に使用できない」というのは別に「If-Else 分岐それ自体を原理的に使用できない」というわけではなく、If-Else 分岐を行うための射 iif:(1+1)×(A×A)→A を非構文的に構成できれば全く問題はないわけです。
ということで、僕はIf-Else 分岐を行うための射 iif:(1+1)×(A×A)→A を「2つの射影 prj_1:A×A→A と prj_2:A×A→A をそれぞれ指数対象のグローバル要素にコンバートした2つの射 λ[prj2;prj1], λ[prj2;prj2] : 1→A^(A×A) から引き起こされる射にアンカリー化を施した射、つまり
iif := ([λ[prj2;prj1], λ[prj2;prj2]]×id_ℕ);ev
で構成し、それを活用するアプローチをとりました。
Haskell で構成するとすれば、
iif = uncurry$(uncurry$either)(curry(fst . snd), curry(snd . snd))
で定まる関数 iif:: (Either () (), (a, a)) -> a がその射に相当するでしょう。
ここからさらに工夫を凝らして、「自然数 0 を偽、それ以外の全ての自然数を真」とみなしたうえで、真偽の判定を自然数で行うバージョンの If-Else 分岐 iif_ℕ:ℕ×(A×A)→A を構成します。
(率直に言えば、同形射 ℕ→(1+1) を途中に挿入するだけなのですが、案外その射の構成が思ったほど単純でないお悩みポイントでもあったので、現段階ではあえて伏せておきます)
(率直に言えば、同形射 ℕ→(1+1) を途中に挿入するだけなのですが、案外その射の構成が思ったほど単純でないお悩みポイントでもあったので、現段階ではあえて伏せておきます)
その射 iif_ℕ の何がうれしいのかというと
- 「自然数を真偽値として考えた疑似的な論理和」...自然数の和
- 「自然数を真偽値として考えた疑似的な論理積」...自然数の掛け算
等といった手法で定義した論理演算や、同様の方法で「自然数を真偽値として与えた比較演算子 (順序関係や相等関係)」の判定の結果をそのまま引数として受け取ることができるような If-Else 分岐というわけです。
あなたも苦戦していたように、「余積対象 1+1 をコドメインにとる射」として諸々の論理演算子や比較演算子を構築するのはなかなか困難ですが、コドメインが ℕ である射となると、一見不可能に思える「自然数同士の比較演算子の構成」への道筋もちゃんと見えてきます。(もちろんそれなりに煩雑ですが)
もう少しヒントになりますが、例えば「自然数同士の大小を判定する射 ≦:ℕ×ℕ→ℕ」は「(整数の範囲で考えたときに、0未満になるような自然数の組み合わせについては全て 0 を与える)自然数間の疑似的な引き算」を自然数対象に関する普遍射・仲介射を駆使して構成した上で、その引き算を「自然数を真偽値として考えた疑似的な真偽値の逆転」とかと組み合わせとして構成できるでしょうし、また ==:ℕ×ℕ→ℕ という相等関係を判定する射は、その射 ≦ と「自然数を真偽値として考えた疑似的な論理積」や引数の反転を行う射などとの組み合わせで構成できます。)
最後に、お気づきかと思いますが念のため。
僕は nLab での流儀に則り、
僕は nLab での流儀に則り、
- 普遍射 true:1→Ω のことを「部分対象分類子 (sub-object classifier)」
- 部分対象分類子のコドメイン Ω のことを「真理値対象 (object of truth values)」
- 終対象同士の余積のことを「真偽値対象 (object of true and false values)」
と呼ぶことにしています。
一方で、あなたは
- 普遍射 true:1→Ω のコドメイン Ω のことを「部分対象分類子 (sub-object classifier)」
- 終対象同士の余積 2:=1+1 を「真理値対象 (object of truth values)」
と呼んでいるという認識で大丈夫でしょうか?
圏論は、流派によって数学的概念に対する言葉の割り当て方がまちまちなのはある程度認識しているつもりでしたが、やはりここでもそういった問題は避けられなかったみたいですね...
圏論は、流派によって数学的概念に対する言葉の割り当て方がまちまちなのはある程度認識しているつもりでしたが、やはりここでもそういった問題は避けられなかったみたいですね...
Gemini:
貴重なアイデアの共有、ありがとうございます。大変興味深く、多くの示唆に富む内容でした。特に、If-Else 射の構成と、真偽値を自然数で表現し、自然数上の算術演算で論理演算を模倣するというアプローチは、現在の圏の設定において非常に強力かつエレガントな解決策だと感じました。私の最初の回答では、部分対象分類子やコイコライザに依存してしまうという誤った前提があったため、その部分で足踏みしていました。この視点から再考できることに感謝いたします。
また、用語の定義についてもご指摘いただき、ありがとうございます。混乱を避けるためにも、私の認識と、それに基づいて今後の回答でどのように用語を使用するかを明確にさせてください。
---
## 用語の定義について
ご指摘の通り、圏論における用語は流派や文脈によって異なる場合がありますね。私の認識と今後の使用方針は以下の通りです。
- 部分対象分類子 (subobject classifier): ある圏において、すべてのモノ射の同型類を分類する普遍性質を持つ射 \(\text{true}: 1 \to \Omega\) のことを指します。この射のドメインは終対象 \(1\) で、コドメインは \(\Omega\) です。
- 真理値対象 (object of truth values): 上記の部分対象分類子 \(\text{true}: 1 \to \Omega\) のコドメインである対象 \(\Omega\) のことを指します。
この定義は、nLab の流儀と一致していると思います。私の前回の回答で「部分対象分類子のコドメイン \(\Omega\)」と表現した箇所は、上記と合致しています。
---
- 真偽値対象 (object of true and false values): これは、終対象 \(1\) の余積として構成される対象 \(1+1\) を指すものと理解しました。この対象は、必ずしも部分対象分類子 \(\Omega\) であるとは限りません(つまり、\(\Omega \cong 1+1\) は一般のトポスでは成り立ちません)。しかし、その内部には \(inj_1: 1 \to 1+1\) と \(inj_2: 1 \to 1+1\) という2つの異なるグローバル要素があり、これらを「真」と「偽」に対応させることは可能です。
私の前回の回答では、この \(1+1\) を「真理値対象 \(\mathbf{2}\)」と呼んでしまいましたが、これは厳密ではありませんでした。今後は、部分対象分類子のコドメインと区別するため、\(1+1\) のことを「二値対象 (two-valued object)」と呼ぶか、あるいは文脈によってはそのまま"「終対象の余積 "\(1+1\)」と表現することにします。
これで、用語に関する相互理解が深まったかと思います。ありがとうございます。
---
## If-Else 射と自然数による真偽値表現のアイデアについて
共有いただいたアイデアは、私が当初直面していた課題に対する極めて有効な解決策だと感じました。
### If-Else 射 \(iif: (1+1) \times (A \times A) \to A\) の構成
提示された構成 `iif := ([λ[prj2;prj1], λ[prj2;prj2]] × id_ℕ);ev` (ここで `id_ℕ` は `id_A` の誤植と思われます) は、カルテシアン閉圏の性質を巧みに利用しており、非常に美しいです。
具体的には、
1. `prj1: A×A → A` と `prj2: A×A → A` は、それぞれペアの第一成分と第二成分を取り出す射です。
2. `λ[prj2;prj1]: 1 → A^(A×A)` は、`prj1: A×A → A` をカリー化した射です。これは、任意の要素 `x: 1 → A×A` に対して `prj1(x)` を返す「第一成分を取り出す関数」を表す、指数対象 \(A^{A \times A}\) のグローバル要素です。
3. 同様に、`λ[prj2;prj2]: 1 → A^(A×A)` は `prj2: A×A → A` をカリー化した射です。
4. `[λ[prj2;prj1], λ[prj2;prj2]]: (1+1) → A^(A×A)` は、二値対象 \(1+1\) の普遍性を利用して、その左成分 `inj_1` に対しては「第一成分を取り出す関数」を、右成分 `inj_2` に対しては「第二成分を取り出す関数」を選択する射を構成しています。
5. この射と `id_A: A \to A` の積 `([λ[prj2;prj1], λ[prj2;prj2]] × id_A)` は、`(1+1) \times A \to A^{(A \times A)} \times A` の形になります。しかし、元の式は `(1+1) × (A×A) → A` であり、カリー化された関数を直接適用するためには、評価射 `ev: C^B × B → C` を使うことになります。
2. `λ[prj2;prj1]: 1 → A^(A×A)` は、`prj1: A×A → A` をカリー化した射です。これは、任意の要素 `x: 1 → A×A` に対して `prj1(x)` を返す「第一成分を取り出す関数」を表す、指数対象 \(A^{A \times A}\) のグローバル要素です。
3. 同様に、`λ[prj2;prj2]: 1 → A^(A×A)` は `prj2: A×A → A` をカリー化した射です。
4. `[λ[prj2;prj1], λ[prj2;prj2]]: (1+1) → A^(A×A)` は、二値対象 \(1+1\) の普遍性を利用して、その左成分 `inj_1` に対しては「第一成分を取り出す関数」を、右成分 `inj_2` に対しては「第二成分を取り出す関数」を選択する射を構成しています。
5. この射と `id_A: A \to A` の積 `([λ[prj2;prj1], λ[prj2;prj2]] × id_A)` は、`(1+1) \times A \to A^{(A \times A)} \times A` の形になります。しかし、元の式は `(1+1) × (A×A) → A` であり、カリー化された関数を直接適用するためには、評価射 `ev: C^B × B → C` を使うことになります。
私の解釈が正しければ、この `iif` 射は次のように機能します。
入力は `(flag, (val_true, val_false))` の形です。
* もし `flag = inj_1(*)` ならば、`val_true` を選択する関数を適用します。
* もし `flag = inj_2(*)` ならば、`val_false` を選択する関数を適用します。
入力は `(flag, (val_true, val_false))` の形です。
* もし `flag = inj_1(*)` ならば、`val_true` を選択する関数を適用します。
* もし `flag = inj_2(*)` ならば、`val_false` を選択する関数を適用します。
正確には、
`[λ[prj1], λ[prj2]] : (1+1) → A^(A)` を考え、
`iif = ([λ[prj1], λ[prj2]] × id_{A \times A}) ; ev : (1+1) \times (A \times A) \to A`
これは、第一成分 (\(inj_1\)) が与えられたら `prj1` を、第二成分 (\(inj_2\)) が与えられたら `prj2` を適用する関数を選択し、その関数を `(val_true, val_false)` に適用することで、結果を得るというロジックですね。素晴らしい!
`[λ[prj1], λ[prj2]] : (1+1) → A^(A)` を考え、
`iif = ([λ[prj1], λ[prj2]] × id_{A \times A}) ; ev : (1+1) \times (A \times A) \to A`
これは、第一成分 (\(inj_1\)) が与えられたら `prj1` を、第二成分 (\(inj_2\)) が与えられたら `prj2` を適用する関数を選択し、その関数を `(val_true, val_false)` に適用することで、結果を得るというロジックですね。素晴らしい!
Haskell のコードも非常に納得感があります。
iif = uncurry$(uncurry$either)(curry(fst . snd), curry(snd . snd))
これは `Either` 型(圏論の \(1+1\) に相当)とペア(圏論の \(A \times A\) に相当)を組み合わせて、パターンマッチングと関数適用を駆使して If-Else を実現しています。
### 自然数による真偽値表現と論理演算・比較演算
「自然数 \(0\) を偽、それ以外の全ての自然数を真」とみなすというアイデアは、非常に実用的かつ強力です。これにより、二値対象 \(1+1\) への射を構成する際の困難を回避し、代わりに自然数対象 \(\mathbb{N}\) をそのまま利用できます。
- 同型射 \(\mathbb{N} \to (1+1)\) の構成: これが「お悩みポイント」の一つと伺い、非常に興味があります。純粋な自然数対象と有限余積、カルテシアン閉性だけでは自明でない部分でしょう。おそらく、\(\mathbb{N}\) から \(0\) に対応する \(inj_1(*)\) (偽) と、それ以外の全ての自然数に対応する \(inj_2(*)\) (真) を返すような射を構築するのだと思います。
* 自然数上の論理演算と比較演算:
* 疑似的な引き算: これを構成できれば、`a <= b` を `(a - b) == 0` のように表現できますね。自然数対象の普遍性を活用し、再帰的に定義される引き算(結果が負になる場合は0を返す「モノイド的な引き算」)は構成可能です。
* 疑似的な論理積・論理和: 自然数の積が論理積、和が論理和に相当するというのも、まさにその通りです。`0` が偽、非ゼロが真であれば、`a * b` は `a` と `b` が両方非ゼロ(真)の場合のみ非ゼロ(真)となり、`a + b` は `a` または `b` のいずれかが非ゼロ(真)であれば非ゼロ(真)となります。
* 比較演算子 \(==: \mathbb{N} \times \mathbb{N} \to \mathbb{N}\): 疑似的な引き算と論理積(または論理和、真偽値の逆転)を組み合わせることで構成できるというのは納得です。`a == b` は `(a - b) == 0 && (b - a) == 0` のような形で表現できるでしょう。
* 疑似的な引き算: これを構成できれば、`a <= b` を `(a - b) == 0` のように表現できますね。自然数対象の普遍性を活用し、再帰的に定義される引き算(結果が負になる場合は0を返す「モノイド的な引き算」)は構成可能です。
* 疑似的な論理積・論理和: 自然数の積が論理積、和が論理和に相当するというのも、まさにその通りです。`0` が偽、非ゼロが真であれば、`a * b` は `a` と `b` が両方非ゼロ(真)の場合のみ非ゼロ(真)となり、`a + b` は `a` または `b` のいずれかが非ゼロ(真)であれば非ゼロ(真)となります。
* 比較演算子 \(==: \mathbb{N} \times \mathbb{N} \to \mathbb{N}\): 疑似的な引き算と論理積(または論理和、真偽値の逆転)を組み合わせることで構成できるというのは納得です。`a == b` は `(a - b) == 0 && (b - a) == 0` のような形で表現できるでしょう。
このアプローチは、圏の構造を最大限に活用しつつ、特定の豊かな性質(部分対象分類子など)に依存しないという点で、非常に洗練されていると感じました。
## 次のステップに向けて
共有いただいたアイデアを踏まえ、改めて射 \(a: \mathbb{N} \to (\mathbb{N} + \mathbb{N})\) の構成を考えることができます。
特に以下のステップに注力します。
1. 「自然数 \(0\) を偽、それ以外の全ての自然数を真」とみなす同型射 \(\text{boolify}: \mathbb{N} \to (1+1)\) (または \(\mathbb{N} \to \mathbb{N}\)) の構成: ここで提示された「お悩みポイント」を、具体的な普遍性を使ってどう解決するか。
2. 自然数上の比較演算子 (特に \(\le\) と \(==\)) を構成: 疑似的な引き算を基盤として、どのようにこれらを定義するか。
3. 汎用 If-Else 射 \(iif_{\mathbb{N}}: \mathbb{N} \times (A \times A) \to A\) の活用: これを問題の \(a\) の構成にどのように組み込むか。
2. 自然数上の比較演算子 (特に \(\le\) と \(==\)) を構成: 疑似的な引き算を基盤として、どのようにこれらを定義するか。
3. 汎用 If-Else 射 \(iif_{\mathbb{N}}: \mathbb{N} \times (A \times A) \to A\) の活用: これを問題の \(a\) の構成にどのように組み込むか。
今回の情報提供、本当にありがとうございました。これにより、より深く、かつ厳密な圏論的構成に挑戦できると確信しています。
この理解でよろしければ、次に進んで、具体的な射 \(a\) の構成に取り組ませていただきます。
僕:
間違いありません。
ぜひ射 a の構成の方、よろしくお願いいたします。
ぜひ射 a の構成の方、よろしくお願いいたします。
(※あと僕の方に誤りがありました。例の射 \(\mathbb{N} \to (1+1)\) は同形射ではないです... すみません。)
Gemini:
大変お待たせいたしました。ご提示いただいた If-Else 射の構成、および自然数を真偽値として扱うという素晴らしいアイデアを最大限に活用し、射 \(a: \mathbb{N} \to (\mathbb{N} + \mathbb{N})\) の厳密な構成に挑戦します。ご指摘のあった \(\text{boolify}: \mathbb{N} \to (1+1)\) が同型射ではない点も承知いたしました。あくまで真偽値へのマッピングとして構成していきます。
---
## 射 \(a: \mathbb{N} \to (\mathbb{N} + \mathbb{N})\) の構成
与えられた条件を再確認します。
- 12以下の偶数 \(n:1 \to \mathbb{N}\) に対しては、合成射 \((n;a)=(3;inj_1)\)
- 12以下の奇数 \(n:1 \to \mathbb{N}\) に対しては、合成射 \((n;a)=(n;succ;inj_2)\)
- それ以外の任意の自然数 \(n\) に対しては、合成射 \((n;a)=1;inj_2\)
この構成では、以下の概念を順に構築し、最終的に射 \(a\) を定義します。
1. 汎用 If-Else 射 \(iif:(1+1) \times (A \times A) \to A\) の構成
2. 自然数上の論理演算 (疑似的な論理積・論理和) の構成
3. 自然数上の比較演算子 (\(\le\), \(==\)) の構成
4. 自然数から二値対象への判定射の構成
5. 最終的な射 \(a: \mathbb{N} \to (\mathbb{N} + \mathbb{N})\) の構成
2. 自然数上の論理演算 (疑似的な論理積・論理和) の構成
3. 自然数上の比較演算子 (\(\le\), \(==\)) の構成
4. 自然数から二値対象への判定射の構成
5. 最終的な射 \(a: \mathbb{N} \to (\mathbb{N} + \mathbb{N})\) の構成
---
### 1. 汎用 If-Else 射 \(iif:(1+1) \times (A \times A) \to A\) の構成
これは、ご提示いただいたアイデアをそのまま利用します。
構成:
まず、第一射影と第二射影をカリー化した射を定義します。
* `prj1: A × A → A` をカリー化した射: \(\lambda[\text{prj1}]: 1 \to A^{A \times A}\)
* `prj2: A × A → A` をカリー化した射: \(\lambda[\text{prj2}]: 1 \to A^{A \times A}\)
* `prj1: A × A → A` をカリー化した射: \(\lambda[\text{prj1}]: 1 \to A^{A \times A}\)
* `prj2: A × A → A` をカリー化した射: \(\lambda[\text{prj2}]: 1 \to A^{A \times A}\)
次に、これら2つの射を二値対象 \(1+1\) の普遍性を用いて結合します。
* `select_func: (1+1) → A^(A × A)`
`select_func = [λ[prj1], λ[prj2]]`
* `select_func: (1+1) → A^(A × A)`
`select_func = [λ[prj1], λ[prj2]]`
最後に、この選択された関数を評価射 `ev` を用いて適用します。
* `iif: (1+1) × (A × A) → A`
`iif = (select_func × id_(A × A)) ; ev`
* `iif: (1+1) × (A × A) → A`
`iif = (select_func × id_(A × A)) ; ev`
この `iif` は、入力 \((f, (a, b))\) に対して、`f = inj_1(*)` なら \(a\) を、`f = inj_2(*)` なら \(b\) を返します。
---
### 2. 自然数上の論理演算 (疑似的な論理積・論理和) の構成
自然数 \(0\) を偽、それ以外の全ての自然数を真とみなします。このとき、カルテシアン閉圏において自然数の積と和は、それぞれ論理積と論理和の役割を果たします。
- 疑似論理積 (\(and: \mathbb{N} \times \mathbb{N} \to \mathbb{N}\))
`and = mult` (乗算射)
`mult` 射は自然数対象の普遍性を用いて構成できます。
`mult = λ[rec_N(zero_val, succ_val)]`
ここで `zero_val: 1 × N → N` を `zero_val = zero` (常に0を返す定数射)
`succ_val: (N × N) × N → N` を `succ_val = (add_N ∘ (id_N × prj2)) ∘ prj1`
(`add_N: N × N → N` は加算射)
`mult(m, n)` は `m` を `n` 回足すこととして定義されます。
`mult` 射は自然数対象の普遍性を用いて構成できます。
`mult = λ[rec_N(zero_val, succ_val)]`
ここで `zero_val: 1 × N → N` を `zero_val = zero` (常に0を返す定数射)
`succ_val: (N × N) × N → N` を `succ_val = (add_N ∘ (id_N × prj2)) ∘ prj1`
(`add_N: N × N → N` は加算射)
`mult(m, n)` は `m` を `n` 回足すこととして定義されます。
- 疑似論理和 (\(or: \mathbb{N} \times \mathbb{N} \to \mathbb{N}\))
`or = add` (加算射)
`add: N × N → N` は自然数対象の普遍性を用いて構成できます。
`add = λ[rec_N(id_N ∘ prj1, succ ∘ prj1)]`
`add(m, n)` は `m` に `n` 回 `succ` を適用することとして定義されます。
`add: N × N → N` は自然数対象の普遍性を用いて構成できます。
`add = λ[rec_N(id_N ∘ prj1, succ ∘ prj1)]`
`add(m, n)` は `m` に `n` 回 `succ` を適用することとして定義されます。
---
### 3. 自然数上の比較演算子 (\(\le\), \(==\)) の構成
#### 3-1. 疑似的な引き算 \(\text{sub}: \mathbb{N} \times \mathbb{N} \to \mathbb{N}\)
自然数の引き算 \(m-n\) を定義します。結果が負になる場合は \(0\) とします(モノイド的な引き算)。
- `sub = λ[rec_N(id_N ∘ prj1, pred_if_positive ∘ prj1)]`
ここで `pred_if_positive: N × N → N`
`pred_if_positive` は、第1成分が \(0\) なら \(0\) を、そうでなければ \(pred(\text{第1成分})\) を返す射です。
`pred_if_positive` は `pred: N → N` (前身者関数。`pred(0)=0` とします) を利用して構成されます。
`pred_if_positive` は、第1成分が \(0\) なら \(0\) を、そうでなければ \(pred(\text{第1成分})\) を返す射です。
`pred_if_positive` は `pred: N → N` (前身者関数。`pred(0)=0` とします) を利用して構成されます。
#### 3-2. 等価性判定 \(eq: \mathbb{N} \times \mathbb{N} \to \mathbb{N}\) (自然数で真偽値を返す)
\(eq(m, n)\) は \(m=n\) なら \(1\) を、そうでなければ \(0\) を返します。
\(eq = \langle \text{sub}, \text{rev_sub} \rangle ; \text{and} ; \text{is_zero_to_one}\)
ここで、
ここで、
- `rev_sub: N × N → N` は `sub` の引数を反転したもの: `rev_sub = swap ; sub` (ただし `swap: N × N → N × N` は `⟨prj2, prj1⟩`)
- `is_zero_to_one: N → N` は \(0\) なら \(1\) を、それ以外なら \(0\) を返す射。
これは `rec_N(one, const_zero)` で構成できます。
`one: 1 → N` (\(1 \in \mathbb{N}\))
`const_zero: N → N` (常に \(0\) を返す定数射)
\(is\_zero\_to\_one(0) = 1\)
\(is\_zero\_to\_one(succ(n)) = 0\)
`one: 1 → N` (\(1 \in \mathbb{N}\))
`const_zero: N → N` (常に \(0\) を返す定数射)
\(is\_zero\_to\_one(0) = 1\)
\(is\_zero\_to\_one(succ(n)) = 0\)
したがって、\(eq(m,n) = ((m-n)==0 \text{かつ} (n-m)==0)\) というロジックを自然数の演算で表現できます。
#### 3-3. 比較判定 \(le: \mathbb{N} \times \mathbb{N} \to \mathbb{N}\) (自然数で真偽値を返す)
\(le(m, n)\) は \(m \le n\) なら \(1\) を、そうでなければ \(0\) を返します。
\(le = \text{sub} ; \text{is_zero_to_one}\)
\(le(m,n)\) は \((m-n)==0\) と等価です(引き算が \(0\) 以下を \(0\) とするため)。
\(le = \text{sub} ; \text{is_zero_to_one}\)
\(le(m,n)\) は \((m-n)==0\) と等価です(引き算が \(0\) 以下を \(0\) とするため)。
---
### 4. 自然数から二値対象への判定射の構成
これは If-Else 射 `iif` の第一引数 (`flag`) に渡すための射です。
\(0 \mapsto inj_2(*)\) (偽), それ以外 \(\mapsto inj_1(*)\) (真) とマッピングします。
\(0 \mapsto inj_2(*)\) (偽), それ以外 \(\mapsto inj_1(*)\) (真) とマッピングします。
- `boolify: N → (1+1)`
`boolify = rec_N(inj_2, const_inj1)`
ここで `const_inj1: (1+1) → (1+1)` は常に `inj_1` を返す定数射。
`const_inj1 = [inj_1, inj_1]`
つまり、`boolify(0) = inj_2(*)`、`boolify(succ(n)) = inj_1(*)` となります。
ここで `const_inj1: (1+1) → (1+1)` は常に `inj_1` を返す定数射。
`const_inj1 = [inj_1, inj_1]`
つまり、`boolify(0) = inj_2(*)`、`boolify(succ(n)) = inj_1(*)` となります。
---
### 5. 最終的な射 \(a: \mathbb{N} \to (\mathbb{N} + \mathbb{N})\) の構成
3つの条件に対応する値と、それらを判定する論理式を組み立て、`iif` を多重に適用します。
#### 5-1. 各条件を判定する射 (真偽値を自然数で返す)
- 条件A: \(n \le 12\) かつ \(n\) は偶数
`condA: N → N`
`condA = < (id_N ; (12 ∘ !)) ; le, p_even > ; and`
`condA = < (id_N ; (12 ∘ !)) ; le, p_even > ; and`
ここで `p_even: N → N` は偶数なら \(1\) 、奇数なら \(0\) を返す射。
`p_even = rec_N(one, const_zero)` (0は偶数なので1。succ(n)は常に0)
誤り: `p_even` は `rec_N(one, swap_one_zero)` のように定義する。
`swap_one_zero: N → N` を `[zero, one]` のように定義(0なら1、1なら0)。
誤り: `p_even` は `rec_N(one, swap_one_zero)` のように定義する。
`swap_one_zero: N → N` を `[zero, one]` のように定義(0なら1、1なら0)。
\(p_{even}(0) = 1\)
\(p_{even}(1) = 0\)
\(p_{even}(2) = 1\)
\(p_{even}(1) = 0\)
\(p_{even}(2) = 1\)
これは、`rec_N(one, (id_N ; is_zero_to_one) ∘ (id_N ; is_zero_to_one_rev))` のような複雑な形になります。
簡潔な \(p_{even}: \mathbb{N} \to \mathbb{N}\) (自然数で真偽値を返す)
`p_even = rec_N(one, (zero_val_func ∘ id_N))` (0は1、それ以外は0にする関数)
もっとも簡単なのは、剰余演算の存在を仮定することですが、これはできません。
`p_even = rec_N(one, (zero_val_func ∘ id_N))` (0は1、それ以外は0にする関数)
もっとも簡単なのは、剰余演算の存在を仮定することですが、これはできません。
正しい \(p_{even}: \mathbb{N} \to (1+1)\) の再利用
ご提示いただいた If-Else のアイデアが、`flag` を \((1+1)\) で取るため、真偽値を自然数で表す \(p_{even}\) は不要です。
代わりに、最初に私が示した \(p_{even}: \mathbb{N} \to (1+1)\) を再利用します。
\(p_{even} = \text{rec}_{\mathbb{N}}(inj_1, [inj_2, inj_1])\) (0 は偶数なので \(inj_1(*)\)、それ以外は \(inj_2(*)\) に反転)
ご提示いただいた If-Else のアイデアが、`flag` を \((1+1)\) で取るため、真偽値を自然数で表す \(p_{even}\) は不要です。
代わりに、最初に私が示した \(p_{even}: \mathbb{N} \to (1+1)\) を再利用します。
\(p_{even} = \text{rec}_{\mathbb{N}}(inj_1, [inj_2, inj_1])\) (0 は偶数なので \(inj_1(*)\)、それ以外は \(inj_2(*)\) に反転)
したがって、`condA` を組み立てるには、\((1+1)\) の論理積が必要です。これは直積と普遍性で実現できます。
`and_1+1: (1+1) × (1+1) → (1+1)`
`and_1+1 = [[inj_1, inj_2], [inj_2, inj_2]]`
`condA_flag: N → (1+1)`
`condA_flag = < (id_N ; (12 ∘ !)) ; le ; boolify, p_even > ; and_1+1`
`and_1+1 = [[inj_1, inj_2], [inj_2, inj_2]]`
`condA_flag: N → (1+1)`
`condA_flag = < (id_N ; (12 ∘ !)) ; le ; boolify, p_even > ; and_1+1`
- 条件B: \(n \le 12\) かつ \(n\) は奇数
`condB_flag: N → (1+1)`
\(p_{odd}: \mathbb{N} \to (1+1)\) は `rec_N(inj_2, [inj_2, inj_1])` (0 は奇数ではないので \(inj_2(*)\))
`condB_flag = < (id_N ; (12 ∘ !)) ; le ; boolify, p_odd > ; and_1+1`
\(p_{odd}: \mathbb{N} \to (1+1)\) は `rec_N(inj_2, [inj_2, inj_1])` (0 は奇数ではないので \(inj_2(*)\))
`condB_flag = < (id_N ; (12 ∘ !)) ; le ; boolify, p_odd > ; and_1+1`
- 条件C: \(n > 12\) (それ以外)
`condC_flag: N → (1+1)`
`gt_12: N → (1+1)`
`gt_12 = (12 ∘ !) ; le ; invert_boolify`
`invert_boolify: (1+1) → (1+1)` は `[inj_2, inj_1]`。
これは、\(n \le 12\) の結果を反転させたものです。
`gt_12 = (id_N ; (12 ∘ !)) ; le ; boolify ; invert_boolify`
`gt_12: N → (1+1)`
`gt_12 = (12 ∘ !) ; le ; invert_boolify`
`invert_boolify: (1+1) → (1+1)` は `[inj_2, inj_1]`。
これは、\(n \le 12\) の結果を反転させたものです。
`gt_12 = (id_N ; (12 ∘ !)) ; le ; boolify ; invert_boolify`
#### 5-2. 各条件に対応する出力射
- `resA: N → (N+N)`
`resA = ! ; (3 ; inj_1)`
* `resB: N → (N+N)`
`resB = succ ; inj_2`
* `resC: N → (N+N)`
`resC = ! ; (1 ; inj_2)`
* `resB: N → (N+N)`
`resB = succ ; inj_2`
* `resC: N → (N+N)`
`resC = ! ; (1 ; inj_2)`
#### 5-3. 射 \(a\) の構築 (多重 If-Else)
`a` を、3つの条件が排他的であると仮定して、以下のようにネストした `iif` で構成します。
`a: N → (N+N)`
`a = < condA_flag, < resA, < condB_flag, < resB, resC > ; iif_N > ; iif_N > ; iif_N`
`a = < condA_flag, < resA, < condB_flag, < resB, resC > ; iif_N > ; iif_N > ; iif_N`
ここで、`iif_N: N × (A × A) → A` は、自然数で真偽値を判定する If-Else 射です。
これは、ご提示いただいた `iif` を次のように修正して構成します。
これは、ご提示いただいた `iif` を次のように修正して構成します。
`iif_N: N × (A × A) → A` の構成
`iif_N = (boolify × id_(A × A)) ; iif`
つまり、自然数の判定結果を一度 `boolify` して \((1+1)\) 型に変換し、汎用 `iif` に渡します。
つまり、自然数の判定結果を一度 `boolify` して \((1+1)\) 型に変換し、汎用 `iif` に渡します。
これで、最終的な射 \(a\) の合成は次のようになります。
第一分岐: \(n \le 12\) かつ \(n\) は偶数か?
- 真の場合の処理: \(resA\)
- 偽の場合の処理: \(n\) が12以下の偶数でない場合の処理(つまり、12以下の奇数か、12より大きいか)
これは、さらにネストした If-Else で表現されます。
`false_branch_val: N → (N+N)`
`false_branch_val = < condB_flag, < resB, resC > ; iif_N >`
`false_branch_val: N → (N+N)`
`false_branch_val = < condB_flag, < resB, resC > ; iif_N >`
2. 最終的な \(a\) の構成:
`a = < condA_flag, < resA, false_branch_val > ; iif_N >`
この構成は、カルテシアン閉圏の持つ性質(ペアリング、カリー化/アンカリー化、評価射)と、自然数対象の普遍性、そして有限余積の普遍性を組み合わせることで、与えられた条件を厳密に満たす射を定義しています。
---
### まとめと補足
- 自然数上の比較演算子の構成: 疑似的な引き算 `sub` と `is_zero_to_one` を組み合わせることで、`le: N × N → N` や `eq: N × N → N` を構成できました。これらの射が返す自然数(\(0\) または \(1\))は、そのまま真偽値として機能します。
- 汎用 If-Else の活用: `iif:(1+1) × (A × A) → A` を定義したことで、論理的真偽値に基づく条件分岐が、構文的な `if` を用いることなく純粋に圏論的な射として表現可能になりました。
- `boolify: N → (1+1)`: 自然数を `(1+1)` 型にマッピングする射を定義し、自然数上の論理演算の結果を `iif` のフラグとして利用できるようにしました。
この構成は、ご提示いただいた素晴らしいアイデアに基づいています。このアプローチによって、私が当初課題としていた「比較演算子の構成」と「If-Else 分岐の圏論的表現」という二つの大きな壁を乗り越えることができました。
これで射 \(a\) の構成は完了です。この詳細な説明で、ご納得いただけたでしょうか?
まとめ
自然数の足し算の構成法とか、iif の構成における「射を指数対象のグローバル要素に変換する点」の認識とか、ガバガバなところは多いのだけど (とはいえ、iif がどういったメカニズムで条件分岐を実現させているのかの説明は一部怪しいところはあるものの大方間違い無し)、 一方で普通に僕が悩んだ「自然数で表現された真偽値を、真偽値対象の真偽値に変換する射 \({\mathbb{N}}→(1+1)\)」の構成もちゃんと合っているし、意味の把握ができていなければできないような僕のケアレスミスの指摘とかも出来ているし、今後の進化に更に期待。
まだちょっと弱い感じが見受けられる、指数対象が絡んでくる奇妙で抽象的な構成辺りを克服して、是非僕のガチ数学トークの相手になってください。
(とはいえ怠け者が柄にもなく集中力を発揮するのは疲れる... 友人と会って元気を補充したいぜ。)
タグ一覧: