src/HOL/List.thy
changeset 15110 78b5636eabc7
parent 15072 4861bf6af0b4
child 15113 fafcd72b9d4b
equal deleted inserted replaced
15109:bba563cdd997 15110:78b5636eabc7
    34   dropWhile :: "('a => bool) => 'a list => 'a list"
    34   dropWhile :: "('a => bool) => 'a list => 'a list"
    35   rev :: "'a list => 'a list"
    35   rev :: "'a list => 'a list"
    36   zip :: "'a list => 'b list => ('a * 'b) list"
    36   zip :: "'a list => 'b list => ('a * 'b) list"
    37   upt :: "nat => nat => nat list" ("(1[_../_'(])")
    37   upt :: "nat => nat => nat list" ("(1[_../_'(])")
    38   remdups :: "'a list => 'a list"
    38   remdups :: "'a list => 'a list"
       
    39   remove1 :: "'a => 'a list => 'a list"
    39   null:: "'a list => bool"
    40   null:: "'a list => bool"
    40   "distinct":: "'a list => bool"
    41   "distinct":: "'a list => bool"
    41   replicate :: "nat => 'a => 'a list"
    42   replicate :: "nat => 'a => 'a list"
    42 
    43 
    43 nonterminals lupdbinds lupdbind
    44 nonterminals lupdbinds lupdbind
   169 "distinct [] = True"
   170 "distinct [] = True"
   170 "distinct (x#xs) = (x ~: set xs \<and> distinct xs)"
   171 "distinct (x#xs) = (x ~: set xs \<and> distinct xs)"
   171 primrec
   172 primrec
   172 "remdups [] = []"
   173 "remdups [] = []"
   173 "remdups (x#xs) = (if x : set xs then remdups xs else x # remdups xs)"
   174 "remdups (x#xs) = (if x : set xs then remdups xs else x # remdups xs)"
       
   175 primrec
       
   176 "remove1 x [] = []"
       
   177 "remove1 x (y#xs) = (if x=y then xs else y # remove1 x xs)"
   174 primrec
   178 primrec
   175 replicate_0: "replicate 0 x = []"
   179 replicate_0: "replicate 0 x = []"
   176 replicate_Suc: "replicate (Suc n) x = x # replicate n x"
   180 replicate_Suc: "replicate (Suc n) x = x # replicate n x"
   177 defs
   181 defs
   178  list_all2_def:
   182  list_all2_def:
   485 
   489 
   486 lemma ex_map_conv:
   490 lemma ex_map_conv:
   487   "(EX xs. ys = map f xs) = (ALL y : set ys. EX x. y = f x)"
   491   "(EX xs. ys = map f xs) = (ALL y : set ys. EX x. y = f x)"
   488 by(induct ys, auto)
   492 by(induct ys, auto)
   489 
   493 
       
   494 lemma map_eq_imp_length_eq:
       
   495   "!!xs. map f xs = map f ys ==> length xs = length ys"
       
   496 apply (induct ys)
       
   497  apply simp
       
   498 apply(simp (no_asm_use))
       
   499 apply clarify
       
   500 apply(simp (no_asm_use))
       
   501 apply fast
       
   502 done
       
   503 
       
   504 lemma map_inj_on:
       
   505  "[| map f xs = map f ys; inj_on f (set xs Un set ys) |]
       
   506   ==> xs = ys"
       
   507 apply(frule map_eq_imp_length_eq)
       
   508 apply(rotate_tac -1)
       
   509 apply(induct rule:list_induct2)
       
   510  apply simp
       
   511 apply(simp)
       
   512 apply (blast intro:sym)
       
   513 done
       
   514 
       
   515 lemma inj_on_map_eq_map:
       
   516  "inj_on f (set xs Un set ys) \<Longrightarrow> (map f xs = map f ys) = (xs = ys)"
       
   517 by(blast dest:map_inj_on)
       
   518 
   490 lemma map_injective:
   519 lemma map_injective:
   491  "!!xs. map f xs = map f ys ==> inj f ==> xs = ys"
   520  "!!xs. map f xs = map f ys ==> inj f ==> xs = ys"
   492 by (induct ys) (auto dest!:injD)
   521 by (induct ys) (auto dest!:injD)
   493 
   522 
   494 lemma inj_map_eq_map[simp]: "inj f \<Longrightarrow> (map f xs = map f ys) = (xs = ys)"
   523 lemma inj_map_eq_map[simp]: "inj f \<Longrightarrow> (map f xs = map f ys) = (xs = ys)"
   510 lemma map_idI: "(\<And>x. x \<in> set xs \<Longrightarrow> f x = x) \<Longrightarrow> map f xs = xs"
   539 lemma map_idI: "(\<And>x. x \<in> set xs \<Longrightarrow> f x = x) \<Longrightarrow> map f xs = xs"
   511 by (induct xs, auto)
   540 by (induct xs, auto)
   512 
   541 
   513 lemma map_fun_upd [simp]: "y \<notin> set xs \<Longrightarrow> map (f(y:=v)) xs = map f xs"
   542 lemma map_fun_upd [simp]: "y \<notin> set xs \<Longrightarrow> map (f(y:=v)) xs = map f xs"
   514 by (induct xs) auto
   543 by (induct xs) auto
       
   544 
       
   545 lemma map_fst_zip[simp]:
       
   546   "length xs = length ys \<Longrightarrow> map fst (zip xs ys) = xs"
       
   547 by (induct rule:list_induct2, simp_all)
       
   548 
       
   549 lemma map_snd_zip[simp]:
       
   550   "length xs = length ys \<Longrightarrow> map snd (zip xs ys) = ys"
       
   551 by (induct rule:list_induct2, simp_all)
       
   552 
   515 
   553 
   516 subsection {* @{text rev} *}
   554 subsection {* @{text rev} *}
   517 
   555 
   518 lemma rev_append [simp]: "rev (xs @ ys) = rev ys @ rev xs"
   556 lemma rev_append [simp]: "rev (xs @ ys) = rev ys @ rev xs"
   519 by (induct xs) auto
   557 by (induct xs) auto
   827 lemma drop_Suc_Cons [simp]: "drop (Suc n) (x # xs) = drop n xs"
   865 lemma drop_Suc_Cons [simp]: "drop (Suc n) (x # xs) = drop n xs"
   828 by simp
   866 by simp
   829 
   867 
   830 declare take_Cons [simp del] and drop_Cons [simp del]
   868 declare take_Cons [simp del] and drop_Cons [simp del]
   831 
   869 
       
   870 lemma take_Suc: "xs ~= [] ==> take (Suc n) xs = hd xs # take n (tl xs)"
       
   871 by(clarsimp simp add:neq_Nil_conv)
       
   872 
   832 lemma drop_Suc: "drop (Suc n) xs = drop n (tl xs)"
   873 lemma drop_Suc: "drop (Suc n) xs = drop n (tl xs)"
   833 by(cases xs, simp_all)
   874 by(cases xs, simp_all)
   834 
   875 
   835 lemma drop_tl: "!!n. drop n (tl xs) = tl(drop n xs)"
   876 lemma drop_tl: "!!n. drop n (tl xs) = tl(drop n xs)"
   836 by(induct xs, simp_all add:drop_Cons drop_Suc split:nat.split)
   877 by(induct xs, simp_all add:drop_Cons drop_Suc split:nat.split)
   895 done
   936 done
   896 
   937 
   897 lemma append_take_drop_id [simp]: "!!xs. take n xs @ drop n xs = xs"
   938 lemma append_take_drop_id [simp]: "!!xs. take n xs @ drop n xs = xs"
   898 apply (induct n, auto)
   939 apply (induct n, auto)
   899 apply (case_tac xs, auto)
   940 apply (case_tac xs, auto)
       
   941 done
       
   942 
       
   943 lemma take_eq_Nil[simp]: "!!n. (take n xs = []) = (n = 0 \<or> xs = [])"
       
   944 apply(induct xs)
       
   945  apply simp
       
   946 apply(simp add:take_Cons split:nat.split)
       
   947 done
       
   948 
       
   949 lemma drop_eq_Nil[simp]: "!!n. (drop n xs = []) = (length xs <= n)"
       
   950 apply(induct xs)
       
   951 apply simp
       
   952 apply(simp add:drop_Cons split:nat.split)
   900 done
   953 done
   901 
   954 
   902 lemma take_map: "!!xs. take n (map f xs) = map f (take n xs)"
   955 lemma take_map: "!!xs. take n (map f xs) = map f (take n xs)"
   903 apply (induct n, auto)
   956 apply (induct n, auto)
   904 apply (case_tac xs, auto)
   957 apply (case_tac xs, auto)
   962    else take (size ys\<^isub>1) xs\<^isub>1 = ys\<^isub>1 \<and> drop (size ys\<^isub>1) xs\<^isub>1 @ xs\<^isub>2 = ys\<^isub>2)"
  1015    else take (size ys\<^isub>1) xs\<^isub>1 = ys\<^isub>1 \<and> drop (size ys\<^isub>1) xs\<^isub>1 @ xs\<^isub>2 = ys\<^isub>2)"
   963 apply(induct xs\<^isub>1)
  1016 apply(induct xs\<^isub>1)
   964  apply simp
  1017  apply simp
   965 apply(case_tac ys\<^isub>1)
  1018 apply(case_tac ys\<^isub>1)
   966 apply simp_all
  1019 apply simp_all
       
  1020 done
       
  1021 
       
  1022 lemma take_hd_drop:
       
  1023   "!!n. n < length xs \<Longrightarrow> take n xs @ [hd (drop n xs)] = take (n+1) xs"
       
  1024 apply(induct xs)
       
  1025 apply simp
       
  1026 apply(simp add:drop_Cons split:nat.split)
   967 done
  1027 done
   968 
  1028 
   969 
  1029 
   970 subsection {* @{text takeWhile} and @{text dropWhile} *}
  1030 subsection {* @{text takeWhile} and @{text dropWhile} *}
   971 
  1031 
  1365  apply (erule_tac x = "Suc i" in allE, simp, clarsimp)
  1425  apply (erule_tac x = "Suc i" in allE, simp, clarsimp)
  1366 apply (erule_tac x = "Suc i" in allE)
  1426 apply (erule_tac x = "Suc i" in allE)
  1367 apply (erule_tac x = "Suc j" in allE, simp)
  1427 apply (erule_tac x = "Suc j" in allE, simp)
  1368 done
  1428 done
  1369 
  1429 
  1370 lemma distinct_card: "distinct xs \<Longrightarrow> card (set xs) = size xs"
  1430 lemma distinct_card: "distinct xs ==> card (set xs) = size xs"
  1371   by (induct xs) auto
  1431   by (induct xs) auto
  1372 
  1432 
  1373 lemma card_distinct: "card (set xs) = size xs \<Longrightarrow> distinct xs"
  1433 lemma card_distinct: "card (set xs) = size xs ==> distinct xs"
  1374 proof (induct xs)
  1434 proof (induct xs)
  1375   case Nil thus ?case by simp
  1435   case Nil thus ?case by simp
  1376 next
  1436 next
  1377   case (Cons x xs)
  1437   case (Cons x xs)
  1378   show ?case
  1438   show ?case
  1385     moreover have "card (set xs) \<le> length xs" by (rule card_length)
  1445     moreover have "card (set xs) \<le> length xs" by (rule card_length)
  1386     ultimately have False by simp
  1446     ultimately have False by simp
  1387     thus ?thesis ..
  1447     thus ?thesis ..
  1388   qed
  1448   qed
  1389 qed
  1449 qed
       
  1450 
       
  1451 lemma inj_on_setI: "distinct(map f xs) ==> inj_on f (set xs)"
       
  1452 apply(induct xs)
       
  1453  apply simp
       
  1454 apply fastsimp
       
  1455 done
       
  1456 
       
  1457 lemma inj_on_set_conv:
       
  1458  "distinct xs \<Longrightarrow> inj_on f (set xs) = distinct(map f xs)"
       
  1459 apply(induct xs)
       
  1460  apply simp
       
  1461 apply fastsimp
       
  1462 done
       
  1463 
       
  1464 
       
  1465 subsection {* @{text remove1} *}
       
  1466 
       
  1467 lemma set_remove1_subset: "set(remove1 x xs) <= set xs"
       
  1468 apply(induct xs)
       
  1469  apply simp
       
  1470 apply simp
       
  1471 apply blast
       
  1472 done
       
  1473 
       
  1474 lemma [simp]: "distinct xs ==> set(remove1 x xs) = set xs - {x}"
       
  1475 apply(induct xs)
       
  1476  apply simp
       
  1477 apply simp
       
  1478 apply blast
       
  1479 done
       
  1480 
       
  1481 lemma notin_set_remove1[simp]: "x ~: set xs ==> x ~: set(remove1 y xs)"
       
  1482 apply(insert set_remove1_subset)
       
  1483 apply fast
       
  1484 done
       
  1485 
       
  1486 lemma distinct_remove1[simp]: "distinct xs ==> distinct(remove1 x xs)"
       
  1487 by (induct xs) simp_all
  1390 
  1488 
  1391 
  1489 
  1392 subsection {* @{text replicate} *}
  1490 subsection {* @{text replicate} *}
  1393 
  1491 
  1394 lemma length_replicate [simp]: "length (replicate n x) = n"
  1492 lemma length_replicate [simp]: "length (replicate n x) = n"