comparison paper/agda.tex @ 51:6318c8f4bb8c

Writing Agda description
author atton <atton@cr.ie.u-ryukyu.ac.jp>
date Tue, 31 Jan 2017 11:57:12 +0900
parents 451c510825de
children fb42478e4c96
comparison
equal deleted inserted replaced
50:451c510825de 51:6318c8f4bb8c
276 \end{table} 276 \end{table}
277 \end{center} 277 \end{center}
278 % }}} 278 % }}}
279 279
280 \section{依存型を持つ証明支援系言語 Agda} 280 \section{依存型を持つ証明支援系言語 Agda}
281 型システムを用いて証明を行なうことができる言語に Agda が存在する。% ref Agda のref
282 Agda は依存型という強力な型システムを持っている。
283 依存型とは型も第一級オブジェクトとする型であり、型を引数に取る関数や値を取って型を返す関数、型の型などが記述できる。
284 この節では Agda の文法的な紹介を行なう。 % ref pdf のアレ
285
286 まず Agda のプログラムは全てモジュールの内部に記述されるため、まずはトップレベルにモジュールを定義する必要がある。
287 トップレベルのモジュールはファイル名と同一となる。
288 例えば \verb/AgdaBasics.agda/ のモジュール名定義はリスト~\ref{src:agda-module}のようになる。
289
290 \lstinputlisting[label=src:agda-module, caption=Agdaのモジュールの定義する] {src/AgdaBasics.agda}
291
292 また、Agda はインデントに意味を持つ言語であるため、インデントはきちんと揃える必要がある。
293
294 まず Agda におけるデータ型について触れていく。
295 Agda における型指定は $:$ を用いて行なう。
296 例えば、変数xが型Aを持つ、ということを表すには \verb/x : A/ と記述する。
297
298 データ型は Haskell や ML に似て代数的なデータ構造のパターンマッチを扱うことができる
299 データ型の定義は \verb/data/ キーワードを用いる。
300 \verb/data/キーワードの後に \verb/where/ 句を書きインデントを深くした後、値にコンストラクタとその型を列挙する。
301 例えば Bool 型を定義するとリスト~\ref{src:agda-bool}のようになる。
302
303 \lstinputlisting[label=src:agda-bool, caption=Agdaにおけるデータ型 Bool の定義] {src/AgdaBool.agda}
304
305 Bool はコンストラクタ \verb/true/ か \verb/false/ を持つデータ型である。
306 Bool 自身の型は \verb/Set/ であり、これは Agda が組み込みで持つ「型の型」である。
307 Set は階層構造を持ち、型の型の型を指定するには Set1 と書く。
308
309 関数の定義は Haskell に近い。
310 関数名と型を記述した後に関数の本体を \verb/=/ の後に指定する。
311 関数の型は単純型付き $ \lambda$ 計算と同様に $ \rightarrow $ を用いる。
312 なお、$\rightarrow$に対しては糖衣構文 \verb/->/ も用意されている。
313 引数は変数名で受けることもできるが、具体的なコンストラクタを指定することでそのコンストラクタが渡された時の挙動を定義できる。
314 これはパターンマッチと呼ばれ、コンストラクタで case 文を行なっているようなものである。
315 例えば Bool 型の値を反転する \verb/not/ 関数を書くとリスト~\ref{src:agda-not}のようになる。
316
317 \lstinputlisting[label=src:agda-not, caption=Agdaにおける関数 not の定義] {src/AgdaNot.agda}
318
319 パターンマッチは全てのコンストラクタのパターンを含まなくてはならない。
320 パターンマッチは上からマッチされていくため、優先順位が存在する。
321 なお、コンストラクタをいくつか指定した後に変数で受けると、変数が持ちうる値は指定したコンストラクタ以外となる。
322 例えばリスト~\ref{src:agda-pattern}のnot は x には true しか入ることは無い。
323
324 \lstinputlisting[label=src:agda-pattern, caption=Agdaにおけるパターンマッチ] {src/AgdaPattern.agda}
325
326 なお、マッチした値を変数として利用しない場合は \verb/_/ を用いて捨てることもできる。
327
328 単純型で利用した自然数もデータ型として定義できる(リスト~\ref{src:agda-nat})。
329 自然数のコンストラクタは2つあり、片方は自然数ゼロ、片方は自然数を取って後続数を返すものである。
330 例えば3は \verb/suc (suc (suc zero))/ となる。
331
332 \lstinputlisting[label=src:agda-nat, caption=Agdaにおける自然数の定義] {src/AgdaNat.agda}
333
334 自然数に対する演算は再帰関数として定義できる。
335 例えば自然数どうしの加算は二項演算子\verb/+/としてリスト~\ref{src:agda-plus}のように書ける。
336
337 この二項演算子は正確には中置関数である。
338 前置や後置で定義できる部分を関数名に \verb/_/ として埋め込んでおくことで、関数を呼ぶ時にあたかも前置演算子のように振る舞う。
339 また、Agda は関数が停止するかを判定できる。
340 この加算の二項演算子は左側がゼロに対しては明かに停止する。
341 左側が1以上の時の再帰時には \verb/suc n/ から \verb/n/へと減っているため、再帰で繰り返し減らすことでいつかは停止する。
342
343 \lstinputlisting[label=src:agda-plus, caption=Agda における自然数の加算の定義] {src/AgdaPlus.agda}
344
345
281 \section{Reasoning} 346 \section{Reasoning}
282 347