Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion LeanByExample/Declarative/Axiom.lean
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ end quot --#

実際に証明していきます。一般に証明を理解するためには、前提を確認することが大切です。「商の公理を使用しなくても、前提として等しいことが分かっているものは何か」をまず確認しましょう。前提として利用できる事実には、次の2つがあります:

* 関数 `f` とラムダ式 `fun x => f x` は等しい。(これは **η 簡約(eta reduce)** と呼ばれます
* 関数 `f` とラムダ式 `fun x => f x` は等しい。(これは **η 簡約(eta reduce)** と呼ばれる簡約ルールより従います
* 関数 `f` と、「関数 `f` を適用する関数」は等しい。

実際に、公理を一切使わずにこれは証明できます。
Expand Down
4 changes: 2 additions & 2 deletions LeanByExample/Declarative/Class.lean
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/-
# class
`class` は型クラスを定義するためのコマンドです。型クラスを用いると、複数の型に対して定義され、型ごとに異なる実装を持つような関数を定義することができます。例えば「和を取る操作」のような、`Nat` や `Int` や `Rat` など複数の型に対して同じ名前で定義したい関数を作りたいとき、型クラスが適しています。
`class` は **型クラス(type class)** を定義するためのコマンドです。型クラスを用いると、複数の型に対して定義され、型ごとに異なる実装を持つような関数を定義することができます。例えば「和を取る操作」のような、`Nat` や `Int` や `Rat` など複数の型に対して同じ名前で定義したい関数を作りたいとき、型クラスが適しています。
-/
namespace Class --#
/-- 証明なしのバージョンのモノイド。
Expand Down Expand Up @@ -74,7 +74,7 @@ def instMonoid'Nat : Monoid' Nat where

#check (Monoid.e : {α : Type} → [_self : Monoid α] → α)

/- これは**インスタンス暗黙引数**と呼ばれるもので、この場合 Lean に対して `Monoid' α` 型の項を自動的に合成するよう指示することを意味します。また、型クラスのインスタンス暗黙引数を自動的に合成する手続きのことを、**型クラス解決**と呼びます。-/
/- これは **インスタンス暗黙引数(instance implicit)** と呼ばれるもので、この場合 Lean に対して `Monoid' α` 型の項を自動的に合成するよう指示することを意味します。また、型クラスのインスタンス暗黙引数を自動的に合成する手続きのことを、 **型クラス解決(type class resolution)** と呼びます。-/

/- ## outParam
足し算を表現する型クラスを自分で定義してみましょう。名前は `Plus` としてみます。足し算は自然数の和 `Nat → Nat → Nat` のように、同じ型の中で完結する操作として定義されることが多いものですが、より一般的に `α → β → γ` で定義されるものとしてみます。
Expand Down
2 changes: 1 addition & 1 deletion LeanByExample/Declarative/Infix.lean
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ scoped infix:60 " ⋄ " => Nat.mul

#guard 2 ⋄ 3 = 6

/- `:` の後に付けている数字はパース優先順位で、高いほど結合するタイミングが早くなります。等号 `=` のパース優先順位は 50 であることを覚えておくと良いかもしれません。-/
/- `:` の後に付けている数字は **パース優先順位(parsing precedence)** で、高いほど結合するタイミングが早くなります。等号 `=` のパース優先順位は 50 であることを覚えておくと良いかもしれません。-/

-- 等号より微妙にパース優先順位が高い
scoped infix:51 " strong " => Nat.add
Expand Down
2 changes: 1 addition & 1 deletion LeanByExample/Declarative/Notation.lean
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ set_option pp.notation false
end

/- ## パース優先順位
`notation` で記法を定義するときに、その記法の他の演算子などと比べたパース優先順位(parsing precedence)を数値で指定することができます。パース優先順位が高い演算子ほど、他の演算子より先に適用されます。言い換えれば、パース優先順位を正しく設定することにより、括弧を省略しても意図通りに式が解釈されるようにすることができます。
`notation` で記法を定義するときに、その記法の他の演算子などと比べた **パース優先順位(parsing precedence)** を数値で指定することができます。パース優先順位が高い演算子ほど、他の演算子より先に適用されます。言い換えれば、パース優先順位を正しく設定することにより、括弧を省略しても意図通りに式が解釈されるようにすることができます。
-/

/-- 結合が弱い方。中身は足し算 -/
Expand Down
2 changes: 1 addition & 1 deletion LeanByExample/Declarative/Syntax.lean
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ using the `set_option diagnostics true` command.
#check_failure (1 + 1 = 2 as Nat)

end --#
/- パース優先順位(parsing precedence)を設定することで、どの構文から順に解釈されるかを指定することができ、問題を修正できることがあります。このあたりは [`notation`](./Notation.md) コマンドと同様です。 -/
/- **パース優先順位(parsing precedence)** を設定することで、どの構文から順に解釈されるかを指定することができ、問題を修正できることがあります。このあたりは [`notation`](./Notation.md) コマンドと同様です。 -/
section --#

-- 十分低いパース優先順位を設定する
Expand Down
4 changes: 2 additions & 2 deletions LeanByExample/Type/List.lean
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/- # List

`List` は**連結リスト**を表す型です。
`List` は **連結リスト(linked list)** を表す型です。

Lean では次のように再帰的に定義されています。
-/
Expand Down Expand Up @@ -59,7 +59,7 @@ end Hidden --#

/- ## 高階関数

「関数を引数に取る関数」や「関数を返す関数」のことを、**高階関数**と呼ぶことがあります。`List` 名前空間には様々な高階関数が定義されています。
「関数を引数に取る関数」や「関数を返す関数」のことを、**高階関数(higher-order function)** と呼ぶことがあります。`List` 名前空間には様々な高階関数が定義されています。

### map

Expand Down
6 changes: 3 additions & 3 deletions LeanByExample/Type/Prop.lean
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#check (1 + 1 = 2 : Prop)
#check (1 + 1 = 3 : Prop)

/- ## Curry Howard 同型対応
/- ## カリー・ハワード同型対応

Lean では、各命題 `P : Prop` は再び型になっています。これは通常の数学では考えないことなので慣れないとわかりにくいのですが、言い換えれば命題 `P` の項というものを考えることができます。

Expand All @@ -20,12 +20,12 @@ Lean では、各命題 `P : Prop` は再び型になっています。これは
-- 項に名前を付けた
def one_and_one_eq_two : 1 + 1 = 2 := rfl

/- 実は、いま構成した `1 + 1 = 2` という型の項は `1 + 1 = 2` の証明になっています。実際のところ、命題 `P : Prop` の証明とは、Lean においては項 `h : P` そのものです。このことを強調するために、**証明項**という呼び方をすることもあります。-/
/- 実は、いま構成した `1 + 1 = 2` という型の項は `1 + 1 = 2` の証明になっています。実際のところ、命題 `P : Prop` の証明とは、Lean においては項 `h : P` そのものです。このことを強調するために、 **証明項(proof term)** という呼び方をすることもあります。-/

-- さっき構成した証明項で証明ができる
example : 1 + 1 = 2 := one_and_one_eq_two

/- このように命題を型として、証明を項として実装できるのは、そもそも直観主義論理と型付きラムダ計算の間に **Curry Howard 同型対応**が存在するからです。簡単に言えば、論理と計算(プログラム)は出自は全く異なるものの何故か同じ構造を持っており、同じものであると見なせるということです。-/
/- このように命題を型として、証明を項として実装できるのは、そもそも直観主義論理と型付きラムダ計算の間に **カリー・ハワード同型対応(correspondence)** が存在するからです。簡単に言えば、論理と計算(プログラム)は出自は全く異なるものの何故か同じ構造を持っており、同じものであると見なせるということです。-/

/- ## 命題論理
[`Bool`](#{root}/Type/Bool.md) には真と偽に対応する `true` と `false` という項がありますが、`Prop` では真偽は `True` と `False` で表されます。
Expand Down
2 changes: 1 addition & 1 deletion LeanByExample/Type/Syntax.lean
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ inductive Syntax where
(val : Name) (preresolved : List Syntax.Preresolved) : Syntax

--#--
-- **Syntax の定義の変更を確認するためのコード**
-- Syntax の定義の変更を確認するためのコード
/--
info: inductive Lean.Syntax : Type
number of parameters: 0
Expand Down
4 changes: 2 additions & 2 deletions LeanByExample/Type/Type.lean
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ example : Sort (u + 1) = Type u := rfl
/- ## なぜ Type : Type ではないのか
何故このような仕様になっているのでしょうか。可算無限個の宇宙を用意するよりも `Type : Type` とした方が簡単ではないでしょうか?実は、`Type : Type` となるような型理論を採用すると矛盾が生じてしまいます。

これは **Girard のパラドックス** と呼ばれる有名な結果です。しかし Girard のパラドックスを直接説明しようとすると準備が多く必要になるので、ここでは Girard のオリジナルの議論を追うことはせず、代わりに濃度による簡潔な議論を紹介します。
これは **ジラールのパラドックス(Girard's paradox)** と呼ばれる有名な結果です。しかしジラールのパラドックスを直接説明しようとすると準備が多く必要になるので、ここではジラールのオリジナルの議論を追うことはせず、代わりに濃度による簡潔な議論を紹介します。

以下証明を説明します。仮に `Type` が `Type` の項だったとしましょう。このとき `α := Type` とすることにより、ある `Type` の項 `α` を選べば、全射 `f : α → Type` を作れることがわかります。したがって、任意の型 `α : Type` に対して関数 `f : α → Type` が全射になることはありえないことを示せばよいことになります。

これは Cantor の定理の単射バージョンに帰着して示すことができます
これは **カントールの定理(Cantor's theorem)** の単射バージョンに帰着して示すことができます
-/

open Function
Expand Down
2 changes: 1 addition & 1 deletion LeanByExample/TypeClass/CoeSort.lean
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ local instance : Coe FinCat Type := ⟨fun S ↦ S.base⟩
#check_failure (Two → Two)

end --#
/- しかし、これは「`Coe` では型宇宙への変換は扱えないから」ではありません。`Coe` と `CoeSort` では型強制が呼ばれるタイミングが異なるからです。`Coe` は「ある型の**項**が期待される場所に、異なる型の項が来た時」にトリガーされますが、`CoeSort` は「**型**が期待される場所に型が来ていないとき」にトリガーされます。
/- しかし、これは「`Coe` では型宇宙への変換は扱えないから」ではありません。`Coe` と `CoeSort` では型強制が呼ばれるタイミングが異なるからです。`Coe` は「ある型の項が期待される場所に、異なる型の項が来た時」にトリガーされますが、`CoeSort` は「型が期待される場所に型が来ていないとき」にトリガーされます。

実際、`Coe` を使っても `Type` への型強制は定義することができます。
-/
Expand Down
2 changes: 1 addition & 1 deletion LeanByExample/TypeClass/GetElem.lean
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ instance : GetElem (MyList α) Nat α (fun as i => i < as.length) where
#guard Three[2] = 3

/- ## インデックスアクセスの種類
コレクション `as` に対して、`i` 番目の要素を取得すると書きましたが、**i 番目の要素があるとは限らない**という問題があります。これに対処するには様々な方法がありえますが、中でも以下のものは専用の構文が用意されています。
コレクション `as` に対して、`i` 番目の要素を取得すると書きましたが、`i` 番目の要素があるとは限らないという問題があります。これに対処するには様々な方法がありえますが、中でも以下のものは専用の構文が用意されています。

* `as[i]`: インデックス `i` が範囲内であることの証明を自動で構成する。`i` が変数になっていて具体的に計算できないときでも、ローカルコンテキスト内に `i` が範囲内であることの証明があれば動作する。
* `as[i]?`: 返り値を [`Option`](#{root}/Type/Option.md) に包む。範囲外の場合は `none` を返す
Expand Down
2 changes: 1 addition & 1 deletion LeanByExample/TypeClass/README.lean
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/- # 型クラス

型クラスとは、和や積、逆数を取る演算など、複数の型に対してそれぞれのやり方で実装されるような演算を定義するものです。
**型クラス(type class)** とは、和や積、逆数を取る演算など、複数の型に対してそれぞれのやり方で実装されるような演算を定義するものです。

型クラスは主に [`class`](#{root}/Declarative/Class.md) コマンドで定義され、インスタンスを宣言するには [`instance`](#{root}/Declarative/Instance.md) コマンドを使用します。
-/
Loading