src/HOL/List.thy
changeset 33639 603320b93668
parent 33593 ef54e2108b74
child 33640 0d82107dc07a
equal deleted inserted replaced
33638:548a34929e98 33639:603320b93668
   270 fun sorted :: "'a list \<Rightarrow> bool" where
   270 fun sorted :: "'a list \<Rightarrow> bool" where
   271 "sorted [] \<longleftrightarrow> True" |
   271 "sorted [] \<longleftrightarrow> True" |
   272 "sorted [x] \<longleftrightarrow> True" |
   272 "sorted [x] \<longleftrightarrow> True" |
   273 "sorted (x#y#zs) \<longleftrightarrow> x <= y \<and> sorted (y#zs)"
   273 "sorted (x#y#zs) \<longleftrightarrow> x <= y \<and> sorted (y#zs)"
   274 
   274 
   275 primrec insort :: "'a \<Rightarrow> 'a list \<Rightarrow> 'a list" where
   275 primrec insort_key :: "('b \<Rightarrow> 'a) \<Rightarrow> 'b \<Rightarrow> 'b list \<Rightarrow> 'b list" where
   276 "insort x [] = [x]" |
   276 "insort_key f x [] = [x]" |
   277 "insort x (y#ys) = (if x <= y then (x#y#ys) else y#(insort x ys))"
   277 "insort_key f x (y#ys) = (if f x \<le> f y then (x#y#ys) else y#(insort_key f x ys))"
   278 
   278 
   279 primrec sort :: "'a list \<Rightarrow> 'a list" where
   279 primrec sort_key :: "('b \<Rightarrow> 'a) \<Rightarrow> 'b list \<Rightarrow> 'b list" where
   280 "sort [] = []" |
   280 "sort_key f [] = []" |
   281 "sort (x#xs) = insort x (sort xs)"
   281 "sort_key f (x#xs) = insort_key f x (sort_key f xs)"
       
   282 
       
   283 abbreviation "sort \<equiv> sort_key (\<lambda>x. x)"
       
   284 abbreviation "insort \<equiv> insort_key (\<lambda>x. x)"
   282 
   285 
   283 end
   286 end
   284 
   287 
   285 
   288 
   286 subsubsection {* List comprehension *}
   289 subsubsection {* List comprehension *}
   696 by (rule ext, induct_tac xs) auto
   699 by (rule ext, induct_tac xs) auto
   697 
   700 
   698 lemma map_append [simp]: "map f (xs @ ys) = map f xs @ map f ys"
   701 lemma map_append [simp]: "map f (xs @ ys) = map f xs @ map f ys"
   699 by (induct xs) auto
   702 by (induct xs) auto
   700 
   703 
   701 lemma map_compose: "map (f o g) xs = map f (map g xs)"
   704 lemma map_map [simp]: "map f (map g xs) = map (f \<circ> g) xs"
   702 by (induct xs) (auto simp add: o_def)
   705 by (induct xs) auto
       
   706 
       
   707 lemma map_compose: "map (f \<circ> g) xs = map f (map g xs)"
       
   708 by simp
   703 
   709 
   704 lemma rev_map: "rev (map f xs) = map f (rev xs)"
   710 lemma rev_map: "rev (map f xs) = map f (rev xs)"
   705 by (induct xs) auto
   711 by (induct xs) auto
   706 
   712 
   707 lemma map_eq_conv[simp]: "(map f xs = map g xs) = (!x : set xs. f x = g x)"
   713 lemma map_eq_conv[simp]: "(map f xs = map g xs) = (!x : set xs. f x = g x)"
  1181   from assms have "yes = fst (partition P xs)" and "no = snd (partition P xs)"
  1187   from assms have "yes = fst (partition P xs)" and "no = snd (partition P xs)"
  1182     by simp_all
  1188     by simp_all
  1183   then show ?thesis by (auto simp add: partition_filter1 partition_filter2) 
  1189   then show ?thesis by (auto simp add: partition_filter1 partition_filter2) 
  1184 qed
  1190 qed
  1185 
  1191 
       
  1192 lemma partition_filter_conv[simp]:
       
  1193   "partition f xs = (filter f xs,filter (Not o f) xs)"
       
  1194 unfolding partition_filter2[symmetric]
       
  1195 unfolding partition_filter1[symmetric] by simp
       
  1196 
       
  1197 declare partition.simps[simp del]
  1186 
  1198 
  1187 subsubsection {* @{text concat} *}
  1199 subsubsection {* @{text concat} *}
  1188 
  1200 
  1189 lemma concat_append [simp]: "concat (xs @ ys) = concat xs @ concat ys"
  1201 lemma concat_append [simp]: "concat (xs @ ys) = concat xs @ concat ys"
  1190 by (induct xs) auto
  1202 by (induct xs) auto
  1720 done
  1732 done
  1721 
  1733 
  1722 
  1734 
  1723 subsubsection {* @{text takeWhile} and @{text dropWhile} *}
  1735 subsubsection {* @{text takeWhile} and @{text dropWhile} *}
  1724 
  1736 
       
  1737 lemma length_takeWhile_le: "length (takeWhile P xs) \<le> length xs"
       
  1738   by (induct xs) auto
       
  1739 
  1725 lemma takeWhile_dropWhile_id [simp]: "takeWhile P xs @ dropWhile P xs = xs"
  1740 lemma takeWhile_dropWhile_id [simp]: "takeWhile P xs @ dropWhile P xs = xs"
  1726 by (induct xs) auto
  1741 by (induct xs) auto
  1727 
  1742 
  1728 lemma takeWhile_append1 [simp]:
  1743 lemma takeWhile_append1 [simp]:
  1729 "[| x:set xs; ~P(x)|] ==> takeWhile P (xs @ ys) = takeWhile P xs"
  1744 "[| x:set xs; ~P(x)|] ==> takeWhile P (xs @ ys) = takeWhile P xs"
  1732 lemma takeWhile_append2 [simp]:
  1747 lemma takeWhile_append2 [simp]:
  1733 "(!!x. x : set xs ==> P x) ==> takeWhile P (xs @ ys) = xs @ takeWhile P ys"
  1748 "(!!x. x : set xs ==> P x) ==> takeWhile P (xs @ ys) = xs @ takeWhile P ys"
  1734 by (induct xs) auto
  1749 by (induct xs) auto
  1735 
  1750 
  1736 lemma takeWhile_tail: "\<not> P x ==> takeWhile P (xs @ (x#l)) = takeWhile P xs"
  1751 lemma takeWhile_tail: "\<not> P x ==> takeWhile P (xs @ (x#l)) = takeWhile P xs"
       
  1752 by (induct xs) auto
       
  1753 
       
  1754 lemma takeWhile_nth: "j < length (takeWhile P xs) \<Longrightarrow> takeWhile P xs ! j = xs ! j"
       
  1755 apply (subst (3) takeWhile_dropWhile_id[symmetric]) unfolding nth_append by auto
       
  1756 
       
  1757 lemma dropWhile_nth: "j < length (dropWhile P xs) \<Longrightarrow> dropWhile P xs ! j = xs ! (j + length (takeWhile P xs))"
       
  1758 apply (subst (3) takeWhile_dropWhile_id[symmetric]) unfolding nth_append by auto
       
  1759 
       
  1760 lemma length_dropWhile_le: "length (dropWhile P xs) \<le> length xs"
  1737 by (induct xs) auto
  1761 by (induct xs) auto
  1738 
  1762 
  1739 lemma dropWhile_append1 [simp]:
  1763 lemma dropWhile_append1 [simp]:
  1740 "[| x : set xs; ~P(x)|] ==> dropWhile P (xs @ ys) = (dropWhile P xs)@ys"
  1764 "[| x : set xs; ~P(x)|] ==> dropWhile P (xs @ ys) = (dropWhile P xs)@ys"
  1741 by (induct xs) auto
  1765 by (induct xs) auto
  1763 by (induct xs) (auto dest: set_takeWhileD)
  1787 by (induct xs) (auto dest: set_takeWhileD)
  1764 
  1788 
  1765 lemma distinct_dropWhile[simp]: "distinct xs ==> distinct (dropWhile P xs)"
  1789 lemma distinct_dropWhile[simp]: "distinct xs ==> distinct (dropWhile P xs)"
  1766 by (induct xs) auto
  1790 by (induct xs) auto
  1767 
  1791 
       
  1792 lemma takeWhile_map: "takeWhile P (map f xs) = map f (takeWhile (P \<circ> f) xs)"
       
  1793 by (induct xs) auto
       
  1794 
       
  1795 lemma dropWhile_map: "dropWhile P (map f xs) = map f (dropWhile (P \<circ> f) xs)"
       
  1796 by (induct xs) auto
       
  1797 
       
  1798 lemma takeWhile_eq_take: "takeWhile P xs = take (length (takeWhile P xs)) xs"
       
  1799 by (induct xs) auto
       
  1800 
       
  1801 lemma dropWhile_eq_drop: "dropWhile P xs = drop (length (takeWhile P xs)) xs"
       
  1802 by (induct xs) auto
       
  1803 
       
  1804 lemma hd_dropWhile:
       
  1805   "dropWhile P xs \<noteq> [] \<Longrightarrow> \<not> P (hd (dropWhile P xs))"
       
  1806 using assms by (induct xs) auto
       
  1807 
       
  1808 lemma takeWhile_eq_filter:
       
  1809   assumes "\<And> x. x \<in> set (dropWhile P xs) \<Longrightarrow> \<not> P x"
       
  1810   shows "takeWhile P xs = filter P xs"
       
  1811 proof -
       
  1812   have A: "filter P xs = filter P (takeWhile P xs @ dropWhile P xs)"
       
  1813     by simp
       
  1814   have B: "filter P (dropWhile P xs) = []"
       
  1815     unfolding filter_empty_conv using assms by blast
       
  1816   have "filter P xs = takeWhile P xs"
       
  1817     unfolding A filter_append B
       
  1818     by (auto simp add: filter_id_conv dest: set_takeWhileD)
       
  1819   thus ?thesis ..
       
  1820 qed
       
  1821 
       
  1822 lemma takeWhile_eq_take_P_nth:
       
  1823   "\<lbrakk> \<And> i. \<lbrakk> i < n ; i < length xs \<rbrakk> \<Longrightarrow> P (xs ! i) ; n < length xs \<Longrightarrow> \<not> P (xs ! n) \<rbrakk> \<Longrightarrow>
       
  1824   takeWhile P xs = take n xs"
       
  1825 proof (induct xs arbitrary: n)
       
  1826   case (Cons x xs)
       
  1827   thus ?case
       
  1828   proof (cases n)
       
  1829     case (Suc n') note this[simp]
       
  1830     have "P x" using Cons.prems(1)[of 0] by simp
       
  1831     moreover have "takeWhile P xs = take n' xs"
       
  1832     proof (rule Cons.hyps)
       
  1833       case goal1 thus "P (xs ! i)" using Cons.prems(1)[of "Suc i"] by simp
       
  1834     next case goal2 thus ?case using Cons by auto
       
  1835     qed
       
  1836     ultimately show ?thesis by simp
       
  1837    qed simp
       
  1838 qed simp
       
  1839 
       
  1840 lemma nth_length_takeWhile:
       
  1841   "length (takeWhile P xs) < length xs \<Longrightarrow> \<not> P (xs ! length (takeWhile P xs))"
       
  1842 by (induct xs) auto
       
  1843 
       
  1844 lemma length_takeWhile_less_P_nth:
       
  1845   assumes all: "\<And> i. i < j \<Longrightarrow> P (xs ! i)" and "j \<le> length xs"
       
  1846   shows "j \<le> length (takeWhile P xs)"
       
  1847 proof (rule classical)
       
  1848   assume "\<not> ?thesis"
       
  1849   hence "length (takeWhile P xs) < length xs" using assms by simp
       
  1850   thus ?thesis using all `\<not> ?thesis` nth_length_takeWhile[of P xs] by auto
       
  1851 qed
  1768 
  1852 
  1769 text{* The following two lemmmas could be generalized to an arbitrary
  1853 text{* The following two lemmmas could be generalized to an arbitrary
  1770 property. *}
  1854 property. *}
  1771 
  1855 
  1772 lemma takeWhile_neq_rev: "\<lbrakk>distinct xs; x \<in> set xs\<rbrakk> \<Longrightarrow>
  1856 lemma takeWhile_neq_rev: "\<lbrakk>distinct xs; x \<in> set xs\<rbrakk> \<Longrightarrow>
  1836 
  1920 
  1837 lemma zip_rev:
  1921 lemma zip_rev:
  1838 "length xs = length ys ==> zip (rev xs) (rev ys) = rev (zip xs ys)"
  1922 "length xs = length ys ==> zip (rev xs) (rev ys) = rev (zip xs ys)"
  1839 by (induct rule:list_induct2, simp_all)
  1923 by (induct rule:list_induct2, simp_all)
  1840 
  1924 
       
  1925 lemma zip_map_map:
       
  1926   "zip (map f xs) (map g ys) = map (\<lambda> (x, y). (f x, g y)) (zip xs ys)"
       
  1927 proof (induct xs arbitrary: ys)
       
  1928   case (Cons x xs) note Cons_x_xs = Cons.hyps
       
  1929   show ?case
       
  1930   proof (cases ys)
       
  1931     case (Cons y ys')
       
  1932     show ?thesis unfolding Cons using Cons_x_xs by simp
       
  1933   qed simp
       
  1934 qed simp
       
  1935 
       
  1936 lemma zip_map1:
       
  1937   "zip (map f xs) ys = map (\<lambda>(x, y). (f x, y)) (zip xs ys)"
       
  1938 using zip_map_map[of f xs "\<lambda>x. x" ys] by simp
       
  1939 
       
  1940 lemma zip_map2:
       
  1941   "zip xs (map f ys) = map (\<lambda>(x, y). (x, f y)) (zip xs ys)"
       
  1942 using zip_map_map[of "\<lambda>x. x" xs f ys] by simp
       
  1943 
  1841 lemma map_zip_map:
  1944 lemma map_zip_map:
  1842  "map f (zip (map g xs) ys) = map (%(x,y). f(g x, y)) (zip xs ys)"
  1945   "map f (zip (map g xs) ys) = map (%(x,y). f(g x, y)) (zip xs ys)"
  1843 apply(induct xs arbitrary:ys) apply simp
  1946 unfolding zip_map1 by auto
  1844 apply(case_tac ys)
       
  1845 apply simp_all
       
  1846 done
       
  1847 
  1947 
  1848 lemma map_zip_map2:
  1948 lemma map_zip_map2:
  1849  "map f (zip xs (map g ys)) = map (%(x,y). f(x, g y)) (zip xs ys)"
  1949   "map f (zip xs (map g ys)) = map (%(x,y). f(x, g y)) (zip xs ys)"
  1850 apply(induct xs arbitrary:ys) apply simp
  1950 unfolding zip_map2 by auto
  1851 apply(case_tac ys)
       
  1852 apply simp_all
       
  1853 done
       
  1854 
  1951 
  1855 text{* Courtesy of Andreas Lochbihler: *}
  1952 text{* Courtesy of Andreas Lochbihler: *}
  1856 lemma zip_same_conv_map: "zip xs xs = map (\<lambda>x. (x, x)) xs"
  1953 lemma zip_same_conv_map: "zip xs xs = map (\<lambda>x. (x, x)) xs"
  1857 by(induct xs) auto
  1954 by(induct xs) auto
  1858 
  1955 
  1864 done
  1961 done
  1865 
  1962 
  1866 lemma set_zip:
  1963 lemma set_zip:
  1867 "set (zip xs ys) = {(xs!i, ys!i) | i. i < min (length xs) (length ys)}"
  1964 "set (zip xs ys) = {(xs!i, ys!i) | i. i < min (length xs) (length ys)}"
  1868 by(simp add: set_conv_nth cong: rev_conj_cong)
  1965 by(simp add: set_conv_nth cong: rev_conj_cong)
       
  1966 
       
  1967 lemma zip_same: "((a,b) \<in> set (zip xs xs)) = (a \<in> set xs \<and> a = b)"
       
  1968 by(induct xs) auto
  1869 
  1969 
  1870 lemma zip_update:
  1970 lemma zip_update:
  1871   "zip (xs[i:=x]) (ys[i:=y]) = (zip xs ys)[i:=(x,y)]"
  1971   "zip (xs[i:=x]) (ys[i:=y]) = (zip xs ys)[i:=(x,y)]"
  1872 by(rule sym, simp add: update_zip)
  1972 by(rule sym, simp add: update_zip)
  1873 
  1973 
  1891  apply simp
  1991  apply simp
  1892 apply (case_tac xs, simp)
  1992 apply (case_tac xs, simp)
  1893 apply (case_tac ys, simp_all)
  1993 apply (case_tac ys, simp_all)
  1894 done
  1994 done
  1895 
  1995 
       
  1996 lemma zip_takeWhile_fst: "zip (takeWhile P xs) ys = takeWhile (P \<circ> fst) (zip xs ys)"
       
  1997 proof (induct xs arbitrary: ys)
       
  1998   case (Cons x xs) thus ?case by (cases ys) auto
       
  1999 qed simp
       
  2000 
       
  2001 lemma zip_takeWhile_snd: "zip xs (takeWhile P ys) = takeWhile (P \<circ> snd) (zip xs ys)"
       
  2002 proof (induct xs arbitrary: ys)
       
  2003   case (Cons x xs) thus ?case by (cases ys) auto
       
  2004 qed simp
       
  2005 
  1896 lemma set_zip_leftD:
  2006 lemma set_zip_leftD:
  1897   "(x,y)\<in> set (zip xs ys) \<Longrightarrow> x \<in> set xs"
  2007   "(x,y)\<in> set (zip xs ys) \<Longrightarrow> x \<in> set xs"
  1898 by (induct xs ys rule:list_induct2') auto
  2008 by (induct xs ys rule:list_induct2') auto
  1899 
  2009 
  1900 lemma set_zip_rightD:
  2010 lemma set_zip_rightD:
  1911 
  2021 
  1912 lemma zip_eq_conv:
  2022 lemma zip_eq_conv:
  1913   "length xs = length ys \<Longrightarrow> zip xs ys = zs \<longleftrightarrow> map fst zs = xs \<and> map snd zs = ys"
  2023   "length xs = length ys \<Longrightarrow> zip xs ys = zs \<longleftrightarrow> map fst zs = xs \<and> map snd zs = ys"
  1914   by (auto simp add: zip_map_fst_snd)
  2024   by (auto simp add: zip_map_fst_snd)
  1915 
  2025 
       
  2026 lemma distinct_zipI1:
       
  2027   "distinct xs \<Longrightarrow> distinct (zip xs ys)"
       
  2028 proof (induct xs arbitrary: ys)
       
  2029   case (Cons x xs)
       
  2030   show ?case
       
  2031   proof (cases ys)
       
  2032     case (Cons y ys')
       
  2033     have "(x, y) \<notin> set (zip xs ys')"
       
  2034       using Cons.prems by (auto simp: set_zip)
       
  2035     thus ?thesis
       
  2036       unfolding Cons zip_Cons_Cons distinct.simps
       
  2037       using Cons.hyps Cons.prems by simp
       
  2038   qed simp
       
  2039 qed simp
       
  2040 
       
  2041 lemma distinct_zipI2:
       
  2042   "distinct xs \<Longrightarrow> distinct (zip xs ys)"
       
  2043 proof (induct xs arbitrary: ys)
       
  2044   case (Cons x xs)
       
  2045   show ?case
       
  2046   proof (cases ys)
       
  2047     case (Cons y ys')
       
  2048      have "(x, y) \<notin> set (zip xs ys')"
       
  2049       using Cons.prems by (auto simp: set_zip)
       
  2050     thus ?thesis
       
  2051       unfolding Cons zip_Cons_Cons distinct.simps
       
  2052       using Cons.hyps Cons.prems by simp
       
  2053   qed simp
       
  2054 qed simp
  1916 
  2055 
  1917 subsubsection {* @{text list_all2} *}
  2056 subsubsection {* @{text list_all2} *}
  1918 
  2057 
  1919 lemma list_all2_lengthD [intro?]: 
  2058 lemma list_all2_lengthD [intro?]: 
  1920   "list_all2 P xs ys ==> length xs = length ys"
  2059   "list_all2 P xs ys ==> length xs = length ys"
  2256 lemma listsum_foldr: "listsum xs = foldr (op +) xs 0"
  2395 lemma listsum_foldr: "listsum xs = foldr (op +) xs 0"
  2257 by (induct xs) auto
  2396 by (induct xs) auto
  2258 
  2397 
  2259 lemma length_concat: "length (concat xss) = listsum (map length xss)"
  2398 lemma length_concat: "length (concat xss) = listsum (map length xss)"
  2260 by (induct xss) simp_all
  2399 by (induct xss) simp_all
       
  2400 
       
  2401 lemma listsum_map_filter:
       
  2402   fixes f :: "'a \<Rightarrow> 'b \<Colon> comm_monoid_add"
       
  2403   assumes "\<And> x. \<lbrakk> x \<in> set xs ; \<not> P x \<rbrakk> \<Longrightarrow> f x = 0"
       
  2404   shows "listsum (map f (filter P xs)) = listsum (map f xs)"
       
  2405 using assms by (induct xs) auto
  2261 
  2406 
  2262 text{* For efficient code generation ---
  2407 text{* For efficient code generation ---
  2263        @{const listsum} is not tail recursive but @{const foldl} is. *}
  2408        @{const listsum} is not tail recursive but @{const foldl} is. *}
  2264 lemma listsum[code_unfold]: "listsum xs = foldl (op +) 0 xs"
  2409 lemma listsum[code_unfold]: "listsum xs = foldl (op +) 0 xs"
  2265 by(simp add:listsum_foldr foldl_foldr1)
  2410 by(simp add:listsum_foldr foldl_foldr1)
  2638 
  2783 
  2639 lemma length_remdups_concat:
  2784 lemma length_remdups_concat:
  2640  "length(remdups(concat xss)) = card(\<Union>xs \<in> set xss. set xs)"
  2785  "length(remdups(concat xss)) = card(\<Union>xs \<in> set xss. set xs)"
  2641 by(simp add: set_concat distinct_card[symmetric])
  2786 by(simp add: set_concat distinct_card[symmetric])
  2642 
  2787 
       
  2788 lemma length_remdups_card_conv: "length(remdups xs) = card(set xs)"
       
  2789 proof -
       
  2790   have xs: "concat[xs] = xs" by simp
       
  2791   from length_remdups_concat[of "[xs]"] show ?thesis unfolding xs by simp
       
  2792 qed
  2643 
  2793 
  2644 subsubsection {* @{text remove1} *}
  2794 subsubsection {* @{text remove1} *}
  2645 
  2795 
  2646 lemma remove1_append:
  2796 lemma remove1_append:
  2647   "remove1 x (xs @ ys) =
  2797   "remove1 x (xs @ ys) =
  3081 that instead of multisets to state the correctness property. *}
  3231 that instead of multisets to state the correctness property. *}
  3082 
  3232 
  3083 context linorder
  3233 context linorder
  3084 begin
  3234 begin
  3085 
  3235 
       
  3236 lemma length_insert[simp] : "length (insort_key f x xs) = Suc (length xs)"
       
  3237 by (induct xs, auto)
       
  3238 
       
  3239 lemma length_sort[simp]: "length (sort_key f xs) = length xs"
       
  3240 by (induct xs, auto)
       
  3241 
  3086 lemma sorted_Cons: "sorted (x#xs) = (sorted xs & (ALL y:set xs. x <= y))"
  3242 lemma sorted_Cons: "sorted (x#xs) = (sorted xs & (ALL y:set xs. x <= y))"
  3087 apply(induct xs arbitrary: x) apply simp
  3243 apply(induct xs arbitrary: x) apply simp
  3088 by simp (blast intro: order_trans)
  3244 by simp (blast intro: order_trans)
  3089 
  3245 
  3090 lemma sorted_append:
  3246 lemma sorted_append:
  3091   "sorted (xs@ys) = (sorted xs & sorted ys & (\<forall>x \<in> set xs. \<forall>y \<in> set ys. x\<le>y))"
  3247   "sorted (xs@ys) = (sorted xs & sorted ys & (\<forall>x \<in> set xs. \<forall>y \<in> set ys. x\<le>y))"
  3092 by (induct xs) (auto simp add:sorted_Cons)
  3248 by (induct xs) (auto simp add:sorted_Cons)
  3093 
  3249 
  3094 lemma sorted_nth_mono:
  3250 lemma sorted_nth_mono:
  3095   "sorted xs \<Longrightarrow> i <= j \<Longrightarrow> j < length xs \<Longrightarrow> xs!i <= xs!j"
  3251   "sorted xs \<Longrightarrow> i \<le> j \<Longrightarrow> j < length xs \<Longrightarrow> xs!i \<le> xs!j"
  3096 by (induct xs arbitrary: i j) (auto simp:nth_Cons' sorted_Cons)
  3252 by (induct xs arbitrary: i j) (auto simp:nth_Cons' sorted_Cons)
  3097 
  3253 
  3098 lemma set_insort: "set(insort x xs) = insert x (set xs)"
  3254 lemma sorted_rev_nth_mono:
  3099 by (induct xs) auto
  3255   "sorted (rev xs) \<Longrightarrow> i \<le> j \<Longrightarrow> j < length xs \<Longrightarrow> xs!j \<le> xs!i"
  3100 
  3256 using sorted_nth_mono[ of "rev xs" "length xs - j - 1" "length xs - i - 1"]
  3101 lemma set_sort[simp]: "set(sort xs) = set xs"
  3257       rev_nth[of "length xs - i - 1" "xs"] rev_nth[of "length xs - j - 1" "xs"]
       
  3258 by auto
       
  3259 
       
  3260 lemma sorted_nth_monoI:
       
  3261   "(\<And> i j. \<lbrakk> i \<le> j ; j < length xs \<rbrakk> \<Longrightarrow> xs ! i \<le> xs ! j) \<Longrightarrow> sorted xs"
       
  3262 proof (induct xs)
       
  3263   case (Cons x xs)
       
  3264   have "sorted xs"
       
  3265   proof (rule Cons.hyps)
       
  3266     fix i j assume "i \<le> j" and "j < length xs"
       
  3267     with Cons.prems[of "Suc i" "Suc j"]
       
  3268     show "xs ! i \<le> xs ! j" by auto
       
  3269   qed
       
  3270   moreover
       
  3271   {
       
  3272     fix y assume "y \<in> set xs"
       
  3273     then obtain j where "j < length xs" and "xs ! j = y"
       
  3274       unfolding in_set_conv_nth by blast
       
  3275     with Cons.prems[of 0 "Suc j"]
       
  3276     have "x \<le> y"
       
  3277       by auto
       
  3278   }
       
  3279   ultimately
       
  3280   show ?case
       
  3281     unfolding sorted_Cons by auto
       
  3282 qed simp
       
  3283 
       
  3284 lemma sorted_equals_nth_mono:
       
  3285   "sorted xs = (\<forall>j < length xs. \<forall>i \<le> j. xs ! i \<le> xs ! j)"
       
  3286 by (auto intro: sorted_nth_monoI sorted_nth_mono)
       
  3287 
       
  3288 lemma set_insort: "set(insort_key f x xs) = insert x (set xs)"
       
  3289 by (induct xs) auto
       
  3290 
       
  3291 lemma set_sort[simp]: "set(sort_key f xs) = set xs"
  3102 by (induct xs) (simp_all add:set_insort)
  3292 by (induct xs) (simp_all add:set_insort)
  3103 
  3293 
  3104 lemma distinct_insort: "distinct (insort x xs) = (x \<notin> set xs \<and> distinct xs)"
  3294 lemma distinct_insort: "distinct (insort_key f x xs) = (x \<notin> set xs \<and> distinct xs)"
  3105 by(induct xs)(auto simp:set_insort)
  3295 by(induct xs)(auto simp:set_insort)
  3106 
  3296 
  3107 lemma distinct_sort[simp]: "distinct (sort xs) = distinct xs"
  3297 lemma distinct_sort[simp]: "distinct (sort_key f xs) = distinct xs"
  3108 by(induct xs)(simp_all add:distinct_insort set_sort)
  3298 by(induct xs)(simp_all add:distinct_insort set_sort)
  3109 
  3299 
       
  3300 lemma sorted_insort_key: "sorted (map f (insort_key f x xs)) = sorted (map f xs)"
       
  3301 by(induct xs)(auto simp:sorted_Cons set_insort)
       
  3302 
  3110 lemma sorted_insort: "sorted (insort x xs) = sorted xs"
  3303 lemma sorted_insort: "sorted (insort x xs) = sorted xs"
  3111 apply (induct xs)
  3304 using sorted_insort_key[where f="\<lambda>x. x"] by simp
  3112  apply(auto simp:sorted_Cons set_insort)
  3305 
  3113 done
  3306 theorem sorted_sort_key[simp]: "sorted (map f (sort_key f xs))"
       
  3307 by(induct xs)(auto simp:sorted_insort_key)
  3114 
  3308 
  3115 theorem sorted_sort[simp]: "sorted (sort xs)"
  3309 theorem sorted_sort[simp]: "sorted (sort xs)"
  3116 by (induct xs) (auto simp:sorted_insort)
  3310 by(induct xs)(auto simp:sorted_insort)
  3117 
  3311 
  3118 lemma insort_is_Cons: "\<forall>x\<in>set xs. a \<le> x \<Longrightarrow> insort a xs = a # xs"
  3312 lemma insort_is_Cons: "\<forall>x\<in>set xs. f a \<le> f x \<Longrightarrow> insort_key f a xs = a # xs"
  3119 by (cases xs) auto
  3313 by (cases xs) auto
  3120 
  3314 
  3121 lemma sorted_remove1: "sorted xs \<Longrightarrow> sorted (remove1 a xs)"
  3315 lemma sorted_remove1: "sorted xs \<Longrightarrow> sorted (remove1 a xs)"
  3122 by (induct xs, auto simp add: sorted_Cons)
  3316 by(induct xs)(auto simp add: sorted_Cons)
       
  3317 
       
  3318 lemma insort_key_remove1: "\<lbrakk> a \<in> set xs; sorted (map f xs) ; inj_on f (set xs) \<rbrakk>
       
  3319   \<Longrightarrow> insort_key f a (remove1 a xs) = xs"
       
  3320 proof (induct xs)
       
  3321   case (Cons x xs)
       
  3322   thus ?case
       
  3323   proof (cases "x = a")
       
  3324     case False
       
  3325     hence "f x \<noteq> f a" using Cons.prems by auto
       
  3326     hence "f x < f a" using Cons.prems by (auto simp: sorted_Cons)
       
  3327     thus ?thesis using Cons by (auto simp: sorted_Cons insort_is_Cons)
       
  3328   qed (auto simp: sorted_Cons insort_is_Cons)
       
  3329 qed simp
  3123 
  3330 
  3124 lemma insort_remove1: "\<lbrakk> a \<in> set xs; sorted xs \<rbrakk> \<Longrightarrow> insort a (remove1 a xs) = xs"
  3331 lemma insort_remove1: "\<lbrakk> a \<in> set xs; sorted xs \<rbrakk> \<Longrightarrow> insort a (remove1 a xs) = xs"
  3125 by (induct xs, auto simp add: sorted_Cons insort_is_Cons)
  3332 using insort_key_remove1[where f="\<lambda>x. x"] by simp
  3126 
  3333 
  3127 lemma sorted_remdups[simp]:
  3334 lemma sorted_remdups[simp]:
  3128   "sorted l \<Longrightarrow> sorted (remdups l)"
  3335   "sorted l \<Longrightarrow> sorted (remdups l)"
  3129 by (induct l) (auto simp: sorted_Cons)
  3336 by (induct l) (auto simp: sorted_Cons)
  3130 
  3337 
  3176   case 2 show ?case by (cases n) simp_all
  3383   case 2 show ?case by (cases n) simp_all
  3177 next
  3384 next
  3178   case 3 then show ?case by (cases n) simp_all
  3385   case 3 then show ?case by (cases n) simp_all
  3179 qed
  3386 qed
  3180 
  3387 
       
  3388 lemma sorted_dropWhile: "sorted xs \<Longrightarrow> sorted (dropWhile P xs)"
       
  3389   unfolding dropWhile_eq_drop by (rule sorted_drop)
       
  3390 
       
  3391 lemma sorted_takeWhile: "sorted xs \<Longrightarrow> sorted (takeWhile P xs)"
       
  3392   apply (subst takeWhile_eq_take) by (rule sorted_take)
  3181 
  3393 
  3182 end
  3394 end
  3183 
  3395 
  3184 lemma sorted_upt[simp]: "sorted[i..<j]"
  3396 lemma sorted_upt[simp]: "sorted[i..<j]"
  3185 by (induct j) (simp_all add:sorted_append)
  3397 by (induct j) (simp_all add:sorted_append)
  3770 where
  3982 where
  3771   "length_unique [] = 0"
  3983   "length_unique [] = 0"
  3772   | "length_unique (x#xs) =
  3984   | "length_unique (x#xs) =
  3773       (if x \<in> set xs then length_unique xs else Suc (length_unique xs))"
  3985       (if x \<in> set xs then length_unique xs else Suc (length_unique xs))"
  3774 
  3986 
       
  3987 primrec
       
  3988   concat_map :: "('a => 'b list) => 'a list => 'b list"
       
  3989 where
       
  3990   "concat_map f [] = []"
       
  3991   | "concat_map f (x#xs) = f x @ concat_map f xs"
       
  3992 
  3775 text {*
  3993 text {*
  3776   Only use @{text mem} for generating executable code.  Otherwise use
  3994   Only use @{text mem} for generating executable code.  Otherwise use
  3777   @{prop "x : set xs"} instead --- it is much easier to reason about.
  3995   @{prop "x : set xs"} instead --- it is much easier to reason about.
  3778   The same is true for @{const list_all} and @{const list_ex}: write
  3996   The same is true for @{const list_all} and @{const list_ex}: write
  3779   @{text "\<forall>x\<in>set xs"} and @{text "\<exists>x\<in>set xs"} instead because the HOL
  3997   @{text "\<forall>x\<in>set xs"} and @{text "\<exists>x\<in>set xs"} instead because the HOL
  3863   "map_filter f P xs = map f (filter P xs)"
  4081   "map_filter f P xs = map f (filter P xs)"
  3864 by (induct xs) auto
  4082 by (induct xs) auto
  3865 
  4083 
  3866 lemma length_remdups_length_unique [code_unfold]:
  4084 lemma length_remdups_length_unique [code_unfold]:
  3867   "length (remdups xs) = length_unique xs"
  4085   "length (remdups xs) = length_unique xs"
  3868   by (induct xs) simp_all
  4086 by (induct xs) simp_all
       
  4087 
       
  4088 lemma concat_map_code[code_unfold]:
       
  4089   "concat(map f xs) = concat_map f xs"
       
  4090 by (induct xs) simp_all
  3869 
  4091 
  3870 declare INFI_def [code_unfold]
  4092 declare INFI_def [code_unfold]
  3871 declare SUPR_def [code_unfold]
  4093 declare SUPR_def [code_unfold]
  3872 
  4094 
  3873 declare set_map [symmetric, code_unfold]
  4095 declare set_map [symmetric, code_unfold]
  3921 
  4143 
  3922 lemma setsum_set_upt_conv_listsum [code_unfold]:
  4144 lemma setsum_set_upt_conv_listsum [code_unfold]:
  3923   "setsum f (set [m..<n]) = listsum (map f [m..<n])"
  4145   "setsum f (set [m..<n]) = listsum (map f [m..<n])"
  3924 by (rule setsum_set_distinct_conv_listsum) simp
  4146 by (rule setsum_set_distinct_conv_listsum) simp
  3925 
  4147 
       
  4148 text {* General equivalence between @{const listsum} and @{const setsum} *}
       
  4149 lemma listsum_setsum_nth:
       
  4150   "listsum xs = (\<Sum> i = 0 ..< length xs. xs ! i)"
       
  4151 using setsum_set_upt_conv_listsum[of "op ! xs" 0 "length xs"]
       
  4152 by (simp add: map_nth)
  3926 
  4153 
  3927 text {* Code for summation over ints. *}
  4154 text {* Code for summation over ints. *}
  3928 
  4155 
  3929 lemma greaterThanLessThan_upto [code_unfold]:
  4156 lemma greaterThanLessThan_upto [code_unfold]:
  3930   "{i<..<j::int} = set [i+1..j - 1]"
  4157   "{i<..<j::int} = set [i+1..j - 1]"