210 using finite1 finite2 by auto |
207 using finite1 finite2 by auto |
211 then show "finite (range (tag_Plus A B))" |
208 then show "finite (range (tag_Plus A B))" |
212 unfolding tag_Plus_def quotient_def |
209 unfolding tag_Plus_def quotient_def |
213 by (rule rev_finite_subset) (auto) |
210 by (rule rev_finite_subset) (auto) |
214 next |
211 next |
215 show "\<And>x y. tag_Plus A B x = tag_Plus A B y \<Longrightarrow> x \<approx>(A \<union> B) y" |
212 show "=tag_Plus A B= \<subseteq> \<approx>(A \<union> B)" |
216 unfolding tag_Plus_def |
213 unfolding tag_eq_def tag_Plus_def str_eq_def by auto |
217 unfolding str_eq_def |
214 qed |
218 by auto |
215 |
219 qed |
216 |
220 |
217 subsubsection {* The inductive case for @{text "Times"} *} |
221 |
|
222 subsubsection {* The inductive case for @{text "Times"}*} |
|
223 |
218 |
224 definition |
219 definition |
225 "Partitions s \<equiv> {(u, v). u @ v = s}" |
220 "Partitions s \<equiv> {(u, v). u @ v = s}" |
226 |
221 |
227 lemma conc_partitions_elim: |
222 lemma conc_partitions_elim: |
228 assumes "x \<in> A \<cdot> B" |
223 assumes "x \<in> A \<cdot> B" |
229 shows "\<exists>(u, v) \<in> Partitions x. u \<in> A \<and> v \<in> B" |
224 shows "\<exists>(u, v) \<in> Partitions x. u \<in> A \<and> v \<in> B" |
230 using assms |
225 using assms unfolding conc_def Partitions_def |
231 unfolding conc_def Partitions_def |
|
232 by auto |
226 by auto |
233 |
227 |
234 lemma conc_partitions_intro: |
228 lemma conc_partitions_intro: |
235 assumes "(u, v) \<in> Partitions x \<and> u \<in> A \<and> v \<in> B" |
229 assumes "(u, v) \<in> Partitions x \<and> u \<in> A \<and> v \<in> B" |
236 shows "x \<in> A \<cdot> B" |
230 shows "x \<in> A \<cdot> B" |
237 using assms |
231 using assms unfolding conc_def Partitions_def |
238 unfolding conc_def Partitions_def |
|
239 by auto |
232 by auto |
240 |
233 |
241 lemma equiv_class_member: |
234 lemma equiv_class_member: |
242 assumes "x \<in> A" |
235 assumes "x \<in> A" |
243 and "\<approx>A `` {x} = \<approx>A `` {y}" |
236 and "\<approx>A `` {x} = \<approx>A `` {y}" |
244 shows "y \<in> A" |
237 shows "y \<in> A" |
245 using assms |
238 using assms |
246 apply(simp add: Image_def str_eq_def set_eq_iff) |
239 apply(simp) |
|
240 apply(simp add: str_eq_def) |
247 apply(metis append_Nil2) |
241 apply(metis append_Nil2) |
248 done |
242 done |
249 |
243 |
250 |
244 |
251 abbreviation |
245 abbreviation |
312 } |
306 } |
313 ultimately show "y @ z \<in> A \<cdot> B" by blast |
307 ultimately show "y @ z \<in> A \<cdot> B" by blast |
314 qed |
308 qed |
315 |
309 |
316 lemma quot_conc_finiteI [intro]: |
310 lemma quot_conc_finiteI [intro]: |
317 fixes A B::"'a lang" |
|
318 assumes fin1: "finite (UNIV // \<approx>A)" |
311 assumes fin1: "finite (UNIV // \<approx>A)" |
319 and fin2: "finite (UNIV // \<approx>B)" |
312 and fin2: "finite (UNIV // \<approx>B)" |
320 shows "finite (UNIV // \<approx>(A \<cdot> B))" |
313 shows "finite (UNIV // \<approx>(A \<cdot> B))" |
321 proof (rule_tac tag = "tag_Times A B" in tag_finite_imageD) |
314 proof (rule_tac tag = "tag_Times A B" in tag_finite_imageD) |
322 have "=(tag_Times A B)= \<subseteq> \<approx>(A \<cdot> B)" |
315 have "\<And>x y z. \<lbrakk>tag_Times A B x = tag_Times A B y; x @ z \<in> A \<cdot> B\<rbrakk> \<Longrightarrow> y @ z \<in> A \<cdot> B" |
323 apply(rule test_refined_intro) |
316 by (rule tag_Times_injI) |
324 apply(rule tag_Times_injI) |
317 (auto simp add: tag_Times_def tag_eq_def) |
325 prefer 3 |
318 then show "=tag_Times A B= \<subseteq> \<approx>(A \<cdot> B)" |
326 apply(assumption) |
319 by (rule refined_intro) |
327 apply(simp add: tag_Times_def tag_eq_def) |
320 (auto simp add: tag_eq_def) |
328 apply(simp add: tag_eq_def tag_Times_def) |
|
329 done |
|
330 then show "\<And>x y. tag_Times A B x = tag_Times A B y \<Longrightarrow> x \<approx>(A \<cdot> B) y" |
|
331 unfolding tag_eq_def by auto |
|
332 next |
321 next |
333 have *: "finite ((UNIV // \<approx>A) \<times> (Pow (UNIV // \<approx>A \<times> UNIV // \<approx>B)))" |
322 have *: "finite ((UNIV // \<approx>A) \<times> (Pow (UNIV // \<approx>A \<times> UNIV // \<approx>B)))" |
334 using fin1 fin2 by auto |
323 using fin1 fin2 by auto |
335 show "finite (range (tag_Times A B))" |
324 show "finite (range (tag_Times A B))" |
336 unfolding tag_Times_def |
325 unfolding tag_Times_def |
340 qed |
329 qed |
341 |
330 |
342 |
331 |
343 subsubsection {* The inductive case for @{const "Star"} *} |
332 subsubsection {* The inductive case for @{const "Star"} *} |
344 |
333 |
345 lemma append_eq_append_conv3: |
334 lemma star_partitions_elim: |
346 assumes "xs @ ys = zs @ ts" "zs < xs" |
|
347 shows "\<exists>us. xs = zs @ us \<and> us @ ys = ts" |
|
348 using assms |
|
349 apply(auto simp add: append_eq_append_conv2 strict_prefix_def) |
|
350 done |
|
351 |
|
352 lemma star_spartitions_elim: |
|
353 assumes "x @ z \<in> A\<star>" "x \<noteq> []" |
335 assumes "x @ z \<in> A\<star>" "x \<noteq> []" |
354 shows "\<exists>(u, v) \<in> Partitions (x @ z). u < x \<and> u \<in> A\<star> \<and> v \<in> A\<star>" |
336 shows "\<exists>(u, v) \<in> Partitions (x @ z). u < x \<and> u \<in> A\<star> \<and> v \<in> A\<star>" |
355 proof - |
337 proof - |
356 have "([], x @ z) \<in> Partitions (x @ z)" "[] < x" "[] \<in> A\<star>" "x @ z \<in> A\<star>" |
338 have "([], x @ z) \<in> Partitions (x @ z)" "[] < x" "[] \<in> A\<star>" "x @ z \<in> A\<star>" |
357 using assms by (auto simp add: Partitions_def strict_prefix_def) |
339 using assms by (auto simp add: Partitions_def strict_prefix_def) |
358 then show "\<exists>(u, v) \<in> Partitions (x @ z). u < x \<and> u \<in> A\<star> \<and> v \<in> A\<star>" |
340 then show "\<exists>(u, v) \<in> Partitions (x @ z). u < x \<and> u \<in> A\<star> \<and> v \<in> A\<star>" |
359 by blast |
341 by blast |
360 qed |
342 qed |
361 |
|
362 |
343 |
363 lemma finite_set_has_max2: |
344 lemma finite_set_has_max2: |
364 "\<lbrakk>finite A; A \<noteq> {}\<rbrakk> \<Longrightarrow> \<exists> max \<in> A. \<forall> a \<in> A. length a \<le> length max" |
345 "\<lbrakk>finite A; A \<noteq> {}\<rbrakk> \<Longrightarrow> \<exists> max \<in> A. \<forall> a \<in> A. length a \<le> length max" |
365 apply(induct rule:finite.induct) |
346 apply(induct rule:finite.induct) |
366 apply(simp) |
347 apply(simp) |
420 moreover |
401 moreover |
421 have "u_max @ a \<in> A\<star>" using i2 h2 by simp |
402 have "u_max @ a \<in> A\<star>" using i2 h2 by simp |
422 moreover |
403 moreover |
423 have "as @ z \<in> A\<star>" using i1' i2 i3 eq by auto |
404 have "as @ z \<in> A\<star>" using i1' i2 i3 eq by auto |
424 ultimately have "length (u_max @ a) \<le> length u_max" using h4 by blast |
405 ultimately have "length (u_max @ a) \<le> length u_max" using h4 by blast |
425 moreover |
406 with i4 show "False" by auto |
426 have "a \<noteq> []" using i4 . |
|
427 ultimately show "False" by auto |
|
428 qed |
407 qed |
429 with i1 obtain za zb |
408 with i1 obtain za zb |
430 where k1: "v @ za = a" |
409 where k1: "v @ za = a" |
431 and k2: "(za, zb) \<in> Partitions z" |
410 and k2: "(za, zb) \<in> Partitions z" |
432 and k4: "zb = b" |
411 and k4: "zb = b" |
433 unfolding Partitions_def prefix_def |
412 unfolding Partitions_def prefix_def |
434 by (auto simp add: append_eq_append_conv2) |
413 by (auto simp add: append_eq_append_conv2) |
435 show "\<exists> (u, v) \<in> Partitions x. \<exists> (u', v') \<in> Partitions z. u < x \<and> u \<in> A\<star> \<and> v @ u' \<in> A \<and> v' \<in> A\<star>" |
414 show "\<exists> (u, v) \<in> Partitions x. \<exists> (u', v') \<in> Partitions z. u < x \<and> u \<in> A\<star> \<and> v @ u' \<in> A \<and> v' \<in> A\<star>" |
436 using h0 k2 h1 h2 i2 k1 i3 k4 unfolding Partitions_def by blast |
415 using h0 h1 h2 i2 i3 k1 k2 k4 unfolding Partitions_def by blast |
437 qed |
416 qed |
438 |
|
439 |
417 |
440 definition |
418 definition |
441 tag_Star :: "'a lang \<Rightarrow> 'a list \<Rightarrow> ('a lang) set" |
419 tag_Star :: "'a lang \<Rightarrow> 'a list \<Rightarrow> ('a lang) set" |
442 where |
420 where |
443 "tag_Star A \<equiv> (\<lambda>x. {\<approx>A `` {v} | u v. u < x \<and> u \<in> A\<star> \<and> (u, v) \<in> Partitions x})" |
421 "tag_Star A \<equiv> (\<lambda>x. {\<approx>A `` {v} | u v. u < x \<and> u \<in> A\<star> \<and> (u, v) \<in> Partitions x})" |
444 |
422 |
445 |
423 lemma tag_Star_non_empty_injI: |
446 lemma tag_Star_injI: |
|
447 fixes x::"'a list" |
|
448 assumes a: "tag_Star A x = tag_Star A y" |
424 assumes a: "tag_Star A x = tag_Star A y" |
449 and c: "x @ z \<in> A\<star>" |
425 and c: "x @ z \<in> A\<star>" |
450 and d: "x \<noteq> []" |
426 and d: "x \<noteq> []" |
451 shows "y @ z \<in> A\<star>" |
427 shows "y @ z \<in> A\<star>" |
452 using c d |
428 proof - |
453 apply(drule_tac star_spartitions_elim2) |
429 obtain u v u' v' |
454 apply(simp) |
430 where a1: "(u, v) \<in> Partitions x" "(u', v')\<in> Partitions z" |
455 apply(simp add: Partitions_def) |
431 and a2: "u < x" |
456 apply(erule exE | erule conjE)+ |
432 and a3: "u \<in> A\<star>" |
457 apply(subgoal_tac "((\<approx>A) `` {b}) \<in> tag_Star A x") |
433 and a4: "v @ u' \<in> A" |
458 apply(simp add: a) |
434 and a5: "v' \<in> A\<star>" |
459 apply(simp add: tag_Star_def) |
435 using c d by (auto dest: star_spartitions_elim2) |
460 apply(erule exE | erule conjE)+ |
436 have "(\<approx>A) `` {v} \<in> tag_Star A x" |
461 apply(simp add: test) |
437 apply(simp add: tag_Star_def Partitions_def str_eq_def) |
462 apply(simp add: Partitions_def) |
438 using a1 a2 a3 by (auto simp add: Partitions_def) |
463 apply(subgoal_tac "v @ aa \<in> A\<star>") |
439 then have "(\<approx>A) `` {v} \<in> tag_Star A y" using a by simp |
464 prefer 2 |
440 then obtain u1 v1 |
465 apply(simp add: str_eq_def) |
441 where b1: "v \<approx>A v1" |
466 apply(subgoal_tac "(u @ v) @ aa @ ba \<in> A\<star>") |
442 and b3: "u1 \<in> A\<star>" |
467 apply(simp) |
443 and b4: "(u1, v1) \<in> Partitions y" |
468 apply(simp (no_asm_use)) |
444 unfolding tag_Star_def by auto |
469 apply(rule append_in_starI) |
445 have c: "v1 @ u' \<in> A\<star>" using b1 a4 unfolding str_eq_def by simp |
470 apply(simp) |
446 have "u1 @ (v1 @ u') @ v' \<in> A\<star>" |
471 apply(simp (no_asm) only: append_assoc[symmetric]) |
447 using b3 c a5 by (simp only: append_in_starI) |
472 apply(rule append_in_starI) |
448 then show "y @ z \<in> A\<star>" using b4 a1 |
473 apply(simp) |
449 unfolding Partitions_def by auto |
474 apply(simp) |
450 qed |
475 apply(simp add: tag_Star_def) |
451 |
476 apply(rule_tac x="a" in exI) |
452 lemma tag_Star_empty_injI: |
477 apply(rule_tac x="b" in exI) |
|
478 apply(simp) |
|
479 apply(simp add: Partitions_def) |
|
480 done |
|
481 |
|
482 lemma tag_Star_injI2: |
|
483 fixes x::"'a list" |
|
484 assumes a: "tag_Star A x = tag_Star A y" |
453 assumes a: "tag_Star A x = tag_Star A y" |
485 and c: "x @ z \<in> A\<star>" |
454 and c: "x @ z \<in> A\<star>" |
486 and d: "x = []" |
455 and d: "x = []" |
487 shows "y @ z \<in> A\<star>" |
456 shows "y @ z \<in> A\<star>" |
488 using c d |
457 using assms |
489 apply(simp) |
458 apply(simp) |
490 using a |
|
491 apply(simp add: tag_Star_def strict_prefix_def) |
459 apply(simp add: tag_Star_def strict_prefix_def) |
492 apply(auto simp add: prefix_def Partitions_def) |
460 apply(auto simp add: prefix_def Partitions_def) |
493 by (metis Nil_in_star append_self_conv2) |
461 by (metis Nil_in_star append_self_conv2) |
494 |
462 |
495 |
|
496 lemma quot_star_finiteI [intro]: |
463 lemma quot_star_finiteI [intro]: |
497 fixes A::"('a::finite) lang" |
|
498 assumes finite1: "finite (UNIV // \<approx>A)" |
464 assumes finite1: "finite (UNIV // \<approx>A)" |
499 shows "finite (UNIV // \<approx>(A\<star>))" |
465 shows "finite (UNIV // \<approx>(A\<star>))" |
500 proof (rule_tac tag = "tag_Star A" in tag_finite_imageD) |
466 proof (rule_tac tag = "tag_Star A" in tag_finite_imageD) |
501 have "=(tag_Star A)= \<subseteq> \<approx>(A\<star>)" |
467 have "\<And>x y z. \<lbrakk>tag_Star A x = tag_Star A y; x @ z \<in> A\<star>\<rbrakk> \<Longrightarrow> y @ z \<in> A\<star>" |
502 apply(rule test_refined_intro) |
468 by (case_tac "x = []") (blast intro: tag_Star_empty_injI tag_Star_non_empty_injI)+ |
503 apply(case_tac "x=[]") |
469 then show "=(tag_Star A)= \<subseteq> \<approx>(A\<star>)" |
504 apply(rule tag_Star_injI2) |
470 by (rule refined_intro) (auto simp add: tag_eq_def) |
505 prefer 3 |
|
506 apply(assumption) |
|
507 prefer 2 |
|
508 apply(assumption) |
|
509 apply(simp add: tag_eq_def) |
|
510 apply(rule tag_Star_injI) |
|
511 prefer 3 |
|
512 apply(assumption) |
|
513 prefer 2 |
|
514 apply(assumption) |
|
515 unfolding tag_eq_def |
|
516 apply(simp) |
|
517 done |
|
518 then show "\<And>x y. tag_Star A x = tag_Star A y \<Longrightarrow> x \<approx>(A\<star>) y" |
|
519 apply(simp add: tag_eq_def) |
|
520 apply(auto) |
|
521 done |
|
522 next |
471 next |
523 have *: "finite (Pow (UNIV // \<approx>A))" |
472 have *: "finite (Pow (UNIV // \<approx>A))" |
524 using finite1 by auto |
473 using finite1 by auto |
525 show "finite (range (tag_Star A))" |
474 show "finite (range (tag_Star A))" |
526 unfolding tag_Star_def |
475 unfolding tag_Star_def |
527 apply(rule finite_subset[OF _ *]) |
476 by (rule finite_subset[OF _ *]) |
528 unfolding quotient_def |
477 (auto simp add: quotient_def) |
529 apply(auto) |
|
530 done |
|
531 qed |
478 qed |
532 |
479 |
533 subsubsection{* The conclusion *} |
480 subsubsection{* The conclusion *} |
534 |
481 |
535 lemma Myhill_Nerode2: |
482 lemma Myhill_Nerode2: |
536 fixes r::"('a::finite) rexp" |
483 fixes r::"'a rexp" |
537 shows "finite (UNIV // \<approx>(lang r))" |
484 shows "finite (UNIV // \<approx>(lang r))" |
538 by (induct r) (auto) |
485 by (induct r) (auto) |
539 |
486 |
540 theorem Myhill_Nerode: |
487 theorem Myhill_Nerode: |
541 fixes A::"('a::finite) lang" |
488 fixes A::"('a::finite) lang" |