---
title: "選択原理"
module: Base.Choice
lang: ja
site: "Bedrock"
description: "選択原理"
stage: "基礎"
reading_order: 5
canonical: https://bedrock.institute/ja/Base.Choice.html
html: Base.Choice.html
agda_source: https://github.com/BedrockInstitute/Bedrock/blob/main/src/Base/Choice.lagda.md
prerequisites: [Base.Prelude, Base.Classical]
routes: [common-foundations]
translations: [https://bedrock.institute/en/Base.Choice.md, https://bedrock.institute/zh/Base.Choice.md]
agent_guide: https://bedrock.institute/llms.txt
license: "CC-BY-NC-SA-4.0"
---


```agda
{-# OPTIONS --cubical --safe --guardedness #-}
module Base.Choice where
```

# 選択原理

```agda
open import Base.Prelude
open import Base.Classical using ( LEM )
```

型の族の各型に要素があることと、すべての型から要素を選ぶ一つの関数をもつことは異なる。命題的切り詰めはこの違いを正確に表す。`∥ B x ∥₁` は個々の添字における存在を述べ、`∥ ((x : X) → B x) ∥₁` は選択関数全体の存在を述べる。本章では、h-集合で添字付けられた h-集合値の族について選択原理を定式化し、一つ上の宇宙レベルでの選択原理が現在のレベルでの選択原理を含意することを示し、選択原理が排中律を含意することを証明する。

## 原理

族 `B : X → Type ℓ` に対し、三種類のデータを区別する。各 `B x` の要素がすでに `x` の関数として与えられているなら、その関数自体が選択関数である。追加の原理が扱うのは、切り詰められた、より弱い入力である。

| 主張 | 得られるもの |
| --- | --- |
| `(x : X) → B x` | 値を計算できる選択関数 |
| `(x : X) → ∥ B x ∥₁` | 添字ごとの存在 |
| `∥ ((x : X) → B x) ∥₁` | すべての添字を扱う一つの関数の存在 |
: 選択に関わる三種類のデータ。関数そのもの、各点での単なる存在、関数全体の単なる存在

**定義** (`SetChoice`) レベル `ℓ` の集合値族に対する選択は、任意の h-集合 `X : Type ℓ` と、<span class="prose-annotation-target">各値 `B x` が h-集合である族 `B : X → Type ℓ`</span><aside class="prose-annotation-note">これは HoTT の教科書にある集合値族の形である。任意の値を許す形はより強く、すべての型が h-集合からの全射を単にもつことも含意する。本書の二つの適用には、この追加の強さは要らない。</aside>に対し、上の表の第二行から第三行が従うと主張する。

```agda
SetChoice : ∀ ℓ → Type (ℓ-suc ℓ)
SetChoice ℓ = (X : Type ℓ) → isSet X → (B : X → Type ℓ)
            → ((x : X) → isSet (B x))
            → ((x : X) → ∥ B x ∥₁) → ∥ ((x : X) → B x) ∥₁
```

切り詰めは依存関数型の外へ移るが、消えるわけではない。したがって仮定 `sc : SetChoice ℓ` が与えるのは、選択関数の単なる存在である。この存在を `rec₁` で使うには、目標が命題でなければならない。`Type ℓ` 全体を量化するので、原理自体は `Type (ℓ-suc ℓ)` に住む。

**補題** (`lowerSetChoice`) 一つ上の宇宙レベルの選択は、一つ下のレベルの選択を含意する。

```agda
lowerSetChoice : ∀ {ℓ} → SetChoice (ℓ-suc ℓ) → SetChoice ℓ
```

**証明** `sc : SetChoice (ℓ-suc ℓ)` が与えられたとする。`SetChoice ℓ` を示すには、任意に与えられた h-集合の添字型 `X` と h-集合値の族 `B` について、前提 `inh : (x : X) → ∥ B x ∥₁` から `∥ ((x : X) → B x) ∥₁` を導けばよい。`inh` は *inhabited* の略であり、各点での単なる存在を与えるだけで、具体的な元は選ばない。`sc` は一つ上の宇宙レベルの族を扱うので、`Lift` でこの選択問題をそのレベルへ移す。下図は、元のレベルから上がり、選択原理を適用し、元のレベルへ戻る流れを示す。

<figure class="book-diagram choice-lift-figure" id="fig-lower-set-choice" aria-describedby="fig-lower-set-choice-caption">
<div class="diagram-framed">
<div class="choice-lift-flow">
<div class="choice-lift-legend">

$$\widehat B\,\hat x := \operatorname{Lift}(B(\operatorname{lower}\,\hat x))$$

</div>
<div class="diagram-space choice-lift-source">

$$(x:X)\to\|B\,x\|_1$$

</div>
<div class="choice-lift-step choice-lift-up"><span class="choice-lift-wide-arrow" aria-hidden="true">$\uparrow$</span><span class="choice-lift-narrow-arrow" aria-hidden="true">$\downarrow$</span> $\operatorname{map}_1\,\operatorname{lift}$</div>
<div class="diagram-space choice-lift-input">

$$(\hat x:\operatorname{Lift}X)\to\|\widehat B\,\hat x\|_1$$

</div>
<div class="choice-lift-step choice-lift-choice"><span class="choice-lift-wide-arrow" aria-hidden="true">$\rightarrow$</span><span class="choice-lift-narrow-arrow" aria-hidden="true">$\downarrow$</span> $\operatorname{sc}$</div>
<div class="diagram-space choice-lift-output">

$$\|(\hat x:\operatorname{Lift}X)\to\widehat B\,\hat x\|_1$$

</div>
<div class="choice-lift-step choice-lift-down"><span aria-hidden="true">$\downarrow$</span> $\operatorname{map}_1$</div>
<div class="diagram-space choice-lift-target">

$$\|(x:X)\to B\,x\|_1$$

</div>
</div>
</div>
<figcaption id="fig-lower-set-choice-caption">

高いレベルの選択から元のレベルの選択を得る流れ。入力を持ち上げ、選択原理を適用し、結果を元のレベルへ戻す

</figcaption>
</figure>

一つ上のレベルで `sc` を適用するには、持ち上げた添字型と族の各値が h-集合であることも示す必要がある。次の表は、その証明を元のレベルで与えられた性質からどう得るかを中心に、他の引数との対応も示す。

| レベル `ℓ` | レベル `ℓ-suc ℓ` |
| --- | --- |
| `X` | `Lift X` |
| `setX` | `isOfHLevelLift 2 setX` |
| `B x` | `Lift (B (lower x̂))`、ただし `x̂ : Lift X` |
| `setB x` | `isOfHLevelLift 2 (setB (lower x̂))` |
| `inh x` | `map₁ lift (inh (lower x̂))` |
: 高いレベルの引数は、元のレベルですでに与えられたデータから構成される

下の Agda コードは図と表を一つにつなぐ。表の右列が中央の選択に必要な入力を与え、コードの入れ子構造が図の上昇、選択原理の適用、元のレベルへの帰還に対応する。式全体の型は図の下端に示した目標そのものである。

```agda
lowerSetChoice sc X setX B setB inh = map₁ (λ f x → lower (f (lift x)))
         (sc (Lift X) (isOfHLevelLift 2 setX)
             (λ x̂ → Lift (B (lower x̂)))
             (λ x̂ → isOfHLevelLift 2 (setB (lower x̂)))
             (λ x̂ → map₁ lift (inh (lower x̂))))
```

## ディアコネスクの定理

代表元を選ぶことから、任意の命題をどう判定できるのだろうか。前章では判定を得てから命題をブール値で符号化した。ここでは順序が逆になる。命題を判定せずに商を構成し、選択によってブール値を得て、その比較から判定を導く。

非公開の部分モジュール `Diaconescu` で任意の `P : hProp ℓ` を固定し、対応する商と補助結果を構成する。最後の定理はそれらを用いて、選択から `P` の判定を得る。

<details open class="submodule-fold">
<summary class="submodule-fold-heading">

```agda
private module Diaconescu {ℓ} (P : hProp ℓ) where
```

</summary>
<div class="submodule-fold-content">

まず、以下で使う集合商と二項関係の道具を導入する。型 `A` と関係 `R` に対し、商 `A / R` は点 `[ a ]` をもち、`R a b` の証明からパス `[ a ] ≡ [ b ]` が得られる。`squash/` はその結果が h-集合であることを保証する。`BinaryRelation` は、これから検証する関係の法則を記述するために使う。ここで導入する同型定理 `isEquivRel→effectiveIso` は、`R` が命題値の同値関係ならば、商におけるパス `[ a ] ≡ [ b ]` と `R a b` の証明が同型になることを述べる。これにより、商の点の等しさを元の関係から理解できる。

```agda
  open import Cubical.HITs.SetQuotients
    using ( _/_; [_]; squash/; []surjective; isEquivRel→effectiveIso )
  open import Cubical.Relation.Binary.Base using ( module BinaryRelation )
```

**構成** (`_~_`) `Bool` 上の関係を、対角成分は常に要素をもち、非対角成分は `⟨ P ⟩` となるように定める。異なる二つのブール値が関係をもつかどうかを `P` が決める。

```agda
  _~_ : Bool → Bool → Type ℓ
  true  ~ true  = ⊤*
  false ~ false = ⊤*
  _     ~ _     = ⟨ P ⟩
```

**構成** (`Glued`) この関係による商を取る。二つの点 `[ true ]` と `[ false ]` の間のパスを、`P` の証明によって特徴付けたい。`_~_` が命題値の同値関係であることを確かめれば、同型定理を適用できる。

```agda
  Glued : Type ℓ
  Glued = Bool / _~_
```

**補題** (`~-prop`) いま構成した商に同型定理を使うには、関係が命題値で同値律を満たす必要がある。検証には `_~_` の定義だけを使う。対角成分は命題 `⊤*` であり、非対角成分は `P` に含まれる命題である。

```agda
  ~-prop : BinaryRelation.isPropValued _~_
  ~-prop true  true  = isProp⊤*
  ~-prop false false = isProp⊤*
  ~-prop true  false = ⟨ P ⟩isProp
  ~-prop false true  = ⟨ P ⟩isProp
```

**補題** (`~-refl`) 対角成分の要素 `tt*` が反射性を証明する。

```agda
  ~-refl : (a : Bool) → a ~ a
  ~-refl true  = tt*
  ~-refl false = tt*
```

**補題** (`~-sym`) 入力を交換しても成分の型は変わらない。対角では `tt*` を返し、非対角では与えられた `P` の証明を再利用する。

```agda
  ~-sym : (a b : Bool) → a ~ b → b ~ a
  ~-sym true  true  _ = tt*
  ~-sym false false _ = tt*
  ~-sym true  false p = p
  ~-sym false true  p = p
```

**補題** (`~-trans`) 推移性では両端 `a` と `c` を見る。一致するなら `tt*` が `a ~ c` を証明する。

```agda
  ~-trans : (a b c : Bool) → a ~ b → b ~ c → a ~ c
  ~-trans true  _     true  _ _ = tt*
  ~-trans false _     false _ _ = tt*
```

両端が異なるなら、中間のブール値はどちらか一方に等しいため、二つの前提の一方がすでに `P` の証明である。それを返せばよい。

```agda
  ~-trans true  false false p _ = p
  ~-trans false true  true  p _ = p
  ~-trans true  true  false _ p = p
  ~-trans false false true  _ p = p
```

**補題** (`~-equivRel`) 三つの法則を、同型定理が要求する同値関係のレコードにまとめる。

```agda
  ~-equivRel : BinaryRelation.isEquivRel _~_
  ~-equivRel = BinaryRelation.equivRel ~-refl ~-sym ~-trans
```

**補題** (`quotientPath≃P`) これらの法則を確認すると、同型定理を適用できる。これは `[ true ]` と `[ false ]` の間のパス型と `true ~ false` の同型を与える。後者は定義上 `⟨ P ⟩` である。この同型を `isoToEquiv` で次の型同値に変換する。

```agda
  quotientPath≃P : ([ true ] ≡ [ false ]) ≃ ⟨ P ⟩
  quotientPath≃P = isoToEquiv
    (isEquivRel→effectiveIso ~-prop ~-equivRel true false)
```

図中の $e$ は `quotientPath≃P` の略記である。順方向の写像はパスを `P` の証明へ、逆方向の写像は証明をパスへ送る。以下は `P` の証明または反証があるときの帰結を示すもので、どちらかがすでに得られているとは仮定しない。

<figure class="book-diagram type-comparison path-figure" id="fig-choice-gluing" aria-describedby="fig-choice-gluing-caption">
<div class="diagram-framed">

$$([\mathsf{true}] \equiv [\mathsf{false}]) \simeq \langle P\rangle$$

<div class="type-comparison-panels">
<div class="type-comparison-panel">

$$p : \langle P\rangle$$

<div class="path-stage diagram-compact-stage" style="aspect-ratio:300/190">
<svg viewBox="0 0 300 190" aria-hidden="true" focusable="false">
<rect class="diagram-space-shape" x="12" y="12" width="276" height="166"/>
<path class="diagram-path" d="M 70 115 Q 150 55 230 115"/>
<circle class="diagram-point" cx="70" cy="115" r="4"/><circle class="diagram-point" cx="230" cy="115" r="4"/>
</svg>
<span class="path-label" style="left:50%;top:20%">$\mathsf{Glued}$</span>
<span class="path-label" style="left:23.33%;top:77%">$[\mathsf{true}]$</span>
<span class="path-label" style="left:76.67%;top:77%">$[\mathsf{false}]$</span>
<span class="path-label" style="left:50%;top:35%">$e^{-1}(p)$</span>
</div>
</div>
<div class="type-comparison-panel">

$$n : \neg\langle P\rangle$$

<div class="path-stage diagram-compact-stage" style="aspect-ratio:300/190">
<svg viewBox="0 0 300 190" aria-hidden="true" focusable="false">
<rect class="diagram-space-shape" x="12" y="12" width="276" height="166"/>
<circle class="diagram-point" cx="70" cy="115" r="4"/><circle class="diagram-point" cx="230" cy="115" r="4"/>
</svg>
<span class="path-label" style="left:50%;top:20%">$\mathsf{Glued}$</span>
<span class="path-label" style="left:23.33%;top:77%">$[\mathsf{true}]$</span>
<span class="path-label" style="left:76.67%;top:77%">$[\mathsf{false}]$</span>
</div>
</div>
</div>
</div>
<figcaption id="fig-choice-gluing-caption">

左図では $e$ の逆写像からパスを得る。右図にパスがあれば、$e$ がそれを `n` と矛盾する証明へ送る

</figcaption>
</figure>

**構成** (`Pick`) 次に `Glued` の等しさを判定できるようにする。点 `x : Glued` の代表元は、ブール値 `b` とパス `[ b ] ≡ x` の組である。その依存対型 `Pick x` は、商写像 `[_] : Bool → Glued` の `x` 上のファイバーにほかならない。第二成分は、そのブール値が指定した商類を代表することを保証する。

```agda
  Pick : Glued → Type ℓ
  Pick x = Σ[ b ∶ Bool ] ([ b ] ≡ x)
```

**補題** (`pickIsSet`) 族 `Pick` は h-集合値である。h-集合 `Bool` に `isSetClass` を適用する。ブール値を固定した第二成分は h-集合 `Glued` のパスなので、命題である。

```agda
  pickIsSet : (x : Glued) → isSet (Pick x)
  pickIsSet x = isSetClass isSetBool (λ b → squash/ [ b ] x)
    where
      open import Cubical.Data.Bool.Properties using ( isSetBool )
```

**補題** (`pickable`) `[]surjective` によって、商の各点には代表元が単に存在する。

```agda
  pickable : (x : Glued) → ∥ Pick x ∥₁
  pickable = []surjective
```

**補題** (`merePicker`) 添字型を `Glued`、その h-集合性の証明を `squash/`、族を `Pick`、各値の h-集合性の証明を `pickIsSet` として `sc` を適用する。`P` についての議論で選択を使うのはここだけである。各商点で代表元を選ぶ関数の単なる存在が得られる。

```agda
  merePicker : SetChoice ℓ → ∥ ((x : Glued) → Pick x) ∥₁
  merePicker sc = sc Glued squash/ Pick pickIsSet pickable
```

次の二つの補助写像を作る間、単なる存在ではなく、実際の関数 `g : (x : Glued) → Pick x` が与えられたと仮定する。内側の引数付き部分モジュールは `g` を固定し、`_` はモジュール自体に名前が不要であることを表す。外で非公開の補助定義を使うときには、なお `g` を渡すので、大域的な選択関数を仮定したわけではない。後で切り詰めを除去し、この一時的な仮定なしに判定を得る。

<details open class="submodule-fold">
<summary class="submodule-fold-heading">

```agda
  private module _ (g : (x : Glued) → Pick x) where
```

</summary>
<div class="submodule-fold-content">

**構成** (`b₀` `b₁`)

- `b₀` は `[ true ]` で `g` が選ぶブール値である。
- `b₁` は `[ false ]` で `g` が選ぶブール値である。

```agda
    b₀ : Bool
    b₀ = g [ true ] .fst

    b₁ : Bool
    b₁ = g [ false ] .fst
```

**構成** (`agree→P` `P→agree`)

- `agree→P` `q : b₀ ≡ b₁` があれば、`g` に含まれる証明によって、この一致を商のパスへ結び付けられる。図中の $s_0$、$s_1$ は、それぞれ `g [ true ] .snd` と `g [ false ] .snd` の略記である。最初の証明は `[ b₀ ]` から `[ true ]` へ向かうため、合成には `sym` で逆にしたものを使う。
- `P→agree` 逆に `p : ⟨ P ⟩` からは、逆写像によってパス `invEq quotientPath≃P p` が得られる。図中の $e^{-1}(p)$ はこのパスを表す。通常の関数 `λ x → g x .fst` はこのパスを `b₀ ≡ b₁` へ送る。第一成分を取れば終域は固定された型 `Bool` なので、`cong` で十分である。

```agda
    agree→P : b₀ ≡ b₁ → ⟨ P ⟩
    agree→P q = equivFun quotientPath≃P
      (sym (g [ true ] .snd) ∙ cong [_] q ∙ g [ false ] .snd)

    P→agree : ⟨ P ⟩ → b₀ ≡ b₁
    P→agree p = cong (λ x → g x .fst) (invEq quotientPath≃P p)
```

</div>
</details>

<figure class="book-diagram type-comparison path-figure" id="fig-choice-agreement" aria-describedby="fig-choice-agreement-caption">
<div class="diagram-framed">
<div class="type-comparison-panels">
<div class="type-comparison-panel">

$$q:b_0\equiv b_1$$

<div class="path-stage diagram-compact-stage" style="aspect-ratio:300/370">
<svg viewBox="0 0 300 370" aria-hidden="true" focusable="false">
<rect class="diagram-space-shape" x="12" y="10" width="276" height="350"/>
<path class="diagram-path" d="M 75 72 L 75 152"/>
<path class="diagram-path" d="M 75 152 L 75 232"/>
<path class="diagram-path" d="M 75 232 L 75 312"/>
<circle class="diagram-point" cx="75" cy="72" r="4"/>
<circle class="diagram-point" cx="75" cy="152" r="4"/>
<circle class="diagram-point" cx="75" cy="232" r="4"/>
<circle class="diagram-point" cx="75" cy="312" r="4"/>

</svg>
<span class="path-label" style="left:50%;top:9%">$\mathsf{Glued}$</span>
<span class="path-label" style="left:42%;top:19.46%">$[\mathsf{true}]$</span>
<span class="path-label" style="left:42%;top:41.08%">$[b_0]$</span>
<span class="path-label" style="left:42%;top:62.7%">$[b_1]$</span>
<span class="path-label" style="left:42%;top:84.32%">$[\mathsf{false}]$</span>
<span class="path-label" style="left:57%;top:30.27%">$\mathsf{sym}(s_0)$</span>
<span class="path-label" style="left:58%;top:51.89%">$\mathsf{cong}\,[{-}]\,q$</span>
<span class="path-label" style="left:57%;top:73.51%">$s_1$</span>
</div>
</div>
<div class="type-comparison-panel">

$$p:\langle P\rangle$$

<div class="path-stage diagram-compact-stage" style="aspect-ratio:300/370">
<svg viewBox="0 0 300 370" aria-hidden="true" focusable="false">
<rect class="diagram-space-shape" x="12" y="10" width="276" height="145"/>
<rect class="diagram-space-shape" x="12" y="215" width="276" height="145"/>
<path class="diagram-path" d="M 65 94 Q 150 48 235 94"/>
<path class="diagram-path" d="M 65 300 Q 150 254 235 300"/>
<circle class="diagram-point" cx="65" cy="94" r="4"/><circle class="diagram-point" cx="65" cy="300" r="4"/><path class="diagram-map-line" d="M 65 145 L 65 232"/><path class="diagram-map-tip" d="M 60 224 L 65 232 L 70 224"/>
<circle class="diagram-point" cx="235" cy="94" r="4"/><circle class="diagram-point" cx="235" cy="300" r="4"/><path class="diagram-map-line" d="M 235 145 L 235 232"/><path class="diagram-map-tip" d="M 230 224 L 235 232 L 240 224"/>

</svg>
<span class="path-label" style="left:50%;top:9%">$\mathsf{Glued}$</span>
<span class="path-label" style="left:50%;top:15%">$e^{-1}(p)$</span>
<span class="path-label" style="left:21.67%;top:33%">$[\mathsf{true}]$</span>
<span class="path-label" style="left:78.33%;top:33%">$[\mathsf{false}]$</span>
<span class="path-label" style="left:50%;top:50%">$x\mapsto g(x).\mathsf{fst}$</span>
<span class="path-label" style="left:50%;top:65%">$\mathsf{Bool}$</span>
<span class="path-label" style="left:21.67%;top:90%">$b_0$</span>
<span class="path-label" style="left:78.33%;top:90%">$b_1$</span>
</div>
</div>
</div>
</div>
<figcaption id="fig-choice-agreement-caption">

左図では $e$ が合成したパスを `P` の証明へ送る。右図では $e^{-1}(p)$ に沿って選んだブール値を読み、両者の等しさを得る

</figcaption>
</figure>

**構成** (`decide`) `g : (x : Glued) → Pick x` が与えられたとき、`_≟_` を使って選ばれた二つのブール値の等しさを判定する。証明した二つの非公開の補助写像によって、結果を次のように変換できる。

| ブール値の比較 | `P` の判定 |
| --- | --- |
| `yes q` | `yes (agree→P g q)` |
| `no ne` | `no (λ p → ne (P→agree g p))` |
: ブール値の比較の二つの結果から、命題についての肯定または否定の判定が得られる

第二行では、`P` の証明があれば、`ne` が否定する等しさが従ってしまう。これが `mapDec` に渡す否定側の写像である。

```agda
  decide : ((x : Glued) → Pick x) → Dec ⟨ P ⟩
  decide g = mapDec (agree→P g) (λ ne p → ne (P→agree g p)) (b₀ g ≟ b₁ g)
    where
      open import Cubical.Data.Bool using ( _≟_ )
```

</div>
</details>

[「基礎語彙」で見た、切り詰めを経由する分解](Base.Prelude.html#fig-truncation-rec)の具体例がここに現れる。図中の $G$ は型 `(x : Glued) → Pick x` の略記である。`decide` は実際の関数を受け取る。`isPropDec ⟨ P ⟩isProp` が目標 `Dec ⟨ P ⟩` の命題性を示すので、`rec₁ (isPropDec ⟨ P ⟩isProp) decide` は関数の単なる存在も受け取れる。

<figure class="book-diagram type-comparison" id="fig-choice-truncation" aria-describedby="fig-choice-truncation-caption">
<div class="diagram-framed type-comparison-panel">

<div class="factorization-stage">
<svg viewBox="0 0 500 230" aria-hidden="true" focusable="false">
<path class="diagram-map-line" d="M88 50 H315"/>
<path class="diagram-map-tip" d="M306 45 L315 50 L306 55"/>
<path class="diagram-map-line" d="M358 76 V160"/>
<path class="diagram-map-tip" d="M353 151 L358 160 L363 151"/>
<path class="diagram-map-line" d="M72 74 L315 177"/>
<path class="diagram-map-tip" d="M303 179 L315 177 L308 167"/>
</svg>
<span class="factorization-label factorization-source">$G$</span>
<span class="factorization-label factorization-truncated">$\|G\|_1$</span>
<span class="factorization-label factorization-target">$\mathsf{Dec}\,\langle P\rangle$</span>
<span class="factorization-label factorization-top-map">$|{-}|_1$</span>
<span class="factorization-label factorization-long-map">$\mathsf{decide}$</span>
<span class="factorization-label factorization-right-map">$\mathsf{rec}_1\,\cdots$</span>
</div>

</div>
<figcaption id="fig-choice-truncation-caption">

選択が $\|G\|_1$ の要素を与え、右側の関数がそこから `P` の判定を返す

</figcaption>
</figure>

**定理 (Diaconescu)** (`SetChoice→LEM`) 集合値族に対する選択は、同じ宇宙レベルの排中律を含意する。

**証明** `rec₁ (isPropDec ⟨ P ⟩isProp) decide` を `merePicker sc` に適用する。`P` は任意だったので、結果は `LEM ℓ` である。

```agda
SetChoice→LEM : ∀ {ℓ} → SetChoice ℓ → LEM ℓ
SetChoice→LEM sc P = rec₁ (isPropDec ⟨ P ⟩isProp) decide (merePicker sc)
  where open Diaconescu P
```

証明を終えたところで、一見簡単そうな方法を振り返ろう。`[ true ]` では `true` を、`[ false ]` では `false` を選ぶだけではなぜ足りないのか。次の図は、各点で別々に代表元を得るところから `SetChoice` を経て、商の上の一つの関数へ進む。`P` が成り立つと仮定し、同じ点の二つの表記を結ぶパスをたどってみよう。

<figure class="book-diagram choice-contrast-figure" id="fig-choice-decision" aria-describedby="fig-choice-decision-caption">
<div class="diagram-framed choice-contrast-frame">
<div class="choice-contrast-premise">

<span>$P$ が成り立つと、商にはパスがある</span>

<strong>$p:[\mathsf{true}]\equiv[\mathsf{false}]$</strong>
</div>
<div class="choice-contrast-columns">
<section class="diagram-panel choice-contrast-panel choice-contrast-pointwise">

<h4>各点で別々に存在</h4>

<div class="choice-contrast-type">$(x : \mathsf{Glued})\to\|\mathsf{Pick}\,x\|_1$</div>

<p>仮に代表元を別々に見つけても：</p>

<div class="choice-contrast-picks">
<div class="choice-contrast-pick"><span>$[\mathsf{true}]$</span><span class="choice-contrast-correspondence" aria-hidden="true"></span><strong>$\mathsf{true}$</strong></div>
<div class="choice-contrast-pick"><span>$[\mathsf{false}]$</span><span class="choice-contrast-correspondence" aria-hidden="true"></span><strong>$\mathsf{false}$</strong></div>
</div>
<div class="choice-contrast-verdict choice-contrast-insufficient">

<span>$P$ が成り立つと、二つの表記は同じ商点を指す。異なる代表元を別々に見つけても矛盾しないが、表記ごとに出力を指定すると同じ入力に true と false の両方を与えてしまい、商の上の関数にならない。</span>

</div>
</section>
<div class="choice-contrast-choice-bridge diagram-implication">
<span>$\mathsf{SetChoice}$</span>
<span class="choice-contrast-choice-arrow" aria-hidden="true"></span>

<span class="choice-contrast-choice-note">一つの関数が単に存在</span>

</div>
<section class="diagram-panel choice-contrast-panel choice-contrast-global">

<h4>商の上の一つの関数</h4>

<div class="choice-contrast-type">$\|((x : \mathsf{Glued})\to\mathsf{Pick}\,x)\|_1$</div>

<p>残る外側の切り詰めの内側で、一つの関数 $g$ を見る：</p>

<div class="choice-contrast-map">
<div class="choice-contrast-map-name"><span>$f:\mathsf{Glued}\to\mathsf{Bool}$</span><span>$f(x)=(g\,x).\mathsf{fst}$</span></div>
<div class="path-stage choice-contrast-path-stage" style="aspect-ratio:360/240">
<svg viewBox="0 0 360 240" aria-hidden="true" focusable="false">
<path class="diagram-path" d="M55 60 Q180 5 305 60 M55 185 Q180 130 305 185"/>
<path class="diagram-map-line" d="M55 72 V165 M305 72 V165"/>
<path class="diagram-map-tip" d="M51 158 L55 165 L59 158 M301 158 L305 165 L309 158"/>
<circle class="diagram-point" cx="55" cy="60" r="4"/><circle class="diagram-point" cx="305" cy="60" r="4"/>
<circle class="diagram-point" cx="55" cy="185" r="4"/><circle class="diagram-point" cx="305" cy="185" r="4"/>
</svg>
<span class="path-label" style="left:15.2778%;top:15.4167%">$[\mathsf{true}]$</span>
<span class="path-label" style="left:84.7222%;top:15.4167%">$[\mathsf{false}]$</span>
<span class="path-label" style="left:50%;top:6.25%">$p$</span>
<span class="path-label" style="left:10.8333%;top:48.75%">$f$</span>
<span class="path-label" style="left:89.4444%;top:48.75%">$f$</span>
<span class="path-label" style="left:15.2778%;top:90%">$b_0$</span>
<span class="path-label" style="left:84.7222%;top:90%">$b_1$</span>
<span class="path-label" style="left:50%;top:56.25%">$\operatorname{cong}\,f\,p$</span>
</div>
</div>
<div class="choice-contrast-verdict choice-contrast-coherent">
<div class="choice-contrast-equivalence">$b_0\equiv b_1\quad\Longleftrightarrow\quad P$</div>

<span>代表元の証明が逆向きの含意を与える。よって $b_0$ と $b_1$ の比較で $P$ を判定できる。</span>

</div>
</section>
</div>
</div>
<figcaption id="fig-choice-decision-caption">

一つの関数が商点間のパスをブール出力間のパスへ送る。判定は命題なので、外側の切り詰めを除ける

</figcaption>
</figure>

## まとめ

本章では、h-集合を添字とする h-集合値の族について `SetChoice ℓ` を定式化した。各添字で要素が単に存在することから、一つの選択関数が単に存在することが従う。`lowerSetChoice` は、`SetChoice (ℓ-suc ℓ)` が `SetChoice ℓ` を含意することを示す。`SetChoice→LEM` の証明では、命題 `P` を二つの商点の等しさに符号化し、選択で得たブール代表元を比較して `P` を判定する。`Dec ⟨ P ⟩` は命題なので、`rec₁` により切り詰めを消去できる。したがって `SetChoice ℓ` から `LEM ℓ` が従う。
