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 |