Myhill_2.thy
changeset 183 c4893e84c88e
parent 182 560712a29a36
child 184 2455db3b06ac
equal deleted inserted replaced
182:560712a29a36 183:c4893e84c88e
    13 abbreviation
    13 abbreviation
    14    tag_eq_applied :: "'a list \<Rightarrow> ('a list \<Rightarrow> 'b) \<Rightarrow> 'a list \<Rightarrow> bool" ("_ =_= _")
    14    tag_eq_applied :: "'a list \<Rightarrow> ('a list \<Rightarrow> 'b) \<Rightarrow> 'a list \<Rightarrow> bool" ("_ =_= _")
    15 where
    15 where
    16    "x =tag= y \<equiv> (x, y) \<in> =tag="
    16    "x =tag= y \<equiv> (x, y) \<in> =tag="
    17 
    17 
    18 lemma test:
    18 lemma [simp]:
    19   shows "(\<approx>A) `` {x} = (\<approx>A) `` {y} \<longleftrightarrow> x \<approx>A y"
    19   shows "(\<approx>A) `` {x} = (\<approx>A) `` {y} \<longleftrightarrow> x \<approx>A y"
    20 unfolding str_eq_def
    20 unfolding str_eq_def by auto
    21 by auto
    21 
    22 
    22 lemma refined_intro:
    23 lemma test_refined_intro:
       
    24   assumes "\<And>x y z. \<lbrakk>x =tag= y; x @ z \<in> A\<rbrakk> \<Longrightarrow> y @ z \<in> A"
    23   assumes "\<And>x y z. \<lbrakk>x =tag= y; x @ z \<in> A\<rbrakk> \<Longrightarrow> y @ z \<in> A"
    25   shows "=tag= \<subseteq> \<approx>A"
    24   shows "=tag= \<subseteq> \<approx>A"
    26 using assms
    25 using assms unfolding str_eq_def tag_eq_def
    27 unfolding str_eq_def tag_eq_def
       
    28 apply(clarify, simp (no_asm_use))
    26 apply(clarify, simp (no_asm_use))
    29 by metis
    27 by metis
    30 
    28 
    31 lemma finite_eq_tag_rel:
    29 lemma finite_eq_tag_rel:
    32   assumes rng_fnt: "finite (range tag)"
    30   assumes rng_fnt: "finite (range tag)"
   101   ultimately show "finite (UNIV // R2)" by (rule finite_imageD)
    99   ultimately show "finite (UNIV // R2)" by (rule finite_imageD)
   102 qed
   100 qed
   103 
   101 
   104 lemma tag_finite_imageD:
   102 lemma tag_finite_imageD:
   105   assumes rng_fnt: "finite (range tag)" 
   103   assumes rng_fnt: "finite (range tag)" 
   106   and same_tag_eqvt: "\<And>m n. tag m = tag n \<Longrightarrow> m \<approx>A n"
   104   and same_tag_eqvt: "=tag=  \<subseteq> \<approx>A"
   107   shows "finite (UNIV // \<approx>A)"
   105   shows "finite (UNIV // \<approx>A)"
   108 proof (rule_tac refined_partition_finite [of "=tag="])
   106 proof (rule_tac refined_partition_finite [of "=tag="])
   109   show "finite (UNIV // =tag=)" by (rule finite_eq_tag_rel[OF rng_fnt])
   107   show "finite (UNIV // =tag=)" by (rule finite_eq_tag_rel[OF rng_fnt])
   110 next
   108 next
   111   from same_tag_eqvt
   109   from same_tag_eqvt
   112   show "=tag= \<subseteq> \<approx>A" unfolding tag_eq_def str_eq_def
   110   show "=tag= \<subseteq> \<approx>A" .
   113     by blast
       
   114 next
   111 next
   115   show "equiv UNIV =tag="
   112   show "equiv UNIV =tag="
   116     unfolding equiv_def tag_eq_def refl_on_def sym_def trans_def
   113     unfolding equiv_def tag_eq_def refl_on_def sym_def trans_def
   117     by auto
   114     by auto
   118 next
   115 next
   197 subsubsection {* The inductive case for @{const Plus} *}
   194 subsubsection {* The inductive case for @{const Plus} *}
   198 
   195 
   199 definition 
   196 definition 
   200   tag_Plus :: "'a lang \<Rightarrow> 'a lang \<Rightarrow> 'a list \<Rightarrow> ('a lang \<times> 'a lang)"
   197   tag_Plus :: "'a lang \<Rightarrow> 'a lang \<Rightarrow> 'a list \<Rightarrow> ('a lang \<times> 'a lang)"
   201 where
   198 where
   202   "tag_Plus A B \<equiv> (\<lambda>x. (\<approx>A `` {x}, \<approx>B `` {x}))"
   199   "tag_Plus A B \<equiv> \<lambda>x. (\<approx>A `` {x}, \<approx>B `` {x})"
   203 
   200 
   204 lemma quot_plus_finiteI [intro]:
   201 lemma quot_plus_finiteI [intro]:
   205   assumes finite1: "finite (UNIV // \<approx>A)"
   202   assumes finite1: "finite (UNIV // \<approx>A)"
   206   and     finite2: "finite (UNIV // \<approx>B)"
   203   and     finite2: "finite (UNIV // \<approx>B)"
   207   shows "finite (UNIV // \<approx>(A \<union> B))"
   204   shows "finite (UNIV // \<approx>(A \<union> B))"
   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
   278     where "(x = u @ us \<and> us @ z = v) \<or> (x @ us = u \<and> z = us @ v)"
   272     where "(x = u @ us \<and> us @ z = v) \<or> (x @ us = u \<and> z = us @ v)"
   279     by (auto simp add: append_eq_append_conv2)
   273     by (auto simp add: append_eq_append_conv2)
   280   moreover
   274   moreover
   281   { assume eq: "x = u @ us" "us @ z = v"
   275   { assume eq: "x = u @ us" "us @ z = v"
   282     have "(\<approx>A `` {u}, \<approx>B `` {us}) \<in> tag_Times_2 A B x"
   276     have "(\<approx>A `` {u}, \<approx>B `` {us}) \<in> tag_Times_2 A B x"
   283       unfolding Partitions_def using eq by auto
   277       unfolding Partitions_def using eq by (auto simp add: str_eq_def)
   284     then have "(\<approx>A `` {u}, \<approx>B `` {us}) \<in> tag_Times_2 A B y"
   278     then have "(\<approx>A `` {u}, \<approx>B `` {us}) \<in> tag_Times_2 A B y"
   285       using b by simp
   279       using b by simp
   286     then obtain u' us' where
   280     then obtain u' us' where
   287       q1: "\<approx>A `` {u} = \<approx>A `` {u'}" and
   281       q1: "\<approx>A `` {u} = \<approx>A `` {u'}" and
   288       q2: "\<approx>B `` {us} = \<approx>B `` {us'}" and
   282       q2: "\<approx>B `` {us} = \<approx>B `` {us'}" and
   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"