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