src/HOL/List.thy
changeset 68109 cebf36c14226
parent 68085 7fe53815cce9
child 68111 bdbf759ddbac
equal deleted inserted replaced
68097:5f3cffe16311 68109:cebf36c14226
   349 
   349 
   350 text \<open>A sorted predicate w.r.t. a relation:\<close>
   350 text \<open>A sorted predicate w.r.t. a relation:\<close>
   351 
   351 
   352 fun sorted_wrt :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> bool" where
   352 fun sorted_wrt :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> bool" where
   353 "sorted_wrt P [] = True" |
   353 "sorted_wrt P [] = True" |
   354 "sorted_wrt P [x] = True" |
   354 "sorted_wrt P (x # ys) = ((\<forall>y \<in> set ys. P x y) \<and> sorted_wrt P ys)"
   355 "sorted_wrt P (x # y # zs) = (P x y \<and> sorted_wrt P (y # zs))"
       
   356 
   355 
   357 (* FIXME: define sorted in terms of sorted_wrt *)
   356 (* FIXME: define sorted in terms of sorted_wrt *)
   358 
   357 
   359 text \<open>A class-based sorted predicate:\<close>
   358 text \<open>A class-based sorted predicate:\<close>
   360 
   359 
   361 context linorder
   360 context linorder
   362 begin
   361 begin
   363 
   362 
   364 fun sorted :: "'a list \<Rightarrow> bool" where
   363 fun sorted :: "'a list \<Rightarrow> bool" where
   365 "sorted [] = True" |
   364 "sorted [] = True" |
   366 "sorted [x] = True" |
   365 "sorted (x # ys) = ((\<forall>y \<in> set ys. x \<le> y) \<and> sorted ys)"
   367 "sorted (x # y # zs) = (x \<le> y \<and> sorted (y # zs))"
       
   368 
   366 
   369 lemma sorted_sorted_wrt: "sorted = sorted_wrt (\<le>)"
   367 lemma sorted_sorted_wrt: "sorted = sorted_wrt (\<le>)"
   370 proof (rule ext)
   368 proof (rule ext)
   371   fix xs show "sorted xs = sorted_wrt (\<le>) xs"
   369   fix xs show "sorted xs = sorted_wrt (\<le>) xs"
   372     by(induction xs rule: sorted.induct) auto
   370     by(induction xs rule: sorted.induct) auto
  4933 subsection \<open>Sorting\<close>
  4931 subsection \<open>Sorting\<close>
  4934 
  4932 
  4935 
  4933 
  4936 subsubsection \<open>@{const sorted_wrt}\<close>
  4934 subsubsection \<open>@{const sorted_wrt}\<close>
  4937 
  4935 
  4938 lemma sorted_wrt_Cons:
       
  4939 assumes "transp P"
       
  4940 shows   "sorted_wrt P (x # xs) = ((\<forall>y \<in> set xs. P x y) \<and> sorted_wrt P xs)"
       
  4941 by(induction xs arbitrary: x)(auto intro: transpD[OF assms])
       
  4942 
       
  4943 lemma sorted_wrt_ConsI:
  4936 lemma sorted_wrt_ConsI:
  4944   "\<lbrakk> \<And>y. y \<in> set xs \<Longrightarrow> P x y; sorted_wrt P xs \<rbrakk> \<Longrightarrow> sorted_wrt P (x # xs)"
  4937   "\<lbrakk> \<And>y. y \<in> set xs \<Longrightarrow> P x y; sorted_wrt P xs \<rbrakk> \<Longrightarrow> sorted_wrt P (x # xs)"
  4945 by (induction xs rule: induct_list012) simp_all
  4938 by (induction xs) simp_all
  4946 
  4939 
  4947 lemma sorted_wrt_append:
  4940 lemma sorted_wrt_append:
  4948 assumes "transp P"
  4941   "sorted_wrt P (xs @ ys) \<longleftrightarrow>
  4949 shows "sorted_wrt P (xs @ ys) \<longleftrightarrow>
       
  4950   sorted_wrt P xs \<and> sorted_wrt P ys \<and> (\<forall>x\<in>set xs. \<forall>y\<in>set ys. P x y)"
  4942   sorted_wrt P xs \<and> sorted_wrt P ys \<and> (\<forall>x\<in>set xs. \<forall>y\<in>set ys. P x y)"
  4951 by (induction xs) (auto simp: sorted_wrt_Cons[OF assms])
  4943 by (induction xs) auto
  4952 
       
  4953 lemma sorted_wrt_backwards:
       
  4954   "sorted_wrt P (xs @ [y, z]) = (P y z \<and> sorted_wrt P (xs @ [y]))"
       
  4955 by (induction xs rule: induct_list012) auto
       
  4956 
  4944 
  4957 lemma sorted_wrt_rev:
  4945 lemma sorted_wrt_rev:
  4958   "sorted_wrt P (rev xs) = sorted_wrt (\<lambda>x y. P y x) xs"
  4946   "sorted_wrt P (rev xs) = sorted_wrt (\<lambda>x y. P y x) xs"
  4959 by (induction xs rule: induct_list012) (simp_all add: sorted_wrt_backwards)
  4947 by (induction xs) (auto simp add: sorted_wrt_append)
  4960 
  4948 
  4961 lemma sorted_wrt_mono:
  4949 lemma sorted_wrt_mono:
  4962   "(\<And>x y. P x y \<Longrightarrow> Q x y) \<Longrightarrow> sorted_wrt P xs \<Longrightarrow> sorted_wrt Q xs"
  4950   "(\<And>x y. P x y \<Longrightarrow> Q x y) \<Longrightarrow> sorted_wrt P xs \<Longrightarrow> sorted_wrt Q xs"
  4963 by(induction xs rule: induct_list012)(auto)
  4951 by(induction xs)(auto)
  4964 
  4952 
  4965 lemma sorted_wrt01: "length xs \<le> 1 \<Longrightarrow> sorted_wrt P xs"
  4953 lemma sorted_wrt01: "length xs \<le> 1 \<Longrightarrow> sorted_wrt P xs"
  4966 by(auto simp: le_Suc_eq length_Suc_conv)
  4954 by(auto simp: le_Suc_eq length_Suc_conv)
  4967 
  4955 
  4968 text \<open>Strictly Ascending Sequences of Natural Numbers\<close>
  4956 text \<open>Strictly Ascending Sequences of Natural Numbers\<close>
  4987 subsubsection \<open>@{const sorted}\<close>
  4975 subsubsection \<open>@{const sorted}\<close>
  4988 
  4976 
  4989 context linorder
  4977 context linorder
  4990 begin
  4978 begin
  4991 
  4979 
  4992 lemma sorted_Cons: "sorted (x#xs) = (sorted xs \<and> (\<forall>y \<in> set xs. x \<le> y))"
       
  4993 apply(induction xs arbitrary: x)
       
  4994  apply simp
       
  4995 by simp (blast intro: order_trans)
       
  4996 (*
       
  4997 lemma sorted_iff_wrt: "sorted xs = sorted_wrt (\<le>) xs"
       
  4998 proof
       
  4999   assume "sorted xs" thus "sorted_wrt (\<le>) xs"
       
  5000   proof (induct xs rule: sorted.induct)
       
  5001     case (Cons xs x) thus ?case by (cases xs) simp_all
       
  5002   qed simp
       
  5003 qed (induct xs rule: induct_list012, simp_all)
       
  5004 *)
       
  5005 lemma sorted_tl:
  4980 lemma sorted_tl:
  5006   "sorted xs \<Longrightarrow> sorted (tl xs)"
  4981   "sorted xs \<Longrightarrow> sorted (tl xs)"
  5007 by (cases xs) (simp_all add: sorted_Cons)
  4982 by (cases xs) (simp_all)
  5008 
  4983 
  5009 lemma sorted_append:
  4984 lemma sorted_append:
  5010   "sorted (xs@ys) = (sorted xs \<and> sorted ys \<and> (\<forall>x \<in> set xs. \<forall>y \<in> set ys. x\<le>y))"
  4985   "sorted (xs@ys) = (sorted xs \<and> sorted ys \<and> (\<forall>x \<in> set xs. \<forall>y \<in> set ys. x\<le>y))"
  5011 by (induct xs) (auto simp add:sorted_Cons)
  4986 by (induct xs) (auto)
  5012 
  4987 
  5013 lemma sorted_nth_mono:
  4988 lemma sorted_nth_mono:
  5014   "sorted xs \<Longrightarrow> i \<le> j \<Longrightarrow> j < length xs \<Longrightarrow> xs!i \<le> xs!j"
  4989   "sorted xs \<Longrightarrow> i \<le> j \<Longrightarrow> j < length xs \<Longrightarrow> xs!i \<le> xs!j"
  5015 by (induct xs arbitrary: i j) (auto simp:nth_Cons' sorted_Cons)
  4990 by (induct xs arbitrary: i j) (auto simp:nth_Cons')
  5016 
  4991 
  5017 lemma sorted_rev_nth_mono:
  4992 lemma sorted_rev_nth_mono:
  5018   "sorted (rev xs) \<Longrightarrow> i \<le> j \<Longrightarrow> j < length xs \<Longrightarrow> xs!j \<le> xs!i"
  4993   "sorted (rev xs) \<Longrightarrow> i \<le> j \<Longrightarrow> j < length xs \<Longrightarrow> xs!j \<le> xs!i"
  5019 using sorted_nth_mono[ of "rev xs" "length xs - j - 1" "length xs - i - 1"]
  4994 using sorted_nth_mono[ of "rev xs" "length xs - j - 1" "length xs - i - 1"]
  5020       rev_nth[of "length xs - i - 1" "xs"] rev_nth[of "length xs - j - 1" "xs"]
  4995       rev_nth[of "length xs - i - 1" "xs"] rev_nth[of "length xs - j - 1" "xs"]
  5033   moreover
  5008   moreover
  5034   {
  5009   {
  5035     fix y assume "y \<in> set xs"
  5010     fix y assume "y \<in> set xs"
  5036     then obtain j where "j < length xs" and "xs ! j = y"
  5011     then obtain j where "j < length xs" and "xs ! j = y"
  5037       unfolding in_set_conv_nth by blast
  5012       unfolding in_set_conv_nth by blast
  5038     with Cons.prems[of 0 "Suc j"]
  5013     with Cons.prems[of 0 "Suc j"] have "x \<le> y" by auto
  5039     have "x \<le> y"
       
  5040       by auto
       
  5041   }
  5014   }
  5042   ultimately
  5015   ultimately
  5043   show ?case
  5016   show ?case by auto
  5044     unfolding sorted_Cons by auto
       
  5045 qed simp
  5017 qed simp
  5046 
  5018 
  5047 lemma sorted_equals_nth_mono:
  5019 lemma sorted_equals_nth_mono:
  5048   "sorted xs = (\<forall>j < length xs. \<forall>i \<le> j. xs ! i \<le> xs ! j)"
  5020   "sorted xs = (\<forall>j < length xs. \<forall>i \<le> j. xs ! i \<le> xs ! j)"
  5049 by (auto intro: sorted_nth_monoI sorted_nth_mono)
  5021 by (auto intro: sorted_nth_monoI sorted_nth_mono)
  5050 
  5022 
  5051 lemma sorted_map_remove1:
  5023 lemma sorted_map_remove1:
  5052   "sorted (map f xs) \<Longrightarrow> sorted (map f (remove1 x xs))"
  5024   "sorted (map f xs) \<Longrightarrow> sorted (map f (remove1 x xs))"
  5053 by (induct xs) (auto simp add: sorted_Cons)
  5025 by (induct xs) (auto)
  5054 
  5026 
  5055 lemma sorted_remove1: "sorted xs \<Longrightarrow> sorted (remove1 a xs)"
  5027 lemma sorted_remove1: "sorted xs \<Longrightarrow> sorted (remove1 a xs)"
  5056 using sorted_map_remove1 [of "\<lambda>x. x"] by simp
  5028 using sorted_map_remove1 [of "\<lambda>x. x"] by simp
  5057 
  5029 
  5058 lemma sorted_butlast:
  5030 lemma sorted_butlast:
  5063     by (cases xs rule: rev_cases) auto
  5035     by (cases xs rule: rev_cases) auto
  5064   with \<open>sorted xs\<close> show ?thesis by (simp add: sorted_append)
  5036   with \<open>sorted xs\<close> show ?thesis by (simp add: sorted_append)
  5065 qed
  5037 qed
  5066 
  5038 
  5067 lemma sorted_replicate [simp]: "sorted(replicate n x)"
  5039 lemma sorted_replicate [simp]: "sorted(replicate n x)"
  5068 by(induction n) (auto simp: sorted_Cons)
  5040 by(induction n) (auto)
  5069 
  5041 
  5070 lemma sorted_remdups[simp]:
  5042 lemma sorted_remdups[simp]:
  5071   "sorted l \<Longrightarrow> sorted (remdups l)"
  5043   "sorted xs \<Longrightarrow> sorted (remdups xs)"
  5072 by (induct l) (auto simp: sorted_Cons)
  5044 by (induct xs) (auto)
  5073 
  5045 
  5074 lemma sorted_remdups_adj[simp]:
  5046 lemma sorted_remdups_adj[simp]:
  5075   "sorted xs \<Longrightarrow> sorted (remdups_adj xs)"
  5047   "sorted xs \<Longrightarrow> sorted (remdups_adj xs)"
  5076 by (induct xs rule: remdups_adj.induct, simp_all split: if_split_asm add: sorted_Cons)
  5048 by (induct xs rule: remdups_adj.induct, simp_all split: if_split_asm)
  5077 
  5049 
  5078 lemma sorted_nths: "sorted xs \<Longrightarrow> sorted (nths xs I)"
  5050 lemma sorted_nths: "sorted xs \<Longrightarrow> sorted (nths xs I)"
  5079 by(induction xs arbitrary: I)(auto simp: sorted_Cons nths_Cons)
  5051 by(induction xs arbitrary: I)(auto simp: nths_Cons)
  5080 
  5052 
  5081 lemma sorted_distinct_set_unique:
  5053 lemma sorted_distinct_set_unique:
  5082 assumes "sorted xs" "distinct xs" "sorted ys" "distinct ys" "set xs = set ys"
  5054 assumes "sorted xs" "distinct xs" "sorted ys" "distinct ys" "set xs = set ys"
  5083 shows "xs = ys"
  5055 shows "xs = ys"
  5084 proof -
  5056 proof -
  5085   from assms have 1: "length xs = length ys" by (auto dest!: distinct_card)
  5057   from assms have 1: "length xs = length ys" by (auto dest!: distinct_card)
  5086   from assms show ?thesis
  5058   from assms show ?thesis
  5087   proof(induct rule:list_induct2[OF 1])
  5059   proof(induct rule:list_induct2[OF 1])
  5088     case 1 show ?case by simp
  5060     case 1 show ?case by simp
  5089   next
  5061   next
  5090     case 2 thus ?case by (simp add: sorted_Cons)
  5062     case 2 thus ?case by simp (metis Diff_insert_absorb antisym insertE insert_iff)
  5091        (metis Diff_insert_absorb antisym insertE insert_iff)
       
  5092   qed
  5063   qed
  5093 qed
  5064 qed
  5094 
  5065 
  5095 lemma map_sorted_distinct_set_unique:
  5066 lemma map_sorted_distinct_set_unique:
  5096   assumes "inj_on f (set xs \<union> set ys)"
  5067   assumes "inj_on f (set xs \<union> set ys)"
  5121 lemma sorted_takeWhile: "sorted xs \<Longrightarrow> sorted (takeWhile P xs)"
  5092 lemma sorted_takeWhile: "sorted xs \<Longrightarrow> sorted (takeWhile P xs)"
  5122   by (subst takeWhile_eq_take) (auto dest: sorted_take)
  5093   by (subst takeWhile_eq_take) (auto dest: sorted_take)
  5123 
  5094 
  5124 lemma sorted_filter:
  5095 lemma sorted_filter:
  5125   "sorted (map f xs) \<Longrightarrow> sorted (map f (filter P xs))"
  5096   "sorted (map f xs) \<Longrightarrow> sorted (map f (filter P xs))"
  5126   by (induct xs) (simp_all add: sorted_Cons)
  5097   by (induct xs) simp_all
  5127 
  5098 
  5128 lemma foldr_max_sorted:
  5099 lemma foldr_max_sorted:
  5129   assumes "sorted (rev xs)"
  5100   assumes "sorted (rev xs)"
  5130   shows "foldr max xs y = (if xs = [] then y else max (xs ! 0) y)"
  5101   shows "foldr max xs y = (if xs = [] then y else max (xs ! 0) y)"
  5131   using assms
  5102   using assms
  5167   case Nil then show ?case by simp
  5138   case Nil then show ?case by simp
  5168 next
  5139 next
  5169   case (Cons x xs)
  5140   case (Cons x xs)
  5170   then have "sorted (map f [y\<leftarrow>xs . f y = (\<lambda>xs. f x) xs])" .
  5141   then have "sorted (map f [y\<leftarrow>xs . f y = (\<lambda>xs. f x) xs])" .
  5171   moreover from Cons have "sorted (map f [y\<leftarrow>xs . f y = (g \<circ> Cons x) xs])" .
  5142   moreover from Cons have "sorted (map f [y\<leftarrow>xs . f y = (g \<circ> Cons x) xs])" .
  5172   ultimately show ?case by (simp_all add: sorted_Cons)
  5143   ultimately show ?case by simp_all
  5173 qed
  5144 qed
  5174 
  5145 
  5175 lemma sorted_same:
  5146 lemma sorted_same:
  5176   "sorted [x\<leftarrow>xs. x = g xs]"
  5147   "sorted [x\<leftarrow>xs. x = g xs]"
  5177 using sorted_map_same [of "\<lambda>x. x"] by simp
  5148 using sorted_map_same [of "\<lambda>x. x"] by simp
  5248 
  5219 
  5249 lemma distinct_sort[simp]: "distinct (sort_key f xs) = distinct xs"
  5220 lemma distinct_sort[simp]: "distinct (sort_key f xs) = distinct xs"
  5250 by (induct xs) (simp_all add: distinct_insort)
  5221 by (induct xs) (simp_all add: distinct_insort)
  5251 
  5222 
  5252 lemma sorted_insort_key: "sorted (map f (insort_key f x xs)) = sorted (map f xs)"
  5223 lemma sorted_insort_key: "sorted (map f (insort_key f x xs)) = sorted (map f xs)"
  5253 by (induct xs) (auto simp: sorted_Cons set_insort_key)
  5224 by (induct xs) (auto simp: set_insort_key)
  5254 
  5225 
  5255 lemma sorted_insort: "sorted (insort x xs) = sorted xs"
  5226 lemma sorted_insort: "sorted (insort x xs) = sorted xs"
  5256 using sorted_insort_key [where f="\<lambda>x. x"] by simp
  5227 using sorted_insort_key [where f="\<lambda>x. x"] by simp
  5257 
  5228 
  5258 theorem sorted_sort_key [simp]: "sorted (map f (sort_key f xs))"
  5229 theorem sorted_sort_key [simp]: "sorted (map f (sort_key f xs))"
  5267 
  5238 
  5268 lemma insort_is_Cons: "\<forall>x\<in>set xs. f a \<le> f x \<Longrightarrow> insort_key f a xs = a # xs"
  5239 lemma insort_is_Cons: "\<forall>x\<in>set xs. f a \<le> f x \<Longrightarrow> insort_key f a xs = a # xs"
  5269 by (cases xs) auto
  5240 by (cases xs) auto
  5270 
  5241 
  5271 lemma sorted_sort_id: "sorted xs \<Longrightarrow> sort xs = xs"
  5242 lemma sorted_sort_id: "sorted xs \<Longrightarrow> sort xs = xs"
  5272 by (induct xs) (auto simp add: sorted_Cons insort_is_Cons)
  5243 by (induct xs) (auto simp add: insort_is_Cons)
  5273 
  5244 
  5274 lemma insort_key_remove1:
  5245 lemma insort_key_remove1:
  5275   assumes "a \<in> set xs" and "sorted (map f xs)" and "hd (filter (\<lambda>x. f a = f x) xs) = a"
  5246   assumes "a \<in> set xs" and "sorted (map f xs)" and "hd (filter (\<lambda>x. f a = f x) xs) = a"
  5276   shows "insort_key f a (remove1 a xs) = xs"
  5247   shows "insort_key f a (remove1 a xs) = xs"
  5277 using assms proof (induct xs)
  5248 using assms proof (induct xs)
  5278   case (Cons x xs)
  5249   case (Cons x xs)
  5279   then show ?case
  5250   then show ?case
  5280   proof (cases "x = a")
  5251   proof (cases "x = a")
  5281     case False
  5252     case False
  5282     then have "f x \<noteq> f a" using Cons.prems by auto
  5253     then have "f x \<noteq> f a" using Cons.prems by auto
  5283     then have "f x < f a" using Cons.prems by (auto simp: sorted_Cons)
  5254     then have "f x < f a" using Cons.prems by auto
  5284     with \<open>f x \<noteq> f a\<close> show ?thesis using Cons by (auto simp: sorted_Cons insort_is_Cons)
  5255     with \<open>f x \<noteq> f a\<close> show ?thesis using Cons by (auto simp: insort_is_Cons)
  5285   qed (auto simp: sorted_Cons insort_is_Cons)
  5256   qed (auto simp: insort_is_Cons)
  5286 qed simp
  5257 qed simp
  5287 
  5258 
  5288 lemma insort_remove1:
  5259 lemma insort_remove1:
  5289   assumes "a \<in> set xs" and "sorted xs"
  5260   assumes "a \<in> set xs" and "sorted xs"
  5290   shows "insort a (remove1 a xs) = xs"
  5261   shows "insort a (remove1 a xs) = xs"
  5349   "\<not> P x \<Longrightarrow> filter P (insort_key f x xs) = filter P xs"
  5320   "\<not> P x \<Longrightarrow> filter P (insort_key f x xs) = filter P xs"
  5350   by (induct xs) simp_all
  5321   by (induct xs) simp_all
  5351 
  5322 
  5352 lemma filter_insort:
  5323 lemma filter_insort:
  5353   "sorted (map f xs) \<Longrightarrow> P x \<Longrightarrow> filter P (insort_key f x xs) = insort_key f x (filter P xs)"
  5324   "sorted (map f xs) \<Longrightarrow> P x \<Longrightarrow> filter P (insort_key f x xs) = insort_key f x (filter P xs)"
  5354   by (induct xs) (auto simp add: sorted_Cons, subst insort_is_Cons, auto)
  5325   by (induct xs) (auto, subst insort_is_Cons, auto)
  5355 
  5326 
  5356 lemma filter_sort:
  5327 lemma filter_sort:
  5357   "filter P (sort_key f xs) = sort_key f (filter P xs)"
  5328   "filter P (sort_key f xs) = sort_key f (filter P xs)"
  5358   by (induct xs) (simp_all add: filter_insort_triv filter_insort)
  5329   by (induct xs) (simp_all add: filter_insort_triv filter_insort)
  5359 
  5330 
  5371   by (rule sorted_sort_id) simp
  5342   by (rule sorted_sort_id) simp
  5372 
  5343 
  5373 lemma sorted_upto[simp]: "sorted[i..j]"
  5344 lemma sorted_upto[simp]: "sorted[i..j]"
  5374 apply(induct i j rule:upto.induct)
  5345 apply(induct i j rule:upto.induct)
  5375 apply(subst upto.simps)
  5346 apply(subst upto.simps)
  5376 apply(simp add:sorted_Cons)
  5347 apply(simp)
  5377 done
  5348 done
  5378 
  5349 
  5379 lemma sorted_find_Min:
  5350 lemma sorted_find_Min:
  5380   "sorted xs \<Longrightarrow> \<exists>x \<in> set xs. P x \<Longrightarrow> List.find P xs = Some (Min {x\<in>set xs. P x})"
  5351   "sorted xs \<Longrightarrow> \<exists>x \<in> set xs. P x \<Longrightarrow> List.find P xs = Some (Min {x\<in>set xs. P x})"
  5381 proof (induct xs)
  5352 proof (induct xs)
  5382   case Nil then show ?case by simp
  5353   case Nil then show ?case by simp
  5383 next
  5354 next
  5384   case (Cons x xs) show ?case proof (cases "P x")
  5355   case (Cons x xs) show ?case proof (cases "P x")
  5385     case True
  5356     case True
  5386     with Cons show ?thesis by (auto simp: sorted_Cons intro: Min_eqI [symmetric])
  5357     with Cons show ?thesis by (auto intro: Min_eqI [symmetric])
  5387   next
  5358   next
  5388     case False then have "{y. (y = x \<or> y \<in> set xs) \<and> P y} = {y \<in> set xs. P y}"
  5359     case False then have "{y. (y = x \<or> y \<in> set xs) \<and> P y} = {y \<in> set xs. P y}"
  5389       by auto
  5360       by auto
  5390     with Cons False show ?thesis by (simp_all add: sorted_Cons)
  5361     with Cons False show ?thesis by (simp_all)
  5391   qed
  5362   qed
  5392 qed
  5363 qed
  5393 
  5364 
  5394 lemma sorted_enumerate [simp]: "sorted (map fst (enumerate n xs))"
  5365 lemma sorted_enumerate [simp]: "sorted (map fst (enumerate n xs))"
  5395 by (simp add: enumerate_eq_zip)
  5366 by (simp add: enumerate_eq_zip)
  6267 by unfold_locales(auto simp add: lexordp_conv_lexordp_eq lexordp_eq_refl lexordp_eq_antisym intro: lexordp_eq_trans del: disjCI intro: lexordp_eq_linear)
  6238 by unfold_locales(auto simp add: lexordp_conv_lexordp_eq lexordp_eq_refl lexordp_eq_antisym intro: lexordp_eq_trans del: disjCI intro: lexordp_eq_linear)
  6268 
  6239 
  6269 end
  6240 end
  6270 
  6241 
  6271 lemma sorted_insort_is_snoc: "sorted xs \<Longrightarrow> \<forall>x \<in> set xs. a \<ge> x \<Longrightarrow> insort a xs = xs @ [a]"
  6242 lemma sorted_insort_is_snoc: "sorted xs \<Longrightarrow> \<forall>x \<in> set xs. a \<ge> x \<Longrightarrow> insort a xs = xs @ [a]"
  6272  by (induct xs) (auto dest!: insort_is_Cons simp: sorted_Cons)
  6243  by (induct xs) (auto dest!: insort_is_Cons)
  6273 
  6244 
  6274 
  6245 
  6275 subsubsection \<open>Lexicographic combination of measure functions\<close>
  6246 subsubsection \<open>Lexicographic combination of measure functions\<close>
  6276 
  6247 
  6277 text \<open>These are useful for termination proofs\<close>
  6248 text \<open>These are useful for termination proofs\<close>
  6838       by (metis Cons Cons_eq_filter_iff in_set_conv_decomp set_sort)
  6809       by (metis Cons Cons_eq_filter_iff in_set_conv_decomp set_sort)
  6839     next
  6810     next
  6840       fix y assume "y \<in> set xs \<and> P y"
  6811       fix y assume "y \<in> set xs \<and> P y"
  6841       hence "y \<in> set (filter P xs)" by auto
  6812       hence "y \<in> set (filter P xs)" by auto
  6842       thus "x \<le> y"
  6813       thus "x \<le> y"
  6843         by (metis Cons eq_iff filter_sort set_ConsD set_sort sorted_Cons sorted_sort)
  6814         by (metis Cons eq_iff filter_sort set_ConsD set_sort sorted.simps(2) sorted_sort)
  6844   qed
  6815   qed
  6845   thus ?thesis using Cons by (simp add: Bleast_def)
  6816   thus ?thesis using Cons by (simp add: Bleast_def)
  6846 qed
  6817 qed
  6847 
  6818 
  6848 declare Bleast_def[symmetric, code_unfold]
  6819 declare Bleast_def[symmetric, code_unfold]