Chap.1ではinsertion sortを例にしてCoqの解説が行われています。そこで、Appendixのinsertion sortのコードをCoqIdeに入力してみました。実際に証明が自分で出来る様になるのは将来の課題として、とりあえずCoqでの開発の流れを追ってみます。
なお証明自体はinsertionv8.vにあります。
まず、list Zがソートされた状態を定義する
sorted : list Z -> Prop
を定義します。こんな感じです。
Inductive sorted : list Z -> Prop :=
| sorted0 : sorted nil
| sorted1 : forall z:Z, sorted (z :: nil)
| sorted2 : forall (z1 z2:Z) (l:list Z),
z1 <= z2 -> sorted (z2 :: l) -> sorted (z1 :: z2 :: l).
sorted
は定義なのでこれ自体は証明の対象ではありません。これを用いて、
を証明します。
Theorem sorted_inv :
forall (z:Z) (l:list Z), sorted (z :: l) -> sorted l.
次いで、並べ替えであることを示す
equiv
を定義します。まず、リストのなかの出現数を示すを定義します。この
Fixpoint nb_occ (z:Z) (l:list Z) {struct l} : nat :=
match l with
| nil => 0%nat
| (z' :: l') =>
match Z_eq_dec z z' with
| left _ => S (nb_occ z l')
| right _ => nb_occ z l'
end
end.
nb_occ
は定義なので証明しません。これを使って、
を定義します。これ自体も証明しません。
Definition equiv (l l':list Z) := forall z:Z, nb_occ z l = nb_occ z l'
nb_occ, equiv
の定義から、下記の補題を証明します。
Lemma equiv_refl :
forall l:list Z, equiv l l.
Lemma equiv_sym :
forall l l':list Z, equiv l l' -> equiv l' l.
Lemma equiv_trans :
forall l l' l'':list Z, equiv l l' -> equiv l' l'' -> equiv l l''.
Lemma equiv_cons :
forall (z:Z) (l l':list Z), equiv l l' -> equiv (z :: l) (z :: l').
Lemma equiv_perm :
forall (a b:Z) (l l':list Z), equiv l l' -> equiv (a :: b :: l) (b :: a :: l').
次いで、実際にinsertion sortを行う関数
aux : Z -> list Z -> list Z
を定義します。
Fixpoint aux (z:Z) (l:list Z) {struct l} : list Z :=
match l with
| nil => z :: nil
| cons a l' =>
match Z_le_gt_dec z a with
| left _ => z :: a :: l'
| right _ => a :: (aux z l')
end
end.
aux
がinsertion sortの性質を持っている事を示す補題、つまりauxの結果がequivであること、sortedであることを証明します。
Lemma aux_equiv :
forall (l:list Z) (x:Z), equiv (x :: l) (aux x l).
Lemma aux_sorted :
forall (l:list Z) (x:Z), sorted l -> sorted (aux x l).
最後に、
sort:list Z -> list Z
を定義というか、sortされた出力の存在を証明します。
Definition sort : forall l:list Z, {l' : list Z | equiv l l' /\ sorted l'}.
証明を追いきれてないのですが、どうも
exists (aux a l')
の様に、実例を示して存在を証明するみたいにaux
を使っているようです。----
sorted, nb_occ, equiv
は定義なので証明の対象ではありません。aux, sort
は成果物として得る、証明済みのプログラムです。sort
を満たす具体的なl'
の値としてaux
を使った式を与えます。その値がl'
の条件を満たす事はaux_equiv, aux_sorted
から保証されます。一般的に
- 仕様を表す様な述語(X -> Prop)を書く。仕様に関する補題も証明しておく。
- 解を与える様な関数を書く。
- その関数の出力が仕様を満たす事を証明する。
----
ある程度、この本を読み終わった後で、またこのプログラムを振り返ってみたいと思います。
No comments:
Post a Comment