1 (* Title: HOL/Imperative_HOL/ex/Sorted_List.thy
2 Author: Lukas Bulwahn, TU Muenchen
5 header {* Sorted lists as representation of finite sets *}
11 text {* Merge function for two distinct sorted lists to get compound distinct sorted list *}
13 fun merge :: "('a::linorder) list \<Rightarrow> 'a list \<Rightarrow> 'a list"
15 "merge (x#xs) (y#ys) =
16 (if x < y then x # merge xs (y#ys) else (if x > y then y # merge (x#xs) ys else x # merge xs ys))"
20 text {* The function package does not derive automatically the more general rewrite rule as follows: *}
21 lemma merge_Nil[simp]: "merge [] ys = ys"
24 lemma set_merge[simp]: "set (merge xs ys) = set xs \<union> set ys"
25 by (induct xs ys rule: merge.induct, auto)
27 lemma sorted_merge[simp]:
28 "List.sorted (merge xs ys) = (List.sorted xs \<and> List.sorted ys)"
29 by (induct xs ys rule: merge.induct, auto simp add: sorted_Cons)
31 lemma distinct_merge[simp]: "\<lbrakk> distinct xs; distinct ys; List.sorted xs; List.sorted ys \<rbrakk> \<Longrightarrow> distinct (merge xs ys)"
32 by (induct xs ys rule: merge.induct, auto simp add: sorted_Cons)
34 text {* The remove function removes an element from a sorted list *}
36 primrec remove :: "('a :: linorder) \<Rightarrow> 'a list \<Rightarrow> 'a list"
39 | "remove a (x#xs) = (if a > x then (x # remove a xs) else (if a = x then xs else x#xs))"
41 lemma remove': "sorted xs \<and> distinct xs \<Longrightarrow> sorted (remove a xs) \<and> distinct (remove a xs) \<and> set (remove a xs) = set xs - {a}"
43 apply (auto simp add: sorted_Cons)
46 lemma set_remove[simp]: "\<lbrakk> sorted xs; distinct xs \<rbrakk> \<Longrightarrow> set (remove a xs) = set xs - {a}"
49 lemma sorted_remove[simp]: "\<lbrakk> sorted xs; distinct xs \<rbrakk> \<Longrightarrow> sorted (remove a xs)"
52 lemma distinct_remove[simp]: "\<lbrakk> sorted xs; distinct xs \<rbrakk> \<Longrightarrow> distinct (remove a xs)"
55 lemma remove_insort_cancel: "remove a (insort a xs) = xs"
61 lemma remove_insort_commute: "\<lbrakk> a \<noteq> b; sorted xs \<rbrakk> \<Longrightarrow> remove b (insort a xs) = insort a (remove b xs)"
64 apply (auto simp add: sorted_Cons)
69 lemma notinset_remove: "x \<notin> set xs \<Longrightarrow> remove x xs = xs"
74 lemma remove1_eq_remove:
75 "sorted xs \<Longrightarrow> distinct xs \<Longrightarrow> remove1 x xs = remove x xs"
77 apply (auto simp add: sorted_Cons)
78 apply (subgoal_tac "x \<notin> set xs")
79 apply (simp add: notinset_remove)
84 "sorted xs \<Longrightarrow> sorted (remove1 x xs)"
86 apply (auto simp add: sorted_Cons)
89 subsection {* Efficient member function for sorted lists *}
91 primrec smember :: "'a list \<Rightarrow> 'a::linorder \<Rightarrow> bool" where
92 "smember [] x \<longleftrightarrow> False"
93 | "smember (y#ys) x \<longleftrightarrow> x = y \<or> (x > y \<and> smember ys x)"
95 lemma "sorted xs \<Longrightarrow> smember xs x \<longleftrightarrow> (x \<in> set xs)"
96 by (induct xs) (auto simp add: sorted_Cons)