| author | paulson | 
| Wed, 23 Jul 1997 11:52:22 +0200 | |
| changeset 3564 | f886dbd91ee5 | 
| parent 3468 | 1f972dc8eafb | 
| child 3571 | f1c8fa0f0bf9 | 
| permissions | -rw-r--r-- | 
| 1465 | 1 | (* Title: HOL/List | 
| 923 | 2 | ID: $Id$ | 
| 1465 | 3 | Author: Tobias Nipkow | 
| 923 | 4 | Copyright 1994 TU Muenchen | 
| 5 | ||
| 6 | List lemmas | |
| 7 | *) | |
| 8 | ||
| 3011 | 9 | goal thy "!x. xs ~= x#xs"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 10 | by (induct_tac "xs" 1); | 
| 1264 
3eb91524b938
added local simpsets; removed IOA from 'make test'
 clasohm parents: 
1202diff
changeset | 11 | by (ALLGOALS Asm_simp_tac); | 
| 2608 | 12 | qed_spec_mp "not_Cons_self"; | 
| 2512 | 13 | Addsimps [not_Cons_self]; | 
| 923 | 14 | |
| 3011 | 15 | goal thy "(xs ~= []) = (? y ys. xs = y#ys)"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 16 | by (induct_tac "xs" 1); | 
| 1264 
3eb91524b938
added local simpsets; removed IOA from 'make test'
 clasohm parents: 
1202diff
changeset | 17 | by (Simp_tac 1); | 
| 
3eb91524b938
added local simpsets; removed IOA from 'make test'
 clasohm parents: 
1202diff
changeset | 18 | by (Asm_simp_tac 1); | 
| 923 | 19 | qed "neq_Nil_conv"; | 
| 20 | ||
| 21 | ||
| 3468 | 22 | (** "lists": the list-forming operator over sets **) | 
| 3342 
ec3b55fcb165
New operator "lists" for formalizing sets of lists
 paulson parents: 
3292diff
changeset | 23 | |
| 
ec3b55fcb165
New operator "lists" for formalizing sets of lists
 paulson parents: 
3292diff
changeset | 24 | goalw thy lists.defs "!!A B. A<=B ==> lists A <= lists B"; | 
| 
ec3b55fcb165
New operator "lists" for formalizing sets of lists
 paulson parents: 
3292diff
changeset | 25 | by (rtac lfp_mono 1); | 
| 
ec3b55fcb165
New operator "lists" for formalizing sets of lists
 paulson parents: 
3292diff
changeset | 26 | by (REPEAT (ares_tac basic_monos 1)); | 
| 
ec3b55fcb165
New operator "lists" for formalizing sets of lists
 paulson parents: 
3292diff
changeset | 27 | qed "lists_mono"; | 
| 3196 | 28 | |
| 3468 | 29 | val listsE = lists.mk_cases list.simps "x#l : lists A"; | 
| 30 | AddSEs [listsE]; | |
| 31 | AddSIs lists.intrs; | |
| 32 | ||
| 33 | goal thy "!!l. l: lists A ==> l: lists B --> l: lists (A Int B)"; | |
| 34 | by (etac lists.induct 1); | |
| 35 | by (ALLGOALS Blast_tac); | |
| 36 | qed_spec_mp "lists_IntI"; | |
| 37 | ||
| 38 | goal thy "lists (A Int B) = lists A Int lists B"; | |
| 39 | br (mono_Int RS equalityI) 1; | |
| 40 | by (simp_tac (!simpset addsimps [mono_def, lists_mono]) 1); | |
| 41 | by (blast_tac (!claset addSIs [lists_IntI]) 1); | |
| 42 | qed "lists_Int_eq"; | |
| 43 | Addsimps [lists_Int_eq]; | |
| 44 | ||
| 3196 | 45 | |
| 2608 | 46 | (** list_case **) | 
| 47 | ||
| 3011 | 48 | goal thy | 
| 2608 | 49 | "P(list_case a f xs) = ((xs=[] --> P(a)) & \ | 
| 2891 | 50 | \ (!y ys. xs=y#ys --> P(f y ys)))"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 51 | by (induct_tac "xs" 1); | 
| 2608 | 52 | by (ALLGOALS Asm_simp_tac); | 
| 2891 | 53 | by (Blast_tac 1); | 
| 2608 | 54 | qed "expand_list_case"; | 
| 55 | ||
| 3011 | 56 | val prems = goal thy "[| P([]); !!x xs. P(x#xs) |] ==> P(xs)"; | 
| 3457 | 57 | by (induct_tac "xs" 1); | 
| 58 | by (REPEAT(resolve_tac prems 1)); | |
| 2608 | 59 | qed "list_cases"; | 
| 60 | ||
| 3011 | 61 | goal thy "(xs=[] --> P([])) & (!y ys. xs=y#ys --> P(y#ys)) --> P(xs)"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 62 | by (induct_tac "xs" 1); | 
| 2891 | 63 | by (Blast_tac 1); | 
| 64 | by (Blast_tac 1); | |
| 2608 | 65 | bind_thm("list_eq_cases",
 | 
| 66 | impI RSN (2,allI RSN (2,allI RSN (2,impI RS (conjI RS (result() RS mp)))))); | |
| 67 | ||
| 68 | ||
| 923 | 69 | (** @ - append **) | 
| 70 | ||
| 3467 | 71 | section "@ - append"; | 
| 72 | ||
| 3011 | 73 | goal thy "(xs@ys)@zs = xs@(ys@zs)"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 74 | by (induct_tac "xs" 1); | 
| 1264 
3eb91524b938
added local simpsets; removed IOA from 'make test'
 clasohm parents: 
1202diff
changeset | 75 | by (ALLGOALS Asm_simp_tac); | 
| 923 | 76 | qed "append_assoc"; | 
| 2512 | 77 | Addsimps [append_assoc]; | 
| 923 | 78 | |
| 3011 | 79 | goal thy "xs @ [] = xs"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 80 | by (induct_tac "xs" 1); | 
| 1264 
3eb91524b938
added local simpsets; removed IOA from 'make test'
 clasohm parents: 
1202diff
changeset | 81 | by (ALLGOALS Asm_simp_tac); | 
| 923 | 82 | qed "append_Nil2"; | 
| 2512 | 83 | Addsimps [append_Nil2]; | 
| 923 | 84 | |
| 3011 | 85 | goal thy "(xs@ys = []) = (xs=[] & ys=[])"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 86 | by (induct_tac "xs" 1); | 
| 1264 
3eb91524b938
added local simpsets; removed IOA from 'make test'
 clasohm parents: 
1202diff
changeset | 87 | by (ALLGOALS Asm_simp_tac); | 
| 2608 | 88 | qed "append_is_Nil_conv"; | 
| 89 | AddIffs [append_is_Nil_conv]; | |
| 90 | ||
| 3011 | 91 | goal thy "([] = xs@ys) = (xs=[] & ys=[])"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 92 | by (induct_tac "xs" 1); | 
| 2608 | 93 | by (ALLGOALS Asm_simp_tac); | 
| 3457 | 94 | by (Blast_tac 1); | 
| 2608 | 95 | qed "Nil_is_append_conv"; | 
| 96 | AddIffs [Nil_is_append_conv]; | |
| 923 | 97 | |
| 3011 | 98 | goal thy "(xs @ ys = xs @ zs) = (ys=zs)"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 99 | by (induct_tac "xs" 1); | 
| 1264 
3eb91524b938
added local simpsets; removed IOA from 'make test'
 clasohm parents: 
1202diff
changeset | 100 | by (ALLGOALS Asm_simp_tac); | 
| 923 | 101 | qed "same_append_eq"; | 
| 2608 | 102 | AddIffs [same_append_eq]; | 
| 103 | ||
| 3011 | 104 | goal thy "!ys. (xs @ [x] = ys @ [y]) = (xs = ys & x = y)"; | 
| 3457 | 105 | by (induct_tac "xs" 1); | 
| 106 | by (rtac allI 1); | |
| 107 | by (induct_tac "ys" 1); | |
| 108 | by (ALLGOALS Asm_simp_tac); | |
| 109 | by (rtac allI 1); | |
| 110 | by (induct_tac "ys" 1); | |
| 111 | by (ALLGOALS Asm_simp_tac); | |
| 2608 | 112 | qed_spec_mp "append1_eq_conv"; | 
| 113 | AddIffs [append1_eq_conv]; | |
| 114 | ||
| 3011 | 115 | goal thy "xs ~= [] --> hd xs # tl xs = xs"; | 
| 3457 | 116 | by (induct_tac "xs" 1); | 
| 117 | by (ALLGOALS Asm_simp_tac); | |
| 2608 | 118 | qed_spec_mp "hd_Cons_tl"; | 
| 119 | Addsimps [hd_Cons_tl]; | |
| 923 | 120 | |
| 3011 | 121 | goal thy "hd(xs@ys) = (if xs=[] then hd ys else hd xs)"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 122 | by (induct_tac "xs" 1); | 
| 1327 
6c29cfab679c
added new arithmetic lemmas and the functions take and drop.
 nipkow parents: 
1301diff
changeset | 123 | by (ALLGOALS Asm_simp_tac); | 
| 
6c29cfab679c
added new arithmetic lemmas and the functions take and drop.
 nipkow parents: 
1301diff
changeset | 124 | qed "hd_append"; | 
| 923 | 125 | |
| 3011 | 126 | goal thy "tl(xs@ys) = (case xs of [] => tl(ys) | z#zs => zs@ys)"; | 
| 3457 | 127 | by (simp_tac (!simpset setloop(split_tac[expand_list_case])) 1); | 
| 2608 | 128 | qed "tl_append"; | 
| 129 | ||
| 130 | (** map **) | |
| 131 | ||
| 3467 | 132 | section "map"; | 
| 133 | ||
| 3011 | 134 | goal thy | 
| 3465 | 135 | "(!x. x : set xs --> f x = g x) --> map f xs = map g xs"; | 
| 3457 | 136 | by (induct_tac "xs" 1); | 
| 137 | by (ALLGOALS Asm_simp_tac); | |
| 2608 | 138 | bind_thm("map_ext", impI RS (allI RS (result() RS mp)));
 | 
| 139 | ||
| 3011 | 140 | goal thy "map (%x.x) = (%xs.xs)"; | 
| 2608 | 141 | by (rtac ext 1); | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 142 | by (induct_tac "xs" 1); | 
| 2608 | 143 | by (ALLGOALS Asm_simp_tac); | 
| 144 | qed "map_ident"; | |
| 145 | Addsimps[map_ident]; | |
| 146 | ||
| 3011 | 147 | goal thy "map f (xs@ys) = map f xs @ map f ys"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 148 | by (induct_tac "xs" 1); | 
| 2608 | 149 | by (ALLGOALS Asm_simp_tac); | 
| 150 | qed "map_append"; | |
| 151 | Addsimps[map_append]; | |
| 152 | ||
| 3011 | 153 | goalw thy [o_def] "map (f o g) xs = map f (map g xs)"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 154 | by (induct_tac "xs" 1); | 
| 2608 | 155 | by (ALLGOALS Asm_simp_tac); | 
| 156 | qed "map_compose"; | |
| 157 | Addsimps[map_compose]; | |
| 158 | ||
| 3011 | 159 | goal thy "rev(map f xs) = map f (rev xs)"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 160 | by (induct_tac "xs" 1); | 
| 2608 | 161 | by (ALLGOALS Asm_simp_tac); | 
| 162 | qed "rev_map"; | |
| 163 | ||
| 1169 | 164 | (** rev **) | 
| 165 | ||
| 3467 | 166 | section "rev"; | 
| 167 | ||
| 3011 | 168 | goal thy "rev(xs@ys) = rev(ys) @ rev(xs)"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 169 | by (induct_tac "xs" 1); | 
| 2512 | 170 | by (ALLGOALS Asm_simp_tac); | 
| 1169 | 171 | qed "rev_append"; | 
| 2512 | 172 | Addsimps[rev_append]; | 
| 1169 | 173 | |
| 3011 | 174 | goal thy "rev(rev l) = l"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 175 | by (induct_tac "l" 1); | 
| 2512 | 176 | by (ALLGOALS Asm_simp_tac); | 
| 1169 | 177 | qed "rev_rev_ident"; | 
| 2512 | 178 | Addsimps[rev_rev_ident]; | 
| 1169 | 179 | |
| 2608 | 180 | |
| 923 | 181 | (** mem **) | 
| 182 | ||
| 3467 | 183 | section "mem"; | 
| 184 | ||
| 3011 | 185 | goal thy "x mem (xs@ys) = (x mem xs | x mem ys)"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 186 | by (induct_tac "xs" 1); | 
| 1264 
3eb91524b938
added local simpsets; removed IOA from 'make test'
 clasohm parents: 
1202diff
changeset | 187 | by (ALLGOALS (asm_simp_tac (!simpset setloop (split_tac [expand_if])))); | 
| 923 | 188 | qed "mem_append"; | 
| 2512 | 189 | Addsimps[mem_append]; | 
| 923 | 190 | |
| 3011 | 191 | goal thy "x mem [x:xs.P(x)] = (x mem xs & P(x))"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 192 | by (induct_tac "xs" 1); | 
| 1264 
3eb91524b938
added local simpsets; removed IOA from 'make test'
 clasohm parents: 
1202diff
changeset | 193 | by (ALLGOALS (asm_simp_tac (!simpset setloop (split_tac [expand_if])))); | 
| 923 | 194 | qed "mem_filter"; | 
| 2512 | 195 | Addsimps[mem_filter]; | 
| 923 | 196 | |
| 3465 | 197 | (** set **) | 
| 1812 | 198 | |
| 3467 | 199 | section "set"; | 
| 200 | ||
| 3465 | 201 | goal thy "set (xs@ys) = (set xs Un set ys)"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 202 | by (induct_tac "xs" 1); | 
| 1812 | 203 | by (ALLGOALS Asm_simp_tac); | 
| 1908 | 204 | qed "set_of_list_append"; | 
| 2512 | 205 | Addsimps[set_of_list_append]; | 
| 1812 | 206 | |
| 3465 | 207 | goal thy "(x mem xs) = (x: set xs)"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 208 | by (induct_tac "xs" 1); | 
| 1812 | 209 | by (ALLGOALS (asm_simp_tac (!simpset setloop (split_tac [expand_if])))); | 
| 2891 | 210 | by (Blast_tac 1); | 
| 1908 | 211 | qed "set_of_list_mem_eq"; | 
| 1812 | 212 | |
| 3465 | 213 | goal thy "set l <= set (x#l)"; | 
| 1936 | 214 | by (Simp_tac 1); | 
| 2891 | 215 | by (Blast_tac 1); | 
| 1936 | 216 | qed "set_of_list_subset_Cons"; | 
| 217 | ||
| 3465 | 218 | goal thy "(set xs = {}) = (xs = [])";
 | 
| 3457 | 219 | by (induct_tac "xs" 1); | 
| 220 | by (ALLGOALS Asm_simp_tac); | |
| 2608 | 221 | qed "set_of_list_empty"; | 
| 222 | Addsimps [set_of_list_empty]; | |
| 223 | ||
| 3465 | 224 | goal thy "set(rev xs) = set(xs)"; | 
| 3457 | 225 | by (induct_tac "xs" 1); | 
| 226 | by (ALLGOALS Asm_simp_tac); | |
| 2608 | 227 | qed "set_of_list_rev"; | 
| 228 | Addsimps [set_of_list_rev]; | |
| 229 | ||
| 3465 | 230 | goal thy "set(map f xs) = f``(set xs)"; | 
| 3457 | 231 | by (induct_tac "xs" 1); | 
| 232 | by (ALLGOALS Asm_simp_tac); | |
| 2608 | 233 | qed "set_of_list_map"; | 
| 234 | Addsimps [set_of_list_map]; | |
| 235 | ||
| 1812 | 236 | |
| 923 | 237 | (** list_all **) | 
| 238 | ||
| 3467 | 239 | section "list_all"; | 
| 240 | ||
| 3011 | 241 | goal thy "list_all (%x.True) xs = True"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 242 | by (induct_tac "xs" 1); | 
| 1264 
3eb91524b938
added local simpsets; removed IOA from 'make test'
 clasohm parents: 
1202diff
changeset | 243 | by (ALLGOALS Asm_simp_tac); | 
| 923 | 244 | qed "list_all_True"; | 
| 2512 | 245 | Addsimps [list_all_True]; | 
| 923 | 246 | |
| 3011 | 247 | goal thy "list_all p (xs@ys) = (list_all p xs & list_all p ys)"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 248 | by (induct_tac "xs" 1); | 
| 1264 
3eb91524b938
added local simpsets; removed IOA from 'make test'
 clasohm parents: 
1202diff
changeset | 249 | by (ALLGOALS Asm_simp_tac); | 
| 2512 | 250 | qed "list_all_append"; | 
| 251 | Addsimps [list_all_append]; | |
| 923 | 252 | |
| 3011 | 253 | goal thy "list_all P xs = (!x. x mem xs --> P(x))"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 254 | by (induct_tac "xs" 1); | 
| 1264 
3eb91524b938
added local simpsets; removed IOA from 'make test'
 clasohm parents: 
1202diff
changeset | 255 | by (ALLGOALS (asm_simp_tac (!simpset setloop (split_tac [expand_if])))); | 
| 2891 | 256 | by (Blast_tac 1); | 
| 923 | 257 | qed "list_all_mem_conv"; | 
| 258 | ||
| 259 | ||
| 2608 | 260 | (** filter **) | 
| 923 | 261 | |
| 3467 | 262 | section "filter"; | 
| 263 | ||
| 3383 
7707cb7a5054
Corrected statement of filter_append;  added filter_size
 paulson parents: 
3342diff
changeset | 264 | goal thy "filter P (xs@ys) = filter P xs @ filter P ys"; | 
| 3457 | 265 | by (induct_tac "xs" 1); | 
| 266 | by (ALLGOALS (asm_simp_tac (!simpset setloop (split_tac [expand_if])))); | |
| 2608 | 267 | qed "filter_append"; | 
| 268 | Addsimps [filter_append]; | |
| 269 | ||
| 3383 
7707cb7a5054
Corrected statement of filter_append;  added filter_size
 paulson parents: 
3342diff
changeset | 270 | goal thy "size (filter P xs) <= size xs"; | 
| 3457 | 271 | by (induct_tac "xs" 1); | 
| 272 | by (ALLGOALS (asm_simp_tac (!simpset setloop (split_tac [expand_if])))); | |
| 3383 
7707cb7a5054
Corrected statement of filter_append;  added filter_size
 paulson parents: 
3342diff
changeset | 273 | qed "filter_size"; | 
| 
7707cb7a5054
Corrected statement of filter_append;  added filter_size
 paulson parents: 
3342diff
changeset | 274 | |
| 2608 | 275 | |
| 276 | (** concat **) | |
| 277 | ||
| 3467 | 278 | section "concat"; | 
| 279 | ||
| 3011 | 280 | goal thy "concat(xs@ys) = concat(xs)@concat(ys)"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 281 | by (induct_tac "xs" 1); | 
| 1264 
3eb91524b938
added local simpsets; removed IOA from 'make test'
 clasohm parents: 
1202diff
changeset | 282 | by (ALLGOALS Asm_simp_tac); | 
| 2608 | 283 | qed"concat_append"; | 
| 284 | Addsimps [concat_append]; | |
| 2512 | 285 | |
| 3467 | 286 | goal thy "set(concat xs) = Union(set `` set xs)"; | 
| 287 | by (induct_tac "xs" 1); | |
| 288 | by (ALLGOALS Asm_simp_tac); | |
| 289 | qed"set_of_list_concat"; | |
| 290 | Addsimps [set_of_list_concat]; | |
| 291 | ||
| 292 | goal thy "map f (concat xs) = concat (map (map f) xs)"; | |
| 293 | by (induct_tac "xs" 1); | |
| 294 | by (ALLGOALS Asm_simp_tac); | |
| 295 | qed "map_concat"; | |
| 296 | ||
| 297 | goal thy "filter p (concat xs) = concat (map (filter p) xs)"; | |
| 298 | by (induct_tac "xs" 1); | |
| 299 | by (ALLGOALS Asm_simp_tac); | |
| 300 | qed"filter_concat"; | |
| 301 | ||
| 302 | goal thy "rev(concat xs) = concat (map rev (rev xs))"; | |
| 303 | by (induct_tac "xs" 1); | |
| 2512 | 304 | by (ALLGOALS Asm_simp_tac); | 
| 2608 | 305 | qed "rev_concat"; | 
| 923 | 306 | |
| 962 | 307 | (** length **) | 
| 308 | ||
| 3467 | 309 | section "length"; | 
| 310 | ||
| 3011 | 311 | goal thy "length(xs@ys) = length(xs)+length(ys)"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 312 | by (induct_tac "xs" 1); | 
| 1264 
3eb91524b938
added local simpsets; removed IOA from 'make test'
 clasohm parents: 
1202diff
changeset | 313 | by (ALLGOALS Asm_simp_tac); | 
| 962 | 314 | qed"length_append"; | 
| 1301 | 315 | Addsimps [length_append]; | 
| 316 | ||
| 3011 | 317 | goal thy "length (map f l) = length l"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 318 | by (induct_tac "l" 1); | 
| 1301 | 319 | by (ALLGOALS Simp_tac); | 
| 320 | qed "length_map"; | |
| 321 | Addsimps [length_map]; | |
| 962 | 322 | |
| 3011 | 323 | goal thy "length(rev xs) = length(xs)"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 324 | by (induct_tac "xs" 1); | 
| 1301 | 325 | by (ALLGOALS Asm_simp_tac); | 
| 1169 | 326 | qed "length_rev"; | 
| 1301 | 327 | Addsimps [length_rev]; | 
| 1169 | 328 | |
| 3011 | 329 | goal thy "(length xs = 0) = (xs = [])"; | 
| 3457 | 330 | by (induct_tac "xs" 1); | 
| 331 | by (ALLGOALS Asm_simp_tac); | |
| 2608 | 332 | qed "length_0_conv"; | 
| 333 | AddIffs [length_0_conv]; | |
| 334 | ||
| 3011 | 335 | goal thy "(0 < length xs) = (xs ~= [])"; | 
| 3457 | 336 | by (induct_tac "xs" 1); | 
| 337 | by (ALLGOALS Asm_simp_tac); | |
| 2608 | 338 | qed "length_greater_0_conv"; | 
| 339 | AddIffs [length_greater_0_conv]; | |
| 340 | ||
| 341 | ||
| 923 | 342 | (** nth **) | 
| 343 | ||
| 3467 | 344 | section "nth"; | 
| 345 | ||
| 3011 | 346 | goal thy | 
| 2608 | 347 | "!xs. nth n (xs@ys) = \ | 
| 348 | \ (if n < length xs then nth n xs else nth (n - length xs) ys)"; | |
| 3457 | 349 | by (nat_ind_tac "n" 1); | 
| 350 | by (Asm_simp_tac 1); | |
| 351 | by (rtac allI 1); | |
| 352 | by (exhaust_tac "xs" 1); | |
| 353 | by (ALLGOALS Asm_simp_tac); | |
| 354 | by (rtac allI 1); | |
| 355 | by (exhaust_tac "xs" 1); | |
| 356 | by (ALLGOALS Asm_simp_tac); | |
| 2608 | 357 | qed_spec_mp "nth_append"; | 
| 358 | ||
| 3011 | 359 | goal thy "!n. n < length xs --> nth n (map f xs) = f (nth n xs)"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 360 | by (induct_tac "xs" 1); | 
| 1301 | 361 | (* case [] *) | 
| 362 | by (Asm_full_simp_tac 1); | |
| 363 | (* case x#xl *) | |
| 364 | by (rtac allI 1); | |
| 365 | by (nat_ind_tac "n" 1); | |
| 366 | by (ALLGOALS Asm_full_simp_tac); | |
| 1485 
240cc98b94a7
Added qed_spec_mp to avoid renaming of bound vars in 'th RS spec'
 nipkow parents: 
1465diff
changeset | 367 | qed_spec_mp "nth_map"; | 
| 1301 | 368 | Addsimps [nth_map]; | 
| 369 | ||
| 3011 | 370 | goal thy "!n. n < length xs --> list_all P xs --> P(nth n xs)"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 371 | by (induct_tac "xs" 1); | 
| 1301 | 372 | (* case [] *) | 
| 373 | by (Simp_tac 1); | |
| 374 | (* case x#xl *) | |
| 375 | by (rtac allI 1); | |
| 376 | by (nat_ind_tac "n" 1); | |
| 377 | by (ALLGOALS Asm_full_simp_tac); | |
| 1485 
240cc98b94a7
Added qed_spec_mp to avoid renaming of bound vars in 'th RS spec'
 nipkow parents: 
1465diff
changeset | 378 | qed_spec_mp "list_all_nth"; | 
| 1301 | 379 | |
| 3011 | 380 | goal thy "!n. n < length xs --> (nth n xs) mem xs"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 381 | by (induct_tac "xs" 1); | 
| 1301 | 382 | (* case [] *) | 
| 383 | by (Simp_tac 1); | |
| 384 | (* case x#xl *) | |
| 385 | by (rtac allI 1); | |
| 386 | by (nat_ind_tac "n" 1); | |
| 387 | (* case 0 *) | |
| 388 | by (Asm_full_simp_tac 1); | |
| 389 | (* case Suc x *) | |
| 390 | by (asm_full_simp_tac (!simpset setloop (split_tac [expand_if])) 1); | |
| 1485 
240cc98b94a7
Added qed_spec_mp to avoid renaming of bound vars in 'th RS spec'
 nipkow parents: 
1465diff
changeset | 391 | qed_spec_mp "nth_mem"; | 
| 1301 | 392 | Addsimps [nth_mem]; | 
| 393 | ||
| 1327 
6c29cfab679c
added new arithmetic lemmas and the functions take and drop.
 nipkow parents: 
1301diff
changeset | 394 | |
| 2608 | 395 | (** take & drop **) | 
| 396 | section "take & drop"; | |
| 1327 
6c29cfab679c
added new arithmetic lemmas and the functions take and drop.
 nipkow parents: 
1301diff
changeset | 397 | |
| 1419 
a6a034a47a71
defined take/drop by induction over list rather than nat.
 nipkow parents: 
1327diff
changeset | 398 | goal thy "take 0 xs = []"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 399 | by (induct_tac "xs" 1); | 
| 1419 
a6a034a47a71
defined take/drop by induction over list rather than nat.
 nipkow parents: 
1327diff
changeset | 400 | by (ALLGOALS Asm_simp_tac); | 
| 1327 
6c29cfab679c
added new arithmetic lemmas and the functions take and drop.
 nipkow parents: 
1301diff
changeset | 401 | qed "take_0"; | 
| 
6c29cfab679c
added new arithmetic lemmas and the functions take and drop.
 nipkow parents: 
1301diff
changeset | 402 | |
| 2608 | 403 | goal thy "drop 0 xs = xs"; | 
| 3040 
7d48671753da
Introduced a generic "induct_tac" which picks up the right induction scheme
 nipkow parents: 
3011diff
changeset | 404 | by (induct_tac "xs" 1); | 
| 2608 | 405 | by (ALLGOALS Asm_simp_tac); | 
| 406 | qed "drop_0"; | |
| 407 | ||
| 1419 
a6a034a47a71
defined take/drop by induction over list rather than nat.
 nipkow parents: 
1327diff
changeset | 408 | goal thy "take (Suc n) (x#xs) = x # take n xs"; | 
| 1552 | 409 | by (Simp_tac 1); | 
| 1419 
a6a034a47a71
defined take/drop by induction over list rather than nat.
 nipkow parents: 
1327diff
changeset | 410 | qed "take_Suc_Cons"; | 
| 1327 
6c29cfab679c
added new arithmetic lemmas and the functions take and drop.
 nipkow parents: 
1301diff
changeset | 411 | |
| 2608 | 412 | goal thy "drop (Suc n) (x#xs) = drop n xs"; | 
| 413 | by (Simp_tac 1); | |
| 414 | qed "drop_Suc_Cons"; | |
| 415 | ||
| 416 | Delsimps [take_Cons,drop_Cons]; | |
| 417 | Addsimps [take_0,take_Suc_Cons,drop_0,drop_Suc_Cons]; | |
| 418 | ||
| 3011 | 419 | goal thy "!xs. length(take n xs) = min (length xs) n"; | 
| 3457 | 420 | by (nat_ind_tac "n" 1); | 
| 421 | by (ALLGOALS Asm_simp_tac); | |
| 422 | by (rtac allI 1); | |
| 423 | by (exhaust_tac "xs" 1); | |
| 424 | by (ALLGOALS Asm_simp_tac); | |
| 2608 | 425 | qed_spec_mp "length_take"; | 
| 426 | Addsimps [length_take]; | |
| 923 | 427 | |
| 3011 | 428 | goal thy "!xs. length(drop n xs) = (length xs - n)"; | 
| 3457 | 429 | by (nat_ind_tac "n" 1); | 
| 430 | by (ALLGOALS Asm_simp_tac); | |
| 431 | by (rtac allI 1); | |
| 432 | by (exhaust_tac "xs" 1); | |
| 433 | by (ALLGOALS Asm_simp_tac); | |
| 2608 | 434 | qed_spec_mp "length_drop"; | 
| 435 | Addsimps [length_drop]; | |
| 436 | ||
| 3011 | 437 | goal thy "!xs. length xs <= n --> take n xs = xs"; | 
| 3457 | 438 | by (nat_ind_tac "n" 1); | 
| 439 | by (ALLGOALS Asm_simp_tac); | |
| 440 | by (rtac allI 1); | |
| 441 | by (exhaust_tac "xs" 1); | |
| 442 | by (ALLGOALS Asm_simp_tac); | |
| 2608 | 443 | qed_spec_mp "take_all"; | 
| 923 | 444 | |
| 3011 | 445 | goal thy "!xs. length xs <= n --> drop n xs = []"; | 
| 3457 | 446 | by (nat_ind_tac "n" 1); | 
| 447 | by (ALLGOALS Asm_simp_tac); | |
| 448 | by (rtac allI 1); | |
| 449 | by (exhaust_tac "xs" 1); | |
| 450 | by (ALLGOALS Asm_simp_tac); | |
| 2608 | 451 | qed_spec_mp "drop_all"; | 
| 452 | ||
| 3011 | 453 | goal thy | 
| 2608 | 454 | "!xs. take n (xs @ ys) = (take n xs @ take (n - length xs) ys)"; | 
| 3457 | 455 | by (nat_ind_tac "n" 1); | 
| 456 | by (ALLGOALS Asm_simp_tac); | |
| 457 | by (rtac allI 1); | |
| 458 | by (exhaust_tac "xs" 1); | |
| 459 | by (ALLGOALS Asm_simp_tac); | |
| 2608 | 460 | qed_spec_mp "take_append"; | 
| 461 | Addsimps [take_append]; | |
| 462 | ||
| 3011 | 463 | goal thy "!xs. drop n (xs@ys) = drop n xs @ drop (n - length xs) ys"; | 
| 3457 | 464 | by (nat_ind_tac "n" 1); | 
| 465 | by (ALLGOALS Asm_simp_tac); | |
| 466 | by (rtac allI 1); | |
| 467 | by (exhaust_tac "xs" 1); | |
| 468 | by (ALLGOALS Asm_simp_tac); | |
| 2608 | 469 | qed_spec_mp "drop_append"; | 
| 470 | Addsimps [drop_append]; | |
| 471 | ||
| 3011 | 472 | goal thy "!xs n. take n (take m xs) = take (min n m) xs"; | 
| 3457 | 473 | by (nat_ind_tac "m" 1); | 
| 474 | by (ALLGOALS Asm_simp_tac); | |
| 475 | by (rtac allI 1); | |
| 476 | by (exhaust_tac "xs" 1); | |
| 477 | by (ALLGOALS Asm_simp_tac); | |
| 478 | by (rtac allI 1); | |
| 479 | by (exhaust_tac "n" 1); | |
| 480 | by (ALLGOALS Asm_simp_tac); | |
| 2608 | 481 | qed_spec_mp "take_take"; | 
| 482 | ||
| 3011 | 483 | goal thy "!xs. drop n (drop m xs) = drop (n + m) xs"; | 
| 3457 | 484 | by (nat_ind_tac "m" 1); | 
| 485 | by (ALLGOALS Asm_simp_tac); | |
| 486 | by (rtac allI 1); | |
| 487 | by (exhaust_tac "xs" 1); | |
| 488 | by (ALLGOALS Asm_simp_tac); | |
| 2608 | 489 | qed_spec_mp "drop_drop"; | 
| 923 | 490 | |
| 3011 | 491 | goal thy "!xs n. take n (drop m xs) = drop m (take (n + m) xs)"; | 
| 3457 | 492 | by (nat_ind_tac "m" 1); | 
| 493 | by (ALLGOALS Asm_simp_tac); | |
| 494 | by (rtac allI 1); | |
| 495 | by (exhaust_tac "xs" 1); | |
| 496 | by (ALLGOALS Asm_simp_tac); | |
| 2608 | 497 | qed_spec_mp "take_drop"; | 
| 498 | ||
| 3011 | 499 | goal thy "!xs. take n (map f xs) = map f (take n xs)"; | 
| 3457 | 500 | by (nat_ind_tac "n" 1); | 
| 501 | by (ALLGOALS Asm_simp_tac); | |
| 502 | by (rtac allI 1); | |
| 503 | by (exhaust_tac "xs" 1); | |
| 504 | by (ALLGOALS Asm_simp_tac); | |
| 2608 | 505 | qed_spec_mp "take_map"; | 
| 506 | ||
| 3011 | 507 | goal thy "!xs. drop n (map f xs) = map f (drop n xs)"; | 
| 3457 | 508 | by (nat_ind_tac "n" 1); | 
| 509 | by (ALLGOALS Asm_simp_tac); | |
| 510 | by (rtac allI 1); | |
| 511 | by (exhaust_tac "xs" 1); | |
| 512 | by (ALLGOALS Asm_simp_tac); | |
| 2608 | 513 | qed_spec_mp "drop_map"; | 
| 514 | ||
| 3283 
0db086394024
Replaced res_inst-list_cases by generic exhaust_tac.
 nipkow parents: 
3196diff
changeset | 515 | goal thy "!n i. i < n --> nth i (take n xs) = nth i xs"; | 
| 3457 | 516 | by (induct_tac "xs" 1); | 
| 517 | by (ALLGOALS Asm_simp_tac); | |
| 518 | by (strip_tac 1); | |
| 519 | by (exhaust_tac "n" 1); | |
| 520 | by (Blast_tac 1); | |
| 521 | by (exhaust_tac "i" 1); | |
| 522 | by (ALLGOALS Asm_full_simp_tac); | |
| 2608 | 523 | qed_spec_mp "nth_take"; | 
| 524 | Addsimps [nth_take]; | |
| 923 | 525 | |
| 3283 
0db086394024
Replaced res_inst-list_cases by generic exhaust_tac.
 nipkow parents: 
3196diff
changeset | 526 | goal thy "!xs i. n + i < length xs --> nth i (drop n xs) = nth (n + i) xs"; | 
| 3457 | 527 | by (nat_ind_tac "n" 1); | 
| 528 | by (ALLGOALS Asm_simp_tac); | |
| 529 | by (rtac allI 1); | |
| 530 | by (exhaust_tac "xs" 1); | |
| 531 | by (ALLGOALS Asm_simp_tac); | |
| 2608 | 532 | qed_spec_mp "nth_drop"; | 
| 533 | Addsimps [nth_drop]; | |
| 534 | ||
| 535 | (** takeWhile & dropWhile **) | |
| 536 | ||
| 3467 | 537 | section "takeWhile & dropWhile"; | 
| 538 | ||
| 3011 | 539 | goal thy | 
| 3465 | 540 | "x:set xs & ~P(x) --> takeWhile P (xs @ ys) = takeWhile P xs"; | 
| 3457 | 541 | by (induct_tac "xs" 1); | 
| 542 | by (Simp_tac 1); | |
| 543 | by (asm_full_simp_tac (!simpset setloop (split_tac[expand_if])) 1); | |
| 544 | by (Blast_tac 1); | |
| 2608 | 545 | bind_thm("takeWhile_append1", conjI RS (result() RS mp));
 | 
| 546 | Addsimps [takeWhile_append1]; | |
| 923 | 547 | |
| 3011 | 548 | goal thy | 
| 3465 | 549 | "(!x:set xs.P(x)) --> takeWhile P (xs @ ys) = xs @ takeWhile P ys"; | 
| 3457 | 550 | by (induct_tac "xs" 1); | 
| 551 | by (Simp_tac 1); | |
| 552 | by (asm_full_simp_tac (!simpset setloop (split_tac[expand_if])) 1); | |
| 2608 | 553 | bind_thm("takeWhile_append2", ballI RS (result() RS mp));
 | 
| 554 | Addsimps [takeWhile_append2]; | |
| 1169 | 555 | |
| 3011 | 556 | goal thy | 
| 3465 | 557 | "x:set xs & ~P(x) --> dropWhile P (xs @ ys) = (dropWhile P xs)@ys"; | 
| 3457 | 558 | by (induct_tac "xs" 1); | 
| 559 | by (Simp_tac 1); | |
| 560 | by (asm_full_simp_tac (!simpset setloop (split_tac[expand_if])) 1); | |
| 561 | by (Blast_tac 1); | |
| 2608 | 562 | bind_thm("dropWhile_append1", conjI RS (result() RS mp));
 | 
| 563 | Addsimps [dropWhile_append1]; | |
| 564 | ||
| 3011 | 565 | goal thy | 
| 3465 | 566 | "(!x:set xs.P(x)) --> dropWhile P (xs @ ys) = dropWhile P ys"; | 
| 3457 | 567 | by (induct_tac "xs" 1); | 
| 568 | by (Simp_tac 1); | |
| 569 | by (asm_full_simp_tac (!simpset setloop (split_tac[expand_if])) 1); | |
| 2608 | 570 | bind_thm("dropWhile_append2", ballI RS (result() RS mp));
 | 
| 571 | Addsimps [dropWhile_append2]; | |
| 572 | ||
| 3465 | 573 | goal thy "x:set(takeWhile P xs) --> x:set xs & P x"; | 
| 3457 | 574 | by (induct_tac "xs" 1); | 
| 575 | by (Simp_tac 1); | |
| 576 | by (asm_full_simp_tac (!simpset setloop (split_tac[expand_if])) 1); | |
| 2608 | 577 | qed_spec_mp"set_of_list_take_whileD"; | 
| 578 |