inductive typeと言われてもピンと来ませんが、例えばその型を持つ有限集合を明示的に定義することが出来ます。
実際に有限集合を明示的に定義してみます。
構文
inductive <型名> : Type
| <要素1> : <型名>
| <要素2> : <型名>
:
| <要素N> : <型名>
inductive S : Type
| a : S
| b : S
この型を持つ要素を扱う場合は、S.a
やS.b
のように指定します。
inductive Person : Type
| Euler : Person
| Gauss : Person
| Cantor : Person
要素を何も書かないことで空集合も定義出来ちゃいます
inductive E : Type
※注意 inductive typeは具体的に集まりを書き表すもので、それを使って複製するものでないことに注意してください。
集合や群、圏など概念の型を定義する方法は後述。
自然数は無限に存在するので上記のようにして列挙することは出来ません。自然数を定義するためにはペアノの定義を用います。
ペアノの定義とは、(1) 0は自然数、(2) Nが自然数ならNのsuccessorも自然数、による定義です。
まず(1)の0が自然数であることを表現してみます:
inductive nat : Type
| Zero : nat
※注意 LEAN4にも自然数の型が組み込まれており、そちらはNat
で呼び出される
#print nat
で定義した型の情報を見てみる
inductive nat : Type
constructors:
nat.Zero : nat
0以外の自然数を定義するにはsucccessorを別途用意する必要があります。
プログラム上ではそれをSucc
で表現することにします。つまり、
inductive nat : Type
| Zero : nat
| Succ (n: nat) : nat
のようにSuccをnatの定義に付け加えます。#print nat
で定義した型の情報を見て見ます:
inductive nat : Type
constructors:
nat.Zero : nat
上の定義で、1、2などは
open nat
#print Succ Zero
#print Succ (Succ Zero)
により表現可能です。
※注意 open nat
により自然数の定義を呼び出しています。
これにより通常nat.Zero
やnat.Succ
と書く必要がなくなりコードが読みやすくなります。
※注意 NのsuccessorをN+1と表現している記事をよく見かけますが、自然数上の和は自然数を定義したあとに定義されるものであるため、和というよりはNの次の数という意味なので、言葉どおり1を足すものでないことに注意してください。
せっかくLEAN4を使っているのでここで簡単な定理を証明してみます。
open nat
def One := Succ Zero
def Two := Succ One
def Two' := Succ (Succ Zero)
このように自然数2を二通りの方法で定義することが可能です。これらは残念なことにLEAN4のなかでは別々の型として扱われてしまいます。
#print Two
-- def Two : nat :=
-- Succ One
#print Two'
-- def Two' : nat :=
-- Succ (Succ Zero)
通常のプログラム言語であればTwo
とTwo'
が等しいことはtest関数などですぐに確かめられそうですが、ここはLEAN4。
自力で証明する必要があります。証明すべき定理は以下の主張です。
theorem Two_eq_Two' : Two = Two' := sorry
証明を保留にするため:= sorry
を使います。sorryを使うとデバッグ画面にdeclaration uses 'sorry'
と出力されます。
証明は単純で、両者が等しいことがわかっているのでrfl
を使います:
theorem Two_eq_Two' : Two = Two' := by
{rfl}
#print Two_eq_Two'
-- theorem Two_eq_Two' : Two = Two' :=
-- rfl
カッコの中にカーソルを合わせるとgoals accomplished
が出力され、証明が完了したことが確認出来ます。
inductive nat : Type
| Zero : nat
| Succ (n: nat) : nat
open nat
def One := Succ Zero
def Two := Succ One
def Two' := Succ (Succ Zero)
#print Two
#print Two'
theorem Two_eq_Two' : Two = Two' := by
{rfl}
#print Two_eq_Two'