Commit c3cba46d by Jean-Christophe Filliâtre

### library: more lemmas on lists

`completed proof of mergesort_list (tail rec version of merge)`
parent 74967c33
 (* Sorting a list of integers using mergesort *) (** Sorting a list of integers using mergesort Author: Jean-Christophe Filliâtre (CNRS) *) module Elt ... ... @@ -15,13 +18,14 @@ module Elt end module Merge module Merge (* : MergeSpec *) use export Elt clone export Elt let rec merge (l1 l2: list elt) : list elt requires { sorted l1 /\ sorted l2 } ensures { sorted result /\ permut result (l1 ++ l2) } ensures { sorted result } ensures { permut result (l1 ++ l2) } variant { length l1 + length l2 } = match l1, l2 with | Nil, _ -> l2 ... ... @@ -32,19 +36,25 @@ module Merge end (* TODO: proof to be completed module EfficientMerge (** tail recursive implementation *) use export Elt module EfficientMerge (* : MergeSpec *) clone export Elt use import list.Mem use import list.Reverse use import list.RevAppend lemma sorted_reverse_cons: forall acc x1. sorted (reverse acc) -> (forall x. mem x acc -> le x x1) -> sorted (reverse (Cons x1 acc)) let rec merge_aux (acc l1 l2: list elt) : list elt requires { sorted (reverse acc) /\ sorted l1 /\ sorted l2 } requires { forall x y: elt. mem x acc -> mem y l1 -> le x y } requires { forall x y: elt. mem x acc -> mem y l2 -> le x y } ensures { sorted result /\ permut result (acc ++ l1 ++ l2) } ensures { sorted result } ensures { permut result (acc ++ l1 ++ l2) } variant { length l1 + length l2 } = match l1, l2 with | Nil, _ -> rev_append acc l2 ... ... @@ -61,11 +71,10 @@ module EfficientMerge merge_aux Nil l1 l2 end *) module Mergesort use import Merge clone import Merge let split (l0: list 'a) : (list 'a, list 'a) requires { length l0 >= 2 } ... ...
This diff is collapsed.
 ... ... @@ -7,6 +7,7 @@ Require list.List. Require list.Length. Require list.Mem. Require list.Append. Require list.Reverse. (* Why3 goal *) Definition num_occ: forall {a:Type} {a_WT:WhyType a}, a -> (list a) -> Z. ... ... @@ -83,3 +84,16 @@ rewrite Zplus_assoc. now case why_decidable_eq. Qed. (* Why3 goal *) Lemma reverse_num_occ : forall {a:Type} {a_WT:WhyType a}, forall (x:a) (l:(list a)), ((num_occ x l) = (num_occ x (Lists.List.rev l))). intros a a_WT x l. induction l; simpl. auto. rewrite Append_Num_Occ. rewrite <- IHl. ring_simplify. simpl (num_occ x (a0 :: nil))%list. ring. Qed.
 ... ... @@ -7,6 +7,7 @@ Require list.List. Require list.Length. Require list.Mem. Require list.Append. Require list.Reverse. Require list.NumOcc. (* Why3 assumption *) ... ...
 ... ... @@ -7,17 +7,18 @@ Require list.List. Require list.Length. Require list.Mem. Require list.Append. Require list.Reverse. (* Why3 goal *) Lemma rev_append_def : forall {a:Type} {a_WT:WhyType a}, forall (s:(list a)) Lemma rev_append_def1 : forall {a:Type} {a_WT:WhyType a}, forall (s:(list a)) (t:(list a)), ((Lists.List.rev_append s t) = match s with | (Init.Datatypes.cons x r) => (Lists.List.rev_append r (Init.Datatypes.cons x t)) | Init.Datatypes.nil => t end). Proof. now intros a a_WT [|sh st] t. intros a a_WT s t. destruct s; simpl; auto. Qed. (* Why3 goal *) ... ... @@ -61,3 +62,15 @@ change (Length.length (sh :: st)) with (1 + Length.length st)%Z. ring. Qed. (* Why3 goal *) Lemma rev_append_def : forall {a:Type} {a_WT:WhyType a}, forall (r:(list a)) (s:(list a)), ((Lists.List.rev_append r s) = (Init.Datatypes.app (Lists.List.rev r) s)). Proof. induction r; simpl. now auto. intro s; rewrite IHr. rewrite <- Append.Append_assoc. simpl. reflexivity. Qed.
 ... ... @@ -29,6 +29,15 @@ simpl. now rewrite <- List.app_assoc. Qed. (* Why3 goal *) Lemma reverse_cons : forall {a:Type} {a_WT:WhyType a}, forall (l:(list a)) (x:a), ((Lists.List.rev (Init.Datatypes.cons x l)) = (Init.Datatypes.app (Lists.List.rev l) (Init.Datatypes.cons x Init.Datatypes.nil))). intros a a_WT l x. simpl. auto. Qed. (* Why3 goal *) Lemma reverse_reverse : forall {a:Type} {a_WT:WhyType a}, forall (l:(list a)), ((Lists.List.rev (Lists.List.rev l)) = l). ... ... @@ -37,6 +46,21 @@ intros a a_WT l. apply List.rev_involutive. Qed. (* Why3 goal *) Lemma reverse_mem : forall {a:Type} {a_WT:WhyType a}, forall (l:(list a)) (x:a), (list.Mem.mem x l) <-> (list.Mem.mem x (Lists.List.rev l)). intros a a_WT l x. induction l; simpl; intuition. rewrite Append.mem_append. right; simpl; now intuition. rewrite Append.mem_append. now auto. assert (Mem.mem x (List.rev l) \/ Mem.mem x (a0 :: nil))%list. rewrite <- Append.mem_append; assumption. intuition; simpl in *. intuition. Qed. (* Why3 goal *) Lemma Reverse_length : forall {a:Type} {a_WT:WhyType a}, forall (l:(list a)), ((list.Length.length (Lists.List.rev l)) = (list.Length.length l)). ... ...
 ... ... @@ -219,9 +219,18 @@ theory Reverse forall l1 l2: list 'a, x: 'a. (reverse (Cons x l1)) ++ l2 = (reverse l1) ++ (Cons x l2) lemma reverse_cons: forall l: list 'a, x: 'a. reverse (Cons x l) = reverse l ++ Cons x Nil lemma reverse_reverse: forall l: list 'a. reverse (reverse l) = l use import Mem lemma reverse_mem: forall l: list 'a, x: 'a. mem x l <-> mem x (reverse l) use import Length lemma Reverse_length: ... ... @@ -258,6 +267,11 @@ theory RevAppend forall s t: list 'a. length (rev_append s t) = length s + length t use import Reverse lemma rev_append_def: forall r s: list 'a. rev_append r s = reverse r ++ s end (** {2 Zip} *) ... ... @@ -298,6 +312,14 @@ theory Sorted forall x: t, l: list t. (forall y: t. mem y l -> le x y) /\ sorted l <-> sorted (Cons x l) use import Append lemma sorted_append: forall l1 l2: list t. sorted l1 -> sorted l2 -> (forall x y: t. mem x l1 -> mem y l2 -> le x y) -> sorted (l1 ++ l2) end (** {2 Sorted lists of integers} *) ... ... @@ -338,15 +360,6 @@ theory RevSorted Decr.sorted (rev_append s t) <-> Incr.sorted s /\ Decr.sorted t /\ compat t s (* use import Reverse lemma rev_sorted_incr: forall s: list t. Incr.sorted (reverse s) <-> Decr.sorted s lemma rev_sorted_decr: forall s: list t. Decr.sorted (reverse s) <-> Incr.sorted s *) end (** {2 Number of occurrences in a list} *) ... ... @@ -374,6 +387,12 @@ theory NumOcc forall x: 'a, l1 l2: list 'a. num_occ x (l1 ++ l2) = num_occ x l1 + num_occ x l2 use import Reverse lemma reverse_num_occ : forall x: 'a, l: list 'a. num_occ x l = num_occ x (reverse l) end (** {2 Permutation of lists} *) ... ...
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment