132 |
132 |
133 declare list.intros [simp,TC] |
133 declare list.intros [simp,TC] |
134 |
134 |
135 (*An elimination rule, for type-checking*) |
135 (*An elimination rule, for type-checking*) |
136 inductive_cases ConsE: "Cons(a,l) : list(A)" |
136 inductive_cases ConsE: "Cons(a,l) : list(A)" |
|
137 |
|
138 lemma Cons_type_iff [simp]: "Cons(a,l) \<in> list(A) <-> a \<in> A & l \<in> list(A)" |
|
139 by (blast elim: ConsE) |
137 |
140 |
138 (*Proving freeness results*) |
141 (*Proving freeness results*) |
139 lemma Cons_iff: "Cons(a,l)=Cons(a',l') <-> a=a' & l=l'" |
142 lemma Cons_iff: "Cons(a,l)=Cons(a',l') <-> a=a' & l=l'" |
140 by auto |
143 by auto |
141 |
144 |
418 "ls: list(list(nat)) ==> list_add(flat(ls)) = list_add(map(list_add,ls))" |
421 "ls: list(list(nat)) ==> list_add(flat(ls)) = list_add(map(list_add,ls))" |
419 apply (induct_tac "ls") |
422 apply (induct_tac "ls") |
420 apply (simp_all (no_asm_simp) add: list_add_app) |
423 apply (simp_all (no_asm_simp) add: list_add_app) |
421 done |
424 done |
422 |
425 |
423 (** New induction rule **) |
426 (** New induction rules **) |
424 |
|
425 |
427 |
426 lemma list_append_induct: |
428 lemma list_append_induct: |
427 "[| l: list(A); |
429 "[| l: list(A); |
428 P(Nil); |
430 P(Nil); |
429 !!x y. [| x: A; y: list(A); P(y) |] ==> P(y @ [x]) |
431 !!x y. [| x: A; y: list(A); P(y) |] ==> P(y @ [x]) |
431 apply (subgoal_tac "P(rev(rev(l)))", simp) |
433 apply (subgoal_tac "P(rev(rev(l)))", simp) |
432 apply (erule rev_type [THEN list.induct], simp_all) |
434 apply (erule rev_type [THEN list.induct], simp_all) |
433 done |
435 done |
434 |
436 |
435 lemmas list_append_induct = list_append_induct [case_names Nil snoc, consumes 1] |
437 lemmas list_append_induct = list_append_induct [case_names Nil snoc, consumes 1] |
|
438 |
|
439 lemma list_complete_induct_lemma [rule_format]: |
|
440 assumes ih: |
|
441 "\<And>l. [| l \<in> list(A); |
|
442 \<forall>l' \<in> list(A). length(l') < length(l) --> P(l')|] |
|
443 ==> P(l)" |
|
444 shows "n \<in> nat ==> \<forall>l \<in> list(A). length(l) < n --> P(l)" |
|
445 apply (induct_tac n, simp) |
|
446 apply (blast intro: ih elim!: leE) |
|
447 done |
|
448 |
|
449 theorem list_complete_induct: |
|
450 "[| l \<in> list(A); |
|
451 \<And>l. [| l \<in> list(A); |
|
452 \<forall>l' \<in> list(A). length(l') < length(l) --> P(l')|] |
|
453 ==> P(l) |
|
454 |] ==> P(l)" |
|
455 apply (rule list_complete_induct_lemma [of A]) |
|
456 prefer 4 apply (rule le_refl, simp) |
|
457 apply blast |
|
458 apply simp |
|
459 apply assumption |
|
460 done |
436 |
461 |
437 |
462 |
438 (*** Thanks to Sidi Ehmety for these results about min, take, etc. ***) |
463 (*** Thanks to Sidi Ehmety for these results about min, take, etc. ***) |
439 |
464 |
440 (** min FIXME: replace by Int! **) |
465 (** min FIXME: replace by Int! **) |
571 apply (rule append_eq_append, auto) |
596 apply (rule append_eq_append, auto) |
572 done |
597 done |
573 |
598 |
574 lemma append_self_iff [simp]: |
599 lemma append_self_iff [simp]: |
575 "[| xs:list(A); ys:list(A); zs:list(A) |] ==> xs@ys=xs@zs <-> ys=zs" |
600 "[| xs:list(A); ys:list(A); zs:list(A) |] ==> xs@ys=xs@zs <-> ys=zs" |
576 apply (simp (no_asm_simp)) |
601 by simp |
577 done |
|
578 |
602 |
579 lemma append_self_iff2 [simp]: |
603 lemma append_self_iff2 [simp]: |
580 "[| xs:list(A); ys:list(A); zs:list(A) |] ==> ys@xs=zs@xs <-> ys=zs" |
604 "[| xs:list(A); ys:list(A); zs:list(A) |] ==> ys@xs=zs@xs <-> ys=zs" |
581 apply (simp (no_asm_simp)) |
605 by simp |
582 done |
|
583 |
606 |
584 (* Can also be proved from append_eq_append_iff2, |
607 (* Can also be proved from append_eq_append_iff2, |
585 but the proof requires two more hypotheses: x:A and y:A *) |
608 but the proof requires two more hypotheses: x:A and y:A *) |
586 lemma append1_eq_iff [rule_format,simp]: |
609 lemma append1_eq_iff [rule_format,simp]: |
587 "xs:list(A) ==> \<forall>ys \<in> list(A). xs@[x] = ys@[y] <-> (xs = ys & x=y)" |
610 "xs:list(A) ==> \<forall>ys \<in> list(A). xs@[x] = ys@[y] <-> (xs = ys & x=y)" |
595 done |
618 done |
596 |
619 |
597 |
620 |
598 lemma append_right_is_self_iff [simp]: |
621 lemma append_right_is_self_iff [simp]: |
599 "[| xs:list(A); ys:list(A) |] ==> (xs@ys = ys) <-> (xs=Nil)" |
622 "[| xs:list(A); ys:list(A) |] ==> (xs@ys = ys) <-> (xs=Nil)" |
600 apply (simp (no_asm_simp) add: append_left_is_Nil_iff) |
623 by (simp (no_asm_simp) add: append_left_is_Nil_iff) |
601 done |
|
602 |
624 |
603 lemma append_right_is_self_iff2 [simp]: |
625 lemma append_right_is_self_iff2 [simp]: |
604 "[| xs:list(A); ys:list(A) |] ==> (ys = xs@ys) <-> (xs=Nil)" |
626 "[| xs:list(A); ys:list(A) |] ==> (ys = xs@ys) <-> (xs=Nil)" |
605 apply (rule iffI) |
627 apply (rule iffI) |
606 apply (drule sym, auto) |
628 apply (drule sym, auto) |
628 done |
650 done |
629 |
651 |
630 lemma rev_list_elim [rule_format]: |
652 lemma rev_list_elim [rule_format]: |
631 "xs:list(A) ==> |
653 "xs:list(A) ==> |
632 (xs=Nil --> P) --> (\<forall>ys \<in> list(A). \<forall>y \<in> A. xs =ys@[y] -->P)-->P" |
654 (xs=Nil --> P) --> (\<forall>ys \<in> list(A). \<forall>y \<in> A. xs =ys@[y] -->P)-->P" |
633 apply (erule list_append_induct, auto) |
655 by (erule list_append_induct, auto) |
634 done |
|
635 |
656 |
636 |
657 |
637 (** more theorems about drop **) |
658 (** more theorems about drop **) |
638 |
659 |
639 lemma length_drop [rule_format,simp]: |
660 lemma length_drop [rule_format,simp]: |