Myhill_2.thy
changeset 170 b1258b7d2789
parent 166 7743d2ad71d1
child 180 b755090d0f3d
equal deleted inserted replaced
169:b794db0b79db 170:b1258b7d2789
     4 begin
     4 begin
     5 
     5 
     6 section {* Direction @{text "regular language \<Rightarrow> finite partition"} *}
     6 section {* Direction @{text "regular language \<Rightarrow> finite partition"} *}
     7 
     7 
     8 definition
     8 definition
     9   str_eq :: "string \<Rightarrow> lang \<Rightarrow> string \<Rightarrow> bool" ("_ \<approx>_ _")
     9   str_eq :: "'a list \<Rightarrow> 'a lang \<Rightarrow> 'a list \<Rightarrow> bool" ("_ \<approx>_ _")
    10 where
    10 where
    11   "x \<approx>A y \<equiv> (x, y) \<in> (\<approx>A)"
    11   "x \<approx>A y \<equiv> (x, y) \<in> (\<approx>A)"
    12 
    12 
    13 lemma str_eq_def2:
    13 lemma str_eq_def2:
    14   shows "\<approx>A = {(x, y) | x y. x \<approx>A y}"
    14   shows "\<approx>A = {(x, y) | x y. x \<approx>A y}"
    15 unfolding str_eq_def
    15 unfolding str_eq_def
    16 by simp
    16 by simp
    17 
    17 
    18 definition 
    18 definition 
    19    tag_eq_rel :: "(string \<Rightarrow> 'b) \<Rightarrow> (string \<times> string) set" ("=_=")
    19    tag_eq_rel :: "('a list \<Rightarrow> 'b) \<Rightarrow> ('a list \<times> 'a list) set" ("=_=")
    20 where
    20 where
    21    "=tag= \<equiv> {(x, y). tag x = tag y}"
    21    "=tag= \<equiv> {(x, y). tag x = tag y}"
    22 
    22 
    23 lemma finite_eq_tag_rel:
    23 lemma finite_eq_tag_rel:
    24   assumes rng_fnt: "finite (range tag)"
    24   assumes rng_fnt: "finite (range tag)"
   114 qed
   114 qed
   115 
   115 
   116 
   116 
   117 subsection {* The proof *}
   117 subsection {* The proof *}
   118 
   118 
   119 subsubsection {* The base case for @{const "NULL"} *}
   119 subsubsection {* The base case for @{const "Zero"} *}
   120 
   120 
   121 lemma quot_null_eq:
   121 lemma quot_zero_eq:
   122   shows "UNIV // \<approx>{} = {UNIV}"
   122   shows "UNIV // \<approx>{} = {UNIV}"
   123 unfolding quotient_def Image_def str_eq_rel_def by auto
   123 unfolding quotient_def Image_def str_eq_rel_def by auto
   124 
   124 
   125 lemma quot_null_finiteI [intro]:
   125 lemma quot_zero_finiteI [intro]:
   126   shows "finite (UNIV // \<approx>{})"
   126   shows "finite (UNIV // \<approx>{})"
   127 unfolding quot_null_eq by simp
   127 unfolding quot_zero_eq by simp
   128 
   128 
   129 
   129 
   130 subsubsection {* The base case for @{const "EMPTY"} *}
   130 subsubsection {* The base case for @{const "One"} *}
   131 
   131 
   132 lemma quot_empty_subset:
   132 lemma quot_one_subset:
   133   shows "UNIV // \<approx>{[]} \<subseteq> {{[]}, UNIV - {[]}}"
   133   shows "UNIV // \<approx>{[]} \<subseteq> {{[]}, UNIV - {[]}}"
   134 proof
   134 proof
   135   fix x
   135   fix x
   136   assume "x \<in> UNIV // \<approx>{[]}"
   136   assume "x \<in> UNIV // \<approx>{[]}"
   137   then obtain y where h: "x = {z. (y, z) \<in> \<approx>{[]}}" 
   137   then obtain y where h: "x = {z. (y, z) \<in> \<approx>{[]}}" 
   146     have "x = UNIV - {[]}" by (auto simp: str_eq_rel_def)
   146     have "x = UNIV - {[]}" by (auto simp: str_eq_rel_def)
   147     thus ?thesis by simp
   147     thus ?thesis by simp
   148   qed
   148   qed
   149 qed
   149 qed
   150 
   150 
   151 lemma quot_empty_finiteI [intro]:
   151 lemma quot_one_finiteI [intro]:
   152   shows "finite (UNIV // \<approx>{[]})"
   152   shows "finite (UNIV // \<approx>{[]})"
   153 by (rule finite_subset[OF quot_empty_subset]) (simp)
   153 by (rule finite_subset[OF quot_one_subset]) (simp)
   154 
   154 
   155 
   155 
   156 subsubsection {* The base case for @{const "CHAR"} *}
   156 subsubsection {* The base case for @{const "Atom"} *}
   157 
   157 
   158 lemma quot_char_subset:
   158 lemma quot_atom_subset:
   159   "UNIV // (\<approx>{[c]}) \<subseteq> {{[]},{[c]}, UNIV - {[], [c]}}"
   159   "UNIV // (\<approx>{[c]}) \<subseteq> {{[]},{[c]}, UNIV - {[], [c]}}"
   160 proof 
   160 proof 
   161   fix x 
   161   fix x 
   162   assume "x \<in> UNIV // \<approx>{[c]}"
   162   assume "x \<in> UNIV // \<approx>{[c]}"
   163   then obtain y where h: "x = {z. (y, z) \<in> \<approx>{[c]}}" 
   163   then obtain y where h: "x = {z. (y, z) \<in> \<approx>{[c]}}" 
   179     } 
   179     } 
   180     ultimately show ?thesis by blast
   180     ultimately show ?thesis by blast
   181   qed
   181   qed
   182 qed
   182 qed
   183 
   183 
   184 lemma quot_char_finiteI [intro]:
   184 lemma quot_atom_finiteI [intro]:
   185   shows "finite (UNIV // \<approx>{[c]})"
   185   shows "finite (UNIV // \<approx>{[c]})"
   186 by (rule finite_subset[OF quot_char_subset]) (simp)
   186 by (rule finite_subset[OF quot_atom_subset]) (simp)
   187 
   187 
   188 
   188 
   189 subsubsection {* The inductive case for @{const ALT} *}
   189 subsubsection {* The inductive case for @{const Plus} *}
   190 
   190 
   191 definition 
   191 definition 
   192   tag_str_ALT :: "lang \<Rightarrow> lang \<Rightarrow> string \<Rightarrow> (lang \<times> lang)"
   192   tag_str_Plus :: "'a lang \<Rightarrow> 'a lang \<Rightarrow> 'a list \<Rightarrow> ('a lang \<times> 'a lang)"
   193 where
   193 where
   194   "tag_str_ALT A B \<equiv> (\<lambda>x. (\<approx>A `` {x}, \<approx>B `` {x}))"
   194   "tag_str_Plus A B \<equiv> (\<lambda>x. (\<approx>A `` {x}, \<approx>B `` {x}))"
   195 
   195 
   196 lemma quot_union_finiteI [intro]:
   196 lemma quot_union_finiteI [intro]:
   197   assumes finite1: "finite (UNIV // \<approx>A)"
   197   assumes finite1: "finite (UNIV // \<approx>A)"
   198   and     finite2: "finite (UNIV // \<approx>B)"
   198   and     finite2: "finite (UNIV // \<approx>B)"
   199   shows "finite (UNIV // \<approx>(A \<union> B))"
   199   shows "finite (UNIV // \<approx>(A \<union> B))"
   200 proof (rule_tac tag = "tag_str_ALT A B" in tag_finite_imageD)
   200 proof (rule_tac tag = "tag_str_Plus A B" in tag_finite_imageD)
   201   have "finite ((UNIV // \<approx>A) \<times> (UNIV // \<approx>B))" 
   201   have "finite ((UNIV // \<approx>A) \<times> (UNIV // \<approx>B))" 
   202     using finite1 finite2 by auto
   202     using finite1 finite2 by auto
   203   then show "finite (range (tag_str_ALT A B))"
   203   then show "finite (range (tag_str_Plus A B))"
   204     unfolding tag_str_ALT_def quotient_def
   204     unfolding tag_str_Plus_def quotient_def
   205     by (rule rev_finite_subset) (auto)
   205     by (rule rev_finite_subset) (auto)
   206 next
   206 next
   207   show "\<And>x y. tag_str_ALT A B x = tag_str_ALT A B y \<Longrightarrow> x \<approx>(A \<union> B) y"
   207   show "\<And>x y. tag_str_Plus A B x = tag_str_Plus A B y \<Longrightarrow> x \<approx>(A \<union> B) y"
   208     unfolding tag_str_ALT_def
   208     unfolding tag_str_Plus_def
   209     unfolding str_eq_def
   209     unfolding str_eq_def
   210     unfolding str_eq_rel_def
   210     unfolding str_eq_rel_def
   211     by auto
   211     by auto
   212 qed
   212 qed
   213 
   213 
   214 
   214 
   215 subsubsection {* The inductive case for @{text "SEQ"}*}
   215 subsubsection {* The inductive case for @{text "Times"}*}
   216 
   216 
   217 definition 
   217 definition 
   218   tag_str_SEQ :: "lang \<Rightarrow> lang \<Rightarrow> string \<Rightarrow> (lang \<times> lang set)"
   218   tag_str_Times :: "'a lang \<Rightarrow> 'a lang \<Rightarrow> 'a list \<Rightarrow> ('a lang \<times> 'a lang set)"
   219 where
   219 where
   220   "tag_str_SEQ L1 L2 \<equiv>
   220   "tag_str_Times L1 L2 \<equiv>
   221      (\<lambda>x. (\<approx>L1 `` {x}, {(\<approx>L2 `` {x - xa}) | xa.  xa \<le> x \<and> xa \<in> L1}))"
   221      (\<lambda>x. (\<approx>L1 `` {x}, {(\<approx>L2 `` {x - xa}) | xa.  xa \<le> x \<and> xa \<in> L1}))"
   222 
   222 
   223 lemma Seq_in_cases:
   223 lemma Seq_in_cases:
   224   assumes "x @ z \<in> A \<cdot> B"
   224   assumes "x @ z \<in> A \<cdot> B"
   225   shows "(\<exists> x' \<le> x. x' \<in> A \<and> (x - x') @ z \<in> B) \<or> 
   225   shows "(\<exists> x' \<le> x. x' \<in> A \<and> (x - x') @ z \<in> B) \<or> 
   226          (\<exists> z' \<le> z. (x @ z') \<in> A \<and> (z - z') \<in> B)"
   226          (\<exists> z' \<le> z. (x @ z') \<in> A \<and> (z - z') \<in> B)"
   227 using assms
   227 using assms
   228 unfolding Seq_def prefix_def
   228 unfolding conc_def prefix_def
   229 by (auto simp add: append_eq_append_conv2)
   229 by (auto simp add: append_eq_append_conv2)
   230 
   230 
   231 lemma tag_str_SEQ_injI:
   231 lemma tag_str_Times_injI:
   232   assumes eq_tag: "tag_str_SEQ A B x = tag_str_SEQ A B y" 
   232   assumes eq_tag: "tag_str_Times A B x = tag_str_Times A B y" 
   233   shows "x \<approx>(A \<cdot> B) y"
   233   shows "x \<approx>(A \<cdot> B) y"
   234 proof -
   234 proof -
   235   { fix x y z
   235   { fix x y z
   236     assume xz_in_seq: "x @ z \<in> A \<cdot> B"
   236     assume xz_in_seq: "x @ z \<in> A \<cdot> B"
   237     and tag_xy: "tag_str_SEQ A B x = tag_str_SEQ A B y"
   237     and tag_xy: "tag_str_Times A B x = tag_str_Times A B y"
   238     have"y @ z \<in> A \<cdot> B" 
   238     have"y @ z \<in> A \<cdot> B" 
   239     proof -
   239     proof -
   240       { (* first case with x' in A and (x - x') @ z in B *)
   240       { (* first case with x' in A and (x - x') @ z in B *)
   241         fix x'
   241         fix x'
   242         assume h1: "x' \<le> x" and h2: "x' \<in> A" and h3: "(x - x') @ z \<in> B"
   242         assume h1: "x' \<le> x" and h2: "x' \<in> A" and h3: "(x - x') @ z \<in> B"
   245           and "y' \<in> A" 
   245           and "y' \<in> A" 
   246           and "(y - y') @ z \<in> B"
   246           and "(y - y') @ z \<in> B"
   247         proof -
   247         proof -
   248           have "{\<approx>B `` {x - x'} |x'. x' \<le> x \<and> x' \<in> A} = 
   248           have "{\<approx>B `` {x - x'} |x'. x' \<le> x \<and> x' \<in> A} = 
   249                 {\<approx>B `` {y - y'} |y'. y' \<le> y \<and> y' \<in> A}" (is "?Left = ?Right")
   249                 {\<approx>B `` {y - y'} |y'. y' \<le> y \<and> y' \<in> A}" (is "?Left = ?Right")
   250             using tag_xy unfolding tag_str_SEQ_def by simp
   250             using tag_xy unfolding tag_str_Times_def by simp
   251           moreover 
   251           moreover 
   252 	  have "\<approx>B `` {x - x'} \<in> ?Left" using h1 h2 by auto
   252 	  have "\<approx>B `` {x - x'} \<in> ?Left" using h1 h2 by auto
   253           ultimately 
   253           ultimately 
   254 	  have "\<approx>B `` {x - x'} \<in> ?Right" by simp
   254 	  have "\<approx>B `` {x - x'} \<in> ?Right" by simp
   255           then obtain y' 
   255           then obtain y' 
   269       moreover 
   269       moreover 
   270       { (* second case with x @ z' in A and z - z' in B *)
   270       { (* second case with x @ z' in A and z - z' in B *)
   271         fix z'
   271         fix z'
   272         assume h1: "z' \<le> z" and h2: "(x @ z') \<in> A" and h3: "z - z' \<in> B"
   272         assume h1: "z' \<le> z" and h2: "(x @ z') \<in> A" and h3: "z - z' \<in> B"
   273 	 have "\<approx>A `` {x} = \<approx>A `` {y}" 
   273 	 have "\<approx>A `` {x} = \<approx>A `` {y}" 
   274            using tag_xy unfolding tag_str_SEQ_def by simp
   274            using tag_xy unfolding tag_str_Times_def by simp
   275          with h2 have "y @ z' \<in> A"
   275          with h2 have "y @ z' \<in> A"
   276             unfolding Image_def str_eq_rel_def str_eq_def by auto
   276             unfolding Image_def str_eq_rel_def str_eq_def by auto
   277         with h1 h3 have "y @ z \<in> A \<cdot> B"
   277         with h1 h3 have "y @ z \<in> A \<cdot> B"
   278 	  unfolding prefix_def Seq_def
   278 	  unfolding prefix_def conc_def
   279 	  by (auto) (metis append_assoc)
   279 	  by (auto) (metis append_assoc)
   280       }
   280       }
   281       ultimately show "y @ z \<in> A \<cdot> B" 
   281       ultimately show "y @ z \<in> A \<cdot> B" 
   282 	using Seq_in_cases [OF xz_in_seq] by blast
   282 	using Seq_in_cases [OF xz_in_seq] by blast
   283     qed
   283     qed
   285   from this [OF _ eq_tag] and this [OF _ eq_tag [THEN sym]]
   285   from this [OF _ eq_tag] and this [OF _ eq_tag [THEN sym]]
   286     show "x \<approx>(A \<cdot> B) y" unfolding str_eq_def str_eq_rel_def by blast
   286     show "x \<approx>(A \<cdot> B) y" unfolding str_eq_def str_eq_rel_def by blast
   287 qed 
   287 qed 
   288 
   288 
   289 lemma quot_seq_finiteI [intro]:
   289 lemma quot_seq_finiteI [intro]:
   290   fixes L1 L2::"lang"
   290   fixes L1 L2::"'a lang"
   291   assumes fin1: "finite (UNIV // \<approx>L1)" 
   291   assumes fin1: "finite (UNIV // \<approx>L1)" 
   292   and     fin2: "finite (UNIV // \<approx>L2)" 
   292   and     fin2: "finite (UNIV // \<approx>L2)" 
   293   shows "finite (UNIV // \<approx>(L1 \<cdot> L2))"
   293   shows "finite (UNIV // \<approx>(L1 \<cdot> L2))"
   294 proof (rule_tac tag = "tag_str_SEQ L1 L2" in tag_finite_imageD)
   294 proof (rule_tac tag = "tag_str_Times L1 L2" in tag_finite_imageD)
   295   show "\<And>x y. tag_str_SEQ L1 L2 x = tag_str_SEQ L1 L2 y \<Longrightarrow> x \<approx>(L1 \<cdot> L2) y"
   295   show "\<And>x y. tag_str_Times L1 L2 x = tag_str_Times L1 L2 y \<Longrightarrow> x \<approx>(L1 \<cdot> L2) y"
   296     by (rule tag_str_SEQ_injI)
   296     by (rule tag_str_Times_injI)
   297 next
   297 next
   298   have *: "finite ((UNIV // \<approx>L1) \<times> (Pow (UNIV // \<approx>L2)))" 
   298   have *: "finite ((UNIV // \<approx>L1) \<times> (Pow (UNIV // \<approx>L2)))" 
   299     using fin1 fin2 by auto
   299     using fin1 fin2 by auto
   300   show "finite (range (tag_str_SEQ L1 L2))" 
   300   show "finite (range (tag_str_Times L1 L2))" 
   301     unfolding tag_str_SEQ_def
   301     unfolding tag_str_Times_def
   302     apply(rule finite_subset[OF _ *])
   302     apply(rule finite_subset[OF _ *])
   303     unfolding quotient_def
   303     unfolding quotient_def
   304     by auto
   304     by auto
   305 qed
   305 qed
   306 
   306 
   307 
   307 
   308 subsubsection {* The inductive case for @{const "STAR"} *}
   308 subsubsection {* The inductive case for @{const "Star"} *}
   309 
   309 
   310 definition 
   310 definition 
   311   tag_str_STAR :: "lang \<Rightarrow> string \<Rightarrow> lang set"
   311   tag_str_Star :: "'a lang \<Rightarrow> 'a list \<Rightarrow> ('a lang) set"
   312 where
   312 where
   313   "tag_str_STAR L1 \<equiv> (\<lambda>x. {\<approx>L1 `` {x - xa} | xa. xa < x \<and> xa \<in> L1\<star>})"
   313   "tag_str_Star L1 \<equiv> (\<lambda>x. {\<approx>L1 `` {x - xa} | xa. xa < x \<and> xa \<in> L1\<star>})"
   314 
   314 
   315 text {* A technical lemma. *}
   315 text {* A technical lemma. *}
   316 lemma finite_set_has_max: "\<lbrakk>finite A; A \<noteq> {}\<rbrakk> \<Longrightarrow> 
   316 lemma finite_set_has_max: "\<lbrakk>finite A; A \<noteq> {}\<rbrakk> \<Longrightarrow> 
   317            (\<exists> max \<in> A. \<forall> a \<in> A. f a <= (f max :: nat))"
   317            (\<exists> max \<in> A. \<forall> a \<in> A. f a <= (f max :: nat))"
   318 proof (induct rule:finite.induct)
   318 proof (induct rule:finite.induct)
   340 qed
   340 qed
   341 
   341 
   342 
   342 
   343 text {* The following is a technical lemma, which helps to show the range finiteness of tag function. *}
   343 text {* The following is a technical lemma, which helps to show the range finiteness of tag function. *}
   344 
   344 
   345 lemma finite_strict_prefix_set: "finite {xa. xa < (x::string)}"
   345 lemma finite_strict_prefix_set: 
       
   346   shows "finite {xa. xa < (x::'a list)}"
   346 apply (induct x rule:rev_induct, simp)
   347 apply (induct x rule:rev_induct, simp)
   347 apply (subgoal_tac "{xa. xa < xs @ [x]} = {xa. xa < xs} \<union> {xs}")
   348 apply (subgoal_tac "{xa. xa < xs @ [x]} = {xa. xa < xs} \<union> {xs}")
   348 by (auto simp:strict_prefix_def)
   349 by (auto simp:strict_prefix_def)
   349 
   350 
   350 
   351 
   351 lemma tag_str_STAR_injI:
   352 lemma tag_str_Star_injI:
   352   assumes eq_tag: "tag_str_STAR L\<^isub>1 v = tag_str_STAR L\<^isub>1 w"
   353   fixes L\<^isub>1::"('a::finite) lang"
       
   354   assumes eq_tag: "tag_str_Star L\<^isub>1 v = tag_str_Star L\<^isub>1 w"
   353   shows "v \<approx>(L\<^isub>1\<star>) w"
   355   shows "v \<approx>(L\<^isub>1\<star>) w"
   354 proof-
   356 proof-
   355   { fix x y z
   357   { fix x y z
   356     assume xz_in_star: "x @ z \<in> L\<^isub>1\<star>" 
   358     assume xz_in_star: "x @ z \<in> L\<^isub>1\<star>" 
   357       and tag_xy: "tag_str_STAR L\<^isub>1 x = tag_str_STAR L\<^isub>1 y"
   359       and tag_xy: "tag_str_Star L\<^isub>1 x = tag_str_Star L\<^isub>1 y"
   358     have "y @ z \<in> L\<^isub>1\<star>"
   360     have "y @ z \<in> L\<^isub>1\<star>"
   359     proof(cases "x = []")
   361     proof(cases "x = []")
   360       case True
   362       case True
   361       with tag_xy have "y = []" 
   363       with tag_xy have "y = []" 
   362         by (auto simp add: tag_str_STAR_def strict_prefix_def)
   364         by (auto simp add: tag_str_Star_def strict_prefix_def)
   363       thus ?thesis using xz_in_star True by simp
   365       thus ?thesis using xz_in_star True by simp
   364     next
   366     next
   365       case False
   367       case False
   366       let ?S = "{xa. xa < x \<and> xa \<in> L\<^isub>1\<star> \<and> (x - xa) @ z \<in> L\<^isub>1\<star>}"
   368       let ?S = "{xa::('a::finite) list. xa < x \<and> xa \<in> L\<^isub>1\<star> \<and> (x - xa) @ z \<in> L\<^isub>1\<star>}"
   367       have "finite ?S"
   369       have "finite ?S"
   368         by (rule_tac B = "{xa. xa < x}" in finite_subset, 
   370 	by (rule_tac B = "{xa. xa < x}" in finite_subset)
   369           auto simp:finite_strict_prefix_set)
   371 	   (auto simp: finite_strict_prefix_set)
   370       moreover have "?S \<noteq> {}" using False xz_in_star
   372       moreover have "?S \<noteq> {}" using False xz_in_star
   371         by (simp, rule_tac x = "[]" in exI, auto simp:strict_prefix_def)
   373         by (simp, rule_tac x = "[]" in exI, auto simp:strict_prefix_def)
   372       ultimately have "\<exists> xa_max \<in> ?S. \<forall> xa \<in> ?S. length xa \<le> length xa_max" 
   374       ultimately have "\<exists> xa_max \<in> ?S. \<forall> xa \<in> ?S. length xa \<le> length xa_max" 
   373         using finite_set_has_max by blast
   375         using finite_set_has_max by blast
   374       then obtain xa_max 
   376       then obtain xa_max 
   382         where h5: "ya < y" and h6: "ya \<in> L\<^isub>1\<star>" 
   384         where h5: "ya < y" and h6: "ya \<in> L\<^isub>1\<star>" 
   383         and eq_xya: "(x - xa_max) \<approx>L\<^isub>1 (y - ya)"
   385         and eq_xya: "(x - xa_max) \<approx>L\<^isub>1 (y - ya)"
   384       proof-
   386       proof-
   385         from tag_xy have "{\<approx>L\<^isub>1 `` {x - xa} |xa. xa < x \<and> xa \<in> L\<^isub>1\<star>} = 
   387         from tag_xy have "{\<approx>L\<^isub>1 `` {x - xa} |xa. xa < x \<and> xa \<in> L\<^isub>1\<star>} = 
   386           {\<approx>L\<^isub>1 `` {y - xa} |xa. xa < y \<and> xa \<in> L\<^isub>1\<star>}" (is "?left = ?right")
   388           {\<approx>L\<^isub>1 `` {y - xa} |xa. xa < y \<and> xa \<in> L\<^isub>1\<star>}" (is "?left = ?right")
   387           by (auto simp:tag_str_STAR_def)
   389           by (auto simp:tag_str_Star_def)
   388         moreover have "\<approx>L\<^isub>1 `` {x - xa_max} \<in> ?left" using h1 h2 by auto
   390         moreover have "\<approx>L\<^isub>1 `` {x - xa_max} \<in> ?left" using h1 h2 by auto
   389         ultimately have "\<approx>L\<^isub>1 `` {x - xa_max} \<in> ?right" by simp
   391         ultimately have "\<approx>L\<^isub>1 `` {x - xa_max} \<in> ?right" by simp
   390         thus ?thesis using that 
   392         thus ?thesis using that 
   391           apply (simp add:Image_def str_eq_rel_def str_eq_def) by blast
   393           apply (simp add:Image_def str_eq_rel_def str_eq_def) by blast
   392       qed 
   394       qed 
   415               proof -
   417               proof -
   416                 let ?xa_max' = "xa_max @ a"
   418                 let ?xa_max' = "xa_max @ a"
   417                 have "?xa_max' < x" 
   419                 have "?xa_max' < x" 
   418                   using np h1 by (clarsimp simp:strict_prefix_def diff_prefix) 
   420                   using np h1 by (clarsimp simp:strict_prefix_def diff_prefix) 
   419                 moreover have "?xa_max' \<in> L\<^isub>1\<star>" 
   421                 moreover have "?xa_max' \<in> L\<^isub>1\<star>" 
   420                   using a_in h2 by (simp add:star_intro3) 
   422                   using a_in h2 by (auto)
   421                 moreover have "(x - ?xa_max') @ z \<in> L\<^isub>1\<star>" 
   423                 moreover have "(x - ?xa_max') @ z \<in> L\<^isub>1\<star>" 
   422                   using b_eqs b_in np h1 by (simp add:diff_diff_append)
   424                   using b_eqs b_in np h1 by (simp add:diff_diff_append)
   423                 moreover have "\<not> (length ?xa_max' \<le> length xa_max)" 
   425                 moreover have "\<not> (length ?xa_max' \<le> length xa_max)" 
   424                   using a_neq by simp
   426                   using a_neq by simp
   425                 ultimately show ?thesis using h4 by blast
   427                 ultimately show ?thesis using h4 by blast
   430           with eq_xya have "(y - ya) @ ?za \<in> L\<^isub>1" 
   432           with eq_xya have "(y - ya) @ ?za \<in> L\<^isub>1" 
   431             by (auto simp:str_eq_def str_eq_rel_def)
   433             by (auto simp:str_eq_def str_eq_rel_def)
   432            with eq_z and b_in 
   434            with eq_z and b_in 
   433           show ?thesis using that by blast
   435           show ?thesis using that by blast
   434         qed
   436         qed
   435         have "((y - ya) @ za) @ zb \<in> L\<^isub>1\<star>" using  l_za ls_zb by blast
   437         have "((y - ya) @ za) @ zb \<in> L\<^isub>1\<star>" using  l_za ls_zb 
       
   438 	  by (rule_tac append_in_starI) (auto)
   436         with eq_zab show ?thesis by simp
   439         with eq_zab show ?thesis by simp
   437       qed
   440       qed
   438       with h5 h6 show ?thesis 
   441       with h5 h6 show ?thesis 	
   439         by (drule_tac star_intro1) (auto simp:strict_prefix_def elim: prefixE)
   442         by (auto simp:strict_prefix_def elim: prefixE)
   440     qed
   443     qed
   441   } 
   444   } 
   442   from this [OF _ eq_tag] and this [OF _ eq_tag [THEN sym]]
   445   from this [OF _ eq_tag] and this [OF _ eq_tag [THEN sym]]
   443     show  ?thesis unfolding str_eq_def str_eq_rel_def by blast
   446     show  ?thesis unfolding str_eq_def str_eq_rel_def by blast
   444 qed
   447 qed
   445 
   448 
   446 lemma quot_star_finiteI [intro]:
   449 lemma quot_star_finiteI [intro]:
       
   450    fixes A::"('a::finite) lang"
   447   assumes finite1: "finite (UNIV // \<approx>A)"
   451   assumes finite1: "finite (UNIV // \<approx>A)"
   448   shows "finite (UNIV // \<approx>(A\<star>))"
   452   shows "finite (UNIV // \<approx>(A\<star>))"
   449 proof (rule_tac tag = "tag_str_STAR A" in tag_finite_imageD)
   453 proof (rule_tac tag = "tag_str_Star A" in tag_finite_imageD)
   450   show "\<And>x y. tag_str_STAR A x = tag_str_STAR A y \<Longrightarrow> x \<approx>(A\<star>) y"
   454   show "\<And>x y. tag_str_Star A x = tag_str_Star A y \<Longrightarrow> x \<approx>(A\<star>) y"
   451     by (rule tag_str_STAR_injI)
   455     by (rule tag_str_Star_injI)
   452 next
   456 next
   453   have *: "finite (Pow (UNIV // \<approx>A))" 
   457   have *: "finite (Pow (UNIV // \<approx>A))" 
   454     using finite1 by auto
   458     using finite1 by auto
   455   show "finite (range (tag_str_STAR A))"
   459   show "finite (range (tag_str_Star A))"
   456     unfolding tag_str_STAR_def
   460     unfolding tag_str_Star_def
   457     apply(rule finite_subset[OF _ *])
   461     apply(rule finite_subset[OF _ *])
   458     unfolding quotient_def
   462     unfolding quotient_def
   459     by auto
   463     by auto
   460 qed
   464 qed
   461 
   465 
   462 subsubsection{* The conclusion *}
   466 subsubsection{* The conclusion *}
   463 
   467 
   464 lemma Myhill_Nerode2:
   468 lemma Myhill_Nerode2:
   465   shows "finite (UNIV // \<approx>(L_rexp r))"
   469   fixes r::"('a::finite) rexp"
       
   470   shows "finite (UNIV // \<approx>(lang r))"
   466 by (induct r) (auto)
   471 by (induct r) (auto)
   467 
   472 
   468 
       
   469 theorem Myhill_Nerode:
   473 theorem Myhill_Nerode:
   470   shows "(\<exists>r. A = L_rexp r) \<longleftrightarrow> finite (UNIV // \<approx>A)"
   474   fixes A::"('a::finite) lang"
       
   475   shows "(\<exists>r. A = lang r) \<longleftrightarrow> finite (UNIV // \<approx>A)"
   471 using Myhill_Nerode1 Myhill_Nerode2 by auto
   476 using Myhill_Nerode1 Myhill_Nerode2 by auto
   472 
   477 
   473 end
   478 end