src/HOL/List.thy
changeset 61799 4cf66f21b764
parent 61699 a81dc5c4d6a9
child 61824 dcbe9f756ae0
equal deleted inserted replaced
61798:27f3c10b0b50 61799:4cf66f21b764
    18   "tl [] = []"
    18   "tl [] = []"
    19 
    19 
    20 datatype_compat list
    20 datatype_compat list
    21 
    21 
    22 lemma [case_names Nil Cons, cases type: list]:
    22 lemma [case_names Nil Cons, cases type: list]:
    23   -- \<open>for backward compatibility -- names of variables differ\<close>
    23   \<comment> \<open>for backward compatibility -- names of variables differ\<close>
    24   "(y = [] \<Longrightarrow> P) \<Longrightarrow> (\<And>a list. y = a # list \<Longrightarrow> P) \<Longrightarrow> P"
    24   "(y = [] \<Longrightarrow> P) \<Longrightarrow> (\<And>a list. y = a # list \<Longrightarrow> P) \<Longrightarrow> P"
    25 by (rule list.exhaust)
    25 by (rule list.exhaust)
    26 
    26 
    27 lemma [case_names Nil Cons, induct type: list]:
    27 lemma [case_names Nil Cons, induct type: list]:
    28   -- \<open>for backward compatibility -- names of variables differ\<close>
    28   \<comment> \<open>for backward compatibility -- names of variables differ\<close>
    29   "P [] \<Longrightarrow> (\<And>a list. P list \<Longrightarrow> P (a # list)) \<Longrightarrow> P list"
    29   "P [] \<Longrightarrow> (\<And>a list. P list \<Longrightarrow> P (a # list)) \<Longrightarrow> P list"
    30 by (rule list.induct)
    30 by (rule list.induct)
    31 
    31 
    32 text \<open>Compatibility:\<close>
    32 text \<open>Compatibility:\<close>
    33 
    33 
    40 setup \<open>Sign.parent_path\<close>
    40 setup \<open>Sign.parent_path\<close>
    41 
    41 
    42 lemmas set_simps = list.set (* legacy *)
    42 lemmas set_simps = list.set (* legacy *)
    43 
    43 
    44 syntax
    44 syntax
    45   -- \<open>list Enumeration\<close>
    45   \<comment> \<open>list Enumeration\<close>
    46   "_list" :: "args => 'a list"    ("[(_)]")
    46   "_list" :: "args => 'a list"    ("[(_)]")
    47 
    47 
    48 translations
    48 translations
    49   "[x, xs]" == "x#[xs]"
    49   "[x, xs]" == "x#[xs]"
    50   "[x]" == "x#[]"
    50   "[x]" == "x#[]"
    76 primrec filter:: "('a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> 'a list" where
    76 primrec filter:: "('a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> 'a list" where
    77 "filter P [] = []" |
    77 "filter P [] = []" |
    78 "filter P (x # xs) = (if P x then x # filter P xs else filter P xs)"
    78 "filter P (x # xs) = (if P x then x # filter P xs else filter P xs)"
    79 
    79 
    80 syntax
    80 syntax
    81   -- \<open>Special syntax for filter\<close>
    81   \<comment> \<open>Special syntax for filter\<close>
    82   "_filter" :: "[pttrn, 'a list, bool] => 'a list"    ("(1[_<-_./ _])")
    82   "_filter" :: "[pttrn, 'a list, bool] => 'a list"    ("(1[_<-_./ _])")
    83 syntax (xsymbols)
    83 syntax (xsymbols)
    84   "_filter" :: "[pttrn, 'a list, bool] => 'a list"("(1[_\<leftarrow>_ ./ _])")
    84   "_filter" :: "[pttrn, 'a list, bool] => 'a list"("(1[_\<leftarrow>_ ./ _])")
    85 translations
    85 translations
    86   "[x<-xs . P]"== "CONST filter (%x. P) xs"
    86   "[x<-xs . P]"== "CONST filter (%x. P) xs"
   102 "concat (x # xs) = x @ concat xs"
   102 "concat (x # xs) = x @ concat xs"
   103 
   103 
   104 primrec drop:: "nat \<Rightarrow> 'a list \<Rightarrow> 'a list" where
   104 primrec drop:: "nat \<Rightarrow> 'a list \<Rightarrow> 'a list" where
   105 drop_Nil: "drop n [] = []" |
   105 drop_Nil: "drop n [] = []" |
   106 drop_Cons: "drop n (x # xs) = (case n of 0 \<Rightarrow> x # xs | Suc m \<Rightarrow> drop m xs)"
   106 drop_Cons: "drop n (x # xs) = (case n of 0 \<Rightarrow> x # xs | Suc m \<Rightarrow> drop m xs)"
   107   -- \<open>Warning: simpset does not contain this definition, but separate
   107   \<comment> \<open>Warning: simpset does not contain this definition, but separate
   108        theorems for @{text "n = 0"} and @{text "n = Suc k"}\<close>
   108        theorems for \<open>n = 0\<close> and \<open>n = Suc k\<close>\<close>
   109 
   109 
   110 primrec take:: "nat \<Rightarrow> 'a list \<Rightarrow> 'a list" where
   110 primrec take:: "nat \<Rightarrow> 'a list \<Rightarrow> 'a list" where
   111 take_Nil:"take n [] = []" |
   111 take_Nil:"take n [] = []" |
   112 take_Cons: "take n (x # xs) = (case n of 0 \<Rightarrow> [] | Suc m \<Rightarrow> x # take m xs)"
   112 take_Cons: "take n (x # xs) = (case n of 0 \<Rightarrow> [] | Suc m \<Rightarrow> x # take m xs)"
   113   -- \<open>Warning: simpset does not contain this definition, but separate
   113   \<comment> \<open>Warning: simpset does not contain this definition, but separate
   114        theorems for @{text "n = 0"} and @{text "n = Suc k"}\<close>
   114        theorems for \<open>n = 0\<close> and \<open>n = Suc k\<close>\<close>
   115 
   115 
   116 primrec (nonexhaustive) nth :: "'a list => nat => 'a" (infixl "!" 100) where
   116 primrec (nonexhaustive) nth :: "'a list => nat => 'a" (infixl "!" 100) where
   117 nth_Cons: "(x # xs) ! n = (case n of 0 \<Rightarrow> x | Suc k \<Rightarrow> xs ! k)"
   117 nth_Cons: "(x # xs) ! n = (case n of 0 \<Rightarrow> x | Suc k \<Rightarrow> xs ! k)"
   118   -- \<open>Warning: simpset does not contain this definition, but separate
   118   \<comment> \<open>Warning: simpset does not contain this definition, but separate
   119        theorems for @{text "n = 0"} and @{text "n = Suc k"}\<close>
   119        theorems for \<open>n = 0\<close> and \<open>n = Suc k\<close>\<close>
   120 
   120 
   121 primrec list_update :: "'a list \<Rightarrow> nat \<Rightarrow> 'a \<Rightarrow> 'a list" where
   121 primrec list_update :: "'a list \<Rightarrow> nat \<Rightarrow> 'a \<Rightarrow> 'a list" where
   122 "list_update [] i v = []" |
   122 "list_update [] i v = []" |
   123 "list_update (x # xs) i v =
   123 "list_update (x # xs) i v =
   124   (case i of 0 \<Rightarrow> v # xs | Suc j \<Rightarrow> x # list_update xs j v)"
   124   (case i of 0 \<Rightarrow> v # xs | Suc j \<Rightarrow> x # list_update xs j v)"
   145 
   145 
   146 primrec zip :: "'a list \<Rightarrow> 'b list \<Rightarrow> ('a \<times> 'b) list" where
   146 primrec zip :: "'a list \<Rightarrow> 'b list \<Rightarrow> ('a \<times> 'b) list" where
   147 "zip xs [] = []" |
   147 "zip xs [] = []" |
   148 zip_Cons: "zip xs (y # ys) =
   148 zip_Cons: "zip xs (y # ys) =
   149   (case xs of [] => [] | z # zs => (z, y) # zip zs ys)"
   149   (case xs of [] => [] | z # zs => (z, y) # zip zs ys)"
   150   -- \<open>Warning: simpset does not contain this definition, but separate
   150   \<comment> \<open>Warning: simpset does not contain this definition, but separate
   151        theorems for @{text "xs = []"} and @{text "xs = z # zs"}\<close>
   151        theorems for \<open>xs = []\<close> and \<open>xs = z # zs\<close>\<close>
   152 
   152 
   153 primrec product :: "'a list \<Rightarrow> 'b list \<Rightarrow> ('a \<times> 'b) list" where
   153 primrec product :: "'a list \<Rightarrow> 'b list \<Rightarrow> ('a \<times> 'b) list" where
   154 "product [] _ = []" |
   154 "product [] _ = []" |
   155 "product (x#xs) ys = map (Pair x) ys @ product xs ys"
   155 "product (x#xs) ys = map (Pair x) ys @ product xs ys"
   156 
   156 
   175 
   175 
   176 primrec find :: "('a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> 'a option" where
   176 primrec find :: "('a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> 'a option" where
   177 "find _ [] = None" |
   177 "find _ [] = None" |
   178 "find P (x#xs) = (if P x then Some x else find P xs)"
   178 "find P (x#xs) = (if P x then Some x else find P xs)"
   179 
   179 
   180 text \<open>In the context of multisets, @{text count_list} is equivalent to
   180 text \<open>In the context of multisets, \<open>count_list\<close> is equivalent to
   181   @{term "count o mset"} and it it advisable to use the latter.\<close>
   181   @{term "count o mset"} and it it advisable to use the latter.\<close>
   182 primrec count_list :: "'a list \<Rightarrow> 'a \<Rightarrow> nat" where
   182 primrec count_list :: "'a list \<Rightarrow> 'a \<Rightarrow> nat" where
   183 "count_list [] y = 0" |
   183 "count_list [] y = 0" |
   184 "count_list (x#xs) y = (if x=y then count_list xs y + 1 else count_list xs y)"
   184 "count_list (x#xs) y = (if x=y then count_list xs y + 1 else count_list xs y)"
   185 
   185 
   223 primrec replicate :: "nat \<Rightarrow> 'a \<Rightarrow> 'a list" where
   223 primrec replicate :: "nat \<Rightarrow> 'a \<Rightarrow> 'a list" where
   224 replicate_0: "replicate 0 x = []" |
   224 replicate_0: "replicate 0 x = []" |
   225 replicate_Suc: "replicate (Suc n) x = x # replicate n x"
   225 replicate_Suc: "replicate (Suc n) x = x # replicate n x"
   226 
   226 
   227 text \<open>
   227 text \<open>
   228   Function @{text size} is overloaded for all datatypes. Users may
   228   Function \<open>size\<close> is overloaded for all datatypes. Users may
   229   refer to the list version as @{text length}.\<close>
   229   refer to the list version as \<open>length\<close>.\<close>
   230 
   230 
   231 abbreviation length :: "'a list \<Rightarrow> nat" where
   231 abbreviation length :: "'a list \<Rightarrow> nat" where
   232 "length \<equiv> size"
   232 "length \<equiv> size"
   233 
   233 
   234 definition enumerate :: "nat \<Rightarrow> 'a list \<Rightarrow> (nat \<times> 'a) list" where
   234 definition enumerate :: "nat \<Rightarrow> 'a list \<Rightarrow> (nat \<times> 'a) list" where
   365 
   365 
   366 
   366 
   367 subsubsection \<open>List comprehension\<close>
   367 subsubsection \<open>List comprehension\<close>
   368 
   368 
   369 text\<open>Input syntax for Haskell-like list comprehension notation.
   369 text\<open>Input syntax for Haskell-like list comprehension notation.
   370 Typical example: @{text"[(x,y). x \<leftarrow> xs, y \<leftarrow> ys, x \<noteq> y]"},
   370 Typical example: \<open>[(x,y). x \<leftarrow> xs, y \<leftarrow> ys, x \<noteq> y]\<close>,
   371 the list of all pairs of distinct elements from @{text xs} and @{text ys}.
   371 the list of all pairs of distinct elements from \<open>xs\<close> and \<open>ys\<close>.
   372 The syntax is as in Haskell, except that @{text"|"} becomes a dot
   372 The syntax is as in Haskell, except that \<open>|\<close> becomes a dot
   373 (like in Isabelle's set comprehension): @{text"[e. x \<leftarrow> xs, \<dots>]"} rather than
   373 (like in Isabelle's set comprehension): \<open>[e. x \<leftarrow> xs, \<dots>]\<close> rather than
   374 \verb![e| x <- xs, ...]!.
   374 \verb![e| x <- xs, ...]!.
   375 
   375 
   376 The qualifiers after the dot are
   376 The qualifiers after the dot are
   377 \begin{description}
   377 \begin{description}
   378 \item[generators] @{text"p \<leftarrow> xs"},
   378 \item[generators] \<open>p \<leftarrow> xs\<close>,
   379  where @{text p} is a pattern and @{text xs} an expression of list type, or
   379  where \<open>p\<close> is a pattern and \<open>xs\<close> an expression of list type, or
   380 \item[guards] @{text"b"}, where @{text b} is a boolean expression.
   380 \item[guards] \<open>b\<close>, where \<open>b\<close> is a boolean expression.
   381 %\item[local bindings] @ {text"let x = e"}.
   381 %\item[local bindings] @ {text"let x = e"}.
   382 \end{description}
   382 \end{description}
   383 
   383 
   384 Just like in Haskell, list comprehension is just a shorthand. To avoid
   384 Just like in Haskell, list comprehension is just a shorthand. To avoid
   385 misunderstandings, the translation into desugared form is not reversed
   385 misunderstandings, the translation into desugared form is not reversed
   386 upon output. Note that the translation of @{text"[e. x \<leftarrow> xs]"} is
   386 upon output. Note that the translation of \<open>[e. x \<leftarrow> xs]\<close> is
   387 optmized to @{term"map (%x. e) xs"}.
   387 optmized to @{term"map (%x. e) xs"}.
   388 
   388 
   389 It is easy to write short list comprehensions which stand for complex
   389 It is easy to write short list comprehensions which stand for complex
   390 expressions. During proofs, they may become unreadable (and
   390 expressions. During proofs, they may become unreadable (and
   391 mangled). In such cases it can be advisable to introduce separate
   391 mangled). In such cases it can be advisable to introduce separate
   799 by(simp add: inj_on_def)
   799 by(simp add: inj_on_def)
   800 
   800 
   801 subsubsection \<open>@{const length}\<close>
   801 subsubsection \<open>@{const length}\<close>
   802 
   802 
   803 text \<open>
   803 text \<open>
   804   Needs to come before @{text "@"} because of theorem @{text
   804   Needs to come before \<open>@\<close> because of theorem \<open>append_eq_append_conv\<close>.
   805   append_eq_append_conv}.
       
   806 \<close>
   805 \<close>
   807 
   806 
   808 lemma length_append [simp]: "length (xs @ ys) = length xs + length ys"
   807 lemma length_append [simp]: "length (xs @ ys) = length xs + length ys"
   809 by (induct xs) auto
   808 by (induct xs) auto
   810 
   809 
   924   end;
   923   end;
   925 in K list_neq end;
   924 in K list_neq end;
   926 \<close>
   925 \<close>
   927 
   926 
   928 
   927 
   929 subsubsection \<open>@{text "@"} -- append\<close>
   928 subsubsection \<open>\<open>@\<close> -- append\<close>
   930 
   929 
   931 lemma append_assoc [simp]: "(xs @ ys) @ zs = xs @ (ys @ zs)"
   930 lemma append_assoc [simp]: "(xs @ ys) @ zs = xs @ (ys @ zs)"
   932 by (induct xs) auto
   931 by (induct xs) auto
   933 
   932 
   934 lemma append_Nil2 [simp]: "xs @ [] = xs"
   933 lemma append_Nil2 [simp]: "xs @ [] = xs"
  1001 lemma append_eq_Cons_conv: "(ys@zs = x#xs) =
  1000 lemma append_eq_Cons_conv: "(ys@zs = x#xs) =
  1002  (ys = [] & zs = x#xs | (EX ys'. ys = x#ys' & ys'@zs = xs))"
  1001  (ys = [] & zs = x#xs | (EX ys'. ys = x#ys' & ys'@zs = xs))"
  1003 by(cases ys) auto
  1002 by(cases ys) auto
  1004 
  1003 
  1005 
  1004 
  1006 text \<open>Trivial rules for solving @{text "@"}-equations automatically.\<close>
  1005 text \<open>Trivial rules for solving \<open>@\<close>-equations automatically.\<close>
  1007 
  1006 
  1008 lemma eq_Nil_appendI: "xs = ys ==> xs = [] @ ys"
  1007 lemma eq_Nil_appendI: "xs = ys ==> xs = [] @ ys"
  1009 by simp
  1008 by simp
  1010 
  1009 
  1011 lemma Cons_eq_appendI:
  1010 lemma Cons_eq_appendI:
  1017 by (drule sym) simp
  1016 by (drule sym) simp
  1018 
  1017 
  1019 
  1018 
  1020 text \<open>
  1019 text \<open>
  1021 Simplification procedure for all list equalities.
  1020 Simplification procedure for all list equalities.
  1022 Currently only tries to rearrange @{text "@"} to see if
  1021 Currently only tries to rearrange \<open>@\<close> to see if
  1023 - both lists end in a singleton list,
  1022 - both lists end in a singleton list,
  1024 - or both lists end in the same list.
  1023 - or both lists end in the same list.
  1025 \<close>
  1024 \<close>
  1026 
  1025 
  1027 simproc_setup list_eq ("(xs::'a list) = ys")  = \<open>
  1026 simproc_setup list_eq ("(xs::'a list) = ys")  = \<open>
  1256 by(rule rev_cases[of xs]) auto
  1255 by(rule rev_cases[of xs]) auto
  1257 
  1256 
  1258 
  1257 
  1259 subsubsection \<open>@{const set}\<close>
  1258 subsubsection \<open>@{const set}\<close>
  1260 
  1259 
  1261 declare list.set[code_post]  --"pretty output"
  1260 declare list.set[code_post]  \<comment>"pretty output"
  1262 
  1261 
  1263 lemma finite_set [iff]: "finite (set xs)"
  1262 lemma finite_set [iff]: "finite (set xs)"
  1264 by (induct xs) auto
  1263 by (induct xs) auto
  1265 
  1264 
  1266 lemma set_append [simp]: "set (xs @ ys) = (set xs \<union> set ys)"
  1265 lemma set_append [simp]: "set (xs @ ys) = (set xs \<union> set ys)"
  2780 qed
  2779 qed
  2781 
  2780 
  2782 
  2781 
  2783 subsubsection \<open>@{const fold} with natural argument order\<close>
  2782 subsubsection \<open>@{const fold} with natural argument order\<close>
  2784 
  2783 
  2785 lemma fold_simps [code]: -- \<open>eta-expanded variant for generated code -- enables tail-recursion optimisation in Scala\<close>
  2784 lemma fold_simps [code]: \<comment> \<open>eta-expanded variant for generated code -- enables tail-recursion optimisation in Scala\<close>
  2786   "fold f [] s = s"
  2785   "fold f [] s = s"
  2787   "fold f (x # xs) s = fold f xs (f x s)" 
  2786   "fold f (x # xs) s = fold f xs (f x s)" 
  2788 by simp_all
  2787 by simp_all
  2789 
  2788 
  2790 lemma fold_remove1_split:
  2789 lemma fold_remove1_split:
  2932 by (induct xs) simp_all
  2931 by (induct xs) simp_all
  2933 
  2932 
  2934 lemma foldl_conv_fold: "foldl f s xs = fold (\<lambda>x s. f s x) xs s"
  2933 lemma foldl_conv_fold: "foldl f s xs = fold (\<lambda>x s. f s x) xs s"
  2935 by (induct xs arbitrary: s) simp_all
  2934 by (induct xs arbitrary: s) simp_all
  2936 
  2935 
  2937 lemma foldr_conv_foldl: -- \<open>The ``Third Duality Theorem'' in Bird \& Wadler:\<close>
  2936 lemma foldr_conv_foldl: \<comment> \<open>The ``Third Duality Theorem'' in Bird \& Wadler:\<close>
  2938   "foldr f xs a = foldl (\<lambda>x y. f y x) a (rev xs)"
  2937   "foldr f xs a = foldl (\<lambda>x y. f y x) a (rev xs)"
  2939 by (simp add: foldr_conv_fold foldl_conv_fold)
  2938 by (simp add: foldr_conv_fold foldl_conv_fold)
  2940 
  2939 
  2941 lemma foldl_conv_foldr:
  2940 lemma foldl_conv_foldr:
  2942   "foldl f a xs = foldr (\<lambda>x y. f y x) (rev xs) a"
  2941   "foldl f a xs = foldr (\<lambda>x y. f y x) (rev xs) a"
  2978 
  2977 
  2979 
  2978 
  2980 subsubsection \<open>@{const upt}\<close>
  2979 subsubsection \<open>@{const upt}\<close>
  2981 
  2980 
  2982 lemma upt_rec[code]: "[i..<j] = (if i<j then i#[Suc i..<j] else [])"
  2981 lemma upt_rec[code]: "[i..<j] = (if i<j then i#[Suc i..<j] else [])"
  2983 -- \<open>simp does not terminate!\<close>
  2982 \<comment> \<open>simp does not terminate!\<close>
  2984 by (induct j) auto
  2983 by (induct j) auto
  2985 
  2984 
  2986 lemmas upt_rec_numeral[simp] = upt_rec[of "numeral m" "numeral n"] for m n
  2985 lemmas upt_rec_numeral[simp] = upt_rec[of "numeral m" "numeral n"] for m n
  2987 
  2986 
  2988 lemma upt_conv_Nil [simp]: "j <= i ==> [i..<j] = []"
  2987 lemma upt_conv_Nil [simp]: "j <= i ==> [i..<j] = []"
  2998 apply(clarsimp simp add: append_eq_Cons_conv)
  2997 apply(clarsimp simp add: append_eq_Cons_conv)
  2999 apply arith
  2998 apply arith
  3000 done
  2999 done
  3001 
  3000 
  3002 lemma upt_Suc_append: "i <= j ==> [i..<(Suc j)] = [i..<j]@[j]"
  3001 lemma upt_Suc_append: "i <= j ==> [i..<(Suc j)] = [i..<j]@[j]"
  3003 -- \<open>Only needed if @{text upt_Suc} is deleted from the simpset.\<close>
  3002 \<comment> \<open>Only needed if \<open>upt_Suc\<close> is deleted from the simpset.\<close>
  3004 by simp
  3003 by simp
  3005 
  3004 
  3006 lemma upt_conv_Cons: "i < j ==> [i..<j] = i # [Suc i..<j]"
  3005 lemma upt_conv_Cons: "i < j ==> [i..<j] = i # [Suc i..<j]"
  3007 by (simp add: upt_rec)
  3006 by (simp add: upt_rec)
  3008 
  3007 
  3009 lemma upt_add_eq_append: "i<=j ==> [i..<j+k] = [i..<j]@[j..<j+k]"
  3008 lemma upt_add_eq_append: "i<=j ==> [i..<j+k] = [i..<j]@[j..<j+k]"
  3010 -- \<open>LOOPS as a simprule, since @{text "j <= j"}.\<close>
  3009 \<comment> \<open>LOOPS as a simprule, since \<open>j <= j\<close>.\<close>
  3011 by (induct k) auto
  3010 by (induct k) auto
  3012 
  3011 
  3013 lemma length_upt [simp]: "length [i..<j] = j - i"
  3012 lemma length_upt [simp]: "length [i..<j] = j - i"
  3014 by (induct j) (auto simp add: Suc_diff_le)
  3013 by (induct j) (auto simp add: Suc_diff_le)
  3015 
  3014 
  3078 apply (simp add: list_all2_conv_all_nth) 
  3077 apply (simp add: list_all2_conv_all_nth) 
  3079 apply (rule nth_equalityI, blast, simp)
  3078 apply (rule nth_equalityI, blast, simp)
  3080 done
  3079 done
  3081 
  3080 
  3082 lemma take_equalityI: "(\<forall>i. take i xs = take i ys) ==> xs = ys"
  3081 lemma take_equalityI: "(\<forall>i. take i xs = take i ys) ==> xs = ys"
  3083 -- \<open>The famous take-lemma.\<close>
  3082 \<comment> \<open>The famous take-lemma.\<close>
  3084 apply (drule_tac x = "max (length xs) (length ys)" in spec)
  3083 apply (drule_tac x = "max (length xs) (length ys)" in spec)
  3085 apply (simp add: le_max_iff_disj)
  3084 apply (simp add: le_max_iff_disj)
  3086 done
  3085 done
  3087 
  3086 
  3088 
  3087 
  3108 lemma nth_Cons_numeral [simp]:
  3107 lemma nth_Cons_numeral [simp]:
  3109   "(x # xs) ! numeral v = xs ! (numeral v - 1)"
  3108   "(x # xs) ! numeral v = xs ! (numeral v - 1)"
  3110 by (simp add: nth_Cons')
  3109 by (simp add: nth_Cons')
  3111 
  3110 
  3112 
  3111 
  3113 subsubsection \<open>@{text upto}: interval-list on @{typ int}\<close>
  3112 subsubsection \<open>\<open>upto\<close>: interval-list on @{typ int}\<close>
  3114 
  3113 
  3115 function upto :: "int \<Rightarrow> int \<Rightarrow> int list" ("(1[_../_])") where
  3114 function upto :: "int \<Rightarrow> int \<Rightarrow> int list" ("(1[_../_])") where
  3116   "upto i j = (if i \<le> j then i # [i+1..j] else [])"
  3115   "upto i j = (if i \<le> j then i # [i+1..j] else [])"
  3117 by auto
  3116 by auto
  3118 termination
  3117 termination
  5153   ultimately show "\<forall>i < length ?trans. ?trans ! i = ?map ! i"
  5152   ultimately show "\<forall>i < length ?trans. ?trans ! i = ?map ! i"
  5154     by (auto simp: nth_transpose intro: nth_equalityI)
  5153     by (auto simp: nth_transpose intro: nth_equalityI)
  5155 qed
  5154 qed
  5156 
  5155 
  5157 
  5156 
  5158 subsubsection \<open>@{text sorted_list_of_set}\<close>
  5157 subsubsection \<open>\<open>sorted_list_of_set\<close>\<close>
  5159 
  5158 
  5160 text\<open>This function maps (finite) linearly ordered sets to sorted
  5159 text\<open>This function maps (finite) linearly ordered sets to sorted
  5161 lists. Warning: in most cases it is not a good idea to convert from
  5160 lists. Warning: in most cases it is not a good idea to convert from
  5162 sets to lists but one should convert in the other direction (via
  5161 sets to lists but one should convert in the other direction (via
  5163 @{const set}).\<close>
  5162 @{const set}).\<close>
  5164 
  5163 
  5165 subsubsection \<open>@{text sorted_list_of_set}\<close>
  5164 subsubsection \<open>\<open>sorted_list_of_set\<close>\<close>
  5166 
  5165 
  5167 text\<open>This function maps (finite) linearly ordered sets to sorted
  5166 text\<open>This function maps (finite) linearly ordered sets to sorted
  5168 lists. Warning: in most cases it is not a good idea to convert from
  5167 lists. Warning: in most cases it is not a good idea to convert from
  5169 sets to lists but one should convert in the other direction (via
  5168 sets to lists but one should convert in the other direction (via
  5170 @{const set}).\<close>
  5169 @{const set}).\<close>
  5228 lemma sorted_list_of_set_range [simp]:
  5227 lemma sorted_list_of_set_range [simp]:
  5229   "sorted_list_of_set {m..<n} = [m..<n]"
  5228   "sorted_list_of_set {m..<n} = [m..<n]"
  5230   by (rule sorted_distinct_set_unique) simp_all
  5229   by (rule sorted_distinct_set_unique) simp_all
  5231 
  5230 
  5232 
  5231 
  5233 subsubsection \<open>@{text lists}: the list-forming operator over sets\<close>
  5232 subsubsection \<open>\<open>lists\<close>: the list-forming operator over sets\<close>
  5234 
  5233 
  5235 inductive_set
  5234 inductive_set
  5236   lists :: "'a set => 'a list set"
  5235   lists :: "'a set => 'a list set"
  5237   for A :: "'a set"
  5236   for A :: "'a set"
  5238 where
  5237 where
  5275 by (induct xs) auto
  5274 by (induct xs) auto
  5276 
  5275 
  5277 lemmas append_in_lists_conv [iff] = append_in_listsp_conv [to_set]
  5276 lemmas append_in_lists_conv [iff] = append_in_listsp_conv [to_set]
  5278 
  5277 
  5279 lemma in_listsp_conv_set: "(listsp A xs) = (\<forall>x \<in> set xs. A x)"
  5278 lemma in_listsp_conv_set: "(listsp A xs) = (\<forall>x \<in> set xs. A x)"
  5280 -- \<open>eliminate @{text listsp} in favour of @{text set}\<close>
  5279 \<comment> \<open>eliminate \<open>listsp\<close> in favour of \<open>set\<close>\<close>
  5281 by (induct xs) auto
  5280 by (induct xs) auto
  5282 
  5281 
  5283 lemmas in_lists_conv_set [code_unfold] = in_listsp_conv_set [to_set]
  5282 lemmas in_lists_conv_set [code_unfold] = in_listsp_conv_set [to_set]
  5284 
  5283 
  5285 lemma in_listspD [dest!]: "listsp A xs ==> \<forall>x\<in>set xs. A x"
  5284 lemma in_listspD [dest!]: "listsp A xs ==> \<forall>x\<in>set xs. A x"
  5324 done
  5323 done
  5325 
  5324 
  5326 
  5325 
  5327 subsubsection \<open>Lists as Cartesian products\<close>
  5326 subsubsection \<open>Lists as Cartesian products\<close>
  5328 
  5327 
  5329 text\<open>@{text"set_Cons A Xs"}: the set of lists with head drawn from
  5328 text\<open>\<open>set_Cons A Xs\<close>: the set of lists with head drawn from
  5330 @{term A} and tail drawn from @{term Xs}.\<close>
  5329 @{term A} and tail drawn from @{term Xs}.\<close>
  5331 
  5330 
  5332 definition set_Cons :: "'a set \<Rightarrow> 'a list set \<Rightarrow> 'a list set" where
  5331 definition set_Cons :: "'a set \<Rightarrow> 'a list set \<Rightarrow> 'a list set" where
  5333 "set_Cons A XS = {z. \<exists>x xs. z = x # xs \<and> x \<in> A \<and> xs \<in> XS}"
  5332 "set_Cons A XS = {z. \<exists>x xs. z = x # xs \<and> x \<in> A \<and> xs \<in> XS}"
  5334 
  5333 
  5348 subsubsection \<open>Length Lexicographic Ordering\<close>
  5347 subsubsection \<open>Length Lexicographic Ordering\<close>
  5349 
  5348 
  5350 text\<open>These orderings preserve well-foundedness: shorter lists 
  5349 text\<open>These orderings preserve well-foundedness: shorter lists 
  5351   precede longer lists. These ordering are not used in dictionaries.\<close>
  5350   precede longer lists. These ordering are not used in dictionaries.\<close>
  5352         
  5351         
  5353 primrec -- \<open>The lexicographic ordering for lists of the specified length\<close>
  5352 primrec \<comment> \<open>The lexicographic ordering for lists of the specified length\<close>
  5354   lexn :: "('a \<times> 'a) set \<Rightarrow> nat \<Rightarrow> ('a list \<times> 'a list) set" where
  5353   lexn :: "('a \<times> 'a) set \<Rightarrow> nat \<Rightarrow> ('a list \<times> 'a list) set" where
  5355 "lexn r 0 = {}" |
  5354 "lexn r 0 = {}" |
  5356 "lexn r (Suc n) =
  5355 "lexn r (Suc n) =
  5357   (map_prod (%(x, xs). x#xs) (%(x, xs). x#xs) ` (r <*lex*> lexn r n)) Int
  5356   (map_prod (%(x, xs). x#xs) (%(x, xs). x#xs) ` (r <*lex*> lexn r n)) Int
  5358   {(xs, ys). length xs = Suc n \<and> length ys = Suc n}"
  5357   {(xs, ys). length xs = Suc n \<and> length ys = Suc n}"
  5359 
  5358 
  5360 definition lex :: "('a \<times> 'a) set \<Rightarrow> ('a list \<times> 'a list) set" where
  5359 definition lex :: "('a \<times> 'a) set \<Rightarrow> ('a list \<times> 'a list) set" where
  5361 "lex r = (\<Union>n. lexn r n)" -- \<open>Holds only between lists of the same length\<close>
  5360 "lex r = (\<Union>n. lexn r n)" \<comment> \<open>Holds only between lists of the same length\<close>
  5362 
  5361 
  5363 definition lenlex :: "('a \<times> 'a) set => ('a list \<times> 'a list) set" where
  5362 definition lenlex :: "('a \<times> 'a) set => ('a list \<times> 'a list) set" where
  5364 "lenlex r = inv_image (less_than <*lex*> lex r) (\<lambda>xs. (length xs, xs))"
  5363 "lenlex r = inv_image (less_than <*lex*> lex r) (\<lambda>xs. (length xs, xs))"
  5365         -- \<open>Compares lists by their length and then lexicographically\<close>
  5364         \<comment> \<open>Compares lists by their length and then lexicographically\<close>
  5366 
  5365 
  5367 lemma wf_lexn: "wf r ==> wf (lexn r n)"
  5366 lemma wf_lexn: "wf r ==> wf (lexn r n)"
  5368 apply (induct n, simp, simp)
  5367 apply (induct n, simp, simp)
  5369 apply(rule wf_subset)
  5368 apply(rule wf_subset)
  5370  prefer 2 apply (rule Int_lower1)
  5369  prefer 2 apply (rule Int_lower1)
  5484   apply (rule_tac x="drop (Suc i) x" in exI)
  5483   apply (rule_tac x="drop (Suc i) x" in exI)
  5485   apply (drule sym, simp add: Cons_nth_drop_Suc) 
  5484   apply (drule sym, simp add: Cons_nth_drop_Suc) 
  5486   apply (rule_tac x="drop (Suc i) y" in exI)
  5485   apply (rule_tac x="drop (Suc i) y" in exI)
  5487   by (simp add: Cons_nth_drop_Suc) 
  5486   by (simp add: Cons_nth_drop_Suc) 
  5488 
  5487 
  5489 -- \<open>lexord is extension of partial ordering List.lex\<close> 
  5488 \<comment> \<open>lexord is extension of partial ordering List.lex\<close> 
  5490 lemma lexord_lex: "(x,y) \<in> lex r = ((x,y) \<in> lexord r \<and> length x = length y)"
  5489 lemma lexord_lex: "(x,y) \<in> lex r = ((x,y) \<in> lexord r \<and> length x = length y)"
  5491   apply (rule_tac x = y in spec) 
  5490   apply (rule_tac x = y in spec) 
  5492   apply (induct_tac x, clarsimp) 
  5491   apply (induct_tac x, clarsimp) 
  5493   by (clarify, case_tac x, simp, force)
  5492   by (clarify, case_tac x, simp, force)
  5494 
  5493 
  6157 
  6156 
  6158 definition member :: "'a list \<Rightarrow> 'a \<Rightarrow> bool" where
  6157 definition member :: "'a list \<Rightarrow> 'a \<Rightarrow> bool" where
  6159 [code_abbrev]: "member xs x \<longleftrightarrow> x \<in> set xs"
  6158 [code_abbrev]: "member xs x \<longleftrightarrow> x \<in> set xs"
  6160 
  6159 
  6161 text \<open>
  6160 text \<open>
  6162   Use @{text member} only for generating executable code.  Otherwise use
  6161   Use \<open>member\<close> only for generating executable code.  Otherwise use
  6163   @{prop "x \<in> set xs"} instead --- it is much easier to reason about.
  6162   @{prop "x \<in> set xs"} instead --- it is much easier to reason about.
  6164 \<close>
  6163 \<close>
  6165 
  6164 
  6166 lemma member_rec [code]:
  6165 lemma member_rec [code]:
  6167   "member (x # xs) y \<longleftrightarrow> x = y \<or> member xs y"
  6166   "member (x # xs) y \<longleftrightarrow> x = y \<or> member xs y"
  6182 
  6181 
  6183 definition list_ex1 :: "('a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> bool" where
  6182 definition list_ex1 :: "('a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> bool" where
  6184 list_ex1_iff [code_abbrev]: "list_ex1 P xs \<longleftrightarrow> (\<exists>! x. x \<in> set xs \<and> P x)"
  6183 list_ex1_iff [code_abbrev]: "list_ex1 P xs \<longleftrightarrow> (\<exists>! x. x \<in> set xs \<and> P x)"
  6185 
  6184 
  6186 text \<open>
  6185 text \<open>
  6187   Usually you should prefer @{text "\<forall>x\<in>set xs"}, @{text "\<exists>x\<in>set xs"}
  6186   Usually you should prefer \<open>\<forall>x\<in>set xs\<close>, \<open>\<exists>x\<in>set xs\<close>
  6188   and @{text "\<exists>!x. x\<in>set xs \<and> _"} over @{const list_all}, @{const list_ex}
  6187   and \<open>\<exists>!x. x\<in>set xs \<and> _\<close> over @{const list_all}, @{const list_ex}
  6189   and @{const list_ex1} in specifications.
  6188   and @{const list_ex1} in specifications.
  6190 \<close>
  6189 \<close>
  6191 
  6190 
  6192 lemma list_all_simps [code]:
  6191 lemma list_all_simps [code]:
  6193   "list_all P (x # xs) \<longleftrightarrow> P x \<and> list_all P xs"
  6192   "list_all P (x # xs) \<longleftrightarrow> P x \<and> list_all P xs"
  6320 
  6319 
  6321 lemma ex_nat_less [code_unfold]:
  6320 lemma ex_nat_less [code_unfold]:
  6322   "(\<exists>m\<le>n::nat. P m) \<longleftrightarrow> (\<exists>m \<in> {0..n}. P m)"
  6321   "(\<exists>m\<le>n::nat. P m) \<longleftrightarrow> (\<exists>m \<in> {0..n}. P m)"
  6323   by auto
  6322   by auto
  6324 
  6323 
  6325 text\<open>Bounded @{text LEAST} operator:\<close>
  6324 text\<open>Bounded \<open>LEAST\<close> operator:\<close>
  6326 
  6325 
  6327 definition "Bleast S P = (LEAST x. x \<in> S \<and> P x)"
  6326 definition "Bleast S P = (LEAST x. x \<in> S \<and> P x)"
  6328 
  6327 
  6329 definition "abort_Bleast S P = (LEAST x. x \<in> S \<and> P x)"
  6328 definition "abort_Bleast S P = (LEAST x. x \<in> S \<and> P x)"
  6330 
  6329 
  6420 
  6419 
  6421 lemma map_filter_map_filter [code_unfold]:
  6420 lemma map_filter_map_filter [code_unfold]:
  6422   "map f (filter P xs) = map_filter (\<lambda>x. if P x then Some (f x) else None) xs"
  6421   "map f (filter P xs) = map_filter (\<lambda>x. if P x then Some (f x) else None) xs"
  6423   by (simp add: map_filter_def)
  6422   by (simp add: map_filter_def)
  6424 
  6423 
  6425 text \<open>Optimized code for @{text"\<forall>i\<in>{a..b::int}"} and @{text"\<forall>n:{a..<b::nat}"}
  6424 text \<open>Optimized code for \<open>\<forall>i\<in>{a..b::int}\<close> and \<open>\<forall>n:{a..<b::nat}\<close>
  6426 and similiarly for @{text"\<exists>"}.\<close>
  6425 and similiarly for \<open>\<exists>\<close>.\<close>
  6427 
  6426 
  6428 definition all_interval_nat :: "(nat \<Rightarrow> bool) \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> bool" where
  6427 definition all_interval_nat :: "(nat \<Rightarrow> bool) \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> bool" where
  6429   "all_interval_nat P i j \<longleftrightarrow> (\<forall>n \<in> {i..<j}. P n)"
  6428   "all_interval_nat P i j \<longleftrightarrow> (\<forall>n \<in> {i..<j}. P n)"
  6430 
  6429 
  6431 lemma [code]:
  6430 lemma [code]: