annotate Agda/tutorial.md @ 134:e965a4b3e697 default tip

backup 2023-11-14
author autobackup
date Tue, 14 Nov 2023 00:10:04 +0900
parents b6c284fd5ae4
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 # Agda入門
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 間違いもあると思うが一応記録していく。
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 ## 基本動作
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 基本的なコードを以下に記載する。
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 ```agda:hello.agda
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 module hello where
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 test1 : Set → Set
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 test1 x = x
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 ```
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 書いた定義を
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 C-c C-l でコンパイルすることができる。
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 書いたコードの解説をすると、
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 - `module hello where`は必要な宣言で、`module`の次にファイル名を記述する。
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 - `test :`の行は関数の宣言と仕様の記述をしている。
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 - `:`の前で関数名を定義している
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 - `:`の後で仕様の記述をしている。
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 - 意味はこの関数は**型**がSetの引数を受けとり、返り値として**型**がSetのものを返す。
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 - `test =`の行は関数の実装を記述している。
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 - `=`の前にxがあるが、これは関数が引数としてxを受け取ったことを表している。
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 - 余談だがHaskellでも同じように関数の後ろに引数を記述する。
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 - 仕様として、引数で受け取った物をそのまま返しても成り立つ
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 - Setを受け取りSetを返すだけなのでこれで良い
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
29
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 また、`=`から後方を削除し、`?`を入力しC-c C-lすることもできる。その際に`{ }`が表示される。
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 - その中でC-c C-, すると引数に何が格納されているのか見ることができる。
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 - また、C-c C-a するとAuto (proof search)ができ、自動でできるならAgdaが自動的に補完をしてくれる。
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
33
2
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
34 関数を実行したい際にはC-c C-n で実行することができる。
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
35
0
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 コマンド群は[ここ](https://agda.wiki.fc2.com/wiki/コマンド一覧)にも記載されている。
2
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
37 特殊文字などもみんなのagdaに記載されている。
0
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 ## 関数定義
2
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
40 関数定義の際に基本となる記述を記載しておく。
0
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
41
2
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
42 ```agda:func.agda
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
43 test2 : (A : Set) → Set
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
44 test2 a = a
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
45
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
46 -- 引数を増やすこともできる。
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
47 test3 : (A B : Set) → Set
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
48 test3 a b = b
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
49
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
50 -- ()ではなく{}で方を定義することもできる。その場合{}で定義した部分の変数を隠すことができる。
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
51 test4 : {A B : Set} → A → (A → B) → B
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
52 test4 a x = x a
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
53
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
54 -- {}で定義した部分を取得することも可能
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
55 test5 : {A B : Set} → A → (A → B) → B
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
56 test5 {A} {B} a x = x a
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
57
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
58 -- 上記の{}で定義した物を()で書き換えると以下のようになる
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
59 test6 : (A B : Set) → A → (A → B) → B
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
60 test6 A B a x = x a
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
61 -- あまりスマートではないし定義の意味が{}で記述した場合と違う
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
62 ```
0
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
63
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 ## data型
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
65
2
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
66 ```agda:data.agda
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
67 -- 次はdata型とrecord型の説明
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
68 -- 記号などはみんなのagdaにほとんど載っていたり、普通にググっても出る。
0
e12992dca4a0 init from Growi
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
69
2
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
70 data _∨_ (A B : Set) : Set where
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
71 front : A → A ∨ B
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
72 back : B → A ∨ B
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
73 -- 関数名として_∨_を定義しているが、これで中置演算子を定義することができる。
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
74 -- 実際にやっていることは下記に定義している関数と同じ
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
75
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
76 data or (A B : Set) : Set where
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
77 front : A → or A B
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
78 back : B → or A B
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
79 ```
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
80 data型というのは分岐のことであり、「どちらか一方が必ず動作する。」ということになる。
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
81
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
82 わかり易い例としてBool型の定義がある。
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
83 ```
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
84 data Bool : Set where
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
85 true : Bool
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
86 false : Bool
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
87 ```
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
88 data型を使用した例としてジャンケンを定義してみる。
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
89 ```agda:rps.agda
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
90 data hand : Set where
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
91 r : hand
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
92 p : hand
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
93 s : hand
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
94
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
95 -- 「手」を二つ受け取って勝った方の手を返すように設計すると
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
96 -- 定義は「handを2つ受け取る。最終的にhandを返す」となり、以下のようになる。
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
97 rps : (A B : hand) → hand
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
98 -- rps : hand → hand → hand これでも良い
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
99 -- rps : (_ _ : hand) → hand これでもできるかもしれない
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
100 rps r r = r
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
101 rps r p = p
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
102 rps r s = r
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
103 rps p r = p
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
104 rps p p = p
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
105 rps p s = s
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
106 rps s r = r
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
107 rps s p = s
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
108 rps s s = s
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
109 ```
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
110 場合分けの数が足りない場合、agdaが親切に怒ってくれる。
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
111
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
112
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
113 ## record型
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
114 data型とは違い、
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
115 オブジェクトあるいは構造体のようなもの。
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
116 以下の関数はAND。p1で前方部分が取得でき、p2で後方部分が取得できる。
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
117
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
118 ``` agda:record.agda
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
119 record _∧_ (A B : Set) : Set where
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
120 field
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
121 p1 : A
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
122 p2 : B
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
123
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
124 -- 普通にANDの後ろの方を取得することもできる
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
125 datatest1 : {A B C : Set} → (A ∧ (B → C )) → (B → C)
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
126 datatest1 x b = _∧_.p2 x b
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
127
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
128
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
129 -- ANDの後ろの方を取得した結果を使用することもできる。
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
130 datatest : {A B C : Set} → B → (A ∧ (B → C )) → C
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
131 datatest b x = _∧_.p2 x b
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
132 ```
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
133
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
134 これらを使用して三段論法を定義することができる。
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
135 定義は「AならばB」かつ「BならばC」なら「AならばC」となる。
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
136 ```
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
137 syllogism : {A B C : Set} → ((A → B) ∧ (B → C)) → (A → C)
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
138 syllogism x a = _∧_.p2 x (_∧_.p1 x a)
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
139 ```
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
140
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
141
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
142
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
143
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
144
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
145
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
146
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
147
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
148
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
149
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
150
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
151
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
152
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
153
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
154
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
155
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
156
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
157
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
158
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
159
b6c284fd5ae4 backup 2020-12-16
autobackup
parents: 0
diff changeset
160