160 apply (simp add: prefix_def) |
160 apply (simp add: prefix_def) |
161 apply (rule_tac x="drop n xs" in exI) |
161 apply (rule_tac x="drop n xs" in exI) |
162 apply simp |
162 apply simp |
163 done |
163 done |
164 |
164 |
165 lemma map_prefixI: |
165 lemma map_prefixI: |
166 "xs \<le> ys \<Longrightarrow> map f xs \<le> map f ys" |
166 "xs \<le> ys \<Longrightarrow> map f xs \<le> map f ys" |
167 by (clarsimp simp: prefix_def) |
167 by (clarsimp simp: prefix_def) |
168 |
168 |
169 lemma prefix_length_less: |
169 lemma prefix_length_less: |
170 "xs < ys \<Longrightarrow> length xs < length ys" |
170 "xs < ys \<Longrightarrow> length xs < length ys" |
186 apply (case_tac ys, simp_all)[1] |
186 apply (case_tac ys, simp_all)[1] |
187 apply (case_tac xs, simp) |
187 apply (case_tac xs, simp) |
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 and c1: "\<lbrakk> ps \<noteq> []; ls = [] \<rbrakk> \<Longrightarrow> R" |
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 and c2: "\<And>a as x xs. \<lbrakk> ps = a#as; ls = x#xs; x = a; \<not> as \<le> xs\<rbrakk> \<Longrightarrow> R" |
195 and c3: "\<And>a as x xs. \<lbrakk> ps = a#as; ls = x#xs; x \<noteq> a\<rbrakk> \<Longrightarrow> R" |
195 and c3: "\<And>a as x xs. \<lbrakk> ps = a#as; ls = x#xs; x \<noteq> a\<rbrakk> \<Longrightarrow> R" |
196 shows "R" |
196 shows "R" |
197 proof (cases ps) |
197 proof (cases ps) |
198 case Nil thus ?thesis using pfx by simp |
198 case Nil then show ?thesis using pfx by simp |
199 next |
199 next |
200 case (Cons a as) |
200 case (Cons a as) |
201 |
201 then have c: "ps = a#as" . |
202 hence c: "ps = a#as" . |
202 |
203 |
|
204 show ?thesis |
203 show ?thesis |
205 proof (cases ls) |
204 proof (cases ls) |
206 case Nil thus ?thesis |
205 case Nil |
207 by (intro c1, simp add: Cons) |
206 have "ps \<noteq> []" by (simp add: Nil Cons) |
|
207 from this and Nil show ?thesis by (rule c1) |
208 next |
208 next |
209 case (Cons x xs) |
209 case (Cons x xs) |
210 show ?thesis |
210 show ?thesis |
211 proof (cases "x = a") |
211 proof (cases "x = a") |
212 case True |
212 case True |
213 show ?thesis |
213 have "\<not> as \<le> xs" using pfx c Cons True by simp |
214 proof (intro c2) |
214 with c Cons True show ?thesis by (rule c2) |
215 show "\<not> as \<le> xs" using pfx c Cons True |
215 next |
216 by simp |
216 case False |
217 qed |
217 with c Cons show ?thesis by (rule c3) |
218 next |
|
219 case False |
|
220 show ?thesis by (rule c3) |
|
221 qed |
218 qed |
222 qed |
219 qed |
223 qed |
220 qed |
224 |
221 |
225 lemma not_prefix_induct [consumes 1, case_names Nil Neq Eq]: |
222 lemma not_prefix_induct [consumes 1, case_names Nil Neq Eq]: |
228 and r1: "\<And>x xs y ys. x \<noteq> y \<Longrightarrow> P (x#xs) (y#ys)" |
225 and r1: "\<And>x xs y ys. x \<noteq> y \<Longrightarrow> P (x#xs) (y#ys)" |
229 and r2: "\<And>x xs y ys. \<lbrakk> x = y; \<not> xs \<le> ys; P xs ys \<rbrakk> \<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)" |
230 shows "P ps ls" |
227 shows "P ps ls" |
231 using np |
228 using np |
232 proof (induct ls arbitrary: ps) |
229 proof (induct ls arbitrary: ps) |
233 case Nil thus ?case |
230 case Nil then show ?case |
234 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) |
235 next |
232 next |
236 case (Cons y ys) |
233 case (Cons y ys) |
237 hence npfx: "\<not> ps \<le> (y # ys)" by simp |
234 then have npfx: "\<not> ps \<le> (y # ys)" by simp |
238 then obtain x xs where pv: "ps = x # xs" |
235 then obtain x xs where pv: "ps = x # xs" |
239 by (rule not_prefix_cases) auto |
236 by (rule not_prefix_cases) auto |
240 |
237 |
241 from Cons |
238 from Cons |
242 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 |
243 |
240 |
244 show ?case using npfx |
241 show ?case using npfx |
245 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) |
246 qed |
243 qed |
247 |
244 |
248 subsection {* Parallel lists *} |
245 subsection {* Parallel lists *} |
303 qed |
300 qed |
304 qed |
301 qed |
305 |
302 |
306 lemma parallel_append: |
303 lemma parallel_append: |
307 "a \<parallel> b \<Longrightarrow> a @ c \<parallel> b @ d" |
304 "a \<parallel> b \<Longrightarrow> a @ c \<parallel> b @ d" |
308 by (rule parallelI) |
305 by (rule parallelI) |
309 (erule parallelE, erule conjE, |
306 (erule parallelE, erule conjE, |
310 induct rule: not_prefix_induct, simp+)+ |
307 induct rule: not_prefix_induct, simp+)+ |
311 |
308 |
312 lemma parallel_appendI: |
309 lemma parallel_appendI: |
313 "\<lbrakk> xs \<parallel> ys; x = xs @ xs' ; y = ys @ ys' \<rbrakk> \<Longrightarrow> x \<parallel> y" |
310 "\<lbrakk> xs \<parallel> ys; x = xs @ xs' ; y = ys @ ys' \<rbrakk> \<Longrightarrow> x \<parallel> y" |
314 by simp (rule parallel_append) |
311 by simp (rule parallel_append) |
315 |
312 |
316 lemma parallel_commute: |
313 lemma parallel_commute: |
317 "(a \<parallel> b) = (b \<parallel> a)" |
314 "(a \<parallel> b) = (b \<parallel> a)" |
318 unfolding parallel_def by auto |
315 unfolding parallel_def by auto |
319 |
316 |
320 subsection {* Postfix order on lists *} |
317 subsection {* Postfix order on lists *} |
321 |
318 |
322 definition |
319 definition |
400 |
397 |
401 lemma postfix_take: |
398 lemma postfix_take: |
402 "xs >>= ys \<Longrightarrow> xs = take (length xs - length ys) xs @ ys" |
399 "xs >>= ys \<Longrightarrow> xs = take (length xs - length ys) xs @ ys" |
403 by (clarsimp elim!: postfixE) |
400 by (clarsimp elim!: postfixE) |
404 |
401 |
405 lemma parallelD1: |
402 lemma parallelD1: |
406 "x \<parallel> y \<Longrightarrow> \<not> x \<le> y" by blast |
403 "x \<parallel> y \<Longrightarrow> \<not> x \<le> y" by blast |
407 |
404 |
408 lemma parallelD2: |
405 lemma parallelD2: |
409 "x \<parallel> y \<Longrightarrow> \<not> y \<le> x" by blast |
406 "x \<parallel> y \<Longrightarrow> \<not> y \<le> x" by blast |
410 |
407 |
411 lemma parallel_Nil1 [simp]: "\<not> x \<parallel> []" |
408 lemma parallel_Nil1 [simp]: "\<not> x \<parallel> []" |
412 unfolding parallel_def by simp |
409 unfolding parallel_def by simp |
413 |
410 |
414 lemma parallel_Nil2 [simp]: "\<not> [] \<parallel> x" |
411 lemma parallel_Nil2 [simp]: "\<not> [] \<parallel> x" |
415 unfolding parallel_def by simp |
412 unfolding parallel_def by simp |
416 |
413 |
417 lemma Cons_parallelI1: |
414 lemma Cons_parallelI1: |
418 "a \<noteq> b \<Longrightarrow> a # as \<parallel> b # bs" by auto |
415 "a \<noteq> b \<Longrightarrow> a # as \<parallel> b # bs" by auto |
419 |
416 |
420 lemma Cons_parallelI2: |
417 lemma Cons_parallelI2: |
421 "\<lbrakk> a = b; as \<parallel> bs \<rbrakk> \<Longrightarrow> a # as \<parallel> b # bs" |
418 "\<lbrakk> a = b; as \<parallel> bs \<rbrakk> \<Longrightarrow> a # as \<parallel> b # bs" |
422 apply simp |
419 apply simp |
423 apply (rule parallelI) |
420 apply (rule parallelI) |
424 apply simp |
421 apply simp |
425 apply (erule parallelD1) |
422 apply (erule parallelD1) |
426 apply simp |
423 apply simp |
430 lemma not_equal_is_parallel: |
427 lemma not_equal_is_parallel: |
431 assumes neq: "xs \<noteq> ys" |
428 assumes neq: "xs \<noteq> ys" |
432 and len: "length xs = length ys" |
429 and len: "length xs = length ys" |
433 shows "xs \<parallel> ys" |
430 shows "xs \<parallel> ys" |
434 using len neq |
431 using len neq |
435 proof (induct rule: list_induct2) |
432 proof (induct rule: list_induct2) |
436 case 1 thus ?case by simp |
433 case 1 then show ?case by simp |
437 next |
434 next |
438 case (2 a as b bs) |
435 case (2 a as b bs) |
439 |
436 have ih: "as \<noteq> bs \<Longrightarrow> as \<parallel> bs" by fact |
440 have ih: "as \<noteq> bs \<Longrightarrow> as \<parallel> bs" . |
437 |
441 |
|
442 show ?case |
438 show ?case |
443 proof (cases "a = b") |
439 proof (cases "a = b") |
444 case True |
440 case True |
445 hence "as \<noteq> bs" using 2 by simp |
441 then have "as \<noteq> bs" using 2 by simp |
446 |
442 then show ?thesis by (rule Cons_parallelI2 [OF True ih]) |
447 thus ?thesis by (rule Cons_parallelI2 [OF True ih]) |
|
448 next |
443 next |
449 case False |
444 case False |
450 thus ?thesis by (rule Cons_parallelI1) |
445 then show ?thesis by (rule Cons_parallelI1) |
451 qed |
446 qed |
452 qed |
447 qed |
|
448 |
453 |
449 |
454 subsection {* Exeuctable code *} |
450 subsection {* Exeuctable code *} |
455 |
451 |
456 lemma less_eq_code [code func]: |
452 lemma less_eq_code [code func]: |
457 "([]\<Colon>'a\<Colon>{eq, ord} list) \<le> xs \<longleftrightarrow> True" |
453 "([]\<Colon>'a\<Colon>{eq, ord} list) \<le> xs \<longleftrightarrow> True" |