431 inductive list_emb :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> 'a list \<Rightarrow> bool" |
431 inductive list_emb :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> 'a list \<Rightarrow> bool" |
432 for P :: "('a \<Rightarrow> 'a \<Rightarrow> bool)" |
432 for P :: "('a \<Rightarrow> 'a \<Rightarrow> bool)" |
433 where |
433 where |
434 list_emb_Nil [intro, simp]: "list_emb P [] ys" |
434 list_emb_Nil [intro, simp]: "list_emb P [] ys" |
435 | list_emb_Cons [intro] : "list_emb P xs ys \<Longrightarrow> list_emb P xs (y#ys)" |
435 | list_emb_Cons [intro] : "list_emb P xs ys \<Longrightarrow> list_emb P xs (y#ys)" |
436 | list_emb_Cons2 [intro]: "P\<^sup>=\<^sup>= x y \<Longrightarrow> list_emb P xs ys \<Longrightarrow> list_emb P (x#xs) (y#ys)" |
436 | list_emb_Cons2 [intro]: "P x y \<Longrightarrow> list_emb P xs ys \<Longrightarrow> list_emb P (x#xs) (y#ys)" |
437 |
437 |
438 lemma list_emb_Nil2 [simp]: |
438 lemma list_emb_Nil2 [simp]: |
439 assumes "list_emb P xs []" shows "xs = []" |
439 assumes "list_emb P xs []" shows "xs = []" |
440 using assms by (cases rule: list_emb.cases) auto |
440 using assms by (cases rule: list_emb.cases) auto |
441 |
441 |
442 lemma list_emb_refl [simp, intro!]: |
442 lemma list_emb_refl: |
443 "list_emb P xs xs" |
443 assumes "\<And>x. x \<in> set xs \<Longrightarrow> P x x" |
444 by (induct xs) auto |
444 shows "list_emb P xs xs" |
|
445 using assms by (induct xs) auto |
445 |
446 |
446 lemma list_emb_Cons_Nil [simp]: "list_emb P (x#xs) [] = False" |
447 lemma list_emb_Cons_Nil [simp]: "list_emb P (x#xs) [] = False" |
447 proof - |
448 proof - |
448 { assume "list_emb P (x#xs) []" |
449 { assume "list_emb P (x#xs) []" |
449 from list_emb_Nil2 [OF this] have False by simp |
450 from list_emb_Nil2 [OF this] have False by simp |
461 using assms |
462 using assms |
462 by (induct arbitrary: zs) auto |
463 by (induct arbitrary: zs) auto |
463 |
464 |
464 lemma list_emb_ConsD: |
465 lemma list_emb_ConsD: |
465 assumes "list_emb P (x#xs) ys" |
466 assumes "list_emb P (x#xs) ys" |
466 shows "\<exists>us v vs. ys = us @ v # vs \<and> P\<^sup>=\<^sup>= x v \<and> list_emb P xs vs" |
467 shows "\<exists>us v vs. ys = us @ v # vs \<and> P x v \<and> list_emb P xs vs" |
467 using assms |
468 using assms |
468 proof (induct x \<equiv> "x # xs" ys arbitrary: x xs) |
469 proof (induct x \<equiv> "x # xs" ys arbitrary: x xs) |
469 case list_emb_Cons |
470 case list_emb_Cons |
470 then show ?case by (metis append_Cons) |
471 then show ?case by (metis append_Cons) |
471 next |
472 next |
480 proof (induction xs arbitrary: ys zs) |
481 proof (induction xs arbitrary: ys zs) |
481 case Nil then show ?case by auto |
482 case Nil then show ?case by auto |
482 next |
483 next |
483 case (Cons x xs) |
484 case (Cons x xs) |
484 then obtain us v vs where |
485 then obtain us v vs where |
485 zs: "zs = us @ v # vs" and p: "P\<^sup>=\<^sup>= x v" and lh: "list_emb P (xs @ ys) vs" |
486 zs: "zs = us @ v # vs" and p: "P x v" and lh: "list_emb P (xs @ ys) vs" |
486 by (auto dest: list_emb_ConsD) |
487 by (auto dest: list_emb_ConsD) |
487 obtain sk\<^sub>0 :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list" and sk\<^sub>1 :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list" where |
488 obtain sk\<^sub>0 :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list" and sk\<^sub>1 :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list" where |
488 sk: "\<forall>x\<^sub>0 x\<^sub>1. \<not> list_emb P (xs @ x\<^sub>0) x\<^sub>1 \<or> sk\<^sub>0 x\<^sub>0 x\<^sub>1 @ sk\<^sub>1 x\<^sub>0 x\<^sub>1 = x\<^sub>1 \<and> list_emb P xs (sk\<^sub>0 x\<^sub>0 x\<^sub>1) \<and> list_emb P x\<^sub>0 (sk\<^sub>1 x\<^sub>0 x\<^sub>1)" |
489 sk: "\<forall>x\<^sub>0 x\<^sub>1. \<not> list_emb P (xs @ x\<^sub>0) x\<^sub>1 \<or> sk\<^sub>0 x\<^sub>0 x\<^sub>1 @ sk\<^sub>1 x\<^sub>0 x\<^sub>1 = x\<^sub>1 \<and> list_emb P xs (sk\<^sub>0 x\<^sub>0 x\<^sub>1) \<and> list_emb P x\<^sub>0 (sk\<^sub>1 x\<^sub>0 x\<^sub>1)" |
489 using Cons(1) by (metis (no_types)) |
490 using Cons(1) by (metis (no_types)) |
490 hence "\<forall>x\<^sub>2. list_emb P (x # xs) (x\<^sub>2 @ v # sk\<^sub>0 ys vs)" using p lh by auto |
491 hence "\<forall>x\<^sub>2. list_emb P (x # xs) (x\<^sub>2 @ v # sk\<^sub>0 ys vs)" using p lh by auto |
516 proof (induction arbitrary: zs) |
517 proof (induction arbitrary: zs) |
517 case list_emb_Nil show ?case by blast |
518 case list_emb_Nil show ?case by blast |
518 next |
519 next |
519 case (list_emb_Cons xs ys y) |
520 case (list_emb_Cons xs ys y) |
520 from list_emb_ConsD [OF `list_emb P (y#ys) zs`] obtain us v vs |
521 from list_emb_ConsD [OF `list_emb P (y#ys) zs`] obtain us v vs |
521 where zs: "zs = us @ v # vs" and "P\<^sup>=\<^sup>= y v" and "list_emb P ys vs" by blast |
522 where zs: "zs = us @ v # vs" and "P y v" and "list_emb P ys vs" by blast |
522 then have "list_emb P ys (v#vs)" by blast |
523 then have "list_emb P ys (v#vs)" by blast |
523 then have "list_emb P ys zs" unfolding zs by (rule list_emb_append2) |
524 then have "list_emb P ys zs" unfolding zs by (rule list_emb_append2) |
524 from list_emb_Cons.IH [OF this] and list_emb_Cons.prems show ?case by simp |
525 from list_emb_Cons.IH [OF this] and list_emb_Cons.prems show ?case by simp |
525 next |
526 next |
526 case (list_emb_Cons2 x y xs ys) |
527 case (list_emb_Cons2 x y xs ys) |
527 from list_emb_ConsD [OF `list_emb P (y#ys) zs`] obtain us v vs |
528 from list_emb_ConsD [OF `list_emb P (y#ys) zs`] obtain us v vs |
528 where zs: "zs = us @ v # vs" and "P\<^sup>=\<^sup>= y v" and "list_emb P ys vs" by blast |
529 where zs: "zs = us @ v # vs" and "P y v" and "list_emb P ys vs" by blast |
529 with list_emb_Cons2 have "list_emb P xs vs" by simp |
530 with list_emb_Cons2 have "list_emb P xs vs" by simp |
530 moreover have "P\<^sup>=\<^sup>= x v" |
531 moreover have "P x v" |
531 proof - |
532 proof - |
532 from zs and `zs \<in> lists A` have "v \<in> A" by auto |
533 from zs and `zs \<in> lists A` have "v \<in> A" by auto |
533 moreover have "x \<in> A" and "y \<in> A" using list_emb_Cons2 by simp_all |
534 moreover have "x \<in> A" and "y \<in> A" using list_emb_Cons2 by simp_all |
534 ultimately show ?thesis |
535 ultimately show ?thesis |
535 using `P\<^sup>=\<^sup>= x y` and `P\<^sup>=\<^sup>= y v` and assms |
536 using `P x y` and `P y v` and assms |
536 by blast |
537 by blast |
537 qed |
538 qed |
538 ultimately have "list_emb P (x#xs) (v#vs)" by blast |
539 ultimately have "list_emb P (x#xs) (v#vs)" by blast |
539 then show ?case unfolding zs by (rule list_emb_append2) |
540 then show ?case unfolding zs by (rule list_emb_append2) |
540 qed |
541 qed |
633 { assume "xs=[]" then have ?case using list_emb_Cons2(1) by auto } |
634 { assume "xs=[]" then have ?case using list_emb_Cons2(1) by auto } |
634 moreover |
635 moreover |
635 { fix us vs assume "xs=x#us" "ys=x#vs" then have ?case using list_emb_Cons2 by auto} |
636 { fix us vs assume "xs=x#us" "ys=x#vs" then have ?case using list_emb_Cons2 by auto} |
636 moreover |
637 moreover |
637 { fix us assume "xs=x#us" "ys=[]" then have ?case using list_emb_Cons2(2) by bestsimp } |
638 { fix us assume "xs=x#us" "ys=[]" then have ?case using list_emb_Cons2(2) by bestsimp } |
638 ultimately show ?case using `op =\<^sup>=\<^sup>= x y` by (auto simp: Cons_eq_append_conv) |
639 ultimately show ?case using `op = x y` by (auto simp: Cons_eq_append_conv) |
639 qed } |
640 qed } |
640 moreover assume ?l |
641 moreover assume ?l |
641 ultimately show ?r by blast |
642 ultimately show ?r by blast |
642 next |
643 next |
643 assume ?r then show ?l by (metis list_emb_append_mono sublisteq_refl) |
644 assume ?r then show ?l by (metis list_emb_append_mono sublisteq_refl) |