src/HOL/Library/Sublist.thy
changeset 63149 f5dbab18c404
parent 63117 acb6d72fc42e
child 63155 ea8540c71581
equal deleted inserted replaced
63144:76130b7cc450 63149:f5dbab18c404
   262   unfolding parallel_def by auto
   262   unfolding parallel_def by auto
   263 
   263 
   264 
   264 
   265 subsection \<open>Suffix order on lists\<close>
   265 subsection \<open>Suffix order on lists\<close>
   266 
   266 
   267 definition suffixeq :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool"
       
   268   where "suffixeq xs ys = (\<exists>zs. ys = zs @ xs)"
       
   269 
       
   270 definition suffix :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool"
   267 definition suffix :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool"
   271   where "suffix xs ys \<longleftrightarrow> (\<exists>us. ys = us @ xs \<and> us \<noteq> [])"
   268   where "suffix xs ys = (\<exists>zs. ys = zs @ xs)"
   272 
   269 
   273 lemma suffix_imp_suffixeq:
   270 definition strict_suffix :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool"
   274   "suffix xs ys \<Longrightarrow> suffixeq xs ys"
   271   where "strict_suffix xs ys \<longleftrightarrow> (\<exists>us. ys = us @ xs \<and> us \<noteq> [])"
   275   by (auto simp: suffixeq_def suffix_def)
   272 
   276 
   273 lemma strict_suffix_imp_suffix:
   277 lemma suffixeqI [intro?]: "ys = zs @ xs \<Longrightarrow> suffixeq xs ys"
   274   "strict_suffix xs ys \<Longrightarrow> suffix xs ys"
   278   unfolding suffixeq_def by blast
   275   by (auto simp: suffix_def strict_suffix_def)
   279 
   276 
   280 lemma suffixeqE [elim?]:
   277 lemma suffixI [intro?]: "ys = zs @ xs \<Longrightarrow> suffix xs ys"
   281   assumes "suffixeq xs ys"
   278   unfolding suffix_def by blast
       
   279 
       
   280 lemma suffixE [elim?]:
       
   281   assumes "suffix xs ys"
   282   obtains zs where "ys = zs @ xs"
   282   obtains zs where "ys = zs @ xs"
   283   using assms unfolding suffixeq_def by blast
   283   using assms unfolding suffix_def by blast
   284 
   284 
   285 lemma suffixeq_refl [iff]: "suffixeq xs xs"
   285 lemma suffix_refl [iff]: "suffix xs xs"
   286   by (auto simp add: suffixeq_def)
   286   by (auto simp add: suffix_def)
       
   287 
   287 lemma suffix_trans:
   288 lemma suffix_trans:
   288   "suffix xs ys \<Longrightarrow> suffix ys zs \<Longrightarrow> suffix xs zs"
   289   "suffix xs ys \<Longrightarrow> suffix ys zs \<Longrightarrow> suffix xs zs"
   289   by (auto simp: suffix_def)
   290   by (auto simp: suffix_def)
   290 lemma suffixeq_trans: "\<lbrakk>suffixeq xs ys; suffixeq ys zs\<rbrakk> \<Longrightarrow> suffixeq xs zs"
   291 
   291   by (auto simp add: suffixeq_def)
   292 lemma strict_suffix_trans:
   292 lemma suffixeq_antisym: "\<lbrakk>suffixeq xs ys; suffixeq ys xs\<rbrakk> \<Longrightarrow> xs = ys"
   293   "\<lbrakk>strict_suffix xs ys; strict_suffix ys zs\<rbrakk> \<Longrightarrow> strict_suffix xs zs"
   293   by (auto simp add: suffixeq_def)
   294 by (auto simp add: strict_suffix_def)
   294 
   295 
   295 lemma suffixeq_tl [simp]: "suffixeq (tl xs) xs"
   296 lemma suffix_antisym: "\<lbrakk>suffix xs ys; suffix ys xs\<rbrakk> \<Longrightarrow> xs = ys"
   296   by (induct xs) (auto simp: suffixeq_def)
   297   by (auto simp add: suffix_def)
   297 
   298 
   298 lemma suffix_tl [simp]: "xs \<noteq> [] \<Longrightarrow> suffix (tl xs) xs"
   299 lemma suffix_tl [simp]: "suffix (tl xs) xs"
   299   by (induct xs) (auto simp: suffix_def)
   300   by (induct xs) (auto simp: suffix_def)
   300 
   301 
   301 lemma Nil_suffixeq [iff]: "suffixeq [] xs"
   302 lemma strict_suffix_tl [simp]: "xs \<noteq> [] \<Longrightarrow> strict_suffix (tl xs) xs"
   302   by (simp add: suffixeq_def)
   303   by (induct xs) (auto simp: strict_suffix_def)
   303 lemma suffixeq_Nil [simp]: "(suffixeq xs []) = (xs = [])"
   304 
   304   by (auto simp add: suffixeq_def)
   305 lemma Nil_suffix [iff]: "suffix [] xs"
   305 
   306   by (simp add: suffix_def)
   306 lemma suffixeq_ConsI: "suffixeq xs ys \<Longrightarrow> suffixeq xs (y # ys)"
   307 
   307   by (auto simp add: suffixeq_def)
   308 lemma suffix_Nil [simp]: "(suffix xs []) = (xs = [])"
   308 lemma suffixeq_ConsD: "suffixeq (x # xs) ys \<Longrightarrow> suffixeq xs ys"
   309   by (auto simp add: suffix_def)
   309   by (auto simp add: suffixeq_def)
   310 
   310 
   311 lemma suffix_ConsI: "suffix xs ys \<Longrightarrow> suffix xs (y # ys)"
   311 lemma suffixeq_appendI: "suffixeq xs ys \<Longrightarrow> suffixeq xs (zs @ ys)"
   312   by (auto simp add: suffix_def)
   312   by (auto simp add: suffixeq_def)
   313 
   313 lemma suffixeq_appendD: "suffixeq (zs @ xs) ys \<Longrightarrow> suffixeq xs ys"
   314 lemma suffix_ConsD: "suffix (x # xs) ys \<Longrightarrow> suffix xs ys"
   314   by (auto simp add: suffixeq_def)
   315   by (auto simp add: suffix_def)
   315 
   316 
   316 lemma suffix_set_subset:
   317 lemma suffix_appendI: "suffix xs ys \<Longrightarrow> suffix xs (zs @ ys)"
   317   "suffix xs ys \<Longrightarrow> set xs \<subseteq> set ys" by (auto simp: suffix_def)
   318   by (auto simp add: suffix_def)
   318 
   319 
   319 lemma suffixeq_set_subset:
   320 lemma suffix_appendD: "suffix (zs @ xs) ys \<Longrightarrow> suffix xs ys"
   320   "suffixeq xs ys \<Longrightarrow> set xs \<subseteq> set ys" by (auto simp: suffixeq_def)
   321   by (auto simp add: suffix_def)
   321 
   322 
   322 lemma suffixeq_ConsD2: "suffixeq (x # xs) (y # ys) \<Longrightarrow> suffixeq xs ys"
   323 lemma strict_suffix_set_subset: "strict_suffix xs ys \<Longrightarrow> set xs \<subseteq> set ys"
       
   324 by (auto simp: strict_suffix_def)
       
   325 
       
   326 lemma suffix_set_subset: "suffix xs ys \<Longrightarrow> set xs \<subseteq> set ys"
       
   327 by (auto simp: suffix_def)
       
   328 
       
   329 lemma suffix_ConsD2: "suffix (x # xs) (y # ys) \<Longrightarrow> suffix xs ys"
   323 proof -
   330 proof -
   324   assume "suffixeq (x # xs) (y # ys)"
   331   assume "suffix (x # xs) (y # ys)"
   325   then obtain zs where "y # ys = zs @ x # xs" ..
   332   then obtain zs where "y # ys = zs @ x # xs" ..
   326   then show ?thesis
   333   then show ?thesis
   327     by (induct zs) (auto intro!: suffixeq_appendI suffixeq_ConsI)
   334     by (induct zs) (auto intro!: suffix_appendI suffix_ConsI)
   328 qed
   335 qed
   329 
   336 
   330 lemma suffixeq_to_prefix [code]: "suffixeq xs ys \<longleftrightarrow> prefix (rev xs) (rev ys)"
   337 lemma suffix_to_prefix [code]: "suffix xs ys \<longleftrightarrow> prefix (rev xs) (rev ys)"
   331 proof
   338 proof
   332   assume "suffixeq xs ys"
   339   assume "suffix xs ys"
   333   then obtain zs where "ys = zs @ xs" ..
   340   then obtain zs where "ys = zs @ xs" ..
   334   then have "rev ys = rev xs @ rev zs" by simp
   341   then have "rev ys = rev xs @ rev zs" by simp
   335   then show "prefix (rev xs) (rev ys)" ..
   342   then show "prefix (rev xs) (rev ys)" ..
   336 next
   343 next
   337   assume "prefix (rev xs) (rev ys)"
   344   assume "prefix (rev xs) (rev ys)"
   338   then obtain zs where "rev ys = rev xs @ zs" ..
   345   then obtain zs where "rev ys = rev xs @ zs" ..
   339   then have "rev (rev ys) = rev zs @ rev (rev xs)" by simp
   346   then have "rev (rev ys) = rev zs @ rev (rev xs)" by simp
   340   then have "ys = rev zs @ xs" by simp
   347   then have "ys = rev zs @ xs" by simp
   341   then show "suffixeq xs ys" ..
   348   then show "suffix xs ys" ..
   342 qed
   349 qed
   343 
   350 
   344 lemma distinct_suffixeq: "distinct ys \<Longrightarrow> suffixeq xs ys \<Longrightarrow> distinct xs"
   351 lemma distinct_suffix: "distinct ys \<Longrightarrow> suffix xs ys \<Longrightarrow> distinct xs"
   345   by (clarsimp elim!: suffixeqE)
   352   by (clarsimp elim!: suffixE)
   346 
   353 
   347 lemma suffixeq_map: "suffixeq xs ys \<Longrightarrow> suffixeq (map f xs) (map f ys)"
   354 lemma suffix_map: "suffix xs ys \<Longrightarrow> suffix (map f xs) (map f ys)"
   348   by (auto elim!: suffixeqE intro: suffixeqI)
   355   by (auto elim!: suffixE intro: suffixI)
   349 
   356 
   350 lemma suffixeq_drop: "suffixeq (drop n as) as"
   357 lemma suffix_drop: "suffix (drop n as) as"
   351   unfolding suffixeq_def
   358   unfolding suffix_def
   352   apply (rule exI [where x = "take n as"])
   359   apply (rule exI [where x = "take n as"])
   353   apply simp
   360   apply simp
   354   done
   361   done
   355 
   362 
   356 lemma suffixeq_take: "suffixeq xs ys \<Longrightarrow> ys = take (length ys - length xs) ys @ xs"
   363 lemma suffix_take: "suffix xs ys \<Longrightarrow> ys = take (length ys - length xs) ys @ xs"
   357   by (auto elim!: suffixeqE)
   364   by (auto elim!: suffixE)
   358 
   365 
   359 lemma suffixeq_suffix_reflclp_conv: "suffixeq = suffix\<^sup>=\<^sup>="
   366 lemma strict_suffix_reflclp_conv: "strict_suffix\<^sup>=\<^sup>= = suffix"
   360 proof (intro ext iffI)
   367 by (intro ext) (auto simp: suffix_def strict_suffix_def)
   361   fix xs ys :: "'a list"
   368 
   362   assume "suffixeq xs ys"
   369 lemma suffix_lists: "suffix xs ys \<Longrightarrow> ys \<in> lists A \<Longrightarrow> xs \<in> lists A"
   363   show "suffix\<^sup>=\<^sup>= xs ys"
   370   unfolding suffix_def by auto
   364   proof
       
   365     assume "xs \<noteq> ys"
       
   366     with \<open>suffixeq xs ys\<close> show "suffix xs ys"
       
   367       by (auto simp: suffixeq_def suffix_def)
       
   368   qed
       
   369 next
       
   370   fix xs ys :: "'a list"
       
   371   assume "suffix\<^sup>=\<^sup>= xs ys"
       
   372   then show "suffixeq xs ys"
       
   373   proof
       
   374     assume "suffix xs ys" then show "suffixeq xs ys"
       
   375       by (rule suffix_imp_suffixeq)
       
   376   next
       
   377     assume "xs = ys" then show "suffixeq xs ys"
       
   378       by (auto simp: suffixeq_def)
       
   379   qed
       
   380 qed
       
   381 
   371 
   382 lemma parallelD1: "x \<parallel> y \<Longrightarrow> \<not> prefix x y"
   372 lemma parallelD1: "x \<parallel> y \<Longrightarrow> \<not> prefix x y"
   383   by blast
   373   by blast
   384 
   374 
   385 lemma parallelD2: "x \<parallel> y \<Longrightarrow> \<not> prefix y x"
   375 lemma parallelD2: "x \<parallel> y \<Longrightarrow> \<not> prefix y x"
   416   next
   406   next
   417     case False
   407     case False
   418     then show ?thesis by (rule Cons_parallelI1)
   408     then show ?thesis by (rule Cons_parallelI1)
   419   qed
   409   qed
   420 qed
   410 qed
   421 
       
   422 lemma suffix_reflclp_conv: "suffix\<^sup>=\<^sup>= = suffixeq"
       
   423   by (intro ext) (auto simp: suffixeq_def suffix_def)
       
   424 
       
   425 lemma suffix_lists: "suffix xs ys \<Longrightarrow> ys \<in> lists A \<Longrightarrow> xs \<in> lists A"
       
   426   unfolding suffix_def by auto
       
   427 
   411 
   428 
   412 
   429 subsection \<open>Homeomorphic embedding on lists\<close>
   413 subsection \<open>Homeomorphic embedding on lists\<close>
   430 
   414 
   431 inductive list_emb :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> 'a list \<Rightarrow> bool"
   415 inductive list_emb :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> 'a list \<Rightarrow> bool"
   498     using Cons(1) by (metis (no_types))
   482     using Cons(1) by (metis (no_types))
   499   hence "\<forall>x\<^sub>2. list_emb P (x # xs) (x\<^sub>2 @ v # sk\<^sub>0 ys vs)" using p lh by auto
   483   hence "\<forall>x\<^sub>2. list_emb P (x # xs) (x\<^sub>2 @ v # sk\<^sub>0 ys vs)" using p lh by auto
   500   thus ?case using lh zs sk by (metis (no_types) append_Cons append_assoc)
   484   thus ?case using lh zs sk by (metis (no_types) append_Cons append_assoc)
   501 qed
   485 qed
   502 
   486 
       
   487 lemma list_emb_strict_suffix:
       
   488   assumes "list_emb P xs ys" and "strict_suffix ys zs"
       
   489   shows "list_emb P xs zs"
       
   490   using assms(2) and list_emb_append2 [OF assms(1)] by (auto simp: strict_suffix_def)
       
   491 
   503 lemma list_emb_suffix:
   492 lemma list_emb_suffix:
   504   assumes "list_emb P xs ys" and "suffix ys zs"
   493   assumes "list_emb P xs ys" and "suffix ys zs"
   505   shows "list_emb P xs zs"
   494   shows "list_emb P xs zs"
   506   using assms(2) and list_emb_append2 [OF assms(1)] by (auto simp: suffix_def)
   495 using assms and list_emb_strict_suffix
   507 
   496 unfolding strict_suffix_reflclp_conv[symmetric] by auto
   508 lemma list_emb_suffixeq:
       
   509   assumes "list_emb P xs ys" and "suffixeq ys zs"
       
   510   shows "list_emb P xs zs"
       
   511   using assms and list_emb_suffix unfolding suffixeq_suffix_reflclp_conv by auto
       
   512 
   497 
   513 lemma list_emb_length: "list_emb P xs ys \<Longrightarrow> length xs \<le> length ys"
   498 lemma list_emb_length: "list_emb P xs ys \<Longrightarrow> length xs \<le> length ys"
   514   by (induct rule: list_emb.induct) auto
   499   by (induct rule: list_emb.induct) auto
   515 
   500 
   516 lemma list_emb_trans:
   501 lemma list_emb_trans: