src/HOL/Library/Sublist.thy
changeset 57498 ea44ec62a574
parent 57497 4106a2bc066a
child 57499 7e22776f2d32
equal deleted inserted replaced
57497:4106a2bc066a 57498:ea44ec62a574
   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)