242 |
242 |
243 Goal "[| xs@xs1 = zs; ys = xs1 @ us |] ==> xs@ys = zs@us"; |
243 Goal "[| xs@xs1 = zs; ys = xs1 @ us |] ==> xs@ys = zs@us"; |
244 by (dtac sym 1); |
244 by (dtac sym 1); |
245 by (Asm_simp_tac 1); |
245 by (Asm_simp_tac 1); |
246 qed "append_eq_appendI"; |
246 qed "append_eq_appendI"; |
247 |
|
248 |
|
249 (** map **) |
|
250 |
|
251 section "map"; |
|
252 |
|
253 Goal "(!x. x : set xs --> f x = g x) --> map f xs = map g xs"; |
|
254 by (induct_tac "xs" 1); |
|
255 by Auto_tac; |
|
256 bind_thm("map_ext", impI RS (allI RS (result() RS mp))); |
|
257 |
|
258 Goal "map (%x. x) = (%xs. xs)"; |
|
259 by (rtac ext 1); |
|
260 by (induct_tac "xs" 1); |
|
261 by Auto_tac; |
|
262 qed "map_ident"; |
|
263 Addsimps[map_ident]; |
|
264 |
|
265 Goal "map f (xs@ys) = map f xs @ map f ys"; |
|
266 by (induct_tac "xs" 1); |
|
267 by Auto_tac; |
|
268 qed "map_append"; |
|
269 Addsimps[map_append]; |
|
270 |
|
271 Goalw [o_def] "map (f o g) xs = map f (map g xs)"; |
|
272 by (induct_tac "xs" 1); |
|
273 by Auto_tac; |
|
274 qed "map_compose"; |
|
275 Addsimps[map_compose]; |
|
276 |
|
277 Goal "rev(map f xs) = map f (rev xs)"; |
|
278 by (induct_tac "xs" 1); |
|
279 by Auto_tac; |
|
280 qed "rev_map"; |
|
281 |
|
282 (* a congruence rule for map: *) |
|
283 Goal "(xs=ys) --> (!x. x : set ys --> f x = g x) --> map f xs = map g ys"; |
|
284 by (rtac impI 1); |
|
285 by (hyp_subst_tac 1); |
|
286 by (induct_tac "ys" 1); |
|
287 by Auto_tac; |
|
288 val lemma = result(); |
|
289 bind_thm("map_cong",impI RSN (2,allI RSN (2,lemma RS mp RS mp))); |
|
290 |
|
291 Goal "(map f xs = []) = (xs = [])"; |
|
292 by (induct_tac "xs" 1); |
|
293 by Auto_tac; |
|
294 qed "map_is_Nil_conv"; |
|
295 AddIffs [map_is_Nil_conv]; |
|
296 |
|
297 Goal "([] = map f xs) = (xs = [])"; |
|
298 by (induct_tac "xs" 1); |
|
299 by Auto_tac; |
|
300 qed "Nil_is_map_conv"; |
|
301 AddIffs [Nil_is_map_conv]; |
|
302 |
|
303 |
|
304 (** rev **) |
|
305 |
|
306 section "rev"; |
|
307 |
|
308 Goal "rev(xs@ys) = rev(ys) @ rev(xs)"; |
|
309 by (induct_tac "xs" 1); |
|
310 by Auto_tac; |
|
311 qed "rev_append"; |
|
312 Addsimps[rev_append]; |
|
313 |
|
314 Goal "rev(rev l) = l"; |
|
315 by (induct_tac "l" 1); |
|
316 by Auto_tac; |
|
317 qed "rev_rev_ident"; |
|
318 Addsimps[rev_rev_ident]; |
|
319 |
|
320 Goal "(rev xs = []) = (xs = [])"; |
|
321 by (induct_tac "xs" 1); |
|
322 by Auto_tac; |
|
323 qed "rev_is_Nil_conv"; |
|
324 AddIffs [rev_is_Nil_conv]; |
|
325 |
|
326 Goal "([] = rev xs) = (xs = [])"; |
|
327 by (induct_tac "xs" 1); |
|
328 by Auto_tac; |
|
329 qed "Nil_is_rev_conv"; |
|
330 AddIffs [Nil_is_rev_conv]; |
|
331 |
|
332 val prems = Goal "[| P []; !!x xs. P xs ==> P(xs@[x]) |] ==> P xs"; |
|
333 by (stac (rev_rev_ident RS sym) 1); |
|
334 br(read_instantiate [("P","%xs. ?P(rev xs)")]list.induct)1; |
|
335 by (ALLGOALS Simp_tac); |
|
336 by (resolve_tac prems 1); |
|
337 by (eresolve_tac prems 1); |
|
338 qed "rev_induct"; |
|
339 |
|
340 fun rev_induct_tac xs = res_inst_tac [("xs",xs)] rev_induct; |
|
341 |
|
342 Goal "(xs = [] --> P) --> (!ys y. xs = ys@[y] --> P) --> P"; |
|
343 by (res_inst_tac [("xs","xs")] rev_induct 1); |
|
344 by Auto_tac; |
|
345 bind_thm ("rev_exhaust", |
|
346 impI RSN (2,allI RSN (2,allI RSN (2,impI RS (result() RS mp RS mp))))); |
|
347 |
|
348 |
|
349 (** mem **) |
|
350 |
|
351 section "mem"; |
|
352 |
|
353 Goal "x mem (xs@ys) = (x mem xs | x mem ys)"; |
|
354 by (induct_tac "xs" 1); |
|
355 by Auto_tac; |
|
356 qed "mem_append"; |
|
357 Addsimps[mem_append]; |
|
358 |
|
359 Goal "x mem [x:xs. P(x)] = (x mem xs & P(x))"; |
|
360 by (induct_tac "xs" 1); |
|
361 by Auto_tac; |
|
362 qed "mem_filter"; |
|
363 Addsimps[mem_filter]; |
|
364 |
|
365 (** set **) |
|
366 |
|
367 section "set"; |
|
368 |
|
369 qed_goal "finite_set" thy "finite (set xs)" |
|
370 (K [induct_tac "xs" 1, Auto_tac]); |
|
371 Addsimps[finite_set]; |
|
372 AddSIs[finite_set]; |
|
373 |
|
374 Goal "set (xs@ys) = (set xs Un set ys)"; |
|
375 by (induct_tac "xs" 1); |
|
376 by Auto_tac; |
|
377 qed "set_append"; |
|
378 Addsimps[set_append]; |
|
379 |
|
380 Goal "(x mem xs) = (x: set xs)"; |
|
381 by (induct_tac "xs" 1); |
|
382 by Auto_tac; |
|
383 qed "set_mem_eq"; |
|
384 |
|
385 Goal "set l <= set (x#l)"; |
|
386 by Auto_tac; |
|
387 qed "set_subset_Cons"; |
|
388 |
|
389 Goal "(set xs = {}) = (xs = [])"; |
|
390 by (induct_tac "xs" 1); |
|
391 by Auto_tac; |
|
392 qed "set_empty"; |
|
393 Addsimps [set_empty]; |
|
394 |
|
395 Goal "set(rev xs) = set(xs)"; |
|
396 by (induct_tac "xs" 1); |
|
397 by Auto_tac; |
|
398 qed "set_rev"; |
|
399 Addsimps [set_rev]; |
|
400 |
|
401 Goal "set(map f xs) = f``(set xs)"; |
|
402 by (induct_tac "xs" 1); |
|
403 by Auto_tac; |
|
404 qed "set_map"; |
|
405 Addsimps [set_map]; |
|
406 |
|
407 Goal "(x : set(filter P xs)) = (x : set xs & P x)"; |
|
408 by (induct_tac "xs" 1); |
|
409 by Auto_tac; |
|
410 qed "in_set_filter"; |
|
411 Addsimps [in_set_filter]; |
|
412 |
|
413 Goal "(x : set xs) = (? ys zs. xs = ys@x#zs)"; |
|
414 by (induct_tac "xs" 1); |
|
415 by (Simp_tac 1); |
|
416 by (Asm_simp_tac 1); |
|
417 by (rtac iffI 1); |
|
418 by (blast_tac (claset() addIs [eq_Nil_appendI,Cons_eq_appendI]) 1); |
|
419 by (REPEAT(etac exE 1)); |
|
420 by (exhaust_tac "ys" 1); |
|
421 by Auto_tac; |
|
422 qed "in_set_conv_decomp"; |
|
423 |
|
424 (* eliminate `lists' in favour of `set' *) |
|
425 |
|
426 Goal "(xs : lists A) = (!x : set xs. x : A)"; |
|
427 by (induct_tac "xs" 1); |
|
428 by Auto_tac; |
|
429 qed "in_lists_conv_set"; |
|
430 |
|
431 bind_thm("in_listsD",in_lists_conv_set RS iffD1); |
|
432 AddSDs [in_listsD]; |
|
433 bind_thm("in_listsI",in_lists_conv_set RS iffD2); |
|
434 AddSIs [in_listsI]; |
|
435 |
|
436 (** list_all **) |
|
437 |
|
438 section "list_all"; |
|
439 |
|
440 Goal "list_all (%x. True) xs = True"; |
|
441 by (induct_tac "xs" 1); |
|
442 by Auto_tac; |
|
443 qed "list_all_True"; |
|
444 Addsimps [list_all_True]; |
|
445 |
|
446 Goal "list_all p (xs@ys) = (list_all p xs & list_all p ys)"; |
|
447 by (induct_tac "xs" 1); |
|
448 by Auto_tac; |
|
449 qed "list_all_append"; |
|
450 Addsimps [list_all_append]; |
|
451 |
|
452 Goal "list_all P xs = (!x. x mem xs --> P(x))"; |
|
453 by (induct_tac "xs" 1); |
|
454 by Auto_tac; |
|
455 qed "list_all_mem_conv"; |
|
456 |
|
457 |
|
458 (** filter **) |
|
459 |
|
460 section "filter"; |
|
461 |
|
462 Goal "filter P (xs@ys) = filter P xs @ filter P ys"; |
|
463 by (induct_tac "xs" 1); |
|
464 by Auto_tac; |
|
465 qed "filter_append"; |
|
466 Addsimps [filter_append]; |
|
467 |
|
468 Goal "filter (%x. True) xs = xs"; |
|
469 by (induct_tac "xs" 1); |
|
470 by Auto_tac; |
|
471 qed "filter_True"; |
|
472 Addsimps [filter_True]; |
|
473 |
|
474 Goal "filter (%x. False) xs = []"; |
|
475 by (induct_tac "xs" 1); |
|
476 by Auto_tac; |
|
477 qed "filter_False"; |
|
478 Addsimps [filter_False]; |
|
479 |
|
480 Goal "length (filter P xs) <= length xs"; |
|
481 by (induct_tac "xs" 1); |
|
482 by Auto_tac; |
|
483 qed "length_filter"; |
|
484 |
|
485 |
|
486 (** concat **) |
|
487 |
|
488 section "concat"; |
|
489 |
|
490 Goal "concat(xs@ys) = concat(xs)@concat(ys)"; |
|
491 by (induct_tac "xs" 1); |
|
492 by Auto_tac; |
|
493 qed"concat_append"; |
|
494 Addsimps [concat_append]; |
|
495 |
|
496 Goal "(concat xss = []) = (!xs:set xss. xs=[])"; |
|
497 by (induct_tac "xss" 1); |
|
498 by Auto_tac; |
|
499 qed "concat_eq_Nil_conv"; |
|
500 AddIffs [concat_eq_Nil_conv]; |
|
501 |
|
502 Goal "([] = concat xss) = (!xs:set xss. xs=[])"; |
|
503 by (induct_tac "xss" 1); |
|
504 by Auto_tac; |
|
505 qed "Nil_eq_concat_conv"; |
|
506 AddIffs [Nil_eq_concat_conv]; |
|
507 |
|
508 Goal "set(concat xs) = Union(set `` set xs)"; |
|
509 by (induct_tac "xs" 1); |
|
510 by Auto_tac; |
|
511 qed"set_concat"; |
|
512 Addsimps [set_concat]; |
|
513 |
|
514 Goal "map f (concat xs) = concat (map (map f) xs)"; |
|
515 by (induct_tac "xs" 1); |
|
516 by Auto_tac; |
|
517 qed "map_concat"; |
|
518 |
|
519 Goal "filter p (concat xs) = concat (map (filter p) xs)"; |
|
520 by (induct_tac "xs" 1); |
|
521 by Auto_tac; |
|
522 qed"filter_concat"; |
|
523 |
|
524 Goal "rev(concat xs) = concat (map rev (rev xs))"; |
|
525 by (induct_tac "xs" 1); |
|
526 by Auto_tac; |
|
527 qed "rev_concat"; |
|
528 |
|
529 (** nth **) |
|
530 |
|
531 section "nth"; |
|
532 |
|
533 Goal "!xs. (xs@ys)!n = (if n < length xs then xs!n else ys!(n - length xs))"; |
|
534 by (induct_tac "n" 1); |
|
535 by (Asm_simp_tac 1); |
|
536 by (rtac allI 1); |
|
537 by (exhaust_tac "xs" 1); |
|
538 by Auto_tac; |
|
539 qed_spec_mp "nth_append"; |
|
540 |
|
541 Goal "!n. n < length xs --> (map f xs)!n = f(xs!n)"; |
|
542 by (induct_tac "xs" 1); |
|
543 (* case [] *) |
|
544 by (Asm_full_simp_tac 1); |
|
545 (* case x#xl *) |
|
546 by (rtac allI 1); |
|
547 by (induct_tac "n" 1); |
|
548 by Auto_tac; |
|
549 qed_spec_mp "nth_map"; |
|
550 Addsimps [nth_map]; |
|
551 |
|
552 Goal "!n. n < length xs --> list_all P xs --> P(xs!n)"; |
|
553 by (induct_tac "xs" 1); |
|
554 (* case [] *) |
|
555 by (Simp_tac 1); |
|
556 (* case x#xl *) |
|
557 by (rtac allI 1); |
|
558 by (induct_tac "n" 1); |
|
559 by Auto_tac; |
|
560 qed_spec_mp "list_all_nth"; |
|
561 |
|
562 Goal "!n. n < length xs --> xs!n mem xs"; |
|
563 by (induct_tac "xs" 1); |
|
564 (* case [] *) |
|
565 by (Simp_tac 1); |
|
566 (* case x#xl *) |
|
567 by (rtac allI 1); |
|
568 by (induct_tac "n" 1); |
|
569 (* case 0 *) |
|
570 by (Asm_full_simp_tac 1); |
|
571 (* case Suc x *) |
|
572 by (Asm_full_simp_tac 1); |
|
573 qed_spec_mp "nth_mem"; |
|
574 Addsimps [nth_mem]; |
|
575 |
|
576 (** list update **) |
|
577 |
|
578 section "list update"; |
|
579 |
|
580 Goal "!i. length(xs[i:=x]) = length xs"; |
|
581 by (induct_tac "xs" 1); |
|
582 by (Simp_tac 1); |
|
583 by (asm_full_simp_tac (simpset() addsplits [nat.split]) 1); |
|
584 qed_spec_mp "length_list_update"; |
|
585 Addsimps [length_list_update]; |
|
586 |
|
587 |
|
588 (** last & butlast **) |
|
589 |
|
590 Goal "last(xs@[x]) = x"; |
|
591 by (induct_tac "xs" 1); |
|
592 by Auto_tac; |
|
593 qed "last_snoc"; |
|
594 Addsimps [last_snoc]; |
|
595 |
|
596 Goal "butlast(xs@[x]) = xs"; |
|
597 by (induct_tac "xs" 1); |
|
598 by Auto_tac; |
|
599 qed "butlast_snoc"; |
|
600 Addsimps [butlast_snoc]; |
|
601 |
|
602 Goal "length(butlast xs) = length xs - 1"; |
|
603 by (res_inst_tac [("xs","xs")] rev_induct 1); |
|
604 by Auto_tac; |
|
605 qed "length_butlast"; |
|
606 Addsimps [length_butlast]; |
|
607 |
|
608 Goal "!ys. butlast (xs@ys) = (if ys=[] then butlast xs else xs@butlast ys)"; |
|
609 by (induct_tac "xs" 1); |
|
610 by Auto_tac; |
|
611 qed_spec_mp "butlast_append"; |
|
612 |
|
613 Goal "x:set(butlast xs) --> x:set xs"; |
|
614 by (induct_tac "xs" 1); |
|
615 by Auto_tac; |
|
616 qed_spec_mp "in_set_butlastD"; |
|
617 |
|
618 Goal "x:set(butlast xs) ==> x:set(butlast(xs@ys))"; |
|
619 by (asm_simp_tac (simpset() addsimps [butlast_append]) 1); |
|
620 by (blast_tac (claset() addDs [in_set_butlastD]) 1); |
|
621 qed "in_set_butlast_appendI1"; |
|
622 |
|
623 Goal "x:set(butlast ys) ==> x:set(butlast(xs@ys))"; |
|
624 by (asm_simp_tac (simpset() addsimps [butlast_append]) 1); |
|
625 by (Clarify_tac 1); |
|
626 by (Full_simp_tac 1); |
|
627 qed "in_set_butlast_appendI2"; |
|
628 |
|
629 (** take & drop **) |
|
630 section "take & drop"; |
|
631 |
|
632 Goal "take 0 xs = []"; |
|
633 by (induct_tac "xs" 1); |
|
634 by Auto_tac; |
|
635 qed "take_0"; |
|
636 |
|
637 Goal "drop 0 xs = xs"; |
|
638 by (induct_tac "xs" 1); |
|
639 by Auto_tac; |
|
640 qed "drop_0"; |
|
641 |
|
642 Goal "take (Suc n) (x#xs) = x # take n xs"; |
|
643 by (Simp_tac 1); |
|
644 qed "take_Suc_Cons"; |
|
645 |
|
646 Goal "drop (Suc n) (x#xs) = drop n xs"; |
|
647 by (Simp_tac 1); |
|
648 qed "drop_Suc_Cons"; |
|
649 |
|
650 Delsimps [take_Cons,drop_Cons]; |
|
651 Addsimps [take_0,take_Suc_Cons,drop_0,drop_Suc_Cons]; |
|
652 |
|
653 Goal "!xs. length(take n xs) = min (length xs) n"; |
|
654 by (induct_tac "n" 1); |
|
655 by Auto_tac; |
|
656 by (exhaust_tac "xs" 1); |
|
657 by Auto_tac; |
|
658 qed_spec_mp "length_take"; |
|
659 Addsimps [length_take]; |
|
660 |
|
661 Goal "!xs. length(drop n xs) = (length xs - n)"; |
|
662 by (induct_tac "n" 1); |
|
663 by Auto_tac; |
|
664 by (exhaust_tac "xs" 1); |
|
665 by Auto_tac; |
|
666 qed_spec_mp "length_drop"; |
|
667 Addsimps [length_drop]; |
|
668 |
|
669 Goal "!xs. length xs <= n --> take n xs = xs"; |
|
670 by (induct_tac "n" 1); |
|
671 by Auto_tac; |
|
672 by (exhaust_tac "xs" 1); |
|
673 by Auto_tac; |
|
674 qed_spec_mp "take_all"; |
|
675 |
|
676 Goal "!xs. length xs <= n --> drop n xs = []"; |
|
677 by (induct_tac "n" 1); |
|
678 by Auto_tac; |
|
679 by (exhaust_tac "xs" 1); |
|
680 by Auto_tac; |
|
681 qed_spec_mp "drop_all"; |
|
682 |
|
683 Goal "!xs. take n (xs @ ys) = (take n xs @ take (n - length xs) ys)"; |
|
684 by (induct_tac "n" 1); |
|
685 by Auto_tac; |
|
686 by (exhaust_tac "xs" 1); |
|
687 by Auto_tac; |
|
688 qed_spec_mp "take_append"; |
|
689 Addsimps [take_append]; |
|
690 |
|
691 Goal "!xs. drop n (xs@ys) = drop n xs @ drop (n - length xs) ys"; |
|
692 by (induct_tac "n" 1); |
|
693 by Auto_tac; |
|
694 by (exhaust_tac "xs" 1); |
|
695 by Auto_tac; |
|
696 qed_spec_mp "drop_append"; |
|
697 Addsimps [drop_append]; |
|
698 |
|
699 Goal "!xs n. take n (take m xs) = take (min n m) xs"; |
|
700 by (induct_tac "m" 1); |
|
701 by Auto_tac; |
|
702 by (exhaust_tac "xs" 1); |
|
703 by Auto_tac; |
|
704 by (exhaust_tac "na" 1); |
|
705 by Auto_tac; |
|
706 qed_spec_mp "take_take"; |
|
707 |
|
708 Goal "!xs. drop n (drop m xs) = drop (n + m) xs"; |
|
709 by (induct_tac "m" 1); |
|
710 by Auto_tac; |
|
711 by (exhaust_tac "xs" 1); |
|
712 by Auto_tac; |
|
713 qed_spec_mp "drop_drop"; |
|
714 |
|
715 Goal "!xs n. take n (drop m xs) = drop m (take (n + m) xs)"; |
|
716 by (induct_tac "m" 1); |
|
717 by Auto_tac; |
|
718 by (exhaust_tac "xs" 1); |
|
719 by Auto_tac; |
|
720 qed_spec_mp "take_drop"; |
|
721 |
|
722 Goal "!xs. take n (map f xs) = map f (take n xs)"; |
|
723 by (induct_tac "n" 1); |
|
724 by Auto_tac; |
|
725 by (exhaust_tac "xs" 1); |
|
726 by Auto_tac; |
|
727 qed_spec_mp "take_map"; |
|
728 |
|
729 Goal "!xs. drop n (map f xs) = map f (drop n xs)"; |
|
730 by (induct_tac "n" 1); |
|
731 by Auto_tac; |
|
732 by (exhaust_tac "xs" 1); |
|
733 by Auto_tac; |
|
734 qed_spec_mp "drop_map"; |
|
735 |
|
736 Goal "!n i. i < n --> (take n xs)!i = xs!i"; |
|
737 by (induct_tac "xs" 1); |
|
738 by Auto_tac; |
|
739 by (exhaust_tac "n" 1); |
|
740 by (Blast_tac 1); |
|
741 by (exhaust_tac "i" 1); |
|
742 by Auto_tac; |
|
743 qed_spec_mp "nth_take"; |
|
744 Addsimps [nth_take]; |
|
745 |
|
746 Goal "!xs i. n + i <= length xs --> (drop n xs)!i = xs!(n+i)"; |
|
747 by (induct_tac "n" 1); |
|
748 by Auto_tac; |
|
749 by (exhaust_tac "xs" 1); |
|
750 by Auto_tac; |
|
751 qed_spec_mp "nth_drop"; |
|
752 Addsimps [nth_drop]; |
|
753 |
|
754 (** takeWhile & dropWhile **) |
|
755 |
|
756 section "takeWhile & dropWhile"; |
|
757 |
|
758 Goal "takeWhile P xs @ dropWhile P xs = xs"; |
|
759 by (induct_tac "xs" 1); |
|
760 by Auto_tac; |
|
761 qed "takeWhile_dropWhile_id"; |
|
762 Addsimps [takeWhile_dropWhile_id]; |
|
763 |
|
764 Goal "x:set xs & ~P(x) --> takeWhile P (xs @ ys) = takeWhile P xs"; |
|
765 by (induct_tac "xs" 1); |
|
766 by Auto_tac; |
|
767 bind_thm("takeWhile_append1", conjI RS (result() RS mp)); |
|
768 Addsimps [takeWhile_append1]; |
|
769 |
|
770 Goal "(!x:set xs. P(x)) --> takeWhile P (xs @ ys) = xs @ takeWhile P ys"; |
|
771 by (induct_tac "xs" 1); |
|
772 by Auto_tac; |
|
773 bind_thm("takeWhile_append2", ballI RS (result() RS mp)); |
|
774 Addsimps [takeWhile_append2]; |
|
775 |
|
776 Goal "x:set xs & ~P(x) --> dropWhile P (xs @ ys) = (dropWhile P xs)@ys"; |
|
777 by (induct_tac "xs" 1); |
|
778 by Auto_tac; |
|
779 bind_thm("dropWhile_append1", conjI RS (result() RS mp)); |
|
780 Addsimps [dropWhile_append1]; |
|
781 |
|
782 Goal "(!x:set xs. P(x)) --> dropWhile P (xs @ ys) = dropWhile P ys"; |
|
783 by (induct_tac "xs" 1); |
|
784 by Auto_tac; |
|
785 bind_thm("dropWhile_append2", ballI RS (result() RS mp)); |
|
786 Addsimps [dropWhile_append2]; |
|
787 |
|
788 Goal "x:set(takeWhile P xs) --> x:set xs & P x"; |
|
789 by (induct_tac "xs" 1); |
|
790 by Auto_tac; |
|
791 qed_spec_mp"set_take_whileD"; |
|
792 |
|
793 qed_goal "zip_Nil_Nil" thy "zip [] [] = []" (K [Simp_tac 1]); |
|
794 qed_goal "zip_Cons_Cons" thy "zip (x#xs) (y#ys) = (x,y)#zip xs ys" |
|
795 (K [Simp_tac 1]); |
|
796 |
|
797 |
|
798 (** foldl **) |
|
799 section "foldl"; |
|
800 |
|
801 Goal "!a. foldl f a (xs @ ys) = foldl f (foldl f a xs) ys"; |
|
802 by (induct_tac "xs" 1); |
|
803 by Auto_tac; |
|
804 qed_spec_mp "foldl_append"; |
|
805 Addsimps [foldl_append]; |
|
806 |
|
807 (* Note: `n <= foldl op+ n ns' looks simpler, but is more difficult to use |
|
808 because it requires an additional transitivity step |
|
809 *) |
|
810 Goal "!n::nat. m <= n --> m <= foldl op+ n ns"; |
|
811 by (induct_tac "ns" 1); |
|
812 by (Simp_tac 1); |
|
813 by (Asm_full_simp_tac 1); |
|
814 by (blast_tac (claset() addIs [trans_le_add1]) 1); |
|
815 qed_spec_mp "start_le_sum"; |
|
816 |
|
817 Goal "n : set ns ==> n <= foldl op+ 0 ns"; |
|
818 by (auto_tac (claset() addIs [start_le_sum], |
|
819 simpset() addsimps [in_set_conv_decomp])); |
|
820 qed "elem_le_sum"; |
|
821 |
|
822 Goal "!m. (foldl op+ m ns = 0) = (m=0 & (!n : set ns. n=0))"; |
|
823 by (induct_tac "ns" 1); |
|
824 by Auto_tac; |
|
825 qed_spec_mp "sum_eq_0_conv"; |
|
826 AddIffs [sum_eq_0_conv]; |
|
827 |
|
828 (** upto **) |
|
829 |
|
830 Goal "!i j. ~ j < i --> j - i < Suc j - i"; |
|
831 by(strip_tac 1); |
|
832 br diff_less_Suc_diff 1; |
|
833 be leI 1; |
|
834 val lemma = result(); |
|
835 |
|
836 Goalw [upto_def] "j<i ==> [i..j] = []"; |
|
837 br trans 1; |
|
838 brs paired_upto.rules 1; |
|
839 br lemma 1; |
|
840 by(Asm_simp_tac 1); |
|
841 qed "upto_conv_Nil"; |
|
842 |
|
843 Goalw [upto_def] "i<=j ==> [i..j] = i#[Suc i..j]"; |
|
844 br trans 1; |
|
845 brs paired_upto.rules 1; |
|
846 br lemma 1; |
|
847 by(asm_simp_tac (simpset() addsimps [leD]) 1); |
|
848 qed "upto_conv_Cons"; |
|
849 |
|
850 Addsimps [upto_conv_Nil,upto_conv_Cons]; |
|
851 |
|
852 (** nodups & remdups **) |
|
853 section "nodups & remdups"; |
|
854 |
|
855 Goal "set(remdups xs) = set xs"; |
|
856 by (induct_tac "xs" 1); |
|
857 by (Simp_tac 1); |
|
858 by (asm_full_simp_tac (simpset() addsimps [insert_absorb]) 1); |
|
859 qed "set_remdups"; |
|
860 Addsimps [set_remdups]; |
|
861 |
|
862 Goal "nodups(remdups xs)"; |
|
863 by (induct_tac "xs" 1); |
|
864 by Auto_tac; |
|
865 qed "nodups_remdups"; |
|
866 |
|
867 Goal "nodups xs --> nodups (filter P xs)"; |
|
868 by (induct_tac "xs" 1); |
|
869 by Auto_tac; |
|
870 qed_spec_mp "nodups_filter"; |
|
871 |
|
872 (** replicate **) |
|
873 section "replicate"; |
|
874 |
|
875 Goal "set(replicate (Suc n) x) = {x}"; |
|
876 by (induct_tac "n" 1); |
|
877 by Auto_tac; |
|
878 val lemma = result(); |
|
879 |
|
880 Goal "n ~= 0 ==> set(replicate n x) = {x}"; |
|
881 by (fast_tac (claset() addSDs [not0_implies_Suc] addSIs [lemma]) 1); |
|
882 qed "set_replicate"; |
|
883 Addsimps [set_replicate]; |
|
884 |
|
885 |
|
886 (*** Lexcicographic orderings on lists ***) |
|
887 section"Lexcicographic orderings on lists"; |
|
888 |
|
889 Goal "wf r ==> wf(lexn r n)"; |
|
890 by (induct_tac "n" 1); |
|
891 by (Simp_tac 1); |
|
892 by (Simp_tac 1); |
|
893 by (rtac wf_subset 1); |
|
894 by (rtac Int_lower1 2); |
|
895 by (rtac wf_prod_fun_image 1); |
|
896 by (rtac injI 2); |
|
897 by (Auto_tac); |
|
898 qed "wf_lexn"; |
|
899 |
|
900 Goal "!xs ys. (xs,ys) : lexn r n --> length xs = n & length ys = n"; |
|
901 by (induct_tac "n" 1); |
|
902 by (Auto_tac); |
|
903 qed_spec_mp "lexn_length"; |
|
904 |
|
905 Goalw [lex_def] "wf r ==> wf(lex r)"; |
|
906 by (rtac wf_UN 1); |
|
907 by (blast_tac (claset() addIs [wf_lexn]) 1); |
|
908 by (Clarify_tac 1); |
|
909 by (rename_tac "m n" 1); |
|
910 by (subgoal_tac "m ~= n" 1); |
|
911 by (Blast_tac 2); |
|
912 by (blast_tac (claset() addDs [lexn_length,not_sym]) 1); |
|
913 qed "wf_lex"; |
|
914 AddSIs [wf_lex]; |
|
915 |
|
916 Goal |
|
917 "lexn r n = \ |
|
918 \ {(xs,ys). length xs = n & length ys = n & \ |
|
919 \ (? xys x y xs' ys'. xs= xys @ x#xs' & ys= xys @ y#ys' & (x,y):r)}"; |
|
920 by (induct_tac "n" 1); |
|
921 by (Simp_tac 1); |
|
922 by (Blast_tac 1); |
|
923 by (asm_full_simp_tac (simpset() delsimps [length_Suc_conv] |
|
924 addsimps [lex_prod_def]) 1); |
|
925 by (auto_tac (claset(), simpset() delsimps [length_Suc_conv])); |
|
926 by (Blast_tac 1); |
|
927 by (rename_tac "a xys x xs' y ys'" 1); |
|
928 by (res_inst_tac [("x","a#xys")] exI 1); |
|
929 by (Simp_tac 1); |
|
930 by (exhaust_tac "xys" 1); |
|
931 by (ALLGOALS (asm_full_simp_tac (simpset() delsimps [length_Suc_conv]))); |
|
932 by (Blast_tac 1); |
|
933 qed "lexn_conv"; |
|
934 |
|
935 Goalw [lex_def] |
|
936 "lex r = \ |
|
937 \ {(xs,ys). length xs = length ys & \ |
|
938 \ (? xys x y xs' ys'. xs= xys @ x#xs' & ys= xys @ y#ys' & (x,y):r)}"; |
|
939 by (force_tac (claset(), simpset() delsimps [length_Suc_conv] addsimps [lexn_conv]) 1); |
|
940 qed "lex_conv"; |
|
941 |
|
942 Goalw [lexico_def] "wf r ==> wf(lexico r)"; |
|
943 by (Blast_tac 1); |
|
944 qed "wf_lexico"; |
|
945 AddSIs [wf_lexico]; |
|
946 |
|
947 Goalw |
|
948 [lexico_def,diag_def,lex_prod_def,measure_def,inv_image_def] |
|
949 "lexico r = {(xs,ys). length xs < length ys | \ |
|
950 \ length xs = length ys & (xs,ys) : lex r}"; |
|
951 by (Simp_tac 1); |
|
952 qed "lexico_conv"; |
|
953 |
|
954 Goal "([],ys) ~: lex r"; |
|
955 by (simp_tac (simpset() addsimps [lex_conv]) 1); |
|
956 qed "Nil_notin_lex"; |
|
957 |
|
958 Goal "(xs,[]) ~: lex r"; |
|
959 by (simp_tac (simpset() addsimps [lex_conv]) 1); |
|
960 qed "Nil2_notin_lex"; |
|
961 |
|
962 AddIffs [Nil_notin_lex,Nil2_notin_lex]; |
|
963 |
|
964 Goal "((x#xs,y#ys) : lex r) = \ |
|
965 \ ((x,y) : r & length xs = length ys | x=y & (xs,ys) : lex r)"; |
|
966 by (simp_tac (simpset() addsimps [lex_conv]) 1); |
|
967 by (rtac iffI 1); |
|
968 by (blast_tac (claset() addIs [Cons_eq_appendI]) 2); |
|
969 by (REPEAT(eresolve_tac [conjE, exE] 1)); |
|
970 by (exhaust_tac "xys" 1); |
|
971 by (Asm_full_simp_tac 1); |
|
972 by (Asm_full_simp_tac 1); |
|
973 by (Blast_tac 1); |
|
974 qed "Cons_in_lex"; |
|
975 AddIffs [Cons_in_lex]; |
|
976 |
247 |
977 |
248 |
978 (*** |
249 (*** |
979 Simplification procedure for all list equalities. |
250 Simplification procedure for all list equalities. |
980 Currently only tries to rearranges @ to see if |
251 Currently only tries to rearranges @ to see if |
1028 in |
299 in |
1029 val list_eq_simproc = mk_simproc "list_eq" [list_eq_pattern] list_eq; |
300 val list_eq_simproc = mk_simproc "list_eq" [list_eq_pattern] list_eq; |
1030 end; |
301 end; |
1031 |
302 |
1032 Addsimprocs [list_eq_simproc]; |
303 Addsimprocs [list_eq_simproc]; |
|
304 |
|
305 |
|
306 (** map **) |
|
307 |
|
308 section "map"; |
|
309 |
|
310 Goal "(!x. x : set xs --> f x = g x) --> map f xs = map g xs"; |
|
311 by (induct_tac "xs" 1); |
|
312 by Auto_tac; |
|
313 bind_thm("map_ext", impI RS (allI RS (result() RS mp))); |
|
314 |
|
315 Goal "map (%x. x) = (%xs. xs)"; |
|
316 by (rtac ext 1); |
|
317 by (induct_tac "xs" 1); |
|
318 by Auto_tac; |
|
319 qed "map_ident"; |
|
320 Addsimps[map_ident]; |
|
321 |
|
322 Goal "map f (xs@ys) = map f xs @ map f ys"; |
|
323 by (induct_tac "xs" 1); |
|
324 by Auto_tac; |
|
325 qed "map_append"; |
|
326 Addsimps[map_append]; |
|
327 |
|
328 Goalw [o_def] "map (f o g) xs = map f (map g xs)"; |
|
329 by (induct_tac "xs" 1); |
|
330 by Auto_tac; |
|
331 qed "map_compose"; |
|
332 Addsimps[map_compose]; |
|
333 |
|
334 Goal "rev(map f xs) = map f (rev xs)"; |
|
335 by (induct_tac "xs" 1); |
|
336 by Auto_tac; |
|
337 qed "rev_map"; |
|
338 |
|
339 (* a congruence rule for map: *) |
|
340 Goal "(xs=ys) --> (!x. x : set ys --> f x = g x) --> map f xs = map g ys"; |
|
341 by (rtac impI 1); |
|
342 by (hyp_subst_tac 1); |
|
343 by (induct_tac "ys" 1); |
|
344 by Auto_tac; |
|
345 val lemma = result(); |
|
346 bind_thm("map_cong",impI RSN (2,allI RSN (2,lemma RS mp RS mp))); |
|
347 |
|
348 Goal "(map f xs = []) = (xs = [])"; |
|
349 by (induct_tac "xs" 1); |
|
350 by Auto_tac; |
|
351 qed "map_is_Nil_conv"; |
|
352 AddIffs [map_is_Nil_conv]; |
|
353 |
|
354 Goal "([] = map f xs) = (xs = [])"; |
|
355 by (induct_tac "xs" 1); |
|
356 by Auto_tac; |
|
357 qed "Nil_is_map_conv"; |
|
358 AddIffs [Nil_is_map_conv]; |
|
359 |
|
360 |
|
361 (** rev **) |
|
362 |
|
363 section "rev"; |
|
364 |
|
365 Goal "rev(xs@ys) = rev(ys) @ rev(xs)"; |
|
366 by (induct_tac "xs" 1); |
|
367 by Auto_tac; |
|
368 qed "rev_append"; |
|
369 Addsimps[rev_append]; |
|
370 |
|
371 Goal "rev(rev l) = l"; |
|
372 by (induct_tac "l" 1); |
|
373 by Auto_tac; |
|
374 qed "rev_rev_ident"; |
|
375 Addsimps[rev_rev_ident]; |
|
376 |
|
377 Goal "(rev xs = []) = (xs = [])"; |
|
378 by (induct_tac "xs" 1); |
|
379 by Auto_tac; |
|
380 qed "rev_is_Nil_conv"; |
|
381 AddIffs [rev_is_Nil_conv]; |
|
382 |
|
383 Goal "([] = rev xs) = (xs = [])"; |
|
384 by (induct_tac "xs" 1); |
|
385 by Auto_tac; |
|
386 qed "Nil_is_rev_conv"; |
|
387 AddIffs [Nil_is_rev_conv]; |
|
388 |
|
389 val prems = Goal "[| P []; !!x xs. P xs ==> P(xs@[x]) |] ==> P xs"; |
|
390 by (stac (rev_rev_ident RS sym) 1); |
|
391 br(read_instantiate [("P","%xs. ?P(rev xs)")]list.induct)1; |
|
392 by (ALLGOALS Simp_tac); |
|
393 by (resolve_tac prems 1); |
|
394 by (eresolve_tac prems 1); |
|
395 qed "rev_induct"; |
|
396 |
|
397 fun rev_induct_tac xs = res_inst_tac [("xs",xs)] rev_induct; |
|
398 |
|
399 Goal "(xs = [] --> P) --> (!ys y. xs = ys@[y] --> P) --> P"; |
|
400 by (res_inst_tac [("xs","xs")] rev_induct 1); |
|
401 by Auto_tac; |
|
402 bind_thm ("rev_exhaust", |
|
403 impI RSN (2,allI RSN (2,allI RSN (2,impI RS (result() RS mp RS mp))))); |
|
404 |
|
405 |
|
406 (** mem **) |
|
407 |
|
408 section "mem"; |
|
409 |
|
410 Goal "x mem (xs@ys) = (x mem xs | x mem ys)"; |
|
411 by (induct_tac "xs" 1); |
|
412 by Auto_tac; |
|
413 qed "mem_append"; |
|
414 Addsimps[mem_append]; |
|
415 |
|
416 Goal "x mem [x:xs. P(x)] = (x mem xs & P(x))"; |
|
417 by (induct_tac "xs" 1); |
|
418 by Auto_tac; |
|
419 qed "mem_filter"; |
|
420 Addsimps[mem_filter]; |
|
421 |
|
422 (** set **) |
|
423 |
|
424 section "set"; |
|
425 |
|
426 qed_goal "finite_set" thy "finite (set xs)" |
|
427 (K [induct_tac "xs" 1, Auto_tac]); |
|
428 Addsimps[finite_set]; |
|
429 AddSIs[finite_set]; |
|
430 |
|
431 Goal "set (xs@ys) = (set xs Un set ys)"; |
|
432 by (induct_tac "xs" 1); |
|
433 by Auto_tac; |
|
434 qed "set_append"; |
|
435 Addsimps[set_append]; |
|
436 |
|
437 Goal "(x mem xs) = (x: set xs)"; |
|
438 by (induct_tac "xs" 1); |
|
439 by Auto_tac; |
|
440 qed "set_mem_eq"; |
|
441 |
|
442 Goal "set l <= set (x#l)"; |
|
443 by Auto_tac; |
|
444 qed "set_subset_Cons"; |
|
445 |
|
446 Goal "(set xs = {}) = (xs = [])"; |
|
447 by (induct_tac "xs" 1); |
|
448 by Auto_tac; |
|
449 qed "set_empty"; |
|
450 Addsimps [set_empty]; |
|
451 |
|
452 Goal "set(rev xs) = set(xs)"; |
|
453 by (induct_tac "xs" 1); |
|
454 by Auto_tac; |
|
455 qed "set_rev"; |
|
456 Addsimps [set_rev]; |
|
457 |
|
458 Goal "set(map f xs) = f``(set xs)"; |
|
459 by (induct_tac "xs" 1); |
|
460 by Auto_tac; |
|
461 qed "set_map"; |
|
462 Addsimps [set_map]; |
|
463 |
|
464 Goal "(x : set(filter P xs)) = (x : set xs & P x)"; |
|
465 by (induct_tac "xs" 1); |
|
466 by Auto_tac; |
|
467 qed "in_set_filter"; |
|
468 Addsimps [in_set_filter]; |
|
469 |
|
470 Goal "(x : set xs) = (? ys zs. xs = ys@x#zs)"; |
|
471 by (induct_tac "xs" 1); |
|
472 by (Simp_tac 1); |
|
473 by (Asm_simp_tac 1); |
|
474 by (rtac iffI 1); |
|
475 by (blast_tac (claset() addIs [eq_Nil_appendI,Cons_eq_appendI]) 1); |
|
476 by (REPEAT(etac exE 1)); |
|
477 by (exhaust_tac "ys" 1); |
|
478 by Auto_tac; |
|
479 qed "in_set_conv_decomp"; |
|
480 |
|
481 (* eliminate `lists' in favour of `set' *) |
|
482 |
|
483 Goal "(xs : lists A) = (!x : set xs. x : A)"; |
|
484 by (induct_tac "xs" 1); |
|
485 by Auto_tac; |
|
486 qed "in_lists_conv_set"; |
|
487 |
|
488 bind_thm("in_listsD",in_lists_conv_set RS iffD1); |
|
489 AddSDs [in_listsD]; |
|
490 bind_thm("in_listsI",in_lists_conv_set RS iffD2); |
|
491 AddSIs [in_listsI]; |
|
492 |
|
493 (** list_all **) |
|
494 |
|
495 section "list_all"; |
|
496 |
|
497 Goal "list_all (%x. True) xs = True"; |
|
498 by (induct_tac "xs" 1); |
|
499 by Auto_tac; |
|
500 qed "list_all_True"; |
|
501 Addsimps [list_all_True]; |
|
502 |
|
503 Goal "list_all p (xs@ys) = (list_all p xs & list_all p ys)"; |
|
504 by (induct_tac "xs" 1); |
|
505 by Auto_tac; |
|
506 qed "list_all_append"; |
|
507 Addsimps [list_all_append]; |
|
508 |
|
509 Goal "list_all P xs = (!x. x mem xs --> P(x))"; |
|
510 by (induct_tac "xs" 1); |
|
511 by Auto_tac; |
|
512 qed "list_all_mem_conv"; |
|
513 |
|
514 |
|
515 (** filter **) |
|
516 |
|
517 section "filter"; |
|
518 |
|
519 Goal "filter P (xs@ys) = filter P xs @ filter P ys"; |
|
520 by (induct_tac "xs" 1); |
|
521 by Auto_tac; |
|
522 qed "filter_append"; |
|
523 Addsimps [filter_append]; |
|
524 |
|
525 Goal "filter (%x. True) xs = xs"; |
|
526 by (induct_tac "xs" 1); |
|
527 by Auto_tac; |
|
528 qed "filter_True"; |
|
529 Addsimps [filter_True]; |
|
530 |
|
531 Goal "filter (%x. False) xs = []"; |
|
532 by (induct_tac "xs" 1); |
|
533 by Auto_tac; |
|
534 qed "filter_False"; |
|
535 Addsimps [filter_False]; |
|
536 |
|
537 Goal "length (filter P xs) <= length xs"; |
|
538 by (induct_tac "xs" 1); |
|
539 by Auto_tac; |
|
540 qed "length_filter"; |
|
541 |
|
542 |
|
543 (** concat **) |
|
544 |
|
545 section "concat"; |
|
546 |
|
547 Goal "concat(xs@ys) = concat(xs)@concat(ys)"; |
|
548 by (induct_tac "xs" 1); |
|
549 by Auto_tac; |
|
550 qed"concat_append"; |
|
551 Addsimps [concat_append]; |
|
552 |
|
553 Goal "(concat xss = []) = (!xs:set xss. xs=[])"; |
|
554 by (induct_tac "xss" 1); |
|
555 by Auto_tac; |
|
556 qed "concat_eq_Nil_conv"; |
|
557 AddIffs [concat_eq_Nil_conv]; |
|
558 |
|
559 Goal "([] = concat xss) = (!xs:set xss. xs=[])"; |
|
560 by (induct_tac "xss" 1); |
|
561 by Auto_tac; |
|
562 qed "Nil_eq_concat_conv"; |
|
563 AddIffs [Nil_eq_concat_conv]; |
|
564 |
|
565 Goal "set(concat xs) = Union(set `` set xs)"; |
|
566 by (induct_tac "xs" 1); |
|
567 by Auto_tac; |
|
568 qed"set_concat"; |
|
569 Addsimps [set_concat]; |
|
570 |
|
571 Goal "map f (concat xs) = concat (map (map f) xs)"; |
|
572 by (induct_tac "xs" 1); |
|
573 by Auto_tac; |
|
574 qed "map_concat"; |
|
575 |
|
576 Goal "filter p (concat xs) = concat (map (filter p) xs)"; |
|
577 by (induct_tac "xs" 1); |
|
578 by Auto_tac; |
|
579 qed"filter_concat"; |
|
580 |
|
581 Goal "rev(concat xs) = concat (map rev (rev xs))"; |
|
582 by (induct_tac "xs" 1); |
|
583 by Auto_tac; |
|
584 qed "rev_concat"; |
|
585 |
|
586 (** nth **) |
|
587 |
|
588 section "nth"; |
|
589 |
|
590 Goal "!xs. (xs@ys)!n = (if n < length xs then xs!n else ys!(n - length xs))"; |
|
591 by (induct_tac "n" 1); |
|
592 by (Asm_simp_tac 1); |
|
593 by (rtac allI 1); |
|
594 by (exhaust_tac "xs" 1); |
|
595 by Auto_tac; |
|
596 qed_spec_mp "nth_append"; |
|
597 |
|
598 Goal "!n. n < length xs --> (map f xs)!n = f(xs!n)"; |
|
599 by (induct_tac "xs" 1); |
|
600 (* case [] *) |
|
601 by (Asm_full_simp_tac 1); |
|
602 (* case x#xl *) |
|
603 by (rtac allI 1); |
|
604 by (induct_tac "n" 1); |
|
605 by Auto_tac; |
|
606 qed_spec_mp "nth_map"; |
|
607 Addsimps [nth_map]; |
|
608 |
|
609 Goal "!n. n < length xs --> list_all P xs --> P(xs!n)"; |
|
610 by (induct_tac "xs" 1); |
|
611 (* case [] *) |
|
612 by (Simp_tac 1); |
|
613 (* case x#xl *) |
|
614 by (rtac allI 1); |
|
615 by (induct_tac "n" 1); |
|
616 by Auto_tac; |
|
617 qed_spec_mp "list_all_nth"; |
|
618 |
|
619 Goal "!n. n < length xs --> xs!n mem xs"; |
|
620 by (induct_tac "xs" 1); |
|
621 (* case [] *) |
|
622 by (Simp_tac 1); |
|
623 (* case x#xl *) |
|
624 by (rtac allI 1); |
|
625 by (induct_tac "n" 1); |
|
626 (* case 0 *) |
|
627 by (Asm_full_simp_tac 1); |
|
628 (* case Suc x *) |
|
629 by (Asm_full_simp_tac 1); |
|
630 qed_spec_mp "nth_mem"; |
|
631 Addsimps [nth_mem]; |
|
632 |
|
633 (** list update **) |
|
634 |
|
635 section "list update"; |
|
636 |
|
637 Goal "!i. length(xs[i:=x]) = length xs"; |
|
638 by (induct_tac "xs" 1); |
|
639 by (Simp_tac 1); |
|
640 by (asm_full_simp_tac (simpset() addsplits [nat.split]) 1); |
|
641 qed_spec_mp "length_list_update"; |
|
642 Addsimps [length_list_update]; |
|
643 |
|
644 |
|
645 (** last & butlast **) |
|
646 |
|
647 Goal "last(xs@[x]) = x"; |
|
648 by (induct_tac "xs" 1); |
|
649 by Auto_tac; |
|
650 qed "last_snoc"; |
|
651 Addsimps [last_snoc]; |
|
652 |
|
653 Goal "butlast(xs@[x]) = xs"; |
|
654 by (induct_tac "xs" 1); |
|
655 by Auto_tac; |
|
656 qed "butlast_snoc"; |
|
657 Addsimps [butlast_snoc]; |
|
658 |
|
659 Goal "length(butlast xs) = length xs - 1"; |
|
660 by (res_inst_tac [("xs","xs")] rev_induct 1); |
|
661 by Auto_tac; |
|
662 qed "length_butlast"; |
|
663 Addsimps [length_butlast]; |
|
664 |
|
665 Goal "!ys. butlast (xs@ys) = (if ys=[] then butlast xs else xs@butlast ys)"; |
|
666 by (induct_tac "xs" 1); |
|
667 by Auto_tac; |
|
668 qed_spec_mp "butlast_append"; |
|
669 |
|
670 Goal "x:set(butlast xs) --> x:set xs"; |
|
671 by (induct_tac "xs" 1); |
|
672 by Auto_tac; |
|
673 qed_spec_mp "in_set_butlastD"; |
|
674 |
|
675 Goal "x:set(butlast xs) ==> x:set(butlast(xs@ys))"; |
|
676 by (asm_simp_tac (simpset() addsimps [butlast_append]) 1); |
|
677 by (blast_tac (claset() addDs [in_set_butlastD]) 1); |
|
678 qed "in_set_butlast_appendI1"; |
|
679 |
|
680 Goal "x:set(butlast ys) ==> x:set(butlast(xs@ys))"; |
|
681 by (asm_simp_tac (simpset() addsimps [butlast_append]) 1); |
|
682 by (Clarify_tac 1); |
|
683 by (Full_simp_tac 1); |
|
684 qed "in_set_butlast_appendI2"; |
|
685 |
|
686 (** take & drop **) |
|
687 section "take & drop"; |
|
688 |
|
689 Goal "take 0 xs = []"; |
|
690 by (induct_tac "xs" 1); |
|
691 by Auto_tac; |
|
692 qed "take_0"; |
|
693 |
|
694 Goal "drop 0 xs = xs"; |
|
695 by (induct_tac "xs" 1); |
|
696 by Auto_tac; |
|
697 qed "drop_0"; |
|
698 |
|
699 Goal "take (Suc n) (x#xs) = x # take n xs"; |
|
700 by (Simp_tac 1); |
|
701 qed "take_Suc_Cons"; |
|
702 |
|
703 Goal "drop (Suc n) (x#xs) = drop n xs"; |
|
704 by (Simp_tac 1); |
|
705 qed "drop_Suc_Cons"; |
|
706 |
|
707 Delsimps [take_Cons,drop_Cons]; |
|
708 Addsimps [take_0,take_Suc_Cons,drop_0,drop_Suc_Cons]; |
|
709 |
|
710 Goal "!xs. length(take n xs) = min (length xs) n"; |
|
711 by (induct_tac "n" 1); |
|
712 by Auto_tac; |
|
713 by (exhaust_tac "xs" 1); |
|
714 by Auto_tac; |
|
715 qed_spec_mp "length_take"; |
|
716 Addsimps [length_take]; |
|
717 |
|
718 Goal "!xs. length(drop n xs) = (length xs - n)"; |
|
719 by (induct_tac "n" 1); |
|
720 by Auto_tac; |
|
721 by (exhaust_tac "xs" 1); |
|
722 by Auto_tac; |
|
723 qed_spec_mp "length_drop"; |
|
724 Addsimps [length_drop]; |
|
725 |
|
726 Goal "!xs. length xs <= n --> take n xs = xs"; |
|
727 by (induct_tac "n" 1); |
|
728 by Auto_tac; |
|
729 by (exhaust_tac "xs" 1); |
|
730 by Auto_tac; |
|
731 qed_spec_mp "take_all"; |
|
732 |
|
733 Goal "!xs. length xs <= n --> drop n xs = []"; |
|
734 by (induct_tac "n" 1); |
|
735 by Auto_tac; |
|
736 by (exhaust_tac "xs" 1); |
|
737 by Auto_tac; |
|
738 qed_spec_mp "drop_all"; |
|
739 |
|
740 Goal "!xs. take n (xs @ ys) = (take n xs @ take (n - length xs) ys)"; |
|
741 by (induct_tac "n" 1); |
|
742 by Auto_tac; |
|
743 by (exhaust_tac "xs" 1); |
|
744 by Auto_tac; |
|
745 qed_spec_mp "take_append"; |
|
746 Addsimps [take_append]; |
|
747 |
|
748 Goal "!xs. drop n (xs@ys) = drop n xs @ drop (n - length xs) ys"; |
|
749 by (induct_tac "n" 1); |
|
750 by Auto_tac; |
|
751 by (exhaust_tac "xs" 1); |
|
752 by Auto_tac; |
|
753 qed_spec_mp "drop_append"; |
|
754 Addsimps [drop_append]; |
|
755 |
|
756 Goal "!xs n. take n (take m xs) = take (min n m) xs"; |
|
757 by (induct_tac "m" 1); |
|
758 by Auto_tac; |
|
759 by (exhaust_tac "xs" 1); |
|
760 by Auto_tac; |
|
761 by (exhaust_tac "na" 1); |
|
762 by Auto_tac; |
|
763 qed_spec_mp "take_take"; |
|
764 |
|
765 Goal "!xs. drop n (drop m xs) = drop (n + m) xs"; |
|
766 by (induct_tac "m" 1); |
|
767 by Auto_tac; |
|
768 by (exhaust_tac "xs" 1); |
|
769 by Auto_tac; |
|
770 qed_spec_mp "drop_drop"; |
|
771 |
|
772 Goal "!xs n. take n (drop m xs) = drop m (take (n + m) xs)"; |
|
773 by (induct_tac "m" 1); |
|
774 by Auto_tac; |
|
775 by (exhaust_tac "xs" 1); |
|
776 by Auto_tac; |
|
777 qed_spec_mp "take_drop"; |
|
778 |
|
779 Goal "!xs. take n (map f xs) = map f (take n xs)"; |
|
780 by (induct_tac "n" 1); |
|
781 by Auto_tac; |
|
782 by (exhaust_tac "xs" 1); |
|
783 by Auto_tac; |
|
784 qed_spec_mp "take_map"; |
|
785 |
|
786 Goal "!xs. drop n (map f xs) = map f (drop n xs)"; |
|
787 by (induct_tac "n" 1); |
|
788 by Auto_tac; |
|
789 by (exhaust_tac "xs" 1); |
|
790 by Auto_tac; |
|
791 qed_spec_mp "drop_map"; |
|
792 |
|
793 Goal "!n i. i < n --> (take n xs)!i = xs!i"; |
|
794 by (induct_tac "xs" 1); |
|
795 by Auto_tac; |
|
796 by (exhaust_tac "n" 1); |
|
797 by (Blast_tac 1); |
|
798 by (exhaust_tac "i" 1); |
|
799 by Auto_tac; |
|
800 qed_spec_mp "nth_take"; |
|
801 Addsimps [nth_take]; |
|
802 |
|
803 Goal "!xs i. n + i <= length xs --> (drop n xs)!i = xs!(n+i)"; |
|
804 by (induct_tac "n" 1); |
|
805 by Auto_tac; |
|
806 by (exhaust_tac "xs" 1); |
|
807 by Auto_tac; |
|
808 qed_spec_mp "nth_drop"; |
|
809 Addsimps [nth_drop]; |
|
810 |
|
811 (** takeWhile & dropWhile **) |
|
812 |
|
813 section "takeWhile & dropWhile"; |
|
814 |
|
815 Goal "takeWhile P xs @ dropWhile P xs = xs"; |
|
816 by (induct_tac "xs" 1); |
|
817 by Auto_tac; |
|
818 qed "takeWhile_dropWhile_id"; |
|
819 Addsimps [takeWhile_dropWhile_id]; |
|
820 |
|
821 Goal "x:set xs & ~P(x) --> takeWhile P (xs @ ys) = takeWhile P xs"; |
|
822 by (induct_tac "xs" 1); |
|
823 by Auto_tac; |
|
824 bind_thm("takeWhile_append1", conjI RS (result() RS mp)); |
|
825 Addsimps [takeWhile_append1]; |
|
826 |
|
827 Goal "(!x:set xs. P(x)) --> takeWhile P (xs @ ys) = xs @ takeWhile P ys"; |
|
828 by (induct_tac "xs" 1); |
|
829 by Auto_tac; |
|
830 bind_thm("takeWhile_append2", ballI RS (result() RS mp)); |
|
831 Addsimps [takeWhile_append2]; |
|
832 |
|
833 Goal "x:set xs & ~P(x) --> dropWhile P (xs @ ys) = (dropWhile P xs)@ys"; |
|
834 by (induct_tac "xs" 1); |
|
835 by Auto_tac; |
|
836 bind_thm("dropWhile_append1", conjI RS (result() RS mp)); |
|
837 Addsimps [dropWhile_append1]; |
|
838 |
|
839 Goal "(!x:set xs. P(x)) --> dropWhile P (xs @ ys) = dropWhile P ys"; |
|
840 by (induct_tac "xs" 1); |
|
841 by Auto_tac; |
|
842 bind_thm("dropWhile_append2", ballI RS (result() RS mp)); |
|
843 Addsimps [dropWhile_append2]; |
|
844 |
|
845 Goal "x:set(takeWhile P xs) --> x:set xs & P x"; |
|
846 by (induct_tac "xs" 1); |
|
847 by Auto_tac; |
|
848 qed_spec_mp"set_take_whileD"; |
|
849 |
|
850 qed_goal "zip_Nil_Nil" thy "zip [] [] = []" (K [Simp_tac 1]); |
|
851 qed_goal "zip_Cons_Cons" thy "zip (x#xs) (y#ys) = (x,y)#zip xs ys" |
|
852 (K [Simp_tac 1]); |
|
853 |
|
854 |
|
855 (** foldl **) |
|
856 section "foldl"; |
|
857 |
|
858 Goal "!a. foldl f a (xs @ ys) = foldl f (foldl f a xs) ys"; |
|
859 by (induct_tac "xs" 1); |
|
860 by Auto_tac; |
|
861 qed_spec_mp "foldl_append"; |
|
862 Addsimps [foldl_append]; |
|
863 |
|
864 (* Note: `n <= foldl op+ n ns' looks simpler, but is more difficult to use |
|
865 because it requires an additional transitivity step |
|
866 *) |
|
867 Goal "!n::nat. m <= n --> m <= foldl op+ n ns"; |
|
868 by (induct_tac "ns" 1); |
|
869 by (Simp_tac 1); |
|
870 by (Asm_full_simp_tac 1); |
|
871 by (blast_tac (claset() addIs [trans_le_add1]) 1); |
|
872 qed_spec_mp "start_le_sum"; |
|
873 |
|
874 Goal "n : set ns ==> n <= foldl op+ 0 ns"; |
|
875 by (auto_tac (claset() addIs [start_le_sum], |
|
876 simpset() addsimps [in_set_conv_decomp])); |
|
877 qed "elem_le_sum"; |
|
878 |
|
879 Goal "!m. (foldl op+ m ns = 0) = (m=0 & (!n : set ns. n=0))"; |
|
880 by (induct_tac "ns" 1); |
|
881 by Auto_tac; |
|
882 qed_spec_mp "sum_eq_0_conv"; |
|
883 AddIffs [sum_eq_0_conv]; |
|
884 |
|
885 (** upto **) |
|
886 |
|
887 (* Does not terminate! *) |
|
888 Goal "[i..j(] = (if i<j then i#[Suc i..j(] else [])"; |
|
889 by(induct_tac "j" 1); |
|
890 by Auto_tac; |
|
891 by(REPEAT(trans_tac 1)); |
|
892 qed "upt_rec"; |
|
893 |
|
894 Goal "j<=i ==> [i..j(] = []"; |
|
895 by(stac upt_rec 1); |
|
896 by(asm_simp_tac (simpset() addSolver cut_trans_tac) 1); |
|
897 qed "upt_conv_Nil"; |
|
898 Addsimps [upt_conv_Nil]; |
|
899 |
|
900 Goal "i<=j ==> [i..(Suc j)(] = [i..j(]@[j]"; |
|
901 by (Asm_simp_tac 1); |
|
902 qed "upt_Suc"; |
|
903 |
|
904 Goal "i<j ==> [i..j(] = i#[Suc i..j(]"; |
|
905 br trans 1; |
|
906 by(stac upt_rec 1); |
|
907 br refl 2; |
|
908 by (Asm_simp_tac 1); |
|
909 qed "upt_conv_Cons"; |
|
910 |
|
911 Goal "length [i..j(] = j-i"; |
|
912 by(induct_tac "j" 1); |
|
913 by (Simp_tac 1); |
|
914 by(asm_simp_tac (simpset() addsimps [Suc_diff_le] addSolver cut_trans_tac) 1); |
|
915 qed "length_upt"; |
|
916 Addsimps [length_upt]; |
|
917 |
|
918 Goal "i+k < j --> [i..j(] ! k = i+k"; |
|
919 by(induct_tac "j" 1); |
|
920 by(Simp_tac 1); |
|
921 by(asm_simp_tac (simpset() addsimps ([nth_append,less_diff_conv]@add_ac) |
|
922 addSolver cut_trans_tac) 1); |
|
923 br conjI 1; |
|
924 by(Clarify_tac 1); |
|
925 bd add_lessD1 1; |
|
926 by(trans_tac 1); |
|
927 by(Clarify_tac 1); |
|
928 br conjI 1; |
|
929 by(Clarify_tac 1); |
|
930 by(subgoal_tac "n=i+k" 1); |
|
931 by(Asm_full_simp_tac 1); |
|
932 by(trans_tac 1); |
|
933 by(Clarify_tac 1); |
|
934 by(subgoal_tac "n=i+k" 1); |
|
935 by(Asm_full_simp_tac 1); |
|
936 by(trans_tac 1); |
|
937 qed_spec_mp "nth_upt"; |
|
938 Addsimps [nth_upt]; |
|
939 |
|
940 |
|
941 (** nodups & remdups **) |
|
942 section "nodups & remdups"; |
|
943 |
|
944 Goal "set(remdups xs) = set xs"; |
|
945 by (induct_tac "xs" 1); |
|
946 by (Simp_tac 1); |
|
947 by (asm_full_simp_tac (simpset() addsimps [insert_absorb]) 1); |
|
948 qed "set_remdups"; |
|
949 Addsimps [set_remdups]; |
|
950 |
|
951 Goal "nodups(remdups xs)"; |
|
952 by (induct_tac "xs" 1); |
|
953 by Auto_tac; |
|
954 qed "nodups_remdups"; |
|
955 |
|
956 Goal "nodups xs --> nodups (filter P xs)"; |
|
957 by (induct_tac "xs" 1); |
|
958 by Auto_tac; |
|
959 qed_spec_mp "nodups_filter"; |
|
960 |
|
961 (** replicate **) |
|
962 section "replicate"; |
|
963 |
|
964 Goal "set(replicate (Suc n) x) = {x}"; |
|
965 by (induct_tac "n" 1); |
|
966 by Auto_tac; |
|
967 val lemma = result(); |
|
968 |
|
969 Goal "n ~= 0 ==> set(replicate n x) = {x}"; |
|
970 by (fast_tac (claset() addSDs [not0_implies_Suc] addSIs [lemma]) 1); |
|
971 qed "set_replicate"; |
|
972 Addsimps [set_replicate]; |
|
973 |
|
974 |
|
975 (*** Lexcicographic orderings on lists ***) |
|
976 section"Lexcicographic orderings on lists"; |
|
977 |
|
978 Goal "wf r ==> wf(lexn r n)"; |
|
979 by (induct_tac "n" 1); |
|
980 by (Simp_tac 1); |
|
981 by (Simp_tac 1); |
|
982 by (rtac wf_subset 1); |
|
983 by (rtac Int_lower1 2); |
|
984 by (rtac wf_prod_fun_image 1); |
|
985 by (rtac injI 2); |
|
986 by (Auto_tac); |
|
987 qed "wf_lexn"; |
|
988 |
|
989 Goal "!xs ys. (xs,ys) : lexn r n --> length xs = n & length ys = n"; |
|
990 by (induct_tac "n" 1); |
|
991 by (Auto_tac); |
|
992 qed_spec_mp "lexn_length"; |
|
993 |
|
994 Goalw [lex_def] "wf r ==> wf(lex r)"; |
|
995 by (rtac wf_UN 1); |
|
996 by (blast_tac (claset() addIs [wf_lexn]) 1); |
|
997 by (Clarify_tac 1); |
|
998 by (rename_tac "m n" 1); |
|
999 by (subgoal_tac "m ~= n" 1); |
|
1000 by (Blast_tac 2); |
|
1001 by (blast_tac (claset() addDs [lexn_length,not_sym]) 1); |
|
1002 qed "wf_lex"; |
|
1003 AddSIs [wf_lex]; |
|
1004 |
|
1005 Goal |
|
1006 "lexn r n = \ |
|
1007 \ {(xs,ys). length xs = n & length ys = n & \ |
|
1008 \ (? xys x y xs' ys'. xs= xys @ x#xs' & ys= xys @ y#ys' & (x,y):r)}"; |
|
1009 by (induct_tac "n" 1); |
|
1010 by (Simp_tac 1); |
|
1011 by (Blast_tac 1); |
|
1012 by (asm_full_simp_tac (simpset() delsimps [length_Suc_conv] |
|
1013 addsimps [lex_prod_def]) 1); |
|
1014 by (auto_tac (claset(), simpset() delsimps [length_Suc_conv])); |
|
1015 by (Blast_tac 1); |
|
1016 by (rename_tac "a xys x xs' y ys'" 1); |
|
1017 by (res_inst_tac [("x","a#xys")] exI 1); |
|
1018 by (Simp_tac 1); |
|
1019 by (exhaust_tac "xys" 1); |
|
1020 by (ALLGOALS (asm_full_simp_tac (simpset() delsimps [length_Suc_conv]))); |
|
1021 by (Blast_tac 1); |
|
1022 qed "lexn_conv"; |
|
1023 |
|
1024 Goalw [lex_def] |
|
1025 "lex r = \ |
|
1026 \ {(xs,ys). length xs = length ys & \ |
|
1027 \ (? xys x y xs' ys'. xs= xys @ x#xs' & ys= xys @ y#ys' & (x,y):r)}"; |
|
1028 by (force_tac (claset(), simpset() delsimps [length_Suc_conv] addsimps [lexn_conv]) 1); |
|
1029 qed "lex_conv"; |
|
1030 |
|
1031 Goalw [lexico_def] "wf r ==> wf(lexico r)"; |
|
1032 by (Blast_tac 1); |
|
1033 qed "wf_lexico"; |
|
1034 AddSIs [wf_lexico]; |
|
1035 |
|
1036 Goalw |
|
1037 [lexico_def,diag_def,lex_prod_def,measure_def,inv_image_def] |
|
1038 "lexico r = {(xs,ys). length xs < length ys | \ |
|
1039 \ length xs = length ys & (xs,ys) : lex r}"; |
|
1040 by (Simp_tac 1); |
|
1041 qed "lexico_conv"; |
|
1042 |
|
1043 Goal "([],ys) ~: lex r"; |
|
1044 by (simp_tac (simpset() addsimps [lex_conv]) 1); |
|
1045 qed "Nil_notin_lex"; |
|
1046 |
|
1047 Goal "(xs,[]) ~: lex r"; |
|
1048 by (simp_tac (simpset() addsimps [lex_conv]) 1); |
|
1049 qed "Nil2_notin_lex"; |
|
1050 |
|
1051 AddIffs [Nil_notin_lex,Nil2_notin_lex]; |
|
1052 |
|
1053 Goal "((x#xs,y#ys) : lex r) = \ |
|
1054 \ ((x,y) : r & length xs = length ys | x=y & (xs,ys) : lex r)"; |
|
1055 by (simp_tac (simpset() addsimps [lex_conv]) 1); |
|
1056 by (rtac iffI 1); |
|
1057 by (blast_tac (claset() addIs [Cons_eq_appendI]) 2); |
|
1058 by (REPEAT(eresolve_tac [conjE, exE] 1)); |
|
1059 by (exhaust_tac "xys" 1); |
|
1060 by (Asm_full_simp_tac 1); |
|
1061 by (Asm_full_simp_tac 1); |
|
1062 by (Blast_tac 1); |
|
1063 qed "Cons_in_lex"; |
|
1064 AddIffs [Cons_in_lex]; |