src/HOL/Library/More_List.thy
author blanchet
Tue, 09 Sep 2014 20:51:36 +0200
changeset 58278 e89c7ac4ce16
parent 58199 5fbe474b5da8
child 58295 c8a8e7c37986
permissions -rw-r--r--
documented extraction plugin
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
58199
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
     1
(* Author: Andreas Lochbihler, ETH Zürich
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
     2
   Author: Florian Haftmann, TU Muenchen  *)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
     3
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
     4
header \<open>Less common functions on lists\<close>
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
     5
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
     6
theory More_List
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
     7
imports Main
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
     8
begin
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
     9
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    10
text \<open>FIXME adapted from @{file "~~/src/HOL/Library/Polynomial.thy"}; to be merged back\<close>
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    11
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    12
definition strip_while :: "('a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> 'a list"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    13
where
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    14
  "strip_while P = rev \<circ> dropWhile P \<circ> rev"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    15
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    16
lemma strip_while_Nil [simp]:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    17
  "strip_while P [] = []"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    18
  by (simp add: strip_while_def)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    19
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    20
lemma strip_while_append [simp]:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    21
  "\<not> P x \<Longrightarrow> strip_while P (xs @ [x]) = xs @ [x]"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    22
  by (simp add: strip_while_def)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    23
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    24
lemma strip_while_append_rec [simp]:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    25
  "P x \<Longrightarrow> strip_while P (xs @ [x]) = strip_while P xs"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    26
  by (simp add: strip_while_def)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    27
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    28
lemma strip_while_Cons [simp]:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    29
  "\<not> P x \<Longrightarrow> strip_while P (x # xs) = x # strip_while P xs"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    30
  by (induct xs rule: rev_induct) (simp_all add: strip_while_def)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    31
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    32
lemma strip_while_eq_Nil [simp]:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    33
  "strip_while P xs = [] \<longleftrightarrow> (\<forall>x\<in>set xs. P x)"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    34
  by (simp add: strip_while_def)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    35
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    36
lemma strip_while_eq_Cons_rec:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    37
  "strip_while P (x # xs) = x # strip_while P xs \<longleftrightarrow> \<not> (P x \<and> (\<forall>x\<in>set xs. P x))"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    38
  by (induct xs rule: rev_induct) (simp_all add: strip_while_def)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    39
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    40
lemma strip_while_not_last [simp]:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    41
  "\<not> P (last xs) \<Longrightarrow> strip_while P xs = xs"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    42
  by (cases xs rule: rev_cases) simp_all
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    43
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    44
lemma split_strip_while_append:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    45
  fixes xs :: "'a list"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    46
  obtains ys zs :: "'a list"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    47
  where "strip_while P xs = ys" and "\<forall>x\<in>set zs. P x" and "xs = ys @ zs"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    48
proof (rule that)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    49
  show "strip_while P xs = strip_while P xs" ..
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    50
  show "\<forall>x\<in>set (rev (takeWhile P (rev xs))). P x" by (simp add: takeWhile_eq_all_conv [symmetric])
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    51
  have "rev xs = rev (strip_while P xs @ rev (takeWhile P (rev xs)))"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    52
    by (simp add: strip_while_def)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    53
  then show "xs = strip_while P xs @ rev (takeWhile P (rev xs))"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    54
    by (simp only: rev_is_rev_conv)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    55
qed
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    56
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    57
lemma strip_while_snoc [simp]:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    58
  "strip_while P (xs @ [x]) = (if P x then strip_while P xs else xs @ [x])"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    59
  by (simp add: strip_while_def)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    60
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    61
lemma strip_while_map:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    62
  "strip_while P (map f xs) = map f (strip_while (P \<circ> f) xs)"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    63
  by (simp add: strip_while_def rev_map dropWhile_map)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    64
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    65
lemma dropWhile_idI:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    66
  "(xs \<noteq> [] \<Longrightarrow> \<not> P (hd xs)) \<Longrightarrow> dropWhile P xs = xs"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    67
  by (metis dropWhile.simps(1) dropWhile.simps(2) list.collapse)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    68
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    69
lemma strip_while_idI:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    70
  "(xs \<noteq> [] \<Longrightarrow> \<not> P (last xs)) \<Longrightarrow> strip_while P xs = xs"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    71
  using dropWhile_idI [of "rev xs"] by (simp add: strip_while_def hd_rev)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    72
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    73
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    74
definition nth_default :: "'a \<Rightarrow> 'a list \<Rightarrow> nat \<Rightarrow> 'a"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    75
where
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    76
  "nth_default x xs n = (if n < length xs then xs ! n else x)"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    77
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    78
lemma nth_default_Nil [simp]:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    79
  "nth_default y [] n = y"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    80
  by (simp add: nth_default_def)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    81
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    82
lemma nth_default_Cons_0 [simp]:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    83
  "nth_default y (x # xs) 0 = x"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    84
  by (simp add: nth_default_def)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    85
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    86
lemma nth_default_Cons_Suc [simp]:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    87
  "nth_default y (x # xs) (Suc n) = nth_default y xs n"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    88
  by (simp add: nth_default_def)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    89
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    90
lemma nth_default_map_eq:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    91
  "f y = x \<Longrightarrow> nth_default x (map f xs) n = f (nth_default y xs n)"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    92
  by (simp add: nth_default_def)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    93
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    94
lemma nth_default_strip_while_eq [simp]:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    95
  "nth_default x (strip_while (HOL.eq x) xs) n = nth_default x xs n"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    96
proof -
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    97
  from split_strip_while_append obtain ys zs
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    98
    where "strip_while (HOL.eq x) xs = ys" and "\<forall>z\<in>set zs. x = z" and "xs = ys @ zs" by blast
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
    99
  then show ?thesis by (simp add: nth_default_def not_less nth_append)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   100
qed
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   101
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   102
lemma nth_default_Cons:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   103
  "nth_default y (x # xs) n = (case n of 0 \<Rightarrow> x | Suc n' \<Rightarrow> nth_default y xs n')"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   104
  by (simp split: nat.split)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   105
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   106
lemma nth_default_nth:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   107
  "n < length xs \<Longrightarrow> nth_default y xs n = xs ! n"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   108
  by (simp add: nth_default_def)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   109
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   110
lemma nth_default_beyond:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   111
  "length xs \<le> n \<Longrightarrow> nth_default y xs n = y"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   112
  by (simp add: nth_default_def)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   113
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   114
lemma range_nth_default [simp]:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   115
  "range (nth_default dflt xs) = insert dflt (set xs)"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   116
  by (auto simp add: nth_default_def[abs_def] in_set_conv_nth)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   117
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   118
lemma nth_strip_while:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   119
  assumes "n < length (strip_while P xs)"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   120
  shows "strip_while P xs ! n = xs ! n"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   121
proof -
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   122
  have "length (dropWhile P (rev xs)) + length (takeWhile P (rev xs)) = length xs"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   123
    by (subst add.commute)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   124
      (simp add: arg_cong [where f=length, OF takeWhile_dropWhile_id, unfolded length_append])
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   125
  then show ?thesis using assms
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   126
    by (simp add: strip_while_def rev_nth dropWhile_nth)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   127
qed
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   128
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   129
lemma length_strip_while_le:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   130
  "length (strip_while P xs) \<le> length xs"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   131
  unfolding strip_while_def o_def length_rev
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   132
  by (subst (2) length_rev[symmetric])
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   133
    (simp add: strip_while_def length_dropWhile_le del: length_rev)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   134
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   135
lemma finite_nth_default_neq_default [simp]:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   136
  "finite {k. nth_default dflt xs k \<noteq> dflt}"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   137
  by (simp add: nth_default_def)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   138
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   139
lemma sorted_list_of_set_nth_default:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   140
  "sorted_list_of_set {k. nth_default dflt xs k \<noteq> dflt} = map fst (filter (\<lambda>(_, x). x \<noteq> dflt) (zip [0..<length xs] xs))"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   141
  by (rule sorted_distinct_set_unique) (auto simp add: nth_default_def in_set_conv_nth sorted_filter distinct_map_filter intro: rev_image_eqI)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   142
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   143
lemma nth_default_snoc_default [simp]:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   144
  "nth_default dflt (xs @ [dflt]) = nth_default dflt xs"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   145
  by (auto simp add: nth_default_def fun_eq_iff nth_append)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   146
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   147
lemma nth_default_strip_while_dflt [simp]:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   148
 "nth_default dflt (strip_while (op = dflt) xs) = nth_default dflt xs"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   149
  by (induct xs rule: rev_induct) auto
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   150
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   151
lemma nth_default_eq_dflt_iff:
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   152
  "nth_default dflt xs k = dflt \<longleftrightarrow> (k < length xs \<longrightarrow> xs ! k = dflt)"
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   153
  by (simp add: nth_default_def)
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   154
5fbe474b5da8 explicit theory with additional, less commonly used list operations
haftmann
parents:
diff changeset
   155
end