equal
deleted
inserted
replaced
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 |