『独習KMC vol.1』「Coqを用いた証明駆動開発」
『独習KMC vol.1』(2011年8月)に掲載した記事「Coqを用いた証明駆動開発」で使用したソースコードです. Coqバージョン8.3pl2でコンパイルが通ることを確認しています.
Require Import Lists.List.
Require Import Sorting.Sorted Sorting.Permutation.
Require Import Recdef.
Require Import Structures.Orders.
Module Sort (Import X: TotalLeBool').
Local Coercion is_true: bool >-> Sortclass.
Local Notation Sorted := (LocallySorted leb) (only parsing).
Definition filter_gt p := filter (fun x => x <=? p).
Definition filter_le p := filter (fun x => negb (x <=? p)).
Function sort (xs: list t) {measure length xs}: list t :=
match xs with
| nil => nil
| p :: xs => sort (filter_gt p xs) ++ p :: sort (filter_le p xs)
end.
Proof.
intros _ p xs _.
induction xs.
auto.
simpl; case leb; auto with arith.
intros _ p xs _.
induction xs.
auto.
simpl; case leb; auto with arith.
Defined.
Lemma Permutation_partition xs p: Permutation xs ((filter_gt p xs) ++ (filter_le p xs)).
Proof.
induction xs; simpl.
reflexivity.
case leb; simpl.
apply perm_skip; assumption.
etransitivity.
apply perm_skip; eassumption.
apply Permutation_middle.
Qed.
Theorem sort_permuting xs: Permutation xs (sort xs).
Proof.
functional induction (sort xs).
reflexivity.
etransitivity.
apply perm_skip.
etransitivity.
apply Permutation_partition.
apply Permutation_app; eassumption.
apply Permutation_middle.
Qed.
Add Morphism sort
with signature (@Permutation t) ==> (@Permutation t)
as qs_permutation_morphism.
Proof.
intros x y.
intro H.
etransitivity.
symmetry; apply sort_permuting.
symmetry; etransitivity.
symmetry; apply sort_permuting.
symmetry; assumption.
Qed.
Lemma Sorted_partition p xs ys:
Sorted xs -> Sorted ys ->
Forall (fun x => (x <=? p) = true) xs ->
Forall (fun x => (x <=? p) = false) ys ->
Sorted (xs ++ p :: ys).
Proof.
intros Sx Sy Ox Oy.
induction xs as [| x xs IHx]; simpl.
induction ys as [| y ys IHy]; simpl.
apply LSorted_cons1.
apply LSorted_consn; try assumption.
inversion Oy.
destruct (leb_total p y); [assumption | congruence].
induction xs; simpl.
apply LSorted_consn.
apply IHx.
apply LSorted_nil.
trivial.
inversion Ox; assumption.
apply LSorted_consn.
apply IHx.
inversion Sx; assumption.
inversion Ox; assumption.
inversion Sx; assumption.
Qed.
Lemma Permutation_Forall (p: t -> Prop) xs ys:
Permutation xs ys -> Forall p xs -> Forall p ys.
Proof.
intros P F.
induction ys as [| y ys].
trivial.
constructor.
destruct (Forall_forall p xs) as [E _].
apply E; try assumption.
eapply Permutation_in.
symmetry; eassumption.
simpl; auto.
destruct (Forall_forall p ys) as [_ D].
apply D.
intros.
destruct (Forall_forall p xs) as [E _].
apply E; try assumption.
eapply Permutation_in.
symmetry; eassumption.
simpl; auto.
Qed.
Proposition filter_gt_le p xs: Forall (fun x => (x <=? p) = true) (filter_gt p xs).
Proof.
induction xs; simpl.
trivial.
case_eq (a <=? p); intro A; simpl; auto.
Qed.
Proposition filter_le_gt p xs: Forall (fun x => (x <=? p) = false) (filter_le p xs).
Proof.
induction xs; simpl.
trivial.
case_eq (a <=? p); intro A; simpl; auto.
Qed.
Theorem sort_sorting xs: Sorted (sort xs).
Proof.
functional induction (sort xs) as [| xs' p xs s IHg IHl].
apply LSorted_nil.
induction xs as [| x xs IHx].
compute; apply LSorted_cons1.
revert IHg IHl; simpl.
case_eq (x <=? p); simpl; intros.
apply Sorted_partition; try assumption.
eapply Permutation_Forall.
apply sort_permuting.
constructor; [assumption | apply filter_gt_le].
eapply Permutation_Forall.
apply sort_permuting.
apply filter_le_gt.
apply Sorted_partition; try assumption.
eapply Permutation_Forall.
apply sort_permuting.
apply filter_gt_le.
eapply Permutation_Forall.
apply sort_permuting.
constructor; [assumption | apply filter_le_gt].
Qed.
End Sort.
Module Nat <: TotalLeBool.
Require Arith.Compare_dec.
Definition t := nat.
Definition leb := Compare_dec.leb.
Definition leb_total x y: leb x y = true \/ leb y x = true.
Proof.
elim (Compare_dec.le_ge_dec x y); [left | right];
auto using Compare_dec.leb_correct.
Defined.
End Nat.
Module NatSort := Sort Nat.
Extraction Language Ocaml.
Extraction "quicksort.ml" NatSort.sort.
Extraction Language Haskell.
Extraction "quicksort.hs" NatSort.sort.
このページの内容に関するお問い合せは@k_hanazukiまでお願いします.