src/HOL/List.ML
changeset 5183 89f162de39cf
parent 5162 53e505c6019c
child 5200 a23c23af335f
equal deleted inserted replaced
5182:69917bbbce45 5183:89f162de39cf
   206 by (Auto_tac);
   206 by (Auto_tac);
   207 qed "hd_append";
   207 qed "hd_append";
   208 
   208 
   209 Goal "xs ~= [] ==> hd(xs @ ys) = hd xs";
   209 Goal "xs ~= [] ==> hd(xs @ ys) = hd xs";
   210 by (asm_simp_tac (simpset() addsimps [hd_append]
   210 by (asm_simp_tac (simpset() addsimps [hd_append]
   211                            addsplits [split_list_case]) 1);
   211                            addsplits [list.split]) 1);
   212 qed "hd_append2";
   212 qed "hd_append2";
   213 Addsimps [hd_append2];
   213 Addsimps [hd_append2];
   214 
   214 
   215 Goal "tl(xs@ys) = (case xs of [] => tl(ys) | z#zs => zs@ys)";
   215 Goal "tl(xs@ys) = (case xs of [] => tl(ys) | z#zs => zs@ys)";
   216 by (simp_tac (simpset() addsplits [split_list_case]) 1);
   216 by (simp_tac (simpset() addsplits [list.split]) 1);
   217 qed "tl_append";
   217 qed "tl_append";
   218 
   218 
   219 Goal "xs ~= [] ==> tl(xs @ ys) = (tl xs) @ ys";
   219 Goal "xs ~= [] ==> tl(xs @ ys) = (tl xs) @ ys";
   220 by (asm_simp_tac (simpset() addsimps [tl_append]
   220 by (asm_simp_tac (simpset() addsimps [tl_append]
   221                            addsplits [split_list_case]) 1);
   221                            addsplits [list.split]) 1);
   222 qed "tl_append2";
   222 qed "tl_append2";
   223 Addsimps [tl_append2];
   223 Addsimps [tl_append2];
   224 
   224 
   225 
   225 
   226 (** map **)
   226 (** map **)
   480 
   480 
   481 section "nth";
   481 section "nth";
   482 
   482 
   483 Goal
   483 Goal
   484   "!xs. (xs@ys)!n = (if n < length xs then xs!n else ys!(n - length xs))";
   484   "!xs. (xs@ys)!n = (if n < length xs then xs!n else ys!(n - length xs))";
   485 by (nat_ind_tac "n" 1);
   485 by (induct_tac "n" 1);
   486  by (Asm_simp_tac 1);
   486  by (Asm_simp_tac 1);
   487  by (rtac allI 1);
   487  by (rtac allI 1);
   488  by (exhaust_tac "xs" 1);
   488  by (exhaust_tac "xs" 1);
   489   by (Auto_tac);
   489   by (Auto_tac);
   490 qed_spec_mp "nth_append";
   490 qed_spec_mp "nth_append";
   493 by (induct_tac "xs" 1);
   493 by (induct_tac "xs" 1);
   494 (* case [] *)
   494 (* case [] *)
   495 by (Asm_full_simp_tac 1);
   495 by (Asm_full_simp_tac 1);
   496 (* case x#xl *)
   496 (* case x#xl *)
   497 by (rtac allI 1);
   497 by (rtac allI 1);
   498 by (nat_ind_tac "n" 1);
   498 by (induct_tac "n" 1);
   499 by (Auto_tac);
   499 by (Auto_tac);
   500 qed_spec_mp "nth_map";
   500 qed_spec_mp "nth_map";
   501 Addsimps [nth_map];
   501 Addsimps [nth_map];
   502 
   502 
   503 Goal "!n. n < length xs --> list_all P xs --> P(xs!n)";
   503 Goal "!n. n < length xs --> list_all P xs --> P(xs!n)";
   504 by (induct_tac "xs" 1);
   504 by (induct_tac "xs" 1);
   505 (* case [] *)
   505 (* case [] *)
   506 by (Simp_tac 1);
   506 by (Simp_tac 1);
   507 (* case x#xl *)
   507 (* case x#xl *)
   508 by (rtac allI 1);
   508 by (rtac allI 1);
   509 by (nat_ind_tac "n" 1);
   509 by (induct_tac "n" 1);
   510 by (Auto_tac);
   510 by (Auto_tac);
   511 qed_spec_mp "list_all_nth";
   511 qed_spec_mp "list_all_nth";
   512 
   512 
   513 Goal "!n. n < length xs --> xs!n mem xs";
   513 Goal "!n. n < length xs --> xs!n mem xs";
   514 by (induct_tac "xs" 1);
   514 by (induct_tac "xs" 1);
   515 (* case [] *)
   515 (* case [] *)
   516 by (Simp_tac 1);
   516 by (Simp_tac 1);
   517 (* case x#xl *)
   517 (* case x#xl *)
   518 by (rtac allI 1);
   518 by (rtac allI 1);
   519 by (nat_ind_tac "n" 1);
   519 by (induct_tac "n" 1);
   520 (* case 0 *)
   520 (* case 0 *)
   521 by (Asm_full_simp_tac 1);
   521 by (Asm_full_simp_tac 1);
   522 (* case Suc x *)
   522 (* case Suc x *)
   523 by (Asm_full_simp_tac 1);
   523 by (Asm_full_simp_tac 1);
   524 qed_spec_mp "nth_mem";
   524 qed_spec_mp "nth_mem";
   529 section "list update";
   529 section "list update";
   530 
   530 
   531 Goal "!i. length(xs[i:=x]) = length xs";
   531 Goal "!i. length(xs[i:=x]) = length xs";
   532 by (induct_tac "xs" 1);
   532 by (induct_tac "xs" 1);
   533 by (Simp_tac 1);
   533 by (Simp_tac 1);
   534 by (asm_full_simp_tac (simpset() addsplits [split_nat_case]) 1);
   534 by (asm_full_simp_tac (simpset() addsplits [nat.split]) 1);
   535 qed_spec_mp "length_list_update";
   535 qed_spec_mp "length_list_update";
   536 Addsimps [length_list_update];
   536 Addsimps [length_list_update];
   537 
   537 
   538 
   538 
   539 (** last & butlast **)
   539 (** last & butlast **)
   601 
   601 
   602 Delsimps [take_Cons,drop_Cons];
   602 Delsimps [take_Cons,drop_Cons];
   603 Addsimps [take_0,take_Suc_Cons,drop_0,drop_Suc_Cons];
   603 Addsimps [take_0,take_Suc_Cons,drop_0,drop_Suc_Cons];
   604 
   604 
   605 Goal "!xs. length(take n xs) = min (length xs) n";
   605 Goal "!xs. length(take n xs) = min (length xs) n";
   606 by (nat_ind_tac "n" 1);
   606 by (induct_tac "n" 1);
   607  by (Auto_tac);
   607  by (Auto_tac);
   608 by (exhaust_tac "xs" 1);
   608 by (exhaust_tac "xs" 1);
   609  by (Auto_tac);
   609  by (Auto_tac);
   610 qed_spec_mp "length_take";
   610 qed_spec_mp "length_take";
   611 Addsimps [length_take];
   611 Addsimps [length_take];
   612 
   612 
   613 Goal "!xs. length(drop n xs) = (length xs - n)";
   613 Goal "!xs. length(drop n xs) = (length xs - n)";
   614 by (nat_ind_tac "n" 1);
   614 by (induct_tac "n" 1);
   615  by (Auto_tac);
   615  by (Auto_tac);
   616 by (exhaust_tac "xs" 1);
   616 by (exhaust_tac "xs" 1);
   617  by (Auto_tac);
   617  by (Auto_tac);
   618 qed_spec_mp "length_drop";
   618 qed_spec_mp "length_drop";
   619 Addsimps [length_drop];
   619 Addsimps [length_drop];
   620 
   620 
   621 Goal "!xs. length xs <= n --> take n xs = xs";
   621 Goal "!xs. length xs <= n --> take n xs = xs";
   622 by (nat_ind_tac "n" 1);
   622 by (induct_tac "n" 1);
   623  by (Auto_tac);
   623  by (Auto_tac);
   624 by (exhaust_tac "xs" 1);
   624 by (exhaust_tac "xs" 1);
   625  by (Auto_tac);
   625  by (Auto_tac);
   626 qed_spec_mp "take_all";
   626 qed_spec_mp "take_all";
   627 
   627 
   628 Goal "!xs. length xs <= n --> drop n xs = []";
   628 Goal "!xs. length xs <= n --> drop n xs = []";
   629 by (nat_ind_tac "n" 1);
   629 by (induct_tac "n" 1);
   630  by (Auto_tac);
   630  by (Auto_tac);
   631 by (exhaust_tac "xs" 1);
   631 by (exhaust_tac "xs" 1);
   632  by (Auto_tac);
   632  by (Auto_tac);
   633 qed_spec_mp "drop_all";
   633 qed_spec_mp "drop_all";
   634 
   634 
   635 Goal 
   635 Goal 
   636   "!xs. take n (xs @ ys) = (take n xs @ take (n - length xs) ys)";
   636   "!xs. take n (xs @ ys) = (take n xs @ take (n - length xs) ys)";
   637 by (nat_ind_tac "n" 1);
   637 by (induct_tac "n" 1);
   638  by (Auto_tac);
   638  by (Auto_tac);
   639 by (exhaust_tac "xs" 1);
   639 by (exhaust_tac "xs" 1);
   640  by (Auto_tac);
   640  by (Auto_tac);
   641 qed_spec_mp "take_append";
   641 qed_spec_mp "take_append";
   642 Addsimps [take_append];
   642 Addsimps [take_append];
   643 
   643 
   644 Goal "!xs. drop n (xs@ys) = drop n xs @ drop (n - length xs) ys"; 
   644 Goal "!xs. drop n (xs@ys) = drop n xs @ drop (n - length xs) ys"; 
   645 by (nat_ind_tac "n" 1);
   645 by (induct_tac "n" 1);
   646  by (Auto_tac);
   646  by (Auto_tac);
   647 by (exhaust_tac "xs" 1);
   647 by (exhaust_tac "xs" 1);
   648  by (Auto_tac);
   648  by (Auto_tac);
   649 qed_spec_mp "drop_append";
   649 qed_spec_mp "drop_append";
   650 Addsimps [drop_append];
   650 Addsimps [drop_append];
   651 
   651 
   652 Goal "!xs n. take n (take m xs) = take (min n m) xs"; 
   652 Goal "!xs n. take n (take m xs) = take (min n m) xs"; 
   653 by (nat_ind_tac "m" 1);
   653 by (induct_tac "m" 1);
   654  by (Auto_tac);
   654  by (Auto_tac);
   655 by (exhaust_tac "xs" 1);
   655 by (exhaust_tac "xs" 1);
   656  by (Auto_tac);
   656  by (Auto_tac);
   657 by (exhaust_tac "n" 1);
   657 by (exhaust_tac "na" 1);
   658  by (Auto_tac);
   658  by (Auto_tac);
   659 qed_spec_mp "take_take";
   659 qed_spec_mp "take_take";
   660 
   660 
   661 Goal "!xs. drop n (drop m xs) = drop (n + m) xs"; 
   661 Goal "!xs. drop n (drop m xs) = drop (n + m) xs"; 
   662 by (nat_ind_tac "m" 1);
   662 by (induct_tac "m" 1);
   663  by (Auto_tac);
   663  by (Auto_tac);
   664 by (exhaust_tac "xs" 1);
   664 by (exhaust_tac "xs" 1);
   665  by (Auto_tac);
   665  by (Auto_tac);
   666 qed_spec_mp "drop_drop";
   666 qed_spec_mp "drop_drop";
   667 
   667 
   668 Goal "!xs n. take n (drop m xs) = drop m (take (n + m) xs)"; 
   668 Goal "!xs n. take n (drop m xs) = drop m (take (n + m) xs)"; 
   669 by (nat_ind_tac "m" 1);
   669 by (induct_tac "m" 1);
   670  by (Auto_tac);
   670  by (Auto_tac);
   671 by (exhaust_tac "xs" 1);
   671 by (exhaust_tac "xs" 1);
   672  by (Auto_tac);
   672  by (Auto_tac);
   673 qed_spec_mp "take_drop";
   673 qed_spec_mp "take_drop";
   674 
   674 
   675 Goal "!xs. take n (map f xs) = map f (take n xs)"; 
   675 Goal "!xs. take n (map f xs) = map f (take n xs)"; 
   676 by (nat_ind_tac "n" 1);
   676 by (induct_tac "n" 1);
   677  by (Auto_tac);
   677  by (Auto_tac);
   678 by (exhaust_tac "xs" 1);
   678 by (exhaust_tac "xs" 1);
   679  by (Auto_tac);
   679  by (Auto_tac);
   680 qed_spec_mp "take_map"; 
   680 qed_spec_mp "take_map"; 
   681 
   681 
   682 Goal "!xs. drop n (map f xs) = map f (drop n xs)"; 
   682 Goal "!xs. drop n (map f xs) = map f (drop n xs)"; 
   683 by (nat_ind_tac "n" 1);
   683 by (induct_tac "n" 1);
   684  by (Auto_tac);
   684  by (Auto_tac);
   685 by (exhaust_tac "xs" 1);
   685 by (exhaust_tac "xs" 1);
   686  by (Auto_tac);
   686  by (Auto_tac);
   687 qed_spec_mp "drop_map";
   687 qed_spec_mp "drop_map";
   688 
   688 
   695  by (Auto_tac);
   695  by (Auto_tac);
   696 qed_spec_mp "nth_take";
   696 qed_spec_mp "nth_take";
   697 Addsimps [nth_take];
   697 Addsimps [nth_take];
   698 
   698 
   699 Goal  "!xs i. n + i <= length xs --> (drop n xs)!i = xs!(n+i)";
   699 Goal  "!xs i. n + i <= length xs --> (drop n xs)!i = xs!(n+i)";
   700 by (nat_ind_tac "n" 1);
   700 by (induct_tac "n" 1);
   701  by (Auto_tac);
   701  by (Auto_tac);
   702 by (exhaust_tac "xs" 1);
   702 by (exhaust_tac "xs" 1);
   703  by (Auto_tac);
   703  by (Auto_tac);
   704 qed_spec_mp "nth_drop";
   704 qed_spec_mp "nth_drop";
   705 Addsimps [nth_drop];
   705 Addsimps [nth_drop];
   790 local
   790 local
   791 
   791 
   792 val list_eq_pattern =
   792 val list_eq_pattern =
   793   read_cterm (sign_of List.thy) ("(xs::'a list) = ys",HOLogic.boolT);
   793   read_cterm (sign_of List.thy) ("(xs::'a list) = ys",HOLogic.boolT);
   794 
   794 
   795 fun last (cons as Const("List.op #",_) $ _ $ xs) =
   795 fun last (cons as Const("List.list.op #",_) $ _ $ xs) =
   796       (case xs of Const("List.[]",_) => cons | _ => last xs)
   796       (case xs of Const("List.list.[]",_) => cons | _ => last xs)
   797   | last (Const("List.op @",_) $ _ $ ys) = last ys
   797   | last (Const("List.list.op @",_) $ _ $ ys) = last ys
   798   | last t = t;
   798   | last t = t;
   799 
   799 
   800 fun list1 (Const("List.op #",_) $ _ $ Const("List.[]",_)) = true
   800 fun list1 (Const("List.list.op #",_) $ _ $ Const("List.list.[]",_)) = true
   801   | list1 _ = false;
   801   | list1 _ = false;
   802 
   802 
   803 fun butlast ((cons as Const("List.op #",_) $ x) $ xs) =
   803 fun butlast ((cons as Const("List.list.op #",_) $ x) $ xs) =
   804       (case xs of Const("List.[]",_) => xs | _ => cons $ butlast xs)
   804       (case xs of Const("List.list.[]",_) => xs | _ => cons $ butlast xs)
   805   | butlast ((app as Const("List.op @",_) $ xs) $ ys) = app $ butlast ys
   805   | butlast ((app as Const("List.list.op @",_) $ xs) $ ys) = app $ butlast ys
   806   | butlast xs = Const("List.[]",fastype_of xs);
   806   | butlast xs = Const("List.list.[]",fastype_of xs);
   807 
   807 
   808 val rearr_tac =
   808 val rearr_tac =
   809   simp_tac (HOL_basic_ss addsimps [append_assoc,append_Nil,append_Cons]);
   809   simp_tac (HOL_basic_ss addsimps [append_assoc,append_Nil,append_Cons]);
   810 
   810 
   811 fun list_eq sg _ (F as (eq as Const(_,eqT)) $ lhs $ rhs) =
   811 fun list_eq sg _ (F as (eq as Const(_,eqT)) $ lhs $ rhs) =
   813     val lastl = last lhs and lastr = last rhs
   813     val lastl = last lhs and lastr = last rhs
   814     fun rearr conv =
   814     fun rearr conv =
   815       let val lhs1 = butlast lhs and rhs1 = butlast rhs
   815       let val lhs1 = butlast lhs and rhs1 = butlast rhs
   816           val Type(_,listT::_) = eqT
   816           val Type(_,listT::_) = eqT
   817           val appT = [listT,listT] ---> listT
   817           val appT = [listT,listT] ---> listT
   818           val app = Const("List.op @",appT)
   818           val app = Const("List.list.op @",appT)
   819           val F2 = eq $ (app$lhs1$lastl) $ (app$rhs1$lastr)
   819           val F2 = eq $ (app$lhs1$lastl) $ (app$rhs1$lastr)
   820           val ct = cterm_of sg (HOLogic.mk_Trueprop(HOLogic.mk_eq(F,F2)))
   820           val ct = cterm_of sg (HOLogic.mk_Trueprop(HOLogic.mk_eq(F,F2)))
   821           val thm = prove_goalw_cterm [] ct (K [rearr_tac 1])
   821           val thm = prove_goalw_cterm [] ct (K [rearr_tac 1])
   822             handle ERROR =>
   822             handle ERROR =>
   823             error("The error(s) above occurred while trying to prove " ^
   823             error("The error(s) above occurred while trying to prove " ^