Skip to content

Commit a8a35e5

Browse files
authored
Merge pull request #1402 from lean-ja/Seasawher/issue1356
無名コンストラクタの説明を「構文」カテゴリに移動させる
2 parents ec5724f + 4b3ed86 commit a8a35e5

File tree

7 files changed

+77
-49
lines changed

7 files changed

+77
-49
lines changed

LeanByExample/Declarative/Structure.lean

+1-44
Original file line numberDiff line numberDiff line change
@@ -63,46 +63,8 @@ def Point.isOrigin (p : Point Int) : Bool :=
6363
-- フィールド記法が使える!
6464
#guard origin.isOrigin
6565

66-
/- ## 無名コンストラクタ { #AnonymousConstructor }
67-
**無名コンストラクタ(anonymous constructor)** は、構造体 `T` に対して `T` 型の項を構成する方法のひとつです。これは以下に示すように、`⟨x1, x2, ...⟩` という構文により使うことができます。
68-
-/
69-
set_option linter.unusedVariables false --#
70-
71-
/-- 2つのフィールドを持つ構造体 -/
72-
structure Hoge where
73-
foo : Nat
74-
bar : Nat
75-
76-
def hoge : Hoge := ⟨1, 2
77-
78-
/- コンストラクタが入れ子になっていても平坦化することができます。例えば、以下の2つの定義は同じものを定義します。-/
79-
80-
def foo : Nat × (Int × String) := ⟨1, ⟨2, "foo"⟩⟩
81-
82-
def foo' : Nat × (Int × String) := ⟨1, 2, "foo"
83-
84-
#guard foo = foo'
85-
86-
/- 一般の[帰納型](../Declarative/Inductive.md)に対しては使用できません。-/
87-
88-
inductive Sample where
89-
| fst (foo bar : Nat) : Sample
90-
| snd (foo bar : String) : Sample
91-
92-
-- 「コンストラクタが一つしかない帰納型でなければ使用できない」というエラーになる
93-
/--
94-
warning: invalid constructor ⟨...⟩, expected type must be an inductive type with only one constructor ⏎
95-
Sample
96-
-/
97-
#guard_msgs in
98-
#check_failure (⟨"foo", "bar"⟩ : Sample)
99-
100-
-- コンストラクタを指定しても使用できない
101-
#guard_msgs (drop warning) in --#
102-
#check_failure (Sample.snd ⟨"foo", "bar"⟩ : Sample)
103-
10466
/- ## 項を定義する様々な構文
105-
構造体の項を定義したい場合、複数の方法があります。波括弧記法が好まれますが、フィールド名が明らかな状況であれば無名コンストラクタを使用することもあります。-/
67+
構造体の項を定義したい場合、複数の方法があります。波括弧記法が好まれますが、フィールド名が明らかな状況であれば[無名コンストラクタ](#{root}/Parser/AnonymousConstructor.md)を使用することもあります。-/
10668

10769
-- コンストラクタを使う
10870
def sample0 : Point Int := Point.mk 1 2
@@ -174,11 +136,6 @@ def Point'.x {α : Type} (p : Point' α) : α :=
174136
let p := Point'.mk 1 2
175137
p.x
176138

177-
/- 無名コンストラクタは最初から使用できます。 -/
178-
179-
-- 無名コンストラクタは使用できる
180-
def origin' : Point Int := ⟨0, 0
181-
182139
/- 波括弧記法は `structure` コマンドで定義された型でなければ使用できないようです。 -/
183140

184141
-- 波括弧記法は使用できない
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/- # 無名コンストラクタ
2+
3+
**無名コンストラクタ(anonymous constructor)** を使用すると、単一のコンストラクタしか持たない帰納型 `T` に対して、コンストラクタ名を指定せずに `T` 型の項を構成することができます。`⟨x1, x2, ...⟩` という構文により使うことができます。
4+
-/
5+
6+
/-- 単一のコンストラクタしか持たない帰納型の例 -/
7+
inductive Foo where
8+
| mk (x y : Nat)
9+
deriving DecidableEq
10+
11+
#guard
12+
-- コンストラクタを使って項を作る場合
13+
let foo₁ := Foo.mk 1 2
14+
15+
-- 無名コンストラクタを使って項を作る場合
16+
let foo₂ := ⟨1, 2
17+
18+
-- 両者は同じものを表す!
19+
foo₁ = foo₂
20+
21+
/- 一般の[帰納型](#{root}/Declarative/Inductive.md)に対しては使用できません。-/
22+
23+
/-- 複数のコンストラクタを持つ帰納型の例 -/
24+
inductive Sample where
25+
| fst (foo bar : Nat) : Sample
26+
| snd (foo bar : String) : Sample
27+
28+
-- 「コンストラクタが一つしかない帰納型でなければ使用できない」というエラーになる
29+
/--
30+
warning: invalid constructor ⟨...⟩, expected type must be an inductive type with only one constructor ⏎
31+
Sample
32+
-/
33+
#guard_msgs in
34+
#check_failure (⟨"foo", "bar"⟩ : Sample)
35+
36+
/- ## 構造体への使用
37+
[構造体](#{root}/Declarative/Structure.md)は単一コンストラクタしか持たない帰納型なので、構造体に対しても無名コンストラクタ構文が使用できます。-/
38+
39+
/-- 2つのフィールドを持つ構造体 -/
40+
structure Hoge where
41+
foo : Nat
42+
bar : Nat
43+
44+
#check (⟨1, 2⟩ : Hoge)
45+
46+
/- ## 平坦化
47+
コンストラクタが入れ子になっている場合でも平坦化することができます。-/
48+
49+
#guard
50+
-- 入れ子にした場合
51+
let x : Nat × (Int × String) := ⟨1, ⟨2, "hello"⟩⟩
52+
53+
-- 平坦化した場合
54+
let y : Nat × (Int × String) := ⟨1, 2, "hello"
55+
56+
-- 両者は同じものを表している!
57+
x = y
58+
59+
/- 上の例は構造体の同種のコンストラクタが入れ子になっている例ですが、構造体でも同種のコンストラクタでもなくても平坦化することができます。 -/
60+
61+
/-- Prod を真似て自作した帰納型 -/
62+
inductive MyProd (α β : Type) where
63+
| mk (fst : α) (snd : β)
64+
deriving DecidableEq
65+
66+
-- Prod のための中置記法
67+
@[inherit_doc] infixr:35 " ×ₘ " => MyProd
68+
69+
-- 平坦化ができている!
70+
#check (⟨1, 2, 1, 2, 1⟩ : Nat × Nat ×ₘ Nat ×ₘ Nat × Nat)

LeanByExample/Tactic/Exact.lean

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ example (hP : P) (hQ : Q) : P ∧ Q := by
1717

1818
example (hP : P) (hQ : Q) : P ∧ Q := And.intro hP hQ
1919

20-
/- なお `And` は[構造体](#{root}/Declarative/Structure.md)なので[無名コンストラクタ](#{root}/Declarative/Structure.md#AnonymousConstructor)記法を用いて次のように書くこともできます。-/
20+
/- なお `And` は[構造体](#{root}/Declarative/Structure.md)なので[無名コンストラクタ](#{root}/Parser/AnonymousConstructor.md)記法を用いて次のように書くこともできます。-/
2121

2222
example (hP : P) (hQ : Q) : P ∧ Q := ⟨hP, hQ⟩
2323

LeanByExample/Tactic/Exists.lean

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ inductive Exists.{u} {α : Sort u} (p : α → Prop) : Prop where
2929
| intro (w : α) (h : p w) : Exists p
3030

3131
end Exists --#
32-
/- したがって `Exists` は単一のコンストラクタを持つ[帰納型](#{root}/Declarative/Inductive.md)、つまり[構造体](#{root}/Declarative/Structure.md)なので、上記の `exists` は `exact` と[無名コンストラクタ](#{root}/Declarative/Structure.md#AnonymousConstructor)で次のように書き直すことができます。-/
32+
/- したがって `Exists` は単一のコンストラクタを持つ[帰納型](#{root}/Declarative/Inductive.md)、つまり[構造体](#{root}/Declarative/Structure.md)なので、上記の `exists` は `exact` と[無名コンストラクタ](#{root}/Parser/AnonymousConstructor.md)で次のように書き直すことができます。-/
3333

3434
example : ∃ x : Nat, 3 * x + 1 = 7 := by
3535
exact ⟨2, show 3 * 2 + 1 = 7 from by rfl⟩

LeanByExample/Tactic/Have.lean

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ example (hPQ: P → Q) (hQR: Q → R) : P → R := by
2525
2626
`P` の証明 `hp : P` と `Q` の証明 `hq : Q` があるとき、`P ∧ Q` の証明は `And.intro hp hq` で構成できます。ここで `And.intro` は構造体 `And` 型のコンストラクタです。
2727
28-
これを、コンストラクタ名を明示せずにシンプルに `⟨hp, hq⟩` と書くことができます。これは[無名コンストラクタ](#{root}/Declarative/Structure.md#AnonymousConstructor)と呼ばれるもので、`And` に限らず任意の[構造体](#{root}/Declarative/Structure.md)に使用することができます。-/
28+
これを、コンストラクタ名を明示せずにシンプルに `⟨hp, hq⟩` と書くことができます。これは[無名コンストラクタ](#{root}/Parser/AnonymousConstructor.md)と呼ばれるもので、`And` に限らず任意の[構造体](#{root}/Declarative/Structure.md)に使用することができます。-/
2929
variable (hp : P) (hq : Q)
3030

3131
def hpq : P ∧ Q := ⟨hp, hq⟩

LeanByExample/Tactic/Intro.lean

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ example (hPQ: P → Q) (hQR: Q → R) : P → R := by
2727
/- ## 特定の形の命題に対しての使用法
2828
2929
### A ∧ B → C
30-
前提が論理積の形をしていた場合、[無名コンストラクタ](#{root}/Declarative/Structure.md#AnonymousConstructor)で仮定を分解することができます。
30+
前提が論理積の形をしていた場合、[無名コンストラクタ](#{root}/Parser/AnonymousConstructor.md)で仮定を分解することができます。
3131
-/
3232

3333
example {S : Prop} (hPR : P → R) (hQR : Q → S) : P ∧ Q → R ∧ S := by

booksrc/SUMMARY.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
- [unsafe: Leanのルールを破る](./Modifier/Unsafe.md)
6868

6969
- [構文](./Parser/README.md)
70+
- [⟨x₁, x₂, ..⟩: 無名コンストラクタ](./Parser/AnonymousConstructor.md)
7071
- [`{x y : A}`: 暗黙の引数](./Parser/ImplicitBinder.md)
7172
- [by: タクティクモードに入る](./Parser/By.md)
7273
- [show .. from: 項の型を明示](./Parser/Show.md)
@@ -122,7 +123,7 @@
122123
- [Type: 型の型](./Type/Type.md)
123124

124125
- [タクティク](./Tactic/README.md)
125-
- [<;> 生成された全ゴールに適用](./Tactic/SeqFocus.md)
126+
- [<;>: 生成された全ゴールに適用](./Tactic/SeqFocus.md)
126127
- [ac_rfl: 可換性と結合性を使う](./Tactic/AcRfl.md)
127128
- [aesop: 自明な証明の自動探索](./Tactic/Aesop.md)
128129
- [all_goals: 全ゴールに対して適用](./Tactic/AllGoals.md)

0 commit comments

Comments
 (0)