src/HOL/List.thy
changeset 24349 0dd8782fb02d
parent 24335 21b4350cf5ec
child 24449 2f05cb7fed85
equal deleted inserted replaced
24348:c708ea5b109a 24349:0dd8782fb02d
   220   "splice (x#xs) ys = (if ys=[] then x#xs else x # hd ys # splice xs (tl ys))"
   220   "splice (x#xs) ys = (if ys=[] then x#xs else x # hd ys # splice xs (tl ys))"
   221     -- {*Warning: simpset does not contain the second eqn but a derived one. *}
   221     -- {*Warning: simpset does not contain the second eqn but a derived one. *}
   222 
   222 
   223 subsubsection {* List comprehension *}
   223 subsubsection {* List comprehension *}
   224 
   224 
   225 text{* Input syntax for Haskell-like list comprehension
   225 text{* Input syntax for Haskell-like list comprehension notation.
   226 notation. Typical example: @{text"[(x,y). x \<leftarrow> xs, y \<leftarrow> ys, x \<noteq> y]"}, the list of all pairs of distinct elements from @{text xs} and @{text ys}.
   226 Typical example: @{text"[(x,y). x \<leftarrow> xs, y \<leftarrow> ys, x \<noteq> y]"},
   227 
   227 the list of all pairs of distinct elements from @{text xs} and @{text ys}.
   228 There are two differences to Haskell.  The general synatx is
   228 The syntax is as in Haskell, except that @{text"|"} becomes a dot
   229 @{text"[e. p \<leftarrow> xs, \<dots>]"} rather than \verb![x| x <- xs, ...]!. Patterns in
   229 (like in Isabelle's set comprehension): @{text"[e. x \<leftarrow> xs, \<dots>]"} rather than
   230 generators can only be tuples (at the moment).
   230 \verb![e| x <- xs, ...]!.
       
   231 
       
   232 The qualifiers after the dot are
       
   233 \begin{description}
       
   234 \item[generators] @{text"p \<leftarrow> xs"},
       
   235  where @{text p} is a pattern and @{text xs} an expression of list type,
       
   236 \item[guards] @{text"b"}, where @{text b} is a boolean expression, or
       
   237 \item[local bindings] @{text"let x = e"}.
       
   238 \end{description}
   231 
   239 
   232 To avoid misunderstandings, the translation is not reversed upon
   240 To avoid misunderstandings, the translation is not reversed upon
   233 output. You can add the inverse translations in your own theory if you
   241 output. You can add the inverse translations in your own theory if you
   234 desire.
   242 desire.
   235 
   243 
   236 Hint: formulae containing complex list comprehensions may become quite
   244 It is easy to write short list comprehensions which stand for complex
   237 unreadable after the simplifier has finished with them. It can be
   245 expressions. During proofs, they may become unreadable (and
   238 helpful to introduce definitions for such list comprehensions and
   246 mangled). In such cases it can be advisable to introduce separate
   239 treat them separately in suitable lemmas.
   247 definitions for the list comprehensions in question.  *}
   240 *}
   248 
   241 (*
   249 (*
   242 Proper theorem proving support would be nice. For example, if
   250 Proper theorem proving support would be nice. For example, if
   243 @{text"set[f x y. x \<leftarrow> xs, y \<leftarrow> ys, P x y]"}
   251 @{text"set[f x y. x \<leftarrow> xs, y \<leftarrow> ys, P x y]"}
   244 produced something like
   252 produced something like
   245 @{term"{z. EX x: set xs. EX y:set ys. P x y \<and> z = f x y}"}.
   253 @{term"{z. EX x: set xs. EX y:set ys. P x y \<and> z = f x y}"}.
   247 
   255 
   248 nonterminals lc_qual lc_quals
   256 nonterminals lc_qual lc_quals
   249 
   257 
   250 syntax
   258 syntax
   251 "_listcompr" :: "'a \<Rightarrow> lc_qual \<Rightarrow> lc_quals \<Rightarrow> 'a list"  ("[_ . __")
   259 "_listcompr" :: "'a \<Rightarrow> lc_qual \<Rightarrow> lc_quals \<Rightarrow> 'a list"  ("[_ . __")
   252 "_lc_gen" :: "pttrn \<Rightarrow> 'a list \<Rightarrow> lc_qual" ("_ <- _")
   260 "_lc_gen" :: "'a \<Rightarrow> 'a list \<Rightarrow> lc_qual" ("_ <- _")
   253 "_lc_test" :: "bool \<Rightarrow> lc_qual" ("_")
   261 "_lc_test" :: "bool \<Rightarrow> lc_qual" ("_")
       
   262 "_lc_let" :: "letbinds => lc_qual"  ("let _")
   254 "_lc_end" :: "lc_quals" ("]")
   263 "_lc_end" :: "lc_quals" ("]")
   255 "_lc_quals" :: "lc_qual \<Rightarrow> lc_quals \<Rightarrow> lc_quals" (", __")
   264 "_lc_quals" :: "lc_qual \<Rightarrow> lc_quals \<Rightarrow> lc_quals" (", __")
       
   265 "_lc_abs" :: "'a => 'b list => 'b list"
   256 
   266 
   257 translations
   267 translations
   258 "[e. p<-xs]" => "map (%p. e) xs"
   268 "[e. p<-xs]" => "concat(map (_lc_abs p [e]) xs)"
   259 "_listcompr e (_lc_gen p xs) (_lc_quals Q Qs)"
   269 "_listcompr e (_lc_gen p xs) (_lc_quals Q Qs)"
   260  => "concat (map (%p. _listcompr e Q Qs) xs)"
   270  => "concat (map (_lc_abs p (_listcompr e Q Qs)) xs)"
   261 "[e. P]" => "if P then [e] else []"
   271 "[e. P]" => "if P then [e] else []"
   262 "_listcompr e (_lc_test P) (_lc_quals Q Qs)"
   272 "_listcompr e (_lc_test P) (_lc_quals Q Qs)"
   263  => "if P then (_listcompr e Q Qs) else []"
   273  => "if P then (_listcompr e Q Qs) else []"
       
   274 "_listcompr e (_lc_let b) (_lc_quals Q Qs)"
       
   275  => "_Let b (_listcompr e Q Qs)"
   264 
   276 
   265 syntax (xsymbols)
   277 syntax (xsymbols)
   266 "_lc_gen" :: "pttrn \<Rightarrow> 'a list \<Rightarrow> lc_qual" ("_ \<leftarrow> _")
   278 "_lc_gen" :: "'a \<Rightarrow> 'a list \<Rightarrow> lc_qual" ("_ \<leftarrow> _")
   267 syntax (HTML output)
   279 syntax (HTML output)
   268 "_lc_gen" :: "pttrn \<Rightarrow> 'a list \<Rightarrow> lc_qual" ("_ \<leftarrow> _")
   280 "_lc_gen" :: "'a \<Rightarrow> 'a list \<Rightarrow> lc_qual" ("_ \<leftarrow> _")
   269 
   281 
       
   282 parse_translation (advanced) {*
       
   283 let
       
   284 
       
   285    fun abs_tr0 ctxt p es =
       
   286     let
       
   287       val x = Free (Name.variant (add_term_free_names (p$es, [])) "x", dummyT);
       
   288       val case1 = Syntax.const "_case1" $ p $ es;
       
   289       val case2 = Syntax.const "_case1" $ Syntax.const Term.dummy_patternN
       
   290                                         $ Syntax.const @{const_name Nil};
       
   291       val cs = Syntax.const "_case2" $ case1 $ case2
       
   292       val ft = DatatypeCase.case_tr false DatatypePackage.datatype_of_constr
       
   293                  ctxt [x, cs]
       
   294     in lambda x ft end;
       
   295 
       
   296   fun abs_tr ctxt [x as Free (s, T), r] =
       
   297         let val thy = ProofContext.theory_of ctxt;
       
   298             val s' = Sign.intern_const thy s
       
   299         in if Sign.declared_const thy s' then abs_tr0 ctxt x r else lambda x r
       
   300         end
       
   301    | abs_tr ctxt [p,es] = abs_tr0 ctxt p es
       
   302 
       
   303 in [("_lc_abs", abs_tr)] end
       
   304 *}
   270 
   305 
   271 (*
   306 (*
   272 term "[(x,y,z). b]"
   307 term "[(x,y,z). b]"
   273 term "[(x,y,z). x \<leftarrow> xs]"
   308 term "[(x,y). Cons True x \<leftarrow> xs]"
       
   309 term "[(x,y,z). Cons x [] \<leftarrow> xs]"
   274 term "[(x,y,z). x<a, x>b]"
   310 term "[(x,y,z). x<a, x>b]"
   275 term "[(x,y,z). x<a, x\<leftarrow>xs]"
   311 term "[(x,y,z). x<a, x\<leftarrow>xs]"
   276 term "[(x,y,z). x\<leftarrow>xs, x>b]"
   312 term "[(x,y,z). x\<leftarrow>xs, x>b]"
   277 term "[(x,y,z). x\<leftarrow>xs, y\<leftarrow>ys]"
   313 term "[(x,y,z). x\<leftarrow>xs, y\<leftarrow>ys]"
   278 term "[(x,y,z). x<a, x>b, x=d]"
   314 term "[(x,y,z). x<a, x>b, x=d]"
   281 term "[(x,y,z). x<a, x\<leftarrow>xs, y\<leftarrow>ys]"
   317 term "[(x,y,z). x<a, x\<leftarrow>xs, y\<leftarrow>ys]"
   282 term "[(x,y,z). x\<leftarrow>xs, x>b, y<a]"
   318 term "[(x,y,z). x\<leftarrow>xs, x>b, y<a]"
   283 term "[(x,y,z). x\<leftarrow>xs, x>b, y\<leftarrow>ys]"
   319 term "[(x,y,z). x\<leftarrow>xs, x>b, y\<leftarrow>ys]"
   284 term "[(x,y,z). x\<leftarrow>xs, y\<leftarrow>ys,y>x]"
   320 term "[(x,y,z). x\<leftarrow>xs, y\<leftarrow>ys,y>x]"
   285 term "[(x,y,z). x\<leftarrow>xs, y\<leftarrow>ys,z\<leftarrow>zs]"
   321 term "[(x,y,z). x\<leftarrow>xs, y\<leftarrow>ys,z\<leftarrow>zs]"
       
   322 term "[(x,y). x\<leftarrow>xs, let xx = x+x, y\<leftarrow>ys, y \<noteq> xx]"
   286 *)
   323 *)
   287 
       
   288 
   324 
   289 subsubsection {* @{const Nil} and @{const Cons} *}
   325 subsubsection {* @{const Nil} and @{const Cons} *}
   290 
   326 
   291 lemma not_Cons_self [simp]:
   327 lemma not_Cons_self [simp]:
   292   "xs \<noteq> x # xs"
   328   "xs \<noteq> x # xs"
   365    \<And>x xs y ys. P xs ys  \<Longrightarrow> P (x#xs) (y#ys) \<rbrakk>
   401    \<And>x xs y ys. P xs ys  \<Longrightarrow> P (x#xs) (y#ys) \<rbrakk>
   366  \<Longrightarrow> P xs ys"
   402  \<Longrightarrow> P xs ys"
   367 by (induct xs arbitrary: ys) (case_tac x, auto)+
   403 by (induct xs arbitrary: ys) (case_tac x, auto)+
   368 
   404 
   369 lemma neq_if_length_neq: "length xs \<noteq> length ys \<Longrightarrow> (xs = ys) == False"
   405 lemma neq_if_length_neq: "length xs \<noteq> length ys \<Longrightarrow> (xs = ys) == False"
   370   by (rule Eq_FalseI) auto
   406 by (rule Eq_FalseI) auto
   371 
   407 
   372 simproc_setup list_neq ("(xs::'a list) = ys") = {*
   408 simproc_setup list_neq ("(xs::'a list) = ys") = {*
   373 (*
   409 (*
   374 Reduces xs=ys to False if xs and ys cannot be of the same length.
   410 Reduces xs=ys to False if xs and ys cannot be of the same length.
   375 This is the case if the atomic sublists of one are a submultiset
   411 This is the case if the atomic sublists of one are a submultiset
   833 
   869 
   834 lemma filter_False [simp]: "\<forall>x \<in> set xs. \<not> P x ==> filter P xs = []"
   870 lemma filter_False [simp]: "\<forall>x \<in> set xs. \<not> P x ==> filter P xs = []"
   835 by (induct xs) auto
   871 by (induct xs) auto
   836 
   872 
   837 lemma filter_empty_conv: "(filter P xs = []) = (\<forall>x\<in>set xs. \<not> P x)" 
   873 lemma filter_empty_conv: "(filter P xs = []) = (\<forall>x\<in>set xs. \<not> P x)" 
   838   by (induct xs) simp_all
   874 by (induct xs) simp_all
   839 
   875 
   840 lemma filter_id_conv: "(filter P xs = xs) = (\<forall>x\<in>set xs. P x)"
   876 lemma filter_id_conv: "(filter P xs = xs) = (\<forall>x\<in>set xs. P x)"
   841 apply (induct xs)
   877 apply (induct xs)
   842  apply auto
   878  apply auto
   843 apply(cut_tac P=P and xs=xs in length_filter_le)
   879 apply(cut_tac P=P and xs=xs in length_filter_le)
   961 by (induct xss) auto
   997 by (induct xss) auto
   962 
   998 
   963 lemma set_concat [simp]: "set (concat xs) = (UN x:set xs. set x)"
   999 lemma set_concat [simp]: "set (concat xs) = (UN x:set xs. set x)"
   964 by (induct xs) auto
  1000 by (induct xs) auto
   965 
  1001 
       
  1002 lemma concat_map_singleton[simp, code]: "concat(map (%x. [f x]) xs) = map f xs"
       
  1003 by (induct xs) auto
       
  1004 
   966 lemma map_concat: "map f (concat xs) = concat (map (map f) xs)"
  1005 lemma map_concat: "map f (concat xs) = concat (map (map f) xs)"
   967 by (induct xs) auto
  1006 by (induct xs) auto
   968 
  1007 
   969 lemma filter_concat: "filter p (concat xs) = concat (map (filter p) xs)"
  1008 lemma filter_concat: "filter p (concat xs) = concat (map (filter p) xs)"
   970 by (induct xs) auto
  1009 by (induct xs) auto
  1430 done
  1469 done
  1431 
  1470 
  1432 lemma takeWhile_cong [fundef_cong, recdef_cong]:
  1471 lemma takeWhile_cong [fundef_cong, recdef_cong]:
  1433   "[| l = k; !!x. x : set l ==> P x = Q x |] 
  1472   "[| l = k; !!x. x : set l ==> P x = Q x |] 
  1434   ==> takeWhile P l = takeWhile Q k"
  1473   ==> takeWhile P l = takeWhile Q k"
  1435   by (induct k arbitrary: l) (simp_all)
  1474 by (induct k arbitrary: l) (simp_all)
  1436 
  1475 
  1437 lemma dropWhile_cong [fundef_cong, recdef_cong]:
  1476 lemma dropWhile_cong [fundef_cong, recdef_cong]:
  1438   "[| l = k; !!x. x : set l ==> P x = Q x |] 
  1477   "[| l = k; !!x. x : set l ==> P x = Q x |] 
  1439   ==> dropWhile P l = dropWhile Q k"
  1478   ==> dropWhile P l = dropWhile Q k"
  1440   by (induct k arbitrary: l, simp_all)
  1479 by (induct k arbitrary: l, simp_all)
  1441 
  1480 
  1442 
  1481 
  1443 subsubsection {* @{text zip} *}
  1482 subsubsection {* @{text zip} *}
  1444 
  1483 
  1445 lemma zip_Nil [simp]: "zip [] ys = []"
  1484 lemma zip_Nil [simp]: "zip [] ys = []"
  1542 
  1581 
  1543 subsubsection {* @{text list_all2} *}
  1582 subsubsection {* @{text list_all2} *}
  1544 
  1583 
  1545 lemma list_all2_lengthD [intro?]: 
  1584 lemma list_all2_lengthD [intro?]: 
  1546   "list_all2 P xs ys ==> length xs = length ys"
  1585   "list_all2 P xs ys ==> length xs = length ys"
  1547   by (simp add: list_all2_def)
  1586 by (simp add: list_all2_def)
  1548 
  1587 
  1549 lemma list_all2_Nil [iff, code]: "list_all2 P [] ys = (ys = [])"
  1588 lemma list_all2_Nil [iff, code]: "list_all2 P [] ys = (ys = [])"
  1550   by (simp add: list_all2_def)
  1589 by (simp add: list_all2_def)
  1551 
  1590 
  1552 lemma list_all2_Nil2 [iff, code]: "list_all2 P xs [] = (xs = [])"
  1591 lemma list_all2_Nil2 [iff, code]: "list_all2 P xs [] = (xs = [])"
  1553   by (simp add: list_all2_def)
  1592 by (simp add: list_all2_def)
  1554 
  1593 
  1555 lemma list_all2_Cons [iff, code]:
  1594 lemma list_all2_Cons [iff, code]:
  1556   "list_all2 P (x # xs) (y # ys) = (P x y \<and> list_all2 P xs ys)"
  1595   "list_all2 P (x # xs) (y # ys) = (P x y \<and> list_all2 P xs ys)"
  1557   by (auto simp add: list_all2_def)
  1596 by (auto simp add: list_all2_def)
  1558 
  1597 
  1559 lemma list_all2_Cons1:
  1598 lemma list_all2_Cons1:
  1560 "list_all2 P (x # xs) ys = (\<exists>z zs. ys = z # zs \<and> P x z \<and> list_all2 P xs zs)"
  1599 "list_all2 P (x # xs) ys = (\<exists>z zs. ys = z # zs \<and> P x z \<and> list_all2 P xs zs)"
  1561 by (cases ys) auto
  1600 by (cases ys) auto
  1562 
  1601 
  1601   list_all2 P (xs@us) (ys@vs) = (list_all2 P xs ys \<and> list_all2 P us vs)"
  1640   list_all2 P (xs@us) (ys@vs) = (list_all2 P xs ys \<and> list_all2 P us vs)"
  1602 by (induct rule:list_induct2, simp_all)
  1641 by (induct rule:list_induct2, simp_all)
  1603 
  1642 
  1604 lemma list_all2_appendI [intro?, trans]:
  1643 lemma list_all2_appendI [intro?, trans]:
  1605   "\<lbrakk> list_all2 P a b; list_all2 P c d \<rbrakk> \<Longrightarrow> list_all2 P (a@c) (b@d)"
  1644   "\<lbrakk> list_all2 P a b; list_all2 P c d \<rbrakk> \<Longrightarrow> list_all2 P (a@c) (b@d)"
  1606   by (simp add: list_all2_append list_all2_lengthD)
  1645 by (simp add: list_all2_append list_all2_lengthD)
  1607 
  1646 
  1608 lemma list_all2_conv_all_nth:
  1647 lemma list_all2_conv_all_nth:
  1609 "list_all2 P xs ys =
  1648 "list_all2 P xs ys =
  1610 (length xs = length ys \<and> (\<forall>i < length xs. P (xs!i) (ys!i)))"
  1649 (length xs = length ys \<and> (\<forall>i < length xs. P (xs!i) (ys!i)))"
  1611 by (force simp add: list_all2_def set_zip)
  1650 by (force simp add: list_all2_def set_zip)
  1624   qed simp
  1663   qed simp
  1625 qed simp
  1664 qed simp
  1626 
  1665 
  1627 lemma list_all2_all_nthI [intro?]:
  1666 lemma list_all2_all_nthI [intro?]:
  1628   "length a = length b \<Longrightarrow> (\<And>n. n < length a \<Longrightarrow> P (a!n) (b!n)) \<Longrightarrow> list_all2 P a b"
  1667   "length a = length b \<Longrightarrow> (\<And>n. n < length a \<Longrightarrow> P (a!n) (b!n)) \<Longrightarrow> list_all2 P a b"
  1629   by (simp add: list_all2_conv_all_nth)
  1668 by (simp add: list_all2_conv_all_nth)
  1630 
  1669 
  1631 lemma list_all2I:
  1670 lemma list_all2I:
  1632   "\<forall>x \<in> set (zip a b). split P x \<Longrightarrow> length a = length b \<Longrightarrow> list_all2 P a b"
  1671   "\<forall>x \<in> set (zip a b). split P x \<Longrightarrow> length a = length b \<Longrightarrow> list_all2 P a b"
  1633   by (simp add: list_all2_def)
  1672 by (simp add: list_all2_def)
  1634 
  1673 
  1635 lemma list_all2_nthD:
  1674 lemma list_all2_nthD:
  1636   "\<lbrakk> list_all2 P xs ys; p < size xs \<rbrakk> \<Longrightarrow> P (xs!p) (ys!p)"
  1675   "\<lbrakk> list_all2 P xs ys; p < size xs \<rbrakk> \<Longrightarrow> P (xs!p) (ys!p)"
  1637   by (simp add: list_all2_conv_all_nth)
  1676 by (simp add: list_all2_conv_all_nth)
  1638 
  1677 
  1639 lemma list_all2_nthD2:
  1678 lemma list_all2_nthD2:
  1640   "\<lbrakk>list_all2 P xs ys; p < size ys\<rbrakk> \<Longrightarrow> P (xs!p) (ys!p)"
  1679   "\<lbrakk>list_all2 P xs ys; p < size ys\<rbrakk> \<Longrightarrow> P (xs!p) (ys!p)"
  1641   by (frule list_all2_lengthD) (auto intro: list_all2_nthD)
  1680 by (frule list_all2_lengthD) (auto intro: list_all2_nthD)
  1642 
  1681 
  1643 lemma list_all2_map1: 
  1682 lemma list_all2_map1: 
  1644   "list_all2 P (map f as) bs = list_all2 (\<lambda>x y. P (f x) y) as bs"
  1683   "list_all2 P (map f as) bs = list_all2 (\<lambda>x y. P (f x) y) as bs"
  1645   by (simp add: list_all2_conv_all_nth)
  1684 by (simp add: list_all2_conv_all_nth)
  1646 
  1685 
  1647 lemma list_all2_map2: 
  1686 lemma list_all2_map2: 
  1648   "list_all2 P as (map f bs) = list_all2 (\<lambda>x y. P x (f y)) as bs"
  1687   "list_all2 P as (map f bs) = list_all2 (\<lambda>x y. P x (f y)) as bs"
  1649   by (auto simp add: list_all2_conv_all_nth)
  1688 by (auto simp add: list_all2_conv_all_nth)
  1650 
  1689 
  1651 lemma list_all2_refl [intro?]:
  1690 lemma list_all2_refl [intro?]:
  1652   "(\<And>x. P x x) \<Longrightarrow> list_all2 P xs xs"
  1691   "(\<And>x. P x x) \<Longrightarrow> list_all2 P xs xs"
  1653   by (simp add: list_all2_conv_all_nth)
  1692 by (simp add: list_all2_conv_all_nth)
  1654 
  1693 
  1655 lemma list_all2_update_cong:
  1694 lemma list_all2_update_cong:
  1656   "\<lbrakk> i<size xs; list_all2 P xs ys; P x y \<rbrakk> \<Longrightarrow> list_all2 P (xs[i:=x]) (ys[i:=y])"
  1695   "\<lbrakk> i<size xs; list_all2 P xs ys; P x y \<rbrakk> \<Longrightarrow> list_all2 P (xs[i:=x]) (ys[i:=y])"
  1657   by (simp add: list_all2_conv_all_nth nth_list_update)
  1696 by (simp add: list_all2_conv_all_nth nth_list_update)
  1658 
  1697 
  1659 lemma list_all2_update_cong2:
  1698 lemma list_all2_update_cong2:
  1660   "\<lbrakk>list_all2 P xs ys; P x y; i < length ys\<rbrakk> \<Longrightarrow> list_all2 P (xs[i:=x]) (ys[i:=y])"
  1699   "\<lbrakk>list_all2 P xs ys; P x y; i < length ys\<rbrakk> \<Longrightarrow> list_all2 P (xs[i:=x]) (ys[i:=y])"
  1661   by (simp add: list_all2_lengthD list_all2_update_cong)
  1700 by (simp add: list_all2_lengthD list_all2_update_cong)
  1662 
  1701 
  1663 lemma list_all2_takeI [simp,intro?]:
  1702 lemma list_all2_takeI [simp,intro?]:
  1664   "\<And>n ys. list_all2 P xs ys \<Longrightarrow> list_all2 P (take n xs) (take n ys)"
  1703   "\<And>n ys. list_all2 P xs ys \<Longrightarrow> list_all2 P (take n xs) (take n ys)"
  1665   apply (induct xs)
  1704   apply (induct xs)
  1666    apply simp
  1705    apply simp
  1682   apply (case_tac y, auto)
  1721   apply (case_tac y, auto)
  1683   done
  1722   done
  1684 
  1723 
  1685 lemma list_all2_eq:
  1724 lemma list_all2_eq:
  1686   "xs = ys \<longleftrightarrow> list_all2 (op =) xs ys"
  1725   "xs = ys \<longleftrightarrow> list_all2 (op =) xs ys"
  1687   by (induct xs ys rule: list_induct2') auto
  1726 by (induct xs ys rule: list_induct2') auto
  1688 
  1727 
  1689 
  1728 
  1690 subsubsection {* @{text foldl} and @{text foldr} *}
  1729 subsubsection {* @{text foldl} and @{text foldr} *}
  1691 
  1730 
  1692 lemma foldl_append [simp]:
  1731 lemma foldl_append [simp]:
  1703 by(induct xs arbitrary:a) simp_all
  1742 by(induct xs arbitrary:a) simp_all
  1704 
  1743 
  1705 lemma foldl_cong [fundef_cong, recdef_cong]:
  1744 lemma foldl_cong [fundef_cong, recdef_cong]:
  1706   "[| a = b; l = k; !!a x. x : set l ==> f a x = g a x |] 
  1745   "[| a = b; l = k; !!a x. x : set l ==> f a x = g a x |] 
  1707   ==> foldl f a l = foldl g b k"
  1746   ==> foldl f a l = foldl g b k"
  1708   by (induct k arbitrary: a b l) simp_all
  1747 by (induct k arbitrary: a b l) simp_all
  1709 
  1748 
  1710 lemma foldr_cong [fundef_cong, recdef_cong]:
  1749 lemma foldr_cong [fundef_cong, recdef_cong]:
  1711   "[| a = b; l = k; !!a x. x : set l ==> f x a = g x a |] 
  1750   "[| a = b; l = k; !!a x. x : set l ==> f x a = g x a |] 
  1712   ==> foldr f l a = foldr g k b"
  1751   ==> foldr f l a = foldr g k b"
  1713   by (induct k arbitrary: a b l) simp_all
  1752 by (induct k arbitrary: a b l) simp_all
  1714 
  1753 
  1715 text{* The ``First Duality Theorem'' in Bird \& Wadler: *}
  1754 text{* The ``First Duality Theorem'' in Bird \& Wadler: *}
  1716 
  1755 
  1717 lemma foldl_foldr1_lemma:
  1756 lemma foldl_foldr1_lemma:
  1718  "foldl op + a xs = a + foldr op + xs (0\<Colon>'a::monoid_add)"
  1757  "foldl op + a xs = a + foldr op + xs (0\<Colon>'a::monoid_add)"
  1921 
  1960 
  1922 lemma distinct_remdups [iff]: "distinct (remdups xs)"
  1961 lemma distinct_remdups [iff]: "distinct (remdups xs)"
  1923 by (induct xs) auto
  1962 by (induct xs) auto
  1924 
  1963 
  1925 lemma remdups_eq_nil_iff [simp]: "(remdups x = []) = (x = [])"
  1964 lemma remdups_eq_nil_iff [simp]: "(remdups x = []) = (x = [])"
  1926   by (induct x, auto) 
  1965 by (induct x, auto) 
  1927 
  1966 
  1928 lemma remdups_eq_nil_right_iff [simp]: "([] = remdups x) = (x = [])"
  1967 lemma remdups_eq_nil_right_iff [simp]: "([] = remdups x) = (x = [])"
  1929   by (induct x, auto)
  1968 by (induct x, auto)
  1930 
  1969 
  1931 lemma length_remdups_leq[iff]: "length(remdups xs) <= length xs"
  1970 lemma length_remdups_leq[iff]: "length(remdups xs) <= length xs"
  1932 by (induct xs) auto
  1971 by (induct xs) auto
  1933 
  1972 
  1934 lemma length_remdups_eq[iff]:
  1973 lemma length_remdups_eq[iff]:
  2006 lemma nth_eq_iff_index_eq:
  2045 lemma nth_eq_iff_index_eq:
  2007  "\<lbrakk> distinct xs; i < length xs; j < length xs \<rbrakk> \<Longrightarrow> (xs!i = xs!j) = (i = j)"
  2046  "\<lbrakk> distinct xs; i < length xs; j < length xs \<rbrakk> \<Longrightarrow> (xs!i = xs!j) = (i = j)"
  2008 by(auto simp: distinct_conv_nth)
  2047 by(auto simp: distinct_conv_nth)
  2009 
  2048 
  2010 lemma distinct_card: "distinct xs ==> card (set xs) = size xs"
  2049 lemma distinct_card: "distinct xs ==> card (set xs) = size xs"
  2011   by (induct xs) auto
  2050 by (induct xs) auto
  2012 
  2051 
  2013 lemma card_distinct: "card (set xs) = size xs ==> distinct xs"
  2052 lemma card_distinct: "card (set xs) = size xs ==> distinct xs"
  2014 proof (induct xs)
  2053 proof (induct xs)
  2015   case Nil thus ?case by simp
  2054   case Nil thus ?case by simp
  2016 next
  2055 next
  2369 
  2408 
  2370 inductive_cases listsE [elim!,noatp]: "x#l : lists A"
  2409 inductive_cases listsE [elim!,noatp]: "x#l : lists A"
  2371 inductive_cases listspE [elim!,noatp]: "listsp A (x # l)"
  2410 inductive_cases listspE [elim!,noatp]: "listsp A (x # l)"
  2372 
  2411 
  2373 lemma listsp_mono [mono]: "A \<le> B ==> listsp A \<le> listsp B"
  2412 lemma listsp_mono [mono]: "A \<le> B ==> listsp A \<le> listsp B"
  2374   by (clarify, erule listsp.induct, blast+)
  2413 by (clarify, erule listsp.induct, blast+)
  2375 
  2414 
  2376 lemmas lists_mono = listsp_mono [to_set]
  2415 lemmas lists_mono = listsp_mono [to_set]
  2377 
  2416 
  2378 lemma listsp_infI:
  2417 lemma listsp_infI:
  2379   assumes l: "listsp A l" shows "listsp B l ==> listsp (inf A B) l" using l
  2418   assumes l: "listsp A l" shows "listsp B l ==> listsp (inf A B) l" using l
  2380   by induct blast+
  2419 by induct blast+
  2381 
  2420 
  2382 lemmas lists_IntI = listsp_infI [to_set]
  2421 lemmas lists_IntI = listsp_infI [to_set]
  2383 
  2422 
  2384 lemma listsp_inf_eq [simp]: "listsp (inf A B) = inf (listsp A) (listsp B)"
  2423 lemma listsp_inf_eq [simp]: "listsp (inf A B) = inf (listsp A) (listsp B)"
  2385 proof (rule mono_inf [where f=listsp, THEN order_antisym])
  2424 proof (rule mono_inf [where f=listsp, THEN order_antisym])
  2554   lexord :: "('a * 'a)set \<Rightarrow> ('a list * 'a list) set" 
  2593   lexord :: "('a * 'a)set \<Rightarrow> ('a list * 'a list) set" 
  2555   "lexord  r == {(x,y). \<exists> a v. y = x @ a # v \<or> 
  2594   "lexord  r == {(x,y). \<exists> a v. y = x @ a # v \<or> 
  2556             (\<exists> u a b v w. (a,b) \<in> r \<and> x = u @ (a # v) \<and> y = u @ (b # w))}"
  2595             (\<exists> u a b v w. (a,b) \<in> r \<and> x = u @ (a # v) \<and> y = u @ (b # w))}"
  2557 
  2596 
  2558 lemma lexord_Nil_left[simp]:  "([],y) \<in> lexord r = (\<exists> a x. y = a # x)"
  2597 lemma lexord_Nil_left[simp]:  "([],y) \<in> lexord r = (\<exists> a x. y = a # x)"
  2559   by (unfold lexord_def, induct_tac y, auto) 
  2598 by (unfold lexord_def, induct_tac y, auto) 
  2560 
  2599 
  2561 lemma lexord_Nil_right[simp]: "(x,[]) \<notin> lexord r"
  2600 lemma lexord_Nil_right[simp]: "(x,[]) \<notin> lexord r"
  2562   by (unfold lexord_def, induct_tac x, auto)
  2601 by (unfold lexord_def, induct_tac x, auto)
  2563 
  2602 
  2564 lemma lexord_cons_cons[simp]:
  2603 lemma lexord_cons_cons[simp]:
  2565      "((a # x, b # y) \<in> lexord r) = ((a,b)\<in> r | (a = b & (x,y)\<in> lexord r))"
  2604      "((a # x, b # y) \<in> lexord r) = ((a,b)\<in> r | (a = b & (x,y)\<in> lexord r))"
  2566   apply (unfold lexord_def, safe, simp_all)
  2605   apply (unfold lexord_def, safe, simp_all)
  2567   apply (case_tac u, simp, simp)
  2606   apply (case_tac u, simp, simp)
  2570   by force
  2609   by force
  2571 
  2610 
  2572 lemmas lexord_simps = lexord_Nil_left lexord_Nil_right lexord_cons_cons
  2611 lemmas lexord_simps = lexord_Nil_left lexord_Nil_right lexord_cons_cons
  2573 
  2612 
  2574 lemma lexord_append_rightI: "\<exists> b z. y = b # z \<Longrightarrow> (x, x @ y) \<in> lexord r"
  2613 lemma lexord_append_rightI: "\<exists> b z. y = b # z \<Longrightarrow> (x, x @ y) \<in> lexord r"
  2575   by (induct_tac x, auto)  
  2614 by (induct_tac x, auto)  
  2576 
  2615 
  2577 lemma lexord_append_left_rightI:
  2616 lemma lexord_append_left_rightI:
  2578      "(a,b) \<in> r \<Longrightarrow> (u @ a # x, u @ b # y) \<in> lexord r"
  2617      "(a,b) \<in> r \<Longrightarrow> (u @ a # x, u @ b # y) \<in> lexord r"
  2579   by (induct_tac u, auto)
  2618 by (induct_tac u, auto)
  2580 
  2619 
  2581 lemma lexord_append_leftI: " (u,v) \<in> lexord r \<Longrightarrow> (x @ u, x @ v) \<in> lexord r"
  2620 lemma lexord_append_leftI: " (u,v) \<in> lexord r \<Longrightarrow> (x @ u, x @ v) \<in> lexord r"
  2582   by (induct x, auto)
  2621 by (induct x, auto)
  2583 
  2622 
  2584 lemma lexord_append_leftD:
  2623 lemma lexord_append_leftD:
  2585      "\<lbrakk> (x @ u, x @ v) \<in> lexord r; (! a. (a,a) \<notin> r) \<rbrakk> \<Longrightarrow> (u,v) \<in> lexord r"
  2624      "\<lbrakk> (x @ u, x @ v) \<in> lexord r; (! a. (a,a) \<notin> r) \<rbrakk> \<Longrightarrow> (u,v) \<in> lexord r"
  2586   by (erule rev_mp, induct_tac x, auto)
  2625 by (erule rev_mp, induct_tac x, auto)
  2587 
  2626 
  2588 lemma lexord_take_index_conv: 
  2627 lemma lexord_take_index_conv: 
  2589    "((x,y) : lexord r) = 
  2628    "((x,y) : lexord r) = 
  2590     ((length x < length y \<and> take (length x) y = x) \<or> 
  2629     ((length x < length y \<and> take (length x) y = x) \<or> 
  2591      (\<exists>i. i < min(length x)(length y) & take i x = take i y & (x!i,y!i) \<in> r))"
  2630      (\<exists>i. i < min(length x)(length y) & take i x = take i y & (x!i,y!i) \<in> r))"
  2627   apply (erule_tac x = lista in allE, simp)
  2666   apply (erule_tac x = lista in allE, simp)
  2628   apply (unfold trans_def)
  2667   apply (unfold trans_def)
  2629   by blast
  2668   by blast
  2630 
  2669 
  2631 lemma lexord_transI:  "trans r \<Longrightarrow> trans (lexord r)"
  2670 lemma lexord_transI:  "trans r \<Longrightarrow> trans (lexord r)"
  2632   by (rule transI, drule lexord_trans, blast) 
  2671 by (rule transI, drule lexord_trans, blast) 
  2633 
  2672 
  2634 lemma lexord_linear: "(! a b. (a,b)\<in> r | a = b | (b,a) \<in> r) \<Longrightarrow> (x,y) : lexord r | x = y | (y,x) : lexord r"
  2673 lemma lexord_linear: "(! a b. (a,b)\<in> r | a = b | (b,a) \<in> r) \<Longrightarrow> (x,y) : lexord r | x = y | (y,x) : lexord r"
  2635   apply (rule_tac x = y in spec) 
  2674   apply (rule_tac x = y in spec) 
  2636   apply (induct_tac x, rule allI) 
  2675   apply (induct_tac x, rule allI) 
  2637   apply (case_tac x, simp, simp) 
  2676   apply (case_tac x, simp, simp) 
  2645 
  2684 
  2646 definition
  2685 definition
  2647   "measures fs = inv_image (lex less_than) (%a. map (%f. f a) fs)"
  2686   "measures fs = inv_image (lex less_than) (%a. map (%f. f a) fs)"
  2648 
  2687 
  2649 lemma wf_measures[recdef_wf, simp]: "wf (measures fs)"
  2688 lemma wf_measures[recdef_wf, simp]: "wf (measures fs)"
  2650   unfolding measures_def
  2689 unfolding measures_def
  2651   by blast
  2690 by blast
  2652 
  2691 
  2653 lemma in_measures[simp]: 
  2692 lemma in_measures[simp]: 
  2654   "(x, y) \<in> measures [] = False"
  2693   "(x, y) \<in> measures [] = False"
  2655   "(x, y) \<in> measures (f # fs)
  2694   "(x, y) \<in> measures (f # fs)
  2656          = (f x < f y \<or> (f x = f y \<and> (x, y) \<in> measures fs))"  
  2695          = (f x < f y \<or> (f x = f y \<and> (x, y) \<in> measures fs))"  
  2657   unfolding measures_def
  2696 unfolding measures_def
  2658   by auto
  2697 by auto
  2659 
  2698 
  2660 lemma measures_less: "f x < f y ==> (x, y) \<in> measures (f#fs)"
  2699 lemma measures_less: "f x < f y ==> (x, y) \<in> measures (f#fs)"
  2661   by simp
  2700 by simp
  2662 
  2701 
  2663 lemma measures_lesseq: "f x <= f y ==> (x, y) \<in> measures fs ==> (x, y) \<in> measures (f#fs)"
  2702 lemma measures_lesseq: "f x <= f y ==> (x, y) \<in> measures fs ==> (x, y) \<in> measures (f#fs)"
  2664   by auto
  2703 by auto
  2665 
  2704 
  2666 (* install the lexicographic_order method and the "fun" command *)
  2705 (* install the lexicographic_order method and the "fun" command *)
  2667 use "Tools/function_package/lexicographic_order.ML"
  2706 use "Tools/function_package/lexicographic_order.ML"
  2668 use "Tools/function_package/fundef_datatype.ML"
  2707 use "Tools/function_package/fundef_datatype.ML"
  2669 setup LexicographicOrder.setup
  2708 setup LexicographicOrder.setup
  2897   show ?case by (induct xs) (auto simp add: Cons aux)
  2936   show ?case by (induct xs) (auto simp add: Cons aux)
  2898 qed
  2937 qed
  2899 
  2938 
  2900 lemma mem_iff [code post]:
  2939 lemma mem_iff [code post]:
  2901   "x mem xs \<longleftrightarrow> x \<in> set xs"
  2940   "x mem xs \<longleftrightarrow> x \<in> set xs"
  2902   by (induct xs) auto
  2941 by (induct xs) auto
  2903 
  2942 
  2904 lemmas in_set_code [code unfold] = mem_iff [symmetric]
  2943 lemmas in_set_code [code unfold] = mem_iff [symmetric]
  2905 
  2944 
  2906 lemma empty_null [code inline]:
  2945 lemma empty_null [code inline]:
  2907   "xs = [] \<longleftrightarrow> null xs"
  2946   "xs = [] \<longleftrightarrow> null xs"
  2908   by (cases xs) simp_all
  2947 by (cases xs) simp_all
  2909 
  2948 
  2910 lemmas null_empty [code post] =
  2949 lemmas null_empty [code post] =
  2911   empty_null [symmetric]
  2950   empty_null [symmetric]
  2912 
  2951 
  2913 lemma list_inter_conv:
  2952 lemma list_inter_conv:
  2914   "set (list_inter xs ys) = set xs \<inter> set ys"
  2953   "set (list_inter xs ys) = set xs \<inter> set ys"
  2915   by (induct xs) auto
  2954 by (induct xs) auto
  2916 
  2955 
  2917 lemma list_all_iff [code post]:
  2956 lemma list_all_iff [code post]:
  2918   "list_all P xs \<longleftrightarrow> (\<forall>x \<in> set xs. P x)"
  2957   "list_all P xs \<longleftrightarrow> (\<forall>x \<in> set xs. P x)"
  2919   by (induct xs) auto
  2958 by (induct xs) auto
  2920 
  2959 
  2921 lemmas list_ball_code [code unfold] = list_all_iff [symmetric]
  2960 lemmas list_ball_code [code unfold] = list_all_iff [symmetric]
  2922 
  2961 
  2923 lemma list_all_append [simp]:
  2962 lemma list_all_append [simp]:
  2924   "list_all P (xs @ ys) \<longleftrightarrow> (list_all P xs \<and> list_all P ys)"
  2963   "list_all P (xs @ ys) \<longleftrightarrow> (list_all P xs \<and> list_all P ys)"
  2925   by (induct xs) auto
  2964 by (induct xs) auto
  2926 
  2965 
  2927 lemma list_all_rev [simp]:
  2966 lemma list_all_rev [simp]:
  2928   "list_all P (rev xs) \<longleftrightarrow> list_all P xs"
  2967   "list_all P (rev xs) \<longleftrightarrow> list_all P xs"
  2929   by (simp add: list_all_iff)
  2968 by (simp add: list_all_iff)
  2930 
  2969 
  2931 lemma list_all_length:
  2970 lemma list_all_length:
  2932   "list_all P xs \<longleftrightarrow> (\<forall>n < length xs. P (xs ! n))"
  2971   "list_all P xs \<longleftrightarrow> (\<forall>n < length xs. P (xs ! n))"
  2933   unfolding list_all_iff by (auto intro: all_nth_imp_all_set)
  2972   unfolding list_all_iff by (auto intro: all_nth_imp_all_set)
  2934 
  2973 
  2935 lemma list_ex_iff [code post]:
  2974 lemma list_ex_iff [code post]:
  2936   "list_ex P xs \<longleftrightarrow> (\<exists>x \<in> set xs. P x)"
  2975   "list_ex P xs \<longleftrightarrow> (\<exists>x \<in> set xs. P x)"
  2937   by (induct xs) simp_all
  2976 by (induct xs) simp_all
  2938 
  2977 
  2939 lemmas list_bex_code [code unfold] =
  2978 lemmas list_bex_code [code unfold] =
  2940   list_ex_iff [symmetric]
  2979   list_ex_iff [symmetric]
  2941 
  2980 
  2942 lemma list_ex_length:
  2981 lemma list_ex_length:
  2943   "list_ex P xs \<longleftrightarrow> (\<exists>n < length xs. P (xs ! n))"
  2982   "list_ex P xs \<longleftrightarrow> (\<exists>n < length xs. P (xs ! n))"
  2944   unfolding list_ex_iff set_conv_nth by auto
  2983   unfolding list_ex_iff set_conv_nth by auto
  2945 
  2984 
  2946 lemma filtermap_conv:
  2985 lemma filtermap_conv:
  2947    "filtermap f xs = map (\<lambda>x. the (f x)) (filter (\<lambda>x. f x \<noteq> None) xs)"
  2986    "filtermap f xs = map (\<lambda>x. the (f x)) (filter (\<lambda>x. f x \<noteq> None) xs)"
  2948   by (induct xs) (simp_all split: option.split) 
  2987 by (induct xs) (simp_all split: option.split) 
  2949 
  2988 
  2950 lemma map_filter_conv [simp]:
  2989 lemma map_filter_conv [simp]:
  2951   "map_filter f P xs = map f (filter P xs)"
  2990   "map_filter f P xs = map f (filter P xs)"
  2952   by (induct xs) auto
  2991 by (induct xs) auto
  2953 
  2992 
  2954 lemma [code inline]: "listsum (map f xs) = foldl (%n x. n + f x) 0 xs"
  2993 lemma [code inline]: "listsum (map f xs) = foldl (%n x. n + f x) 0 xs"
  2955   by (simp add: listsum_foldr foldl_map [symmetric] foldl_foldr1)
  2994 by (simp add: listsum_foldr foldl_map [symmetric] foldl_foldr1)
  2956 
  2995 
  2957 
  2996 
  2958 text {* Code for bounded quantification over nats. *}
  2997 text {* Code for bounded quantification over nats. *}
  2959 
  2998 
  2960 lemma atMost_upto [code unfold]:
  2999 lemma atMost_upto [code unfold]:
  2961   "{..n} = set [0..n]"
  3000   "{..n} = set [0..n]"
  2962   by auto
  3001 by auto
  2963 
  3002 
  2964 lemma atLeast_upt [code unfold]:
  3003 lemma atLeast_upt [code unfold]:
  2965   "{..<n} = set [0..<n]"
  3004   "{..<n} = set [0..<n]"
  2966   by auto
  3005 by auto
  2967 
  3006 
  2968 lemma greaterThanLessThan_upd [code unfold]:
  3007 lemma greaterThanLessThan_upd [code unfold]:
  2969   "{n<..<m} = set [Suc n..<m]"
  3008   "{n<..<m} = set [Suc n..<m]"
  2970   by auto
  3009 by auto
  2971 
  3010 
  2972 lemma atLeastLessThan_upd [code unfold]:
  3011 lemma atLeastLessThan_upd [code unfold]:
  2973   "{n..<m} = set [n..<m]"
  3012   "{n..<m} = set [n..<m]"
  2974   by auto
  3013 by auto
  2975 
  3014 
  2976 lemma greaterThanAtMost_upto [code unfold]:
  3015 lemma greaterThanAtMost_upto [code unfold]:
  2977   "{n<..m} = set [Suc n..m]"
  3016   "{n<..m} = set [Suc n..m]"
  2978   by auto
  3017 by auto
  2979 
  3018 
  2980 lemma atLeastAtMost_upto [code unfold]:
  3019 lemma atLeastAtMost_upto [code unfold]:
  2981   "{n..m} = set [n..m]"
  3020   "{n..m} = set [n..m]"
  2982   by auto
  3021 by auto
  2983 
  3022 
  2984 lemma all_nat_less_eq [code unfold]:
  3023 lemma all_nat_less_eq [code unfold]:
  2985   "(\<forall>m<n\<Colon>nat. P m) \<longleftrightarrow> (\<forall>m \<in> {0..<n}. P m)"
  3024   "(\<forall>m<n\<Colon>nat. P m) \<longleftrightarrow> (\<forall>m \<in> {0..<n}. P m)"
  2986   by auto
  3025 by auto
  2987 
  3026 
  2988 lemma ex_nat_less_eq [code unfold]:
  3027 lemma ex_nat_less_eq [code unfold]:
  2989   "(\<exists>m<n\<Colon>nat. P m) \<longleftrightarrow> (\<exists>m \<in> {0..<n}. P m)"
  3028   "(\<exists>m<n\<Colon>nat. P m) \<longleftrightarrow> (\<exists>m \<in> {0..<n}. P m)"
  2990   by auto
  3029 by auto
  2991 
  3030 
  2992 lemma all_nat_less [code unfold]:
  3031 lemma all_nat_less [code unfold]:
  2993   "(\<forall>m\<le>n\<Colon>nat. P m) \<longleftrightarrow> (\<forall>m \<in> {0..n}. P m)"
  3032   "(\<forall>m\<le>n\<Colon>nat. P m) \<longleftrightarrow> (\<forall>m \<in> {0..n}. P m)"
  2994   by auto
  3033 by auto
  2995 
  3034 
  2996 lemma ex_nat_less [code unfold]:
  3035 lemma ex_nat_less [code unfold]:
  2997   "(\<exists>m\<le>n\<Colon>nat. P m) \<longleftrightarrow> (\<exists>m \<in> {0..n}. P m)"
  3036   "(\<exists>m\<le>n\<Colon>nat. P m) \<longleftrightarrow> (\<exists>m \<in> {0..n}. P m)"
  2998   by auto
  3037 by auto
  2999 
  3038 
  3000 lemma foldl_append_append: "\<And> ss ss'. foldl (op @) (ss@ss') xs = ss@(foldl (op @) ss' xs)"
  3039 lemma foldl_append_append: "\<And> ss ss'. foldl (op @) (ss@ss') xs = ss@(foldl (op @) ss' xs)"
  3001 by (induct xs, simp_all)
  3040 by (induct xs, simp_all)
  3002 
  3041 
  3003 lemma foldl_append_map_set: "\<And> ss. set (foldl (op @) ss (map f xs)) = set ss \<union> UNION (set xs) (\<lambda>x. set (f x))"
  3042 lemma foldl_append_map_set: "\<And> ss. set (foldl (op @) ss (map f xs)) = set ss \<union> UNION (set xs) (\<lambda>x. set (f x))"
  3004 proof(induct xs)
  3043 proof(induct xs)
  3005   case Nil thus ?case by simp
  3044   case Nil thus ?case by simp
  3006 next
  3045 next
  3007   case (Cons x xs ss)
  3046   case (Cons x xs ss)
  3008   have "set (foldl op @ ss (map f (x # xs))) = set (foldl op @ (ss @ f x) (map f xs))" by simp
  3047   have "set (foldl op @ ss (map f (x # xs))) = set (foldl op @ (ss @ f x) (map f xs))" by simp
  3009   also have "\<dots> = set (ss@ f x) \<union> UNION (set xs) (\<lambda>x. set (f x))" using prems  by simp
  3048   also have "\<dots> = set (ss@ f x) \<union> UNION (set xs) (\<lambda>x. set (f x))"
       
  3049     using prems by simp
  3010   also have "\<dots>= set ss \<union> set (f x) \<union> UNION (set xs) (\<lambda>x. set (f x))" by simp
  3050   also have "\<dots>= set ss \<union> set (f x) \<union> UNION (set xs) (\<lambda>x. set (f x))" by simp
  3011   also have "\<dots> = set ss \<union> UNION (set (x#xs)) (\<lambda>x. set (f x))"
  3051   also have "\<dots> = set ss \<union> UNION (set (x#xs)) (\<lambda>x. set (f x))"
  3012     by (simp add: Un_assoc)
  3052     by (simp add: Un_assoc)
  3013   finally show ?case by simp
  3053   finally show ?case by simp
  3014 qed
  3054 qed
  3055   qed
  3095   qed
  3056 qed
  3096 qed
  3057 
  3097 
  3058 lemma partition_filter1:
  3098 lemma partition_filter1:
  3059     "fst (partition P xs) = filter P xs"
  3099     "fst (partition P xs) = filter P xs"
  3060   by (induct xs rule: partition.induct) (auto simp add: Let_def split_def)
  3100 by (induct xs rule: partition.induct) (auto simp add: Let_def split_def)
  3061 
  3101 
  3062 lemma partition_filter2:
  3102 lemma partition_filter2:
  3063     "snd (partition P xs) = filter (Not o P) xs"
  3103     "snd (partition P xs) = filter (Not o P) xs"
  3064   by (induct xs rule: partition.induct) (auto simp add: Let_def split_def)
  3104 by (induct xs rule: partition.induct) (auto simp add: Let_def split_def)
  3065 
  3105 
  3066 lemma partition_set:
  3106 lemma partition_set:
  3067   assumes "partition P xs = (yes, no)"
  3107   assumes "partition P xs = (yes, no)"
  3068   shows "set yes \<union> set no = set xs"
  3108   shows "set yes \<union> set no = set xs"
  3069 proof -
  3109 proof -