188 apply (case_tac ys, simp_all) |
188 apply (case_tac ys, simp_all) |
189 done |
189 done |
190 |
190 |
191 lemma not_prefix_cases: |
191 lemma not_prefix_cases: |
192 assumes pfx: "\<not> ps \<le> ls" |
192 assumes pfx: "\<not> ps \<le> ls" |
193 and c1: "\<lbrakk> ps \<noteq> []; ls = [] \<rbrakk> \<Longrightarrow> R" |
193 obtains |
194 and c2: "\<And>a as x xs. \<lbrakk> ps = a#as; ls = x#xs; x = a; \<not> as \<le> xs\<rbrakk> \<Longrightarrow> R" |
194 (c1) "ps \<noteq> []" and "ls = []" |
195 and c3: "\<And>a as x xs. \<lbrakk> ps = a#as; ls = x#xs; x \<noteq> a\<rbrakk> \<Longrightarrow> R" |
195 | (c2) a as x xs where "ps = a#as" and "ls = x#xs" and "x = a" and "\<not> as \<le> xs" |
196 shows "R" |
196 | (c3) a as x xs where "ps = a#as" and "ls = x#xs" and "x \<noteq> a" |
197 proof (cases ps) |
197 proof (cases ps) |
198 case Nil then show ?thesis using pfx by simp |
198 case Nil |
|
199 then show ?thesis using pfx by simp |
199 next |
200 next |
200 case (Cons a as) |
201 case (Cons a as) |
201 then have c: "ps = a#as" . |
202 then have c: "ps = a#as" . |
202 |
203 |
203 show ?thesis |
204 show ?thesis |
219 qed |
220 qed |
220 qed |
221 qed |
221 |
222 |
222 lemma not_prefix_induct [consumes 1, case_names Nil Neq Eq]: |
223 lemma not_prefix_induct [consumes 1, case_names Nil Neq Eq]: |
223 assumes np: "\<not> ps \<le> ls" |
224 assumes np: "\<not> ps \<le> ls" |
224 and base: "\<And>x xs. P (x#xs) []" |
225 and base: "\<And>x xs. P (x#xs) []" |
225 and r1: "\<And>x xs y ys. x \<noteq> y \<Longrightarrow> P (x#xs) (y#ys)" |
226 and r1: "\<And>x xs y ys. x \<noteq> y \<Longrightarrow> P (x#xs) (y#ys)" |
226 and r2: "\<And>x xs y ys. \<lbrakk> x = y; \<not> xs \<le> ys; P xs ys \<rbrakk> \<Longrightarrow> P (x#xs) (y#ys)" |
227 and r2: "\<And>x xs y ys. \<lbrakk> x = y; \<not> xs \<le> ys; P xs ys \<rbrakk> \<Longrightarrow> P (x#xs) (y#ys)" |
227 shows "P ps ls" |
228 shows "P ps ls" using np |
228 using np |
|
229 proof (induct ls arbitrary: ps) |
229 proof (induct ls arbitrary: ps) |
230 case Nil then show ?case |
230 case Nil then show ?case |
231 by (auto simp: neq_Nil_conv elim!: not_prefix_cases intro!: base) |
231 by (auto simp: neq_Nil_conv elim!: not_prefix_cases intro!: base) |
232 next |
232 next |
233 case (Cons y ys) |
233 case (Cons y ys) |
239 have ih: "\<And>ps. \<not>ps \<le> ys \<Longrightarrow> P ps ys" by simp |
239 have ih: "\<And>ps. \<not>ps \<le> ys \<Longrightarrow> P ps ys" by simp |
240 |
240 |
241 show ?case using npfx |
241 show ?case using npfx |
242 by (simp only: pv) (erule not_prefix_cases, auto intro: r1 r2 ih) |
242 by (simp only: pv) (erule not_prefix_cases, auto intro: r1 r2 ih) |
243 qed |
243 qed |
|
244 |
244 |
245 |
245 subsection {* Parallel lists *} |
246 subsection {* Parallel lists *} |
246 |
247 |
247 definition |
248 definition |
248 parallel :: "'a list => 'a list => bool" (infixl "\<parallel>" 50) where |
249 parallel :: "'a list => 'a list => bool" (infixl "\<parallel>" 50) where |
308 |
309 |
309 lemma parallel_appendI: |
310 lemma parallel_appendI: |
310 "\<lbrakk> xs \<parallel> ys; x = xs @ xs' ; y = ys @ ys' \<rbrakk> \<Longrightarrow> x \<parallel> y" |
311 "\<lbrakk> xs \<parallel> ys; x = xs @ xs' ; y = ys @ ys' \<rbrakk> \<Longrightarrow> x \<parallel> y" |
311 by simp (rule parallel_append) |
312 by simp (rule parallel_append) |
312 |
313 |
313 lemma parallel_commute: |
314 lemma parallel_commute: "(a \<parallel> b) = (b \<parallel> a)" |
314 "(a \<parallel> b) = (b \<parallel> a)" |
|
315 unfolding parallel_def by auto |
315 unfolding parallel_def by auto |
|
316 |
316 |
317 |
317 subsection {* Postfix order on lists *} |
318 subsection {* Postfix order on lists *} |
318 |
319 |
319 definition |
320 definition |
320 postfix :: "'a list => 'a list => bool" ("(_/ >>= _)" [51, 50] 50) where |
321 postfix :: "'a list => 'a list => bool" ("(_/ >>= _)" [51, 50] 50) where |
378 then have "xs = rev zs @ ys" by simp |
379 then have "xs = rev zs @ ys" by simp |
379 then show "xs >>= ys" .. |
380 then show "xs >>= ys" .. |
380 qed |
381 qed |
381 |
382 |
382 lemma distinct_postfix: |
383 lemma distinct_postfix: |
383 assumes dx: "distinct xs" |
384 assumes "distinct xs" |
384 and pf: "xs >>= ys" |
385 and "xs >>= ys" |
385 shows "distinct ys" |
386 shows "distinct ys" |
386 using dx pf by (clarsimp elim!: postfixE) |
387 using assms by (clarsimp elim!: postfixE) |
387 |
388 |
388 lemma postfix_map: |
389 lemma postfix_map: |
389 assumes pf: "xs >>= ys" |
390 assumes "xs >>= ys" |
390 shows "map f xs >>= map f ys" |
391 shows "map f xs >>= map f ys" |
391 using pf by (auto elim!: postfixE intro: postfixI) |
392 using assms by (auto elim!: postfixE intro: postfixI) |
392 |
393 |
393 lemma postfix_drop: |
394 lemma postfix_drop: "as >>= drop n as" |
394 "as >>= drop n as" |
|
395 unfolding postfix_def |
395 unfolding postfix_def |
396 by (rule exI [where x = "take n as"]) simp |
396 by (rule exI [where x = "take n as"]) simp |
397 |
397 |
398 lemma postfix_take: |
398 lemma postfix_take: |
399 "xs >>= ys \<Longrightarrow> xs = take (length xs - length ys) xs @ ys" |
399 "xs >>= ys \<Longrightarrow> xs = take (length xs - length ys) xs @ ys" |
400 by (clarsimp elim!: postfixE) |
400 by (clarsimp elim!: postfixE) |
401 |
401 |
402 lemma parallelD1: |
402 lemma parallelD1: "x \<parallel> y \<Longrightarrow> \<not> x \<le> y" |
403 "x \<parallel> y \<Longrightarrow> \<not> x \<le> y" by blast |
403 by blast |
404 |
404 |
405 lemma parallelD2: |
405 lemma parallelD2: "x \<parallel> y \<Longrightarrow> \<not> y \<le> x" |
406 "x \<parallel> y \<Longrightarrow> \<not> y \<le> x" by blast |
406 by blast |
407 |
407 |
408 lemma parallel_Nil1 [simp]: "\<not> x \<parallel> []" |
408 lemma parallel_Nil1 [simp]: "\<not> x \<parallel> []" |
409 unfolding parallel_def by simp |
409 unfolding parallel_def by simp |
410 |
410 |
411 lemma parallel_Nil2 [simp]: "\<not> [] \<parallel> x" |
411 lemma parallel_Nil2 [simp]: "\<not> [] \<parallel> x" |
424 apply (erule parallelD2) |
424 apply (erule parallelD2) |
425 done |
425 done |
426 |
426 |
427 lemma not_equal_is_parallel: |
427 lemma not_equal_is_parallel: |
428 assumes neq: "xs \<noteq> ys" |
428 assumes neq: "xs \<noteq> ys" |
429 and len: "length xs = length ys" |
429 and len: "length xs = length ys" |
430 shows "xs \<parallel> ys" |
430 shows "xs \<parallel> ys" |
431 using len neq |
431 using len neq |
432 proof (induct rule: list_induct2) |
432 proof (induct rule: list_induct2) |
433 case 1 then show ?case by simp |
433 case 1 |
|
434 then show ?case by simp |
434 next |
435 next |
435 case (2 a as b bs) |
436 case (2 a as b bs) |
436 have ih: "as \<noteq> bs \<Longrightarrow> as \<parallel> bs" by fact |
437 have ih: "as \<noteq> bs \<Longrightarrow> as \<parallel> bs" by fact |
437 |
438 |
438 show ?case |
439 show ?case |
445 then show ?thesis by (rule Cons_parallelI1) |
446 then show ?thesis by (rule Cons_parallelI1) |
446 qed |
447 qed |
447 qed |
448 qed |
448 |
449 |
449 |
450 |
450 subsection {* Exeuctable code *} |
451 subsection {* Executable code *} |
451 |
452 |
452 lemma less_eq_code [code func]: |
453 lemma less_eq_code [code func]: |
453 "([]\<Colon>'a\<Colon>{eq, ord} list) \<le> xs \<longleftrightarrow> True" |
454 "([]\<Colon>'a\<Colon>{eq, ord} list) \<le> xs \<longleftrightarrow> True" |
454 "(x\<Colon>'a\<Colon>{eq, ord}) # xs \<le> [] \<longleftrightarrow> False" |
455 "(x\<Colon>'a\<Colon>{eq, ord}) # xs \<le> [] \<longleftrightarrow> False" |
455 "(x\<Colon>'a\<Colon>{eq, ord}) # xs \<le> y # ys \<longleftrightarrow> x = y \<and> xs \<le> ys" |
456 "(x\<Colon>'a\<Colon>{eq, ord}) # xs \<le> y # ys \<longleftrightarrow> x = y \<and> xs \<le> ys" |
456 by simp_all |
457 by simp_all |
457 |
458 |
458 lemma less_code [code func]: |
459 lemma less_code [code func]: |
459 "xs < ([]\<Colon>'a\<Colon>{eq, ord} list) \<longleftrightarrow> False" |
460 "xs < ([]\<Colon>'a\<Colon>{eq, ord} list) \<longleftrightarrow> False" |
460 "[] < (x\<Colon>'a\<Colon>{eq, ord})# xs \<longleftrightarrow> True" |
461 "[] < (x\<Colon>'a\<Colon>{eq, ord})# xs \<longleftrightarrow> True" |
461 "(x\<Colon>'a\<Colon>{eq, ord}) # xs < y # ys \<longleftrightarrow> x = y \<and> xs < ys" |
462 "(x\<Colon>'a\<Colon>{eq, ord}) # xs < y # ys \<longleftrightarrow> x = y \<and> xs < ys" |
462 unfolding strict_prefix_def by auto |
463 unfolding strict_prefix_def by auto |
463 |
464 |
464 lemmas [code func] = postfix_to_prefix |
465 lemmas [code func] = postfix_to_prefix |
465 |
466 |
466 end |
467 end |