src/HOL/Library/Sublist.thy
changeset 63173 3413b1cf30cd
parent 63155 ea8540c71581
child 63649 e690d6f2185b
equal deleted inserted replaced
63172:d4f459eb7ed0 63173:3413b1cf30cd
   125 
   125 
   126 lemma prefix_same_cases:
   126 lemma prefix_same_cases:
   127   "prefix (xs\<^sub>1::'a list) ys \<Longrightarrow> prefix xs\<^sub>2 ys \<Longrightarrow> prefix xs\<^sub>1 xs\<^sub>2 \<or> prefix xs\<^sub>2 xs\<^sub>1"
   127   "prefix (xs\<^sub>1::'a list) ys \<Longrightarrow> prefix xs\<^sub>2 ys \<Longrightarrow> prefix xs\<^sub>1 xs\<^sub>2 \<or> prefix xs\<^sub>2 xs\<^sub>1"
   128   unfolding prefix_def by (force simp: append_eq_append_conv2)
   128   unfolding prefix_def by (force simp: append_eq_append_conv2)
   129 
   129 
       
   130 lemma prefix_length_prefix:
       
   131   "prefix ps xs \<Longrightarrow> prefix qs xs \<Longrightarrow> length ps \<le> length qs \<Longrightarrow> prefix ps qs"
       
   132 by (auto simp: prefix_def) (metis append_Nil2 append_eq_append_conv_if)
       
   133 
   130 lemma set_mono_prefix: "prefix xs ys \<Longrightarrow> set xs \<subseteq> set ys"
   134 lemma set_mono_prefix: "prefix xs ys \<Longrightarrow> set xs \<subseteq> set ys"
   131   by (auto simp add: prefix_def)
   135   by (auto simp add: prefix_def)
   132 
   136 
   133 lemma take_is_prefix: "prefix (take n xs) xs"
   137 lemma take_is_prefix: "prefix (take n xs) xs"
   134   unfolding prefix_def by (metis append_take_drop_id)
   138   unfolding prefix_def by (metis append_take_drop_id)
   222 
   226 
   223 lemma prefixes_eq_Snoc:
   227 lemma prefixes_eq_Snoc:
   224   "prefixes ys = xs @ [x] \<longleftrightarrow>
   228   "prefixes ys = xs @ [x] \<longleftrightarrow>
   225   (ys = [] \<and> xs = [] \<or> (\<exists>z zs. ys = zs@[z] \<and> xs = prefixes zs)) \<and> x = ys"
   229   (ys = [] \<and> xs = [] \<or> (\<exists>z zs. ys = zs@[z] \<and> xs = prefixes zs)) \<and> x = ys"
   226 by (cases ys rule: rev_cases) auto
   230 by (cases ys rule: rev_cases) auto
       
   231 
       
   232 
       
   233 subsection \<open>Longest Common Prefix\<close>
       
   234 
       
   235 definition Longest_common_prefix :: "'a list set \<Rightarrow> 'a list" where
       
   236 "Longest_common_prefix L = (GREATEST ps WRT length. \<forall>xs \<in> L. prefix ps xs)"
       
   237 
       
   238 lemma Longest_common_prefix_ex: "L \<noteq> {} \<Longrightarrow>
       
   239   \<exists>ps. (\<forall>xs \<in> L. prefix ps xs) \<and> (\<forall>qs. (\<forall>xs \<in> L. prefix qs xs) \<longrightarrow> size qs \<le> size ps)"
       
   240   (is "_ \<Longrightarrow> \<exists>ps. ?P L ps")
       
   241 proof(induction "LEAST n. \<exists>xs \<in>L. n = length xs" arbitrary: L)
       
   242   case 0
       
   243   have "[] : L" using "0.hyps" LeastI[of "\<lambda>n. \<exists>xs\<in>L. n = length xs"] \<open>L \<noteq> {}\<close>
       
   244     by auto
       
   245   hence "?P L []" by(auto)
       
   246   thus ?case ..
       
   247 next
       
   248   case (Suc n)
       
   249   let ?EX = "\<lambda>n. \<exists>xs\<in>L. n = length xs"
       
   250   obtain x xs where xxs: "x#xs \<in> L" "size xs = n" using Suc.prems Suc.hyps(2)
       
   251     by(metis LeastI_ex[of ?EX] Suc_length_conv ex_in_conv)
       
   252   hence "[] \<notin> L" using Suc.hyps(2) by auto
       
   253   show ?case
       
   254   proof (cases "\<forall>xs \<in> L. \<exists>ys. xs = x#ys")
       
   255     case True
       
   256     let ?L = "{ys. x#ys \<in> L}"
       
   257     have 1: "(LEAST n. \<exists>xs \<in> ?L. n = length xs) = n"
       
   258       using xxs Suc.prems Suc.hyps(2) Least_le[of "?EX"]
       
   259       by - (rule Least_equality, fastforce+)
       
   260     have 2: "?L \<noteq> {}" using \<open>x # xs \<in> L\<close> by auto
       
   261     from Suc.hyps(1)[OF 1[symmetric] 2] obtain ps where IH: "?P ?L ps" ..
       
   262     { fix qs
       
   263       assume "\<forall>qs. (\<forall>xa. x # xa \<in> L \<longrightarrow> prefix qs xa) \<longrightarrow> length qs \<le> length ps"
       
   264       and "\<forall>xs\<in>L. prefix qs xs"
       
   265       hence "length (tl qs) \<le> length ps"
       
   266         by (metis Cons_prefix_Cons hd_Cons_tl list.sel(2) Nil_prefix) 
       
   267       hence "length qs \<le> Suc (length ps)" by auto
       
   268     }
       
   269     hence "?P L (x#ps)" using True IH by auto
       
   270     thus ?thesis ..
       
   271   next
       
   272     case False
       
   273     then obtain y ys where yys: "x\<noteq>y" "y#ys \<in> L" using \<open>[] \<notin> L\<close>
       
   274       by (auto) (metis list.exhaust)
       
   275     have "\<forall>qs. (\<forall>xs\<in>L. prefix qs xs) \<longrightarrow> qs = []" using yys \<open>x#xs \<in> L\<close>
       
   276       by auto (metis Cons_prefix_Cons prefix_Cons)
       
   277     hence "?P L []" by auto
       
   278     thus ?thesis ..
       
   279   qed
       
   280 qed
       
   281 
       
   282 lemma Longest_common_prefix_unique: "L \<noteq> {} \<Longrightarrow>
       
   283   \<exists>! ps. (\<forall>xs \<in> L. prefix ps xs) \<and> (\<forall>qs. (\<forall>xs \<in> L. prefix qs xs) \<longrightarrow> size qs \<le> size ps)"
       
   284 by(rule ex_ex1I[OF Longest_common_prefix_ex];
       
   285    meson equals0I prefix_length_prefix prefix_order.antisym)
       
   286 
       
   287 lemma Longest_common_prefix_eq:
       
   288  "\<lbrakk> L \<noteq> {};  \<forall>xs \<in> L. prefix ps xs;
       
   289     \<forall>qs. (\<forall>xs \<in> L. prefix qs xs) \<longrightarrow> size qs \<le> size ps \<rbrakk>
       
   290   \<Longrightarrow> Longest_common_prefix L = ps"
       
   291 unfolding Longest_common_prefix_def GreatestM_def
       
   292 by(rule some1_equality[OF Longest_common_prefix_unique]) auto
       
   293 
       
   294 lemma Longest_common_prefix_prefix:
       
   295   "xs \<in> L \<Longrightarrow> prefix (Longest_common_prefix L) xs"
       
   296 unfolding Longest_common_prefix_def GreatestM_def
       
   297 by(rule someI2_ex[OF Longest_common_prefix_ex]) auto
       
   298 
       
   299 lemma Longest_common_prefix_longest:
       
   300   "L \<noteq> {} \<Longrightarrow> \<forall>xs\<in>L. prefix ps xs \<Longrightarrow> length ps \<le> length(Longest_common_prefix L)"
       
   301 unfolding Longest_common_prefix_def GreatestM_def
       
   302 by(rule someI2_ex[OF Longest_common_prefix_ex]) auto
       
   303 
       
   304 lemma Longest_common_prefix_max_prefix:
       
   305   "L \<noteq> {} \<Longrightarrow> \<forall>xs\<in>L. prefix ps xs \<Longrightarrow> prefix ps (Longest_common_prefix L)"
       
   306 by(metis Longest_common_prefix_prefix Longest_common_prefix_longest
       
   307      prefix_length_prefix ex_in_conv)
       
   308 
       
   309 lemma Longest_common_prefix_Nil: "[] \<in> L \<Longrightarrow> Longest_common_prefix L = []"
       
   310 using Longest_common_prefix_prefix prefix_Nil by blast
       
   311 
       
   312 lemma Longest_common_prefix_image_Cons: "L \<noteq> {} \<Longrightarrow>
       
   313   Longest_common_prefix (op # x ` L) = x # Longest_common_prefix L"
       
   314 apply(rule Longest_common_prefix_eq)
       
   315   apply(simp)
       
   316  apply (simp add: Longest_common_prefix_prefix)
       
   317 apply simp
       
   318 by(metis Longest_common_prefix_longest[of L] Cons_prefix_Cons Nitpick.size_list_simp(2)
       
   319      Suc_le_mono hd_Cons_tl order.strict_implies_order zero_less_Suc)
       
   320 
       
   321 lemma Longest_common_prefix_eq_Cons: assumes "L \<noteq> {}" "[] \<notin> L"  "\<forall>xs\<in>L. hd xs = x"
       
   322 shows "Longest_common_prefix L = x # Longest_common_prefix {ys. x#ys \<in> L}"
       
   323 proof -
       
   324   have "L = op # x ` {ys. x#ys \<in> L}" using assms(2,3)
       
   325     by (auto simp: image_def)(metis hd_Cons_tl)
       
   326   thus ?thesis
       
   327     by (metis Longest_common_prefix_image_Cons image_is_empty assms(1))
       
   328 qed
       
   329 
       
   330 lemma Longest_common_prefix_eq_Nil:
       
   331   "\<lbrakk>x#ys \<in> L; y#zs \<in> L; x \<noteq> y \<rbrakk> \<Longrightarrow> Longest_common_prefix L = []"
       
   332 by (metis Longest_common_prefix_prefix list.inject prefix_Cons)
       
   333 
       
   334 
       
   335 fun longest_common_prefix :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list" where
       
   336 "longest_common_prefix (x#xs) (y#ys) =
       
   337   (if x=y then x # longest_common_prefix xs ys else [])" |
       
   338 "longest_common_prefix _ _ = []"
       
   339 
       
   340 lemma longest_common_prefix_prefix1:
       
   341   "prefix (longest_common_prefix xs ys) xs"
       
   342 by(induction xs ys rule: longest_common_prefix.induct) auto
       
   343 
       
   344 lemma longest_common_prefix_prefix2:
       
   345   "prefix (longest_common_prefix xs ys) ys"
       
   346 by(induction xs ys rule: longest_common_prefix.induct) auto
       
   347 
       
   348 lemma longest_common_prefix_max_prefix:
       
   349   "\<lbrakk> prefix ps xs; prefix ps ys \<rbrakk>
       
   350    \<Longrightarrow> prefix ps (longest_common_prefix xs ys)"
       
   351 by(induction xs ys arbitrary: ps rule: longest_common_prefix.induct)
       
   352   (auto simp: prefix_Cons)
   227 
   353 
   228 
   354 
   229 subsection \<open>Parallel lists\<close>
   355 subsection \<open>Parallel lists\<close>
   230 
   356 
   231 definition parallel :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool"  (infixl "\<parallel>" 50)
   357 definition parallel :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool"  (infixl "\<parallel>" 50)