Skip to content

Commit

Permalink
全射/単射の分裂
Browse files Browse the repository at this point in the history
Fixes #882
  • Loading branch information
Seasawher committed Sep 24, 2024
1 parent d879831 commit 1a7defd
Show file tree
Hide file tree
Showing 3 changed files with 204 additions and 0 deletions.
123 changes: 123 additions & 0 deletions Examples/Solution/InverseSurjInj.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/- # 全射・単射と左逆・右逆写像
関数 `f : A → B` が**全射**であるとは、任意の `b : B` に対して `f a = b` となる `a : A` が存在することをいいます。また、`f` が**単射**であるとは、任意の `a₁, a₂ : A` に対して `f a₁ = f a₂` ならば `a₁ = a₂` となることをいいます。
これを Lean で表現すると次のようになります。
-/
set_option autoImplicit false --#
set_option relaxedAutoImplicit false --#

variable {A B : Type}

/-- 関数の全射性 -/
def Function.Surjective (f : A → B) : Prop := ∀ b, ∃ a, f a = b

/-- 関数の単射性 -/
def Function.Injective (f : A → B) : Prop := ∀ {a₁ a₂ : A}, f a₁ = f a₂ → a₁ = a₂

/- 一見すると、全射と単射はペアになる概念とは思えないかもしれません。束縛変数の数も違いますし、意味上もまったく独立した概念のように見えます。
しかし、`A` が空でないと仮定すれば、選択原理 [`Classical.choice`](../Declarative/Axiom.md#ClassicalChoice) を使うことによって、全射 `f : A → B` があれば逆方向の単射 `g : B → A` が構成でき、逆に単射 `f : A → B` があれば逆方向の全射 `g : B → A` を構成することができます。
ある意味で、全射と単射はペアをなす概念であると言えるかもしれないですね。今回の演習問題のテーマはこの定理です。
-/

/- ## 問1: 全射から逆方向の単射
まずは、全射 `f : A → B` が存在すれば逆方向の単射 `g : B → A` も存在することを示しましょう。
実際にはより強く、`f ∘ g = id` を満たすような `g` が構成できます。一般に、`f ∘ g = id` が成り立つとき、`g` を `f` の右逆写像であるとか、切断(section)であるとかいいます。
-/

-- 選択原理を使用する
open Function Classical

/-- 全射 `f : A → B` があれば、選択原理を使用することにより
単射 `g : B → A` を作ることができる。-/
theorem surj_to_inj (f : A → B) (hsurj : Surjective f)
: ∃ g : B → A, Injective g := by
-- まず `g` を構成する。
-- 任意の `b : B` に対して `f` の全射性より
-- `f a = b` となる `a : A` が存在するのでそれを返す。
--##--
let g' : (b : B) → {a : A // f a = b} := fun b =>
have h : ∃ a, f a = b := hsurj b
⟨Classical.choose h, Classical.choose_spec h⟩
--##--
let g : B → A := fun b => /- sorry -/ (g' b).val

-- `g` の定義と `f` の全射性から、`f (g b) = b` が成り立つ。
have gdef : ∀ b, f (g b) = b := by
-- sorry
intro b
rw [show g b = (g' b).val from rfl]
simp_all [(g' b).property]
-- sorry

-- `g` が単射であることを示したい。
-- それには、`f ∘ g = id` を示せば十分。
suffices ∀ b, f (g b) = b from by
-- sorry
exists g
intro b₁ b₂ h
replace h : b₁ = b₂ := calc
_ = f (g b₁) := by rw [this]
_ = f (g b₂) := by rw [h]
_ = _ := by rw [this]
exact h
-- sorry

-- 後は `f ∘ g = id` を示せば良いが、これは既に示した。
exact gdef

/- ## 問2: 単射から逆方向の全射
次に `f : A → B` が単射であれば、逆方向の全射 `g : B → A` も存在することを示しましょう。
これも実際にはより強く、`g ∘ f = id` を満たすような `g` が構成できます。一般に、`g ∘ f = id` が成り立つとき、`g` を `f` の左逆写像であるとか、引き込み(retraction)であるとかいいます。
-/

/-- 単射 `f : A → B` があれば、選択原理を使用することにより
全射 `g : B → A` を作ることができる。 -/
theorem inj_to_surj [Inhabited A] (f : A → B) (hinj : Injective f)
: ∃ g : B → A, Surjective g := by
-- まず `g` を構成する。
-- `g b` の値を構成するために、`b : B` が `f` の像に入っているかで場合分けをし、
-- 入っていなければ適当な値、入っていれば `b = f a` となる `a` を返すようにする。
let g : B → A := fun b => /- sorry -/
if h : ∃ a, f a = b then Classical.choose h --##
else default --##

-- `g` の定義と `f` の単射性から、`g (f a) = a` が成り立つ。
have gdef : ∀ a, g (f a) = a := by
-- sorry
-- `a : A` が与えられたとする。
intro a

-- `g` の定義を展開する
dsimp only [g]

-- `f a` は明らかに `f` の像に入っているということを利用して、
-- `g` の定義の中の `if` 式を簡約する。
split
case isFalse h =>
have : ∃ a₁, f a₁ = f a := ⟨a, rfl⟩
simp_all [this]

-- 後は `f` の単射性から従う。
case isTrue h =>
have := Classical.choose_spec h
apply hinj
assumption
-- sorry

-- `g` が全射であることを示したい。
-- それには、`g ∘ f = id` を示せば十分。
suffices ∀ a, g (f a) = a from by
-- sorry
exists g
intro a
exists f a
apply this
-- sorry

-- 後は `g ∘ f = id` を示せば良いが、これは既に示した。
exact gdef
80 changes: 80 additions & 0 deletions Exercise/InverseSurjInj.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/- # 全射・単射と左逆・右逆写像
関数 `f : A → B` が**全射**であるとは、任意の `b : B` に対して `f a = b` となる `a : A` が存在することをいいます。また、`f` が**単射**であるとは、任意の `a₁, a₂ : A` に対して `f a₁ = f a₂` ならば `a₁ = a₂` となることをいいます。
これを Lean で表現すると次のようになります。
-/
set_option autoImplicit false --#
set_option relaxedAutoImplicit false --#

variable {A B : Type}

/-- 関数の全射性 -/
def Function.Surjective (f : A → B) : Prop := ∀ b, ∃ a, f a = b

/-- 関数の単射性 -/
def Function.Injective (f : A → B) : Prop := ∀ {a₁ a₂ : A}, f a₁ = f a₂ → a₁ = a₂

/- 一見すると、全射と単射はペアになる概念とは思えないかもしれません。束縛変数の数も違いますし、意味上もまったく独立した概念のように見えます。
しかし、`A` が空でないと仮定すれば、選択原理 [`Classical.choice`](../Declarative/Axiom.md#ClassicalChoice) を使うことによって、全射 `f : A → B` があれば逆方向の単射 `g : B → A` が構成でき、逆に単射 `f : A → B` があれば逆方向の全射 `g : B → A` を構成することができます。
ある意味で、全射と単射はペアをなす概念であると言えるかもしれないですね。今回の演習問題のテーマはこの定理です。
-/

/- ## 問1: 全射から逆方向の単射
まずは、全射 `f : A → B` が存在すれば逆方向の単射 `g : B → A` も存在することを示しましょう。
実際にはより強く、`f ∘ g = id` を満たすような `g` が構成できます。一般に、`f ∘ g = id` が成り立つとき、`g` を `f` の右逆写像であるとか、切断(section)であるとかいいます。
-/

-- 選択原理を使用する
open Function Classical

/-- 全射 `f : A → B` があれば、選択原理を使用することにより
単射 `g : B → A` を作ることができる。-/
theorem surj_to_inj (f : A → B) (hsurj : Surjective f)
: ∃ g : B → A, Injective g := by
-- まず `g` を構成する。
-- 任意の `b : B` に対して `f` の全射性より
-- `f a = b` となる `a : A` が存在するのでそれを返す。
let g : B → A := fun b => sorry

-- `g` の定義と `f` の全射性から、`f (g b) = b` が成り立つ。
have gdef : ∀ b, f (g b) = b := by
sorry

-- `g` が単射であることを示したい。
-- それには、`f ∘ g = id` を示せば十分。
suffices ∀ b, f (g b) = b from by
sorry

-- 後は `f ∘ g = id` を示せば良いが、これは既に示した。
exact gdef

/- ## 問2: 単射から逆方向の全射
次に `f : A → B` が単射であれば、逆方向の全射 `g : B → A` も存在することを示しましょう。
これも実際にはより強く、`g ∘ f = id` を満たすような `g` が構成できます。一般に、`g ∘ f = id` が成り立つとき、`g` を `f` の左逆写像であるとか、引き込み(retraction)であるとかいいます。
-/

/-- 単射 `f : A → B` があれば、選択原理を使用することにより
全射 `g : B → A` を作ることができる。 -/
theorem inj_to_surj [Inhabited A] (f : A → B) (hinj : Injective f)
: ∃ g : B → A, Surjective g := by
-- まず `g` を構成する。
-- `g b` の値を構成するために、`b : B` が `f` の像に入っているかで場合分けをし、
-- 入っていなければ適当な値、入っていれば `b = f a` となる `a` を返すようにする。
let g : B → A := fun b => sorry

-- `g` の定義と `f` の単射性から、`g (f a) = a` が成り立つ。
have gdef : ∀ a, g (f a) = a := by
sorry

-- `g` が全射であることを示したい。
-- それには、`g ∘ f = id` を示せば十分。
suffices ∀ a, g (f a) = a from by
sorry

-- 後は `g ∘ f = id` を示せば良いが、これは既に示した。
exact gdef
1 change: 1 addition & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@
- [床屋のパラドクス](./Exercise/BarberParadox.md)
- [騎士と悪党のパズル](./Exercise/KnightAndKnave.md)
- [「ならば」の定義を疑う](./Exercise/DoubtImplication.md)
- [全射・単射と左逆・右逆写像](./Exercise/InverseSurjInj.md)
- [Cantorの定理](./Exercise/CantorTheorem.md)
- [Cantorの対関数の全単射性](./Exercise/CantorPairing.md)
- [Heying代数とBool代数](./Exercise/HeytingAndBooleanAlgebra.md)

0 comments on commit 1a7defd

Please sign in to comment.