src/HOL/ex/LList.ML
changeset 1465 5d7a7e439cec
parent 1303 010be89a7541
child 1642 21db0cf9a1a4
equal deleted inserted replaced
1464:a608f83e3421 1465:5d7a7e439cec
     1 (*  Title: 	HOL/llist
     1 (*  Title:      HOL/llist
     2     ID:         $Id$
     2     ID:         $Id$
     3     Author: 	Lawrence C Paulson, Cambridge University Computer Laboratory
     3     Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     4     Copyright   1993  University of Cambridge
     4     Copyright   1993  University of Cambridge
     5 
     5 
     6 SHOULD LListD_Fun_CONS_I, etc., be equations (for rewriting)?
     6 SHOULD LListD_Fun_CONS_I, etc., be equations (for rewriting)?
     7 *)
     7 *)
     8 
     8 
    80     "[| M<=M';  N<=N' |] ==> CONS M N <= CONS M' N'";
    80     "[| M<=M';  N<=N' |] ==> CONS M N <= CONS M' N'";
    81 by (REPEAT (resolve_tac ([In1_mono,Scons_mono]@prems) 1));
    81 by (REPEAT (resolve_tac ([In1_mono,Scons_mono]@prems) 1));
    82 qed "CONS_mono";
    82 qed "CONS_mono";
    83 
    83 
    84 Addsimps [LList_corec_fun_def RS def_nat_rec_0,
    84 Addsimps [LList_corec_fun_def RS def_nat_rec_0,
    85 	  LList_corec_fun_def RS def_nat_rec_Suc];
    85           LList_corec_fun_def RS def_nat_rec_Suc];
    86 
    86 
    87 (** The directions of the equality are proved separately **)
    87 (** The directions of the equality are proved separately **)
    88 
    88 
    89 goalw LList.thy [LList_corec_def]
    89 goalw LList.thy [LList_corec_def]
    90     "LList_corec a f <= sum_case (%u.NIL) \
    90     "LList_corec a f <= sum_case (%u.NIL) \
    91 \			   (split(%z w. CONS z (LList_corec w f))) (f a)";
    91 \                          (split(%z w. CONS z (LList_corec w f))) (f a)";
    92 by (rtac UN1_least 1);
    92 by (rtac UN1_least 1);
    93 by (res_inst_tac [("n","k")] natE 1);
    93 by (res_inst_tac [("n","k")] natE 1);
    94 by (ALLGOALS (Asm_simp_tac));
    94 by (ALLGOALS (Asm_simp_tac));
    95 by (REPEAT (resolve_tac [allI, impI, subset_refl RS CONS_mono, UN1_upper] 1));
    95 by (REPEAT (resolve_tac [allI, impI, subset_refl RS CONS_mono, UN1_upper] 1));
    96 qed "LList_corec_subset1";
    96 qed "LList_corec_subset1";
   104 qed "LList_corec_subset2";
   104 qed "LList_corec_subset2";
   105 
   105 
   106 (*the recursion equation for LList_corec -- NOT SUITABLE FOR REWRITING!*)
   106 (*the recursion equation for LList_corec -- NOT SUITABLE FOR REWRITING!*)
   107 goal LList.thy
   107 goal LList.thy
   108     "LList_corec a f = sum_case (%u. NIL) \
   108     "LList_corec a f = sum_case (%u. NIL) \
   109 \			    (split(%z w. CONS z (LList_corec w f))) (f a)";
   109 \                           (split(%z w. CONS z (LList_corec w f))) (f a)";
   110 by (REPEAT (resolve_tac [equalityI, LList_corec_subset1, 
   110 by (REPEAT (resolve_tac [equalityI, LList_corec_subset1, 
   111 			 LList_corec_subset2] 1));
   111                          LList_corec_subset2] 1));
   112 qed "LList_corec";
   112 qed "LList_corec";
   113 
   113 
   114 (*definitional version of same*)
   114 (*definitional version of same*)
   115 val [rew] = goal LList.thy
   115 val [rew] = goal LList.thy
   116     "[| !!x. h(x) == LList_corec x f |] ==>	\
   116     "[| !!x. h(x) == LList_corec x f |] ==>     \
   117 \    h(a) = sum_case (%u.NIL) (split(%z w. CONS z (h w))) (f a)";
   117 \    h(a) = sum_case (%u.NIL) (split(%z w. CONS z (h w))) (f a)";
   118 by (rewtac rew);
   118 by (rewtac rew);
   119 by (rtac LList_corec 1);
   119 by (rtac LList_corec 1);
   120 qed "def_LList_corec";
   120 qed "def_LList_corec";
   121 
   121 
   181 by (rtac subsetI 1);
   181 by (rtac subsetI 1);
   182 by (res_inst_tac [("p","x")] PairE 1);
   182 by (res_inst_tac [("p","x")] PairE 1);
   183 by (safe_tac HOL_cs);
   183 by (safe_tac HOL_cs);
   184 by (rtac diag_eqI 1);
   184 by (rtac diag_eqI 1);
   185 by (rtac (LListD_implies_ntrunc_equality RS spec RS spec RS mp RS 
   185 by (rtac (LListD_implies_ntrunc_equality RS spec RS spec RS mp RS 
   186 	  ntrunc_equality) 1);
   186           ntrunc_equality) 1);
   187 by (assume_tac 1);
   187 by (assume_tac 1);
   188 by (etac (fst_imageI RS (fst_image_LListD RS subsetD)) 1);
   188 by (etac (fst_imageI RS (fst_image_LListD RS subsetD)) 1);
   189 qed "LListD_subset_diag";
   189 qed "LListD_subset_diag";
   190 
   190 
   191 (** Coinduction, using LListD_Fun
   191 (** Coinduction, using LListD_Fun
   223 by (etac diagE 1);
   223 by (etac diagE 1);
   224 by (etac ssubst 1);
   224 by (etac ssubst 1);
   225 by (eresolve_tac [llist.elim] 1);
   225 by (eresolve_tac [llist.elim] 1);
   226 by (ALLGOALS
   226 by (ALLGOALS
   227     (asm_simp_tac (!simpset addsimps [diagI, LListD_Fun_NIL_I,
   227     (asm_simp_tac (!simpset addsimps [diagI, LListD_Fun_NIL_I,
   228 				      LListD_Fun_CONS_I])));
   228                                       LListD_Fun_CONS_I])));
   229 qed "diag_subset_LListD";
   229 qed "diag_subset_LListD";
   230 
   230 
   231 goal LList.thy "LListD(diag(A)) = diag(llist(A))";
   231 goal LList.thy "LListD(diag(A)) = diag(llist(A))";
   232 by (REPEAT (resolve_tac [equalityI, LListD_subset_diag, 
   232 by (REPEAT (resolve_tac [equalityI, LListD_subset_diag, 
   233 			 diag_subset_LListD] 1));
   233                          diag_subset_LListD] 1));
   234 qed "LListD_eq_diag";
   234 qed "LListD_eq_diag";
   235 
   235 
   236 goal LList.thy 
   236 goal LList.thy 
   237     "!!M N. M: llist(A) ==> (M,M) : LListD_Fun (diag A) (X Un diag(llist(A)))";
   237     "!!M N. M: llist(A) ==> (M,M) : LListD_Fun (diag A) (X Un diag(llist(A)))";
   238 by (rtac (LListD_eq_diag RS subst) 1);
   238 by (rtac (LListD_eq_diag RS subst) 1);
   262 \    !!x. h2(x) = sum_case (%u.NIL) (split(%z w. CONS z (h2 w))) (f x) |]\
   262 \    !!x. h2(x) = sum_case (%u.NIL) (split(%z w. CONS z (h2 w))) (f x) |]\
   263 \ ==> h1=h2";
   263 \ ==> h1=h2";
   264 by (rtac ext 1);
   264 by (rtac ext 1);
   265 (*next step avoids an unknown (and flexflex pair) in simplification*)
   265 (*next step avoids an unknown (and flexflex pair) in simplification*)
   266 by (res_inst_tac [("A", "{u.True}"),
   266 by (res_inst_tac [("A", "{u.True}"),
   267 		  ("r", "range(%u. (h1(u),h2(u)))")] LList_equalityI 1);
   267                   ("r", "range(%u. (h1(u),h2(u)))")] LList_equalityI 1);
   268 by (rtac rangeI 1);
   268 by (rtac rangeI 1);
   269 by (safe_tac set_cs);
   269 by (safe_tac set_cs);
   270 by (stac prem1 1);
   270 by (stac prem1 1);
   271 by (stac prem2 1);
   271 by (stac prem2 1);
   272 by (simp_tac (!simpset addsimps [LListD_Fun_NIL_I,
   272 by (simp_tac (!simpset addsimps [LListD_Fun_NIL_I,
   273 				 CollectI RS LListD_Fun_CONS_I]
   273                                  CollectI RS LListD_Fun_CONS_I]
   274 	               |> add_eqI) 1);
   274                        |> add_eqI) 1);
   275 qed "LList_corec_unique";
   275 qed "LList_corec_unique";
   276 
   276 
   277 val [prem] = goal LList.thy
   277 val [prem] = goal LList.thy
   278  "[| !!x. h(x) = sum_case (%u.NIL) (split(%z w. CONS z (h w))) (f x) |] \
   278  "[| !!x. h(x) = sum_case (%u.NIL) (split(%z w. CONS z (h w))) (f x) |] \
   279 \ ==> h = (%x.LList_corec x f)";
   279 \ ==> h = (%x.LList_corec x f)";
   375 qed "Rep_llist_LNil";
   375 qed "Rep_llist_LNil";
   376 
   376 
   377 goalw LList.thy [LCons_def]
   377 goalw LList.thy [LCons_def]
   378     "Rep_llist(LCons x l) = CONS (Leaf x) (Rep_llist l)";
   378     "Rep_llist(LCons x l) = CONS (Leaf x) (Rep_llist l)";
   379 by (REPEAT (resolve_tac [llist.CONS_I RS Abs_llist_inverse,
   379 by (REPEAT (resolve_tac [llist.CONS_I RS Abs_llist_inverse,
   380 			 rangeI, Rep_llist] 1));
   380                          rangeI, Rep_llist] 1));
   381 qed "Rep_llist_LCons";
   381 qed "Rep_llist_LCons";
   382 
   382 
   383 (** Injectiveness of CONS and LCons **)
   383 (** Injectiveness of CONS and LCons **)
   384 
   384 
   385 goalw LList.thy [CONS_def] "(CONS M N=CONS M' N') = (M=M' & N=N')";
   385 goalw LList.thy [CONS_def] "(CONS M N=CONS M' N') = (M=M' & N=N')";
   389 bind_thm ("CONS_inject", (CONS_CONS_eq RS iffD1 RS conjE));
   389 bind_thm ("CONS_inject", (CONS_CONS_eq RS iffD1 RS conjE));
   390 
   390 
   391 
   391 
   392 (*For reasoning about abstract llist constructors*)
   392 (*For reasoning about abstract llist constructors*)
   393 val llist_cs = set_cs addIs [Rep_llist]@llist.intrs
   393 val llist_cs = set_cs addIs [Rep_llist]@llist.intrs
   394 	              addSEs [CONS_neq_NIL,NIL_neq_CONS,CONS_inject]
   394                       addSEs [CONS_neq_NIL,NIL_neq_CONS,CONS_inject]
   395 		      addSDs [inj_onto_Abs_llist RS inj_ontoD,
   395                       addSDs [inj_onto_Abs_llist RS inj_ontoD,
   396 			      inj_Rep_llist RS injD, Leaf_inject];
   396                               inj_Rep_llist RS injD, Leaf_inject];
   397 
   397 
   398 goalw LList.thy [LCons_def] "(LCons x xs=LCons y ys) = (x=y & xs=ys)";
   398 goalw LList.thy [LCons_def] "(LCons x xs=LCons y ys) = (x=y & xs=ys)";
   399 by (fast_tac llist_cs 1);
   399 by (fast_tac llist_cs 1);
   400 qed "LCons_LCons_eq";
   400 qed "LCons_LCons_eq";
   401 bind_thm ("LCons_inject", (LCons_LCons_eq RS iffD1 RS conjE));
   401 bind_thm ("LCons_inject", (LCons_LCons_eq RS iffD1 RS conjE));
   411 
   411 
   412 Addsimps [List_case_NIL, List_case_CONS];
   412 Addsimps [List_case_NIL, List_case_CONS];
   413 
   413 
   414 (*A special case of list_equality for functions over lazy lists*)
   414 (*A special case of list_equality for functions over lazy lists*)
   415 val [Mlist,gMlist,NILcase,CONScase] = goal LList.thy
   415 val [Mlist,gMlist,NILcase,CONScase] = goal LList.thy
   416  "[| M: llist(A); g(NIL): llist(A); 				\
   416  "[| M: llist(A); g(NIL): llist(A);                             \
   417 \    f(NIL)=g(NIL);						\
   417 \    f(NIL)=g(NIL);                                             \
   418 \    !!x l. [| x:A;  l: llist(A) |] ==>				\
   418 \    !!x l. [| x:A;  l: llist(A) |] ==>                         \
   419 \	    (f(CONS x l),g(CONS x l)) :				\
   419 \           (f(CONS x l),g(CONS x l)) :                         \
   420 \               LListD_Fun (diag A) ((%u.(f(u),g(u)))``llist(A) Un  \
   420 \               LListD_Fun (diag A) ((%u.(f(u),g(u)))``llist(A) Un  \
   421 \                                   diag(llist(A)))		\
   421 \                                   diag(llist(A)))             \
   422 \ |] ==> f(M) = g(M)";
   422 \ |] ==> f(M) = g(M)";
   423 by (rtac LList_equalityI 1);
   423 by (rtac LList_equalityI 1);
   424 by (rtac (Mlist RS imageI) 1);
   424 by (rtac (Mlist RS imageI) 1);
   425 by (rtac subsetI 1);
   425 by (rtac subsetI 1);
   426 by (etac imageE 1);
   426 by (etac imageE 1);
   452 by (rtac (major RS imageI RS llist_coinduct) 1);
   452 by (rtac (major RS imageI RS llist_coinduct) 1);
   453 by (safe_tac set_cs);
   453 by (safe_tac set_cs);
   454 by (etac llist.elim 1);
   454 by (etac llist.elim 1);
   455 by (ALLGOALS (asm_simp_tac (!simpset addsimps [Lmap_NIL,Lmap_CONS])));
   455 by (ALLGOALS (asm_simp_tac (!simpset addsimps [Lmap_NIL,Lmap_CONS])));
   456 by (REPEAT (ares_tac [list_Fun_NIL_I, list_Fun_CONS_I, 
   456 by (REPEAT (ares_tac [list_Fun_NIL_I, list_Fun_CONS_I, 
   457 		      minor, imageI, UnI1] 1));
   457                       minor, imageI, UnI1] 1));
   458 qed "Lmap_type";
   458 qed "Lmap_type";
   459 
   459 
   460 (*This type checking rule synthesises a sufficiently large set for f*)
   460 (*This type checking rule synthesises a sufficiently large set for f*)
   461 val [major] = goal LList.thy  "M: llist(A) ==> Lmap f M: llist(f``A)";
   461 val [major] = goal LList.thy  "M: llist(A) ==> Lmap f M: llist(f``A)";
   462 by (rtac (major RS Lmap_type) 1);
   462 by (rtac (major RS Lmap_type) 1);
   470 by (rtac (prem RS imageI RS LList_equalityI) 1);
   470 by (rtac (prem RS imageI RS LList_equalityI) 1);
   471 by (safe_tac set_cs);
   471 by (safe_tac set_cs);
   472 by (etac llist.elim 1);
   472 by (etac llist.elim 1);
   473 by (ALLGOALS (asm_simp_tac (!simpset addsimps [Lmap_NIL,Lmap_CONS])));
   473 by (ALLGOALS (asm_simp_tac (!simpset addsimps [Lmap_NIL,Lmap_CONS])));
   474 by (REPEAT (ares_tac [LListD_Fun_NIL_I, imageI, UnI1,
   474 by (REPEAT (ares_tac [LListD_Fun_NIL_I, imageI, UnI1,
   475 		      rangeI RS LListD_Fun_CONS_I] 1));
   475                       rangeI RS LListD_Fun_CONS_I] 1));
   476 qed "Lmap_compose";
   476 qed "Lmap_compose";
   477 
   477 
   478 val [prem] = goal LList.thy "M: llist(A) ==> Lmap (%x.x) M = M";
   478 val [prem] = goal LList.thy "M: llist(A) ==> Lmap (%x.x) M = M";
   479 by (rtac (prem RS imageI RS LList_equalityI) 1);
   479 by (rtac (prem RS imageI RS LList_equalityI) 1);
   480 by (safe_tac set_cs);
   480 by (safe_tac set_cs);
   481 by (etac llist.elim 1);
   481 by (etac llist.elim 1);
   482 by (ALLGOALS (asm_simp_tac (!simpset addsimps [Lmap_NIL,Lmap_CONS])));
   482 by (ALLGOALS (asm_simp_tac (!simpset addsimps [Lmap_NIL,Lmap_CONS])));
   483 by (REPEAT (ares_tac [LListD_Fun_NIL_I, imageI RS UnI1,
   483 by (REPEAT (ares_tac [LListD_Fun_NIL_I, imageI RS UnI1,
   484 		      rangeI RS LListD_Fun_CONS_I] 1));
   484                       rangeI RS LListD_Fun_CONS_I] 1));
   485 qed "Lmap_ident";
   485 qed "Lmap_ident";
   486 
   486 
   487 
   487 
   488 (*** Lappend -- its two arguments cause some complications! ***)
   488 (*** Lappend -- its two arguments cause some complications! ***)
   489 
   489 
   503 by (rtac (LList_corec RS trans) 1);
   503 by (rtac (LList_corec RS trans) 1);
   504 by (Simp_tac 1);
   504 by (Simp_tac 1);
   505 qed "Lappend_CONS";
   505 qed "Lappend_CONS";
   506 
   506 
   507 Addsimps [llist.NIL_I, Lappend_NIL_NIL, Lappend_NIL_CONS,
   507 Addsimps [llist.NIL_I, Lappend_NIL_NIL, Lappend_NIL_CONS,
   508 	  Lappend_CONS, LListD_Fun_CONS_I, range_eqI, image_eqI];
   508           Lappend_CONS, LListD_Fun_CONS_I, range_eqI, image_eqI];
   509 Delsimps [Pair_eq];
   509 Delsimps [Pair_eq];
   510 
   510 
   511 goal LList.thy "!!M. M: llist(A) ==> Lappend NIL M = M";
   511 goal LList.thy "!!M. M: llist(A) ==> Lappend NIL M = M";
   512 by (etac LList_fun_equalityI 1);
   512 by (etac LList_fun_equalityI 1);
   513 by (ALLGOALS Asm_simp_tac);
   513 by (ALLGOALS Asm_simp_tac);
   580 
   580 
   581 (** llist_corec: corecursion for 'a llist **)
   581 (** llist_corec: corecursion for 'a llist **)
   582 
   582 
   583 goalw LList.thy [llist_corec_def,LNil_def,LCons_def]
   583 goalw LList.thy [llist_corec_def,LNil_def,LCons_def]
   584     "llist_corec a f = sum_case (%u. LNil) \
   584     "llist_corec a f = sum_case (%u. LNil) \
   585 \			    (split(%z w. LCons z (llist_corec w f))) (f a)";
   585 \                           (split(%z w. LCons z (llist_corec w f))) (f a)";
   586 by (stac LList_corec 1);
   586 by (stac LList_corec 1);
   587 by (res_inst_tac [("s","f(a)")] sumE 1);
   587 by (res_inst_tac [("s","f(a)")] sumE 1);
   588 by (asm_simp_tac (!simpset addsimps [LList_corec_type2]) 1);
   588 by (asm_simp_tac (!simpset addsimps [LList_corec_type2]) 1);
   589 by (res_inst_tac [("p","y")] PairE 1);
   589 by (res_inst_tac [("p","y")] PairE 1);
   590 by (asm_simp_tac (!simpset addsimps [LList_corec_type2]) 1);
   590 by (asm_simp_tac (!simpset addsimps [LList_corec_type2]) 1);
   592 by (ASM_SIMP_TAC(!simpset addsimps [LList_corec_type2]) 1);*)
   592 by (ASM_SIMP_TAC(!simpset addsimps [LList_corec_type2]) 1);*)
   593 qed "llist_corec";
   593 qed "llist_corec";
   594 
   594 
   595 (*definitional version of same*)
   595 (*definitional version of same*)
   596 val [rew] = goal LList.thy
   596 val [rew] = goal LList.thy
   597     "[| !!x. h(x) == llist_corec x f |] ==>	\
   597     "[| !!x. h(x) == llist_corec x f |] ==>     \
   598 \    h(a) = sum_case (%u.LNil) (split(%z w. LCons z (h w))) (f a)";
   598 \    h(a) = sum_case (%u.LNil) (split(%z w. LCons z (h w))) (f a)";
   599 by (rewtac rew);
   599 by (rewtac rew);
   600 by (rtac llist_corec 1);
   600 by (rtac llist_corec 1);
   601 qed "def_llist_corec";
   601 qed "def_llist_corec";
   602 
   602 
   639       [also admits true equality] **)
   639       [also admits true equality] **)
   640 val [prem1,prem2] = goalw LList.thy [llistD_Fun_def]
   640 val [prem1,prem2] = goalw LList.thy [llistD_Fun_def]
   641     "[| (l1,l2) : r;  r <= llistD_Fun(r Un range(%x.(x,x))) |] ==> l1=l2";
   641     "[| (l1,l2) : r;  r <= llistD_Fun(r Un range(%x.(x,x))) |] ==> l1=l2";
   642 by (rtac (inj_Rep_llist RS injD) 1);
   642 by (rtac (inj_Rep_llist RS injD) 1);
   643 by (res_inst_tac [("r", "prod_fun Rep_llist Rep_llist ``r"),
   643 by (res_inst_tac [("r", "prod_fun Rep_llist Rep_llist ``r"),
   644 		  ("A", "range(Leaf)")] 
   644                   ("A", "range(Leaf)")] 
   645 	LList_equalityI 1);
   645         LList_equalityI 1);
   646 by (rtac (prem1 RS prod_fun_imageI) 1);
   646 by (rtac (prem1 RS prod_fun_imageI) 1);
   647 by (rtac (prem2 RS image_mono RS subset_trans) 1);
   647 by (rtac (prem2 RS image_mono RS subset_trans) 1);
   648 by (rtac (image_compose RS subst) 1);
   648 by (rtac (image_compose RS subst) 1);
   649 by (rtac (prod_fun_compose RS subst) 1);
   649 by (rtac (prod_fun_compose RS subst) 1);
   650 by (rtac (image_Un RS ssubst) 1);
   650 by (rtac (image_Un RS ssubst) 1);
   675 by (rtac (Rep_llist RS LListD_Fun_diag_I) 1);
   675 by (rtac (Rep_llist RS LListD_Fun_diag_I) 1);
   676 qed "llistD_Fun_range_I";
   676 qed "llistD_Fun_range_I";
   677 
   677 
   678 (*A special case of list_equality for functions over lazy lists*)
   678 (*A special case of list_equality for functions over lazy lists*)
   679 val [prem1,prem2] = goal LList.thy
   679 val [prem1,prem2] = goal LList.thy
   680     "[| f(LNil)=g(LNil);						\
   680     "[| f(LNil)=g(LNil);                                                \
   681 \       !!x l. (f(LCons x l),g(LCons x l)) :				\
   681 \       !!x l. (f(LCons x l),g(LCons x l)) :                            \
   682 \              llistD_Fun(range(%u. (f(u),g(u))) Un range(%v. (v,v)))	\
   682 \              llistD_Fun(range(%u. (f(u),g(u))) Un range(%v. (v,v)))   \
   683 \    |]	==> f(l) = (g(l :: 'a llist) :: 'b llist)";
   683 \    |] ==> f(l) = (g(l :: 'a llist) :: 'b llist)";
   684 by (res_inst_tac [("r", "range(%u. (f(u),g(u)))")] llist_equalityI 1);
   684 by (res_inst_tac [("r", "range(%u. (f(u),g(u)))")] llist_equalityI 1);
   685 by (rtac rangeI 1);
   685 by (rtac rangeI 1);
   686 by (rtac subsetI 1);
   686 by (rtac subsetI 1);
   687 by (etac rangeE 1);
   687 by (etac rangeE 1);
   688 by (etac ssubst 1);
   688 by (etac ssubst 1);
   694 by (rtac prem2 1);
   694 by (rtac prem2 1);
   695 qed "llist_fun_equalityI";
   695 qed "llist_fun_equalityI";
   696 
   696 
   697 (*simpset for llist bisimulations*)
   697 (*simpset for llist bisimulations*)
   698 Addsimps [llist_case_LNil, llist_case_LCons, 
   698 Addsimps [llist_case_LNil, llist_case_LCons, 
   699 	  llistD_Fun_LNil_I, llistD_Fun_LCons_I];
   699           llistD_Fun_LNil_I, llistD_Fun_LCons_I];
   700 
   700 
   701 
   701 
   702 (*** The functional "lmap" ***)
   702 (*** The functional "lmap" ***)
   703 
   703 
   704 goal LList.thy "lmap f LNil = LNil";
   704 goal LList.thy "lmap f LNil = LNil";
   750 (*** A rather complex proof about iterates -- cf Andy Pitts ***)
   750 (*** A rather complex proof about iterates -- cf Andy Pitts ***)
   751 
   751 
   752 (** Two lemmas about natrec n x (%m.g), which is essentially (g^n)(x) **)
   752 (** Two lemmas about natrec n x (%m.g), which is essentially (g^n)(x) **)
   753 
   753 
   754 goal LList.thy
   754 goal LList.thy
   755     "nat_rec n (LCons b l) (%m. lmap(f)) =	\
   755     "nat_rec n (LCons b l) (%m. lmap(f)) =      \
   756 \    LCons (nat_rec n b (%m. f)) (nat_rec n l (%m. lmap(f)))";
   756 \    LCons (nat_rec n b (%m. f)) (nat_rec n l (%m. lmap(f)))";
   757 by (nat_ind_tac "n" 1);
   757 by (nat_ind_tac "n" 1);
   758 by (ALLGOALS (asm_simp_tac (!simpset addsimps [lmap_LCons])));
   758 by (ALLGOALS (asm_simp_tac (!simpset addsimps [lmap_LCons])));
   759 qed "fun_power_lmap";
   759 qed "fun_power_lmap";
   760 
   760