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) |