3.4 基數與鴿籠原理#
本節目標#
- 理解等勢(equinumerous)作為「一樣多」的型別論式定義。
- 認識有限與無限的直覺定義。
- 掌握鴿籠原理的 Lean 敘述與簡單應用。
- 認識可數無限: \(\mathbb{N} \to \mathbb{Z}\) 的對應。
- 了解 Cantor 對角線法的概念與 Lean 中的敘述(不給完整證明)。
等勢(equinumerous)#
問「兩個集合一樣多嗎?」最穩健的方式不是去「數」, 而是配對:若存在一個雙射把兩邊一一套起來,就稱它們等勢。 遠古牧人用石子數羊——每隻羊丟一顆石子、回來時每隻羊撿回一顆—— 正是雙射的思想,不需要知道「5」是什麼。
Lean 中,兩個型別等勢由 Equiv 表示(雙射連同反函數的套裝):
def Equiv (α : Type u) (β : Type v) where
toFun : α → β
invFun : β → α
left_inv : invFun ∘ toFun = id
right_inv : toFun ∘ invFun = id
記號 α ≃ β。集合層次則有 Set.Equinumerous 風格的概念 (Mathlib 以 Equiv 與 Set 結合),核心思想不變:
Equiv 比裸的 Function.Bijective 更好用,因為它內建了反函數, 方便計算與重寫;兩者可由 Equiv.ofBijective 互換。
有限與無限的直覺定義#
- 有限:一個型別
α有限,若它與某個Fin n(前 \(n\) 個自然數)等勢。 Mathlib 的Finite α即是此意義(存在 \(n\) 與等價 \(\alpha \simeq \text{Fin } n\) )。 - 無限:
Infinite α,即不有限。直覺上,無限集合可以「不斷拿出新元素」。 - 集合層次:
Set.Finite s( \(s\) 可與某有限型別配對)、Set.Infinite s。
import Mathlib
example : Finite (Fin 10) := inferInstance
example : Infinite ℕ := inferInstance
example : Set.Finite ({1, 2, 3} : Set ℕ) := Set.toFinite _
example : Set.Infinite (Set.univ : Set ℕ) := Set.infinite_univ
有限與無限的關鍵差異:有限集合與其真子集不可能等勢; 無限集合可以。例如 \(n \mapsto 2n\) 把 \(\mathbb{N}\) 雙射到偶數這個真子集—— 這是 Hilbert 旅館悖論的核心,也是「無限」的組合學定義基礎。
鴿籠原理#
把 \(n+1\) 隻鴿子放進 \(n\) 個籠子,必有兩隻同籠。 Lean 敘述(Fintype 版本):
theorem pigeonhole {α β : Type*} [Finite α] [Fintype β]
(f : α → β) : ∃ a b, a ≠ b ∧ f a = f b
即:定義域比對應域「大」的函數必不單射。 Mathlib 對應引理為 Function.Injective.exists_ne_map_eq_of_card_lt、 Fintype.card_le_of_injective(單射給出基數不等式 \(\lvert \alpha\rvert \leq \lvert \beta\rvert\) )。
簡單應用——抽屜裡 13 個人,必有兩人生日同月:
example : ¬ Function.Injective (fun (_ : Fin 13) => (12 : Fin 12)) := by
intro hinj
have hcard : Fintype.card (Fin 13) ≤ Fintype.card (Fin 12) :=
Fintype.card_le_of_injective _ hinj
simp at hcard
Fintype.card_le_of_injective 把「單射」轉成「基數不等式」, 而 13 ≤ 12 顯然荒謬。套路:把組合問題翻譯成基數問題。
更口語的版本:
example {α : Type*} [Fintype α] {β : Type*} [Fintype β]
(h : Fintype.card β < Fintype.card α) (f : α → β) :
∃ a b, a ≠ b ∧ f a = f b := by
by_contra hcon
push_neg at hcon
have : Fintype.card α ≤ Fintype.card β :=
Fintype.card_le_of_injective _ hcon
omega
可數無限: \(\mathbb{N} \to \mathbb{Z}\) 的對應#
可數無限=與 \(\mathbb{N}\) 等勢。 \(\mathbb{Z}\) 看起來「比 \(\mathbb{N}\) 多一倍」, 但雙射
說明它們一樣多。Lean 中的實現(示意):
def zEncode : ℤ → ℕ
| Int.ofNat n => 2 * n
| Int.negSucc n => 2 * n + 1
def zDecode : ℕ → ℤ
| 0 => 0
| (n + 1) => if (n + 1) % 2 = 1 then Int.ofNat ((n + 1) / 2 - (n + 1) / 2) * 0 + Int.negSucc ((n + 1) / 2 - 1)
else Int.ofNat ((n + 1) / 2)
實務上 Mathlib 已內建 Int 與 ℕ 等勢的各種工具 (如 Int.equivNat 風格的構造與 Countable 實例), 我們不需要手寫;重點是理解交錯列舉的技巧: 把負數與非負數「編織」進同一條無窮序列。 一般化後:可數個可數集合的聯集仍是可數的(沿對角線列舉)。
Lean 中的概念:
Countable α:存在從 \(\alpha\) 到 \(\mathbb{N}\) 的單射。Set.Countable s: \(s\) 是可數集合。Set.Countable.mono:可數集的子集可數。Set.Countable.of_finite:有限必可數。
example : Countable ℤ := inferInstance
example (s : Set ℤ) : Set.Countable s := Set.to_countable s
Cantor 對角線法#
定理(Cantor, 1891):不存在從 \(X\) 到其冪集 \(\mathcal{P}(X)\) 的滿射。 特別地, \(\mathbb{N}\) 與 \(\mathbb{R}\) (或 \(\mathcal{P}(\mathbb{N})\) )不等勢, 無限也分大小。
證明概念:設 \(f : X \to \mathcal{P}(X)\) ,定義「對角線集合」
若 \(D = f(d)\) ,問 \(d \in D\) 嗎?兩種情況都矛盾—— 正是羅素悖論的「良性版本」。列表圖像化:把 \(f(x_1), f(x_2), \dots\) 排成 0/1 表,沿對角線翻轉,得到的新行不在表中。
Lean 敘述(Mathlib 內建,Set.not_injective_of_self_empty 風格的 一般形式為 Cantor.surjection_not_injective / 核心: Set.eq_empty_iff_forall_notMem 配合構造對角集):
theorem cantor {α : Type*} (f : α → Set α) : ∃ D, ∀ x, f x ≠ D := by
refine ⟨{x | x ∉ f x}, fun x hx => ?_⟩
by_cases h : x ∈ f x
· exact absurd (hx ▸ h) (fun h' => h' h) -- d ∈ f(d) 但對角集說 d ∉ f(d)
· -- d ∉ f(d),但對角集定義說 d 應在其中
exact (hx ▸ h).elim
(示意骨架,Mathlib 有正式版本 Cantor 相關引理; 完整證明涉及精細的邏輯翻轉,此處只展示「對角集」如何出場。)
Set.Infinite 與對角線法的結論: Set.univ : Set (Set ℕ) 不可數——
example : ¬ Set.Countable (Set.univ : Set (Set ℕ)) := by
intro hc
-- 冪集可數 ⟹ 可與 ℕ 配對 ⟹ 與對角線法矛盾
exact absurd hc (by
intro h
exact (Set.countable_iff_exists_injective.mp h) ▸ fun _ => trivial)
(同樣為示意框架;正式證明見 Mathlib 的 Set.Countable 相關檔案。)
小結與練習#
「一樣多」的正確定義是存在雙射,而不是看起來差不多; 有限與無限的分界在於「能否與自己的真子集等勢」; 鴿籠原理把組合直覺變成基數不等式; 可數無限可用交錯列舉處理 \(\mathbb{Z}\) ,但 Cantor 對角線法 說明無限有階梯, \(\mathcal{P}(\mathbb{N})\) 嚴格比 \(\mathbb{N}\) 大。
練習:
- 證明
Equiv.refl、Equiv.symm、Equiv.trans的存在 (即等勢是等價關係;Mathlib 已提供,練習寫出敘述並理解)。 - 用
Fintype.card_le_of_injective證明: 從Fin 5到Fin 3的任何函數都有兩個輸入映到同一輸出。 - 證明偶自然數集合
{n | Even n} : Set ℕ是無限的 (提示:Set.Infinite.mono從Set.univ出發,或用雙射n ↦ 2n)。 - 寫出交錯列舉的下一步:證明
ℕ × ℕ可數(Countable (ℕ × ℕ)), 並想清楚對角線列舉法如何對應到 Lean 的證明策略。 - 挑戰(概念題):寫出「對角線集合 \(D\) 不在 \(f\) 的像中」的 完整 Lean 敘述,並說明每一步的矛盾來自哪裡。