src/ZF/List.thy
changeset 76215 a642599ffdea
parent 76214 0c18df79b1c8
child 76216 9fc34f76b4e8
equal deleted inserted replaced
76214:0c18df79b1c8 76215:a642599ffdea
     6 section\<open>Lists in Zermelo-Fraenkel Set Theory\<close>
     6 section\<open>Lists in Zermelo-Fraenkel Set Theory\<close>
     7 
     7 
     8 theory List imports Datatype ArithSimp begin
     8 theory List imports Datatype ArithSimp begin
     9 
     9 
    10 consts
    10 consts
    11   list       :: "i=>i"
    11   list       :: "i\<Rightarrow>i"
    12 
    12 
    13 datatype
    13 datatype
    14   "list(A)" = Nil | Cons ("a \<in> A", "l \<in> list(A)")
    14   "list(A)" = Nil | Cons ("a \<in> A", "l \<in> list(A)")
    15 
    15 
    16 
    16 
    17 syntax
    17 syntax
    18  "_Nil" :: i  (\<open>[]\<close>)
    18  "_Nil" :: i  (\<open>[]\<close>)
    19  "_List" :: "is => i"  (\<open>[(_)]\<close>)
    19  "_List" :: "is \<Rightarrow> i"  (\<open>[(_)]\<close>)
    20 
    20 
    21 translations
    21 translations
    22   "[x, xs]"     == "CONST Cons(x, [xs])"
    22   "[x, xs]"     == "CONST Cons(x, [xs])"
    23   "[x]"         == "CONST Cons(x, [])"
    23   "[x]"         == "CONST Cons(x, [])"
    24   "[]"          == "CONST Nil"
    24   "[]"          == "CONST Nil"
    25 
    25 
    26 
    26 
    27 consts
    27 consts
    28   length :: "i=>i"
    28   length :: "i\<Rightarrow>i"
    29   hd     :: "i=>i"
    29   hd     :: "i\<Rightarrow>i"
    30   tl     :: "i=>i"
    30   tl     :: "i\<Rightarrow>i"
    31 
    31 
    32 primrec
    32 primrec
    33   "length([]) = 0"
    33   "length([]) = 0"
    34   "length(Cons(a,l)) = succ(length(l))"
    34   "length(Cons(a,l)) = succ(length(l))"
    35 
    35 
    41   "tl([]) = []"
    41   "tl([]) = []"
    42   "tl(Cons(a,l)) = l"
    42   "tl(Cons(a,l)) = l"
    43 
    43 
    44 
    44 
    45 consts
    45 consts
    46   map         :: "[i=>i, i] => i"
    46   map         :: "[i\<Rightarrow>i, i] \<Rightarrow> i"
    47   set_of_list :: "i=>i"
    47   set_of_list :: "i\<Rightarrow>i"
    48   app         :: "[i,i]=>i"                        (infixr \<open>@\<close> 60)
    48   app         :: "[i,i]\<Rightarrow>i"                        (infixr \<open>@\<close> 60)
    49 
    49 
    50 (*map is a binding operator -- it applies to meta-level functions, not
    50 (*map is a binding operator -- it applies to meta-level functions, not
    51 object-level functions.  This simplifies the final form of term_rec_conv,
    51 object-level functions.  This simplifies the final form of term_rec_conv,
    52 although complicating its derivation.*)
    52 although complicating its derivation.*)
    53 primrec
    53 primrec
    62   app_Nil:  "[] @ ys = ys"
    62   app_Nil:  "[] @ ys = ys"
    63   app_Cons: "(Cons(a,l)) @ ys = Cons(a, l @ ys)"
    63   app_Cons: "(Cons(a,l)) @ ys = Cons(a, l @ ys)"
    64 
    64 
    65 
    65 
    66 consts
    66 consts
    67   rev :: "i=>i"
    67   rev :: "i\<Rightarrow>i"
    68   flat       :: "i=>i"
    68   flat       :: "i\<Rightarrow>i"
    69   list_add   :: "i=>i"
    69   list_add   :: "i\<Rightarrow>i"
    70 
    70 
    71 primrec
    71 primrec
    72   "rev([]) = []"
    72   "rev([]) = []"
    73   "rev(Cons(a,l)) = rev(l) @ [a]"
    73   "rev(Cons(a,l)) = rev(l) @ [a]"
    74 
    74 
    79 primrec
    79 primrec
    80   "list_add([]) = 0"
    80   "list_add([]) = 0"
    81   "list_add(Cons(a,l)) = a #+ list_add(l)"
    81   "list_add(Cons(a,l)) = a #+ list_add(l)"
    82 
    82 
    83 consts
    83 consts
    84   drop       :: "[i,i]=>i"
    84   drop       :: "[i,i]\<Rightarrow>i"
    85 
    85 
    86 primrec
    86 primrec
    87   drop_0:    "drop(0,l) = l"
    87   drop_0:    "drop(0,l) = l"
    88   drop_succ: "drop(succ(i), l) = tl (drop(i,l))"
    88   drop_succ: "drop(succ(i), l) = tl (drop(i,l))"
    89 
    89 
    90 
    90 
    91 (*** Thanks to Sidi Ehmety for the following ***)
    91 (*** Thanks to Sidi Ehmety for the following ***)
    92 
    92 
    93 definition
    93 definition
    94 (* Function `take' returns the first n elements of a list *)
    94 (* Function `take' returns the first n elements of a list *)
    95   take     :: "[i,i]=>i"  where
    95   take     :: "[i,i]\<Rightarrow>i"  where
    96   "take(n, as) \<equiv> list_rec(\<lambda>n\<in>nat. [],
    96   "take(n, as) \<equiv> list_rec(\<lambda>n\<in>nat. [],
    97                 %a l r. \<lambda>n\<in>nat. nat_case([], %m. Cons(a, r`m), n), as)`n"
    97                 \<lambda>a l r. \<lambda>n\<in>nat. nat_case([], \<lambda>m. Cons(a, r`m), n), as)`n"
    98 
    98 
    99 definition
    99 definition
   100   nth :: "[i, i]=>i"  where
   100   nth :: "[i, i]\<Rightarrow>i"  where
   101   \<comment> \<open>returns the (n+1)th element of a list, or 0 if the
   101   \<comment> \<open>returns the (n+1)th element of a list, or 0 if the
   102    list is too short.\<close>
   102    list is too short.\<close>
   103   "nth(n, as) \<equiv> list_rec(\<lambda>n\<in>nat. 0,
   103   "nth(n, as) \<equiv> list_rec(\<lambda>n\<in>nat. 0,
   104                           %a l r. \<lambda>n\<in>nat. nat_case(a, %m. r`m, n), as) ` n"
   104                           \<lambda>a l r. \<lambda>n\<in>nat. nat_case(a, \<lambda>m. r`m, n), as) ` n"
   105 
   105 
   106 definition
   106 definition
   107   list_update :: "[i, i, i]=>i"  where
   107   list_update :: "[i, i, i]\<Rightarrow>i"  where
   108   "list_update(xs, i, v) \<equiv> list_rec(\<lambda>n\<in>nat. Nil,
   108   "list_update(xs, i, v) \<equiv> list_rec(\<lambda>n\<in>nat. Nil,
   109       %u us vs. \<lambda>n\<in>nat. nat_case(Cons(v, us), %m. Cons(u, vs`m), n), xs)`i"
   109       \<lambda>u us vs. \<lambda>n\<in>nat. nat_case(Cons(v, us), \<lambda>m. Cons(u, vs`m), n), xs)`i"
   110 
   110 
   111 consts
   111 consts
   112   filter :: "[i=>o, i] => i"
   112   filter :: "[i\<Rightarrow>o, i] \<Rightarrow> i"
   113   upt :: "[i, i] =>i"
   113   upt :: "[i, i] \<Rightarrow>i"
   114 
   114 
   115 primrec
   115 primrec
   116   "filter(P, Nil) = Nil"
   116   "filter(P, Nil) = Nil"
   117   "filter(P, Cons(x, xs)) =
   117   "filter(P, Cons(x, xs)) =
   118      (if P(x) then Cons(x, filter(P, xs)) else filter(P, xs))"
   118      (if P(x) then Cons(x, filter(P, xs)) else filter(P, xs))"
   120 primrec
   120 primrec
   121   "upt(i, 0) = Nil"
   121   "upt(i, 0) = Nil"
   122   "upt(i, succ(j)) = (if i \<le> j then upt(i, j)@[j] else Nil)"
   122   "upt(i, succ(j)) = (if i \<le> j then upt(i, j)@[j] else Nil)"
   123 
   123 
   124 definition
   124 definition
   125   min :: "[i,i] =>i"  where
   125   min :: "[i,i] \<Rightarrow>i"  where
   126     "min(x, y) \<equiv> (if x \<le> y then x else y)"
   126     "min(x, y) \<equiv> (if x \<le> y then x else y)"
   127 
   127 
   128 definition
   128 definition
   129   max :: "[i, i] =>i"  where
   129   max :: "[i, i] \<Rightarrow>i"  where
   130     "max(x, y) \<equiv> (if x \<le> y then y else x)"
   130     "max(x, y) \<equiv> (if x \<le> y then y else x)"
   131 
   131 
   132 (*** Aspects of the datatype definition ***)
   132 (*** Aspects of the datatype definition ***)
   133 
   133 
   134 declare list.intros [simp,TC]
   134 declare list.intros [simp,TC]
   284 by (simp add: list_add_list_def)
   284 by (simp add: list_add_list_def)
   285 
   285 
   286 
   286 
   287 (*** theorems about map ***)
   287 (*** theorems about map ***)
   288 
   288 
   289 lemma map_ident [simp]: "l \<in> list(A) \<Longrightarrow> map(%u. u, l) = l"
   289 lemma map_ident [simp]: "l \<in> list(A) \<Longrightarrow> map(\<lambda>u. u, l) = l"
   290 apply (induct_tac "l")
   290 apply (induct_tac "l")
   291 apply (simp_all (no_asm_simp))
   291 apply (simp_all (no_asm_simp))
   292 done
   292 done
   293 
   293 
   294 lemma map_compose: "l \<in> list(A) \<Longrightarrow> map(h, map(j,l)) = map(%u. h(j(u)), l)"
   294 lemma map_compose: "l \<in> list(A) \<Longrightarrow> map(h, map(j,l)) = map(\<lambda>u. h(j(u)), l)"
   295 apply (induct_tac "l")
   295 apply (induct_tac "l")
   296 apply (simp_all (no_asm_simp))
   296 apply (simp_all (no_asm_simp))
   297 done
   297 done
   298 
   298 
   299 lemma map_app_distrib: "xs: list(A) \<Longrightarrow> map(h, xs@ys) = map(h,xs) @ map(h,ys)"
   299 lemma map_app_distrib: "xs: list(A) \<Longrightarrow> map(h, xs@ys) = map(h,xs) @ map(h,ys)"
   307 done
   307 done
   308 
   308 
   309 lemma list_rec_map:
   309 lemma list_rec_map:
   310      "l \<in> list(A) \<Longrightarrow>
   310      "l \<in> list(A) \<Longrightarrow>
   311       list_rec(c, d, map(h,l)) =
   311       list_rec(c, d, map(h,l)) =
   312       list_rec(c, %x xs r. d(h(x), map(h,xs), r), l)"
   312       list_rec(c, \<lambda>x xs r. d(h(x), map(h,xs), r), l)"
   313 apply (induct_tac "l")
   313 apply (induct_tac "l")
   314 apply (simp_all (no_asm_simp))
   314 apply (simp_all (no_asm_simp))
   315 done
   315 done
   316 
   316 
   317 (** theorems about list(Collect(A,P)) -- used in Induct/Term.thy **)
   317 (** theorems about list(Collect(A,P)) -- used in Induct/Term.thy **)
   508 done
   508 done
   509 
   509 
   510 lemma filter_is_subset: "xs:list(A) \<Longrightarrow> set_of_list(filter(P,xs)) \<subseteq> set_of_list(xs)"
   510 lemma filter_is_subset: "xs:list(A) \<Longrightarrow> set_of_list(filter(P,xs)) \<subseteq> set_of_list(xs)"
   511 by (induct_tac "xs", auto)
   511 by (induct_tac "xs", auto)
   512 
   512 
   513 lemma filter_False [simp]: "xs:list(A) \<Longrightarrow> filter(%p. False, xs) = Nil"
   513 lemma filter_False [simp]: "xs:list(A) \<Longrightarrow> filter(\<lambda>p. False, xs) = Nil"
   514 by (induct_tac "xs", auto)
   514 by (induct_tac "xs", auto)
   515 
   515 
   516 lemma filter_True [simp]: "xs:list(A) \<Longrightarrow> filter(%p. True, xs) = xs"
   516 lemma filter_True [simp]: "xs:list(A) \<Longrightarrow> filter(\<lambda>p. True, xs) = xs"
   517 by (induct_tac "xs", auto)
   517 by (induct_tac "xs", auto)
   518 
   518 
   519 (** length **)
   519 (** length **)
   520 
   520 
   521 lemma length_is_0_iff [simp]: "xs:list(A) \<Longrightarrow> length(xs)=0 \<longleftrightarrow> xs=Nil"
   521 lemma length_is_0_iff [simp]: "xs:list(A) \<Longrightarrow> length(xs)=0 \<longleftrightarrow> xs=Nil"
   851 subsection\<open>The function zip\<close>
   851 subsection\<open>The function zip\<close>
   852 
   852 
   853 text\<open>Crafty definition to eliminate a type argument\<close>
   853 text\<open>Crafty definition to eliminate a type argument\<close>
   854 
   854 
   855 consts
   855 consts
   856   zip_aux        :: "[i,i]=>i"
   856   zip_aux        :: "[i,i]\<Rightarrow>i"
   857 
   857 
   858 primrec (*explicit lambda is required because both arguments of "un" vary*)
   858 primrec (*explicit lambda is required because both arguments of "un" vary*)
   859   "zip_aux(B,[]) =
   859   "zip_aux(B,[]) =
   860      (\<lambda>ys \<in> list(B). list_case([], %y l. [], ys))"
   860      (\<lambda>ys \<in> list(B). list_case([], \<lambda>y l. [], ys))"
   861 
   861 
   862   "zip_aux(B,Cons(x,l)) =
   862   "zip_aux(B,Cons(x,l)) =
   863      (\<lambda>ys \<in> list(B).
   863      (\<lambda>ys \<in> list(B).
   864         list_case(Nil, %y zs. Cons(<x,y>, zip_aux(B,l)`zs), ys))"
   864         list_case(Nil, \<lambda>y zs. Cons(\<langle>x,y\<rangle>, zip_aux(B,l)`zs), ys))"
   865 
   865 
   866 definition
   866 definition
   867   zip :: "[i, i]=>i"  where
   867   zip :: "[i, i]\<Rightarrow>i"  where
   868    "zip(xs, ys) \<equiv> zip_aux(set_of_list(ys),xs)`ys"
   868    "zip(xs, ys) \<equiv> zip_aux(set_of_list(ys),xs)`ys"
   869 
   869 
   870 
   870 
   871 (* zip equations *)
   871 (* zip equations *)
   872 
   872 
   895 apply (blast intro: list_mono [THEN subsetD])
   895 apply (blast intro: list_mono [THEN subsetD])
   896 done
   896 done
   897 
   897 
   898 lemma zip_Cons_Cons [simp]:
   898 lemma zip_Cons_Cons [simp]:
   899      "\<lbrakk>xs:list(A); ys:list(B); x \<in> A; y \<in> B\<rbrakk> \<Longrightarrow>
   899      "\<lbrakk>xs:list(A); ys:list(B); x \<in> A; y \<in> B\<rbrakk> \<Longrightarrow>
   900       zip(Cons(x,xs), Cons(y, ys)) = Cons(<x,y>, zip(xs, ys))"
   900       zip(Cons(x,xs), Cons(y, ys)) = Cons(\<langle>x,y\<rangle>, zip(xs, ys))"
   901 apply (simp add: zip_def, auto)
   901 apply (simp add: zip_def, auto)
   902 apply (rule zip_aux_unique, auto)
   902 apply (rule zip_aux_unique, auto)
   903 apply (simp add: list_on_set_of_list [of _ B])
   903 apply (simp add: list_on_set_of_list [of _ B])
   904 apply (blast intro: list_on_set_of_list list_mono [THEN subsetD])
   904 apply (blast intro: list_on_set_of_list list_mono [THEN subsetD])
   905 done
   905 done
   965 declare nth_zip [simp]
   965 declare nth_zip [simp]
   966 
   966 
   967 lemma set_of_list_zip [rule_format]:
   967 lemma set_of_list_zip [rule_format]:
   968      "\<lbrakk>xs:list(A); ys:list(B); i \<in> nat\<rbrakk>
   968      "\<lbrakk>xs:list(A); ys:list(B); i \<in> nat\<rbrakk>
   969       \<Longrightarrow> set_of_list(zip(xs, ys)) =
   969       \<Longrightarrow> set_of_list(zip(xs, ys)) =
   970           {<x, y>:A*B. \<exists>i\<in>nat. i < min(length(xs), length(ys))
   970           {\<langle>x, y\<rangle>:A*B. \<exists>i\<in>nat. i < min(length(xs), length(ys))
   971           \<and> x = nth(i, xs) \<and> y = nth(i, ys)}"
   971           \<and> x = nth(i, xs) \<and> y = nth(i, ys)}"
   972 by (force intro!: Collect_cong simp add: lt_min_iff set_of_list_conv_nth)
   972 by (force intro!: Collect_cong simp add: lt_min_iff set_of_list_conv_nth)
   973 
   973 
   974 (** list_update **)
   974 (** list_update **)
   975 
   975 
  1177 done
  1177 done
  1178 
  1178 
  1179 (** sublist (a generalization of nth to sets) **)
  1179 (** sublist (a generalization of nth to sets) **)
  1180 
  1180 
  1181 definition
  1181 definition
  1182   sublist :: "[i, i] => i"  where
  1182   sublist :: "[i, i] \<Rightarrow> i"  where
  1183     "sublist(xs, A)\<equiv>
  1183     "sublist(xs, A)\<equiv>
  1184      map(fst, (filter(%p. snd(p): A, zip(xs, upt(0,length(xs))))))"
  1184      map(fst, (filter(\<lambda>p. snd(p): A, zip(xs, upt(0,length(xs))))))"
  1185 
  1185 
  1186 lemma sublist_0 [simp]: "xs:list(A) \<Longrightarrow>sublist(xs, 0) =Nil"
  1186 lemma sublist_0 [simp]: "xs:list(A) \<Longrightarrow>sublist(xs, 0) =Nil"
  1187 by (unfold sublist_def, auto)
  1187 by (unfold sublist_def, auto)
  1188 
  1188 
  1189 lemma sublist_Nil [simp]: "sublist(Nil, A) = Nil"
  1189 lemma sublist_Nil [simp]: "sublist(Nil, A) = Nil"
  1190 by (unfold sublist_def, auto)
  1190 by (unfold sublist_def, auto)
  1191 
  1191 
  1192 lemma sublist_shift_lemma:
  1192 lemma sublist_shift_lemma:
  1193  "\<lbrakk>xs:list(B); i \<in> nat\<rbrakk> \<Longrightarrow>
  1193  "\<lbrakk>xs:list(B); i \<in> nat\<rbrakk> \<Longrightarrow>
  1194   map(fst, filter(%p. snd(p):A, zip(xs, upt(i,i #+ length(xs))))) =
  1194   map(fst, filter(\<lambda>p. snd(p):A, zip(xs, upt(i,i #+ length(xs))))) =
  1195   map(fst, filter(%p. snd(p):nat \<and> snd(p) #+ i \<in> A, zip(xs,upt(0,length(xs)))))"
  1195   map(fst, filter(\<lambda>p. snd(p):nat \<and> snd(p) #+ i \<in> A, zip(xs,upt(0,length(xs)))))"
  1196 apply (erule list_append_induct)
  1196 apply (erule list_append_induct)
  1197 apply (simp (no_asm_simp))
  1197 apply (simp (no_asm_simp))
  1198 apply (auto simp add: add_commute length_app filter_append map_app_distrib)
  1198 apply (auto simp add: add_commute length_app filter_append map_app_distrib)
  1199 done
  1199 done
  1200 
  1200 
  1248 apply (simp_all add: sublist_Cons)
  1248 apply (simp_all add: sublist_Cons)
  1249 done
  1249 done
  1250 
  1250 
  1251 text\<open>Repetition of a List Element\<close>
  1251 text\<open>Repetition of a List Element\<close>
  1252 
  1252 
  1253 consts   repeat :: "[i,i]=>i"
  1253 consts   repeat :: "[i,i]\<Rightarrow>i"
  1254 primrec
  1254 primrec
  1255   "repeat(a,0) = []"
  1255   "repeat(a,0) = []"
  1256 
  1256 
  1257   "repeat(a,succ(n)) = Cons(a,repeat(a,n))"
  1257   "repeat(a,succ(n)) = Cons(a,repeat(a,n))"
  1258 
  1258