src/HOL/List.thy
changeset 40122 1d8ad2ff3e01
parent 40077 c8a9eaaa2f59
child 40195 430fff4a9167
equal deleted inserted replaced
40121:e7a80c6752c9 40122:1d8ad2ff3e01
     3 *)
     3 *)
     4 
     4 
     5 header {* The datatype of finite lists *}
     5 header {* The datatype of finite lists *}
     6 
     6 
     7 theory List
     7 theory List
     8 imports Plain Quotient Presburger Code_Numeral Recdef
     8 imports Plain Presburger Recdef Code_Numeral Quotient
     9 uses ("Tools/list_code.ML")
     9 uses ("Tools/list_code.ML")
    10 begin
    10 begin
    11 
    11 
    12 datatype 'a list =
    12 datatype 'a list =
    13     Nil    ("[]")
    13     Nil    ("[]")
   172 primrec
   172 primrec
   173   removeAll :: "'a \<Rightarrow> 'a list \<Rightarrow> 'a list" where
   173   removeAll :: "'a \<Rightarrow> 'a list \<Rightarrow> 'a list" where
   174     "removeAll x [] = []"
   174     "removeAll x [] = []"
   175   | "removeAll x (y # xs) = (if x = y then removeAll x xs else y # removeAll x xs)"
   175   | "removeAll x (y # xs) = (if x = y then removeAll x xs else y # removeAll x xs)"
   176 
   176 
   177 inductive
   177 primrec
   178   distinct :: "'a list \<Rightarrow> bool" where
   178   distinct :: "'a list \<Rightarrow> bool" where
   179     Nil: "distinct []"
   179     "distinct [] \<longleftrightarrow> True"
   180   | insert: "x \<notin> set xs \<Longrightarrow> distinct xs \<Longrightarrow> distinct (x # xs)"
   180   | "distinct (x # xs) \<longleftrightarrow> x \<notin> set xs \<and> distinct xs"
   181 
       
   182 lemma distinct_simps [simp, code]:
       
   183   "distinct [] \<longleftrightarrow> True"
       
   184   "distinct (x # xs) \<longleftrightarrow> x \<notin> set xs \<and> distinct xs"
       
   185   by (auto intro: distinct.intros elim: distinct.cases)
       
   186 
   181 
   187 primrec
   182 primrec
   188   remdups :: "'a list \<Rightarrow> 'a list" where
   183   remdups :: "'a list \<Rightarrow> 'a list" where
   189     "remdups [] = []"
   184     "remdups [] = []"
   190   | "remdups (x # xs) = (if x \<in> set xs then remdups xs else x # remdups xs)"
   185   | "remdups (x # xs) = (if x \<in> set xs then remdups xs else x # remdups xs)"
   784 
   779 
   785 lemma map_eq_conv[simp]: "(map f xs = map g xs) = (!x : set xs. f x = g x)"
   780 lemma map_eq_conv[simp]: "(map f xs = map g xs) = (!x : set xs. f x = g x)"
   786 by (induct xs) auto
   781 by (induct xs) auto
   787 
   782 
   788 lemma map_cong [fundef_cong, recdef_cong]:
   783 lemma map_cong [fundef_cong, recdef_cong]:
   789 "xs = ys ==> (!!x. x : set ys ==> f x = g x) ==> map f xs = map g ys"
   784   "xs = ys \<Longrightarrow> (\<And>x. x \<in> set ys \<Longrightarrow> f x = g x) \<Longrightarrow> map f xs = map g ys"
   790 -- {* a congruence rule for @{text map} *}
   785   by simp
   791 by simp
       
   792 
   786 
   793 lemma map_is_Nil_conv [iff]: "(map f xs = []) = (xs = [])"
   787 lemma map_is_Nil_conv [iff]: "(map f xs = []) = (xs = [])"
   794 by (cases xs) auto
   788 by (cases xs) auto
   795 
   789 
   796 lemma Nil_is_map_conv [iff]: "([] = map f xs) = (xs = [])"
   790 lemma Nil_is_map_conv [iff]: "([] = map f xs) = (xs = [])"
   988 
   982 
   989 lemma in_set_conv_decomp_first:
   983 lemma in_set_conv_decomp_first:
   990   "(x : set xs) = (\<exists>ys zs. xs = ys @ x # zs \<and> x \<notin> set ys)"
   984   "(x : set xs) = (\<exists>ys zs. xs = ys @ x # zs \<and> x \<notin> set ys)"
   991   by (auto dest!: split_list_first)
   985   by (auto dest!: split_list_first)
   992 
   986 
   993 lemma split_list_last: "x : set xs \<Longrightarrow> \<exists>ys zs. xs = ys @ x # zs \<and> x \<notin> set zs"
   987 lemma split_list_last: "x \<in> set xs \<Longrightarrow> \<exists>ys zs. xs = ys @ x # zs \<and> x \<notin> set zs"
   994 proof (induct xs rule:rev_induct)
   988 proof (induct xs rule: rev_induct)
   995   case Nil thus ?case by simp
   989   case Nil thus ?case by simp
   996 next
   990 next
   997   case (snoc a xs)
   991   case (snoc a xs)
   998   show ?case
   992   show ?case
   999   proof cases
   993   proof cases
  1000     assume "x = a" thus ?case using snoc by simp (metis ex_in_conv set_empty2)
   994     assume "x = a" thus ?case using snoc by (metis List.set.simps(1) emptyE)
  1001   next
   995   next
  1002     assume "x \<noteq> a" thus ?case using snoc by fastsimp
   996     assume "x \<noteq> a" thus ?case using snoc by fastsimp
  1003   qed
   997   qed
  1004 qed
   998 qed
  1005 
   999 
  1028 next
  1022 next
  1029   case (Cons x xs)
  1023   case (Cons x xs)
  1030   show ?case
  1024   show ?case
  1031   proof cases
  1025   proof cases
  1032     assume "P x"
  1026     assume "P x"
  1033     thus ?thesis by simp
  1027     thus ?thesis by simp (metis Un_upper1 contra_subsetD in_set_conv_decomp_first self_append_conv2 set_append)
  1034       (metis Un_upper1 contra_subsetD in_set_conv_decomp_first self_append_conv2 set_append)
       
  1035   next
  1028   next
  1036     assume "\<not> P x"
  1029     assume "\<not> P x"
  1037     hence "\<exists>x\<in>set xs. P x" using Cons(2) by simp
  1030     hence "\<exists>x\<in>set xs. P x" using Cons(2) by simp
  1038     thus ?thesis using `\<not> P x` Cons(1) by (metis append_Cons set_ConsD)
  1031     thus ?thesis using `\<not> P x` Cons(1) by (metis append_Cons set_ConsD)
  1039   qed
  1032   qed