Attic/MyhillNerode.thy
changeset 170 b1258b7d2789
parent 23 e31b733ace44
equal deleted inserted replaced
169:b794db0b79db 170:b1258b7d2789
       
     1 theory MyhillNerode
       
     2   imports "Main" "List_Prefix"
       
     3 begin
       
     4 
       
     5 text {* sequential composition of languages *}
       
     6 
       
     7 definition
       
     8   lang_seq :: "string set \<Rightarrow> string set \<Rightarrow> string set" ("_ ; _" [100,100] 100)
       
     9 where 
       
    10   "L1 ; L2 = {s1 @ s2 | s1 s2. s1 \<in> L1 \<and> s2 \<in> L2}"
       
    11 
       
    12 lemma lang_seq_empty:
       
    13   shows "{[]} ; L = L"
       
    14   and   "L ; {[]} = L"
       
    15 unfolding lang_seq_def by auto
       
    16 
       
    17 lemma lang_seq_null:
       
    18   shows "{} ; L = {}"
       
    19   and   "L ; {} = {}"
       
    20 unfolding lang_seq_def by auto
       
    21 
       
    22 lemma lang_seq_append:
       
    23   assumes a: "s1 \<in> L1"
       
    24   and     b: "s2 \<in> L2"
       
    25   shows "s1@s2 \<in> L1 ; L2"
       
    26 unfolding lang_seq_def
       
    27 using a b by auto 
       
    28 
       
    29 lemma lang_seq_union:
       
    30   shows "(L1 \<union> L2); L3 = (L1; L3) \<union> (L2; L3)"
       
    31   and   "L1; (L2 \<union> L3) = (L1; L2) \<union> (L1; L3)"
       
    32 unfolding lang_seq_def by auto
       
    33 
       
    34 lemma lang_seq_assoc:
       
    35   shows "(L1 ; L2) ; L3 = L1 ; (L2 ; L3)"
       
    36 unfolding lang_seq_def
       
    37 apply(auto)
       
    38 apply(metis)
       
    39 by (metis append_assoc)
       
    40 
       
    41 
       
    42 section {* Kleene star for languages defined as least fixed point *}
       
    43 
       
    44 inductive_set
       
    45   Star :: "string set \<Rightarrow> string set" ("_\<star>" [101] 102)
       
    46   for L :: "string set"
       
    47 where
       
    48   start[intro]: "[] \<in> L\<star>"
       
    49 | step[intro]:  "\<lbrakk>s1 \<in> L; s2 \<in> L\<star>\<rbrakk> \<Longrightarrow> s1@s2 \<in> L\<star>"
       
    50 
       
    51 lemma lang_star_empty:
       
    52   shows "{}\<star> = {[]}"
       
    53 by (auto elim: Star.cases)
       
    54 
       
    55 lemma lang_star_cases:
       
    56   shows "L\<star> =  {[]} \<union> L ; L\<star>"
       
    57 proof
       
    58   { fix x
       
    59     have "x \<in> L\<star> \<Longrightarrow> x \<in> {[]} \<union> L ; L\<star>"
       
    60       unfolding lang_seq_def
       
    61     by (induct rule: Star.induct) (auto)
       
    62   }
       
    63   then show "L\<star> \<subseteq> {[]} \<union> L ; L\<star>" by auto
       
    64 next
       
    65   show "{[]} \<union> L ; L\<star> \<subseteq> L\<star>" 
       
    66     unfolding lang_seq_def by auto
       
    67 qed
       
    68 
       
    69 lemma lang_star_cases':
       
    70   shows "L\<star> =  {[]} \<union> L\<star> ; L"
       
    71 proof
       
    72   { fix x
       
    73     have "x \<in> L\<star> \<Longrightarrow> x \<in> {[]} \<union> L\<star> ; L"
       
    74       unfolding lang_seq_def
       
    75     apply (induct rule: Star.induct)
       
    76     apply simp
       
    77     apply simp
       
    78     apply (erule disjE)
       
    79     apply (auto)[1]
       
    80     apply (erule exE | erule conjE)+
       
    81     apply (rule disjI2)
       
    82     apply (rule_tac x = "s1 @ s1a" in exI)
       
    83     by auto
       
    84   }
       
    85   then show "L\<star> \<subseteq> {[]} \<union> L\<star> ; L" by auto
       
    86 next
       
    87   show "{[]} \<union> L\<star> ; L \<subseteq> L\<star>" 
       
    88     unfolding lang_seq_def
       
    89     apply auto
       
    90     apply (erule Star.induct)
       
    91     apply auto
       
    92     apply (drule step[of _ _ "[]"])
       
    93     by (auto intro:start)
       
    94 qed
       
    95 
       
    96 lemma lang_star_simple:
       
    97   shows "L \<subseteq> L\<star>"
       
    98 by (subst lang_star_cases)
       
    99    (auto simp only: lang_seq_def)
       
   100 
       
   101 lemma lang_star_prop0_aux:
       
   102   "s2 \<in> L\<star> \<Longrightarrow> \<forall> s1. s1 \<in> L \<longrightarrow> (\<exists> s3 s4. s3 \<in> L\<star> \<and> s4 \<in> L \<and> s1 @ s2 = s3 @ s4)" 
       
   103 apply (erule Star.induct)
       
   104 apply (clarify, rule_tac x = "[]" in exI, rule_tac x = s1 in exI, simp add:start)
       
   105 apply (clarify, drule_tac x = s1 in spec)
       
   106 apply (drule mp, simp, clarify)
       
   107 apply (rule_tac x = "s1a @ s3" in exI, rule_tac x = s4 in exI)
       
   108 by auto
       
   109 
       
   110 lemma lang_star_prop0:
       
   111   "\<lbrakk>s1 \<in> L; s2 \<in> L\<star>\<rbrakk> \<Longrightarrow> \<exists> s3 s4. s3 \<in> L\<star> \<and> s4 \<in> L \<and> s1 @ s2 = s3 @ s4" 
       
   112 by (auto dest:lang_star_prop0_aux)
       
   113 
       
   114 lemma lang_star_prop1:
       
   115   assumes asm: "L1; L2 \<subseteq> L2" 
       
   116   shows "L1\<star>; L2 \<subseteq> L2"
       
   117 proof -
       
   118   { fix s1 s2
       
   119     assume minor: "s2 \<in> L2"
       
   120     assume major: "s1 \<in> L1\<star>"
       
   121     then have "s1@s2 \<in> L2"
       
   122     proof(induct rule: Star.induct)
       
   123       case start
       
   124       show "[]@s2 \<in> L2" using minor by simp
       
   125     next
       
   126       case (step s1 s1')
       
   127       have "s1 \<in> L1" by fact
       
   128       moreover
       
   129       have "s1'@s2 \<in> L2" by fact
       
   130       ultimately have "s1@(s1'@s2) \<in> L1; L2" by (auto simp add: lang_seq_def)
       
   131       with asm have "s1@(s1'@s2) \<in> L2" by auto
       
   132       then show "(s1@s1')@s2 \<in> L2" by simp
       
   133     qed
       
   134   } 
       
   135   then show "L1\<star>; L2 \<subseteq> L2" by (auto simp add: lang_seq_def)
       
   136 qed
       
   137 
       
   138 lemma lang_star_prop2_aux:
       
   139   "s2 \<in> L2\<star> \<Longrightarrow> \<forall> s1. s1 \<in> L1 \<and> L1 ; L2 \<subseteq> L1 \<longrightarrow> s1 @ s2 \<in> L1"
       
   140 apply (erule Star.induct, simp)
       
   141 apply (clarify, drule_tac x = "s1a @ s1" in spec)
       
   142 by (auto simp:lang_seq_def)
       
   143 
       
   144 lemma lang_star_prop2:
       
   145   "L1; L2 \<subseteq> L1 \<Longrightarrow> L1 ; L2\<star> \<subseteq> L1"
       
   146 by (auto dest!:lang_star_prop2_aux simp:lang_seq_def)
       
   147 
       
   148 lemma lang_star_seq_subseteq: 
       
   149   shows "L ; L\<star> \<subseteq> L\<star>"
       
   150 using lang_star_cases by blast
       
   151 
       
   152 lemma lang_star_double:
       
   153   shows "L\<star>; L\<star> = L\<star>"
       
   154 proof
       
   155   show "L\<star> ; L\<star> \<subseteq> L\<star>" 
       
   156     using lang_star_prop1 lang_star_seq_subseteq by blast
       
   157 next
       
   158   have "L\<star> \<subseteq> L\<star> \<union> L\<star>; (L; L\<star>)" by auto
       
   159   also have "\<dots> = L\<star>;{[]} \<union> L\<star>; (L; L\<star>)" by (simp add: lang_seq_empty)
       
   160   also have "\<dots> = L\<star>; ({[]} \<union> L; L\<star>)" by (simp only: lang_seq_union)
       
   161   also have "\<dots> = L\<star>; L\<star>" using lang_star_cases by simp 
       
   162   finally show "L\<star> \<subseteq> L\<star> ; L\<star>" by simp
       
   163 qed
       
   164 
       
   165 lemma lang_star_seq_subseteq': 
       
   166   shows "L\<star>; L \<subseteq> L\<star>"
       
   167 proof -
       
   168   have "L \<subseteq> L\<star>" by (rule lang_star_simple)
       
   169   then have "L\<star>; L \<subseteq> L\<star>; L\<star>" by (auto simp add: lang_seq_def)
       
   170   then show "L\<star>; L \<subseteq> L\<star>" using lang_star_double by blast
       
   171 qed
       
   172 
       
   173 lemma
       
   174   shows "L\<star> \<subseteq> L\<star>\<star>"
       
   175 by (rule lang_star_simple)
       
   176 
       
   177 
       
   178 section {* regular expressions *}
       
   179 
       
   180 datatype rexp =
       
   181   NULL
       
   182 | EMPTY
       
   183 | CHAR char
       
   184 | SEQ rexp rexp
       
   185 | ALT rexp rexp
       
   186 | STAR rexp
       
   187 
       
   188 
       
   189 consts L:: "'a \<Rightarrow> string set"
       
   190 
       
   191 overloading L_rexp \<equiv> "L::  rexp \<Rightarrow> string set"
       
   192 begin
       
   193 fun
       
   194   L_rexp :: "rexp \<Rightarrow> string set"
       
   195 where
       
   196     "L_rexp (NULL) = {}"
       
   197   | "L_rexp (EMPTY) = {[]}"
       
   198   | "L_rexp (CHAR c) = {[c]}"
       
   199   | "L_rexp (SEQ r1 r2) = (L_rexp r1) ; (L_rexp r2)"
       
   200   | "L_rexp (ALT r1 r2) = (L_rexp r1) \<union> (L_rexp r2)"
       
   201   | "L_rexp (STAR r) = (L_rexp r)\<star>"
       
   202 end
       
   203 
       
   204 
       
   205 text{* ************ now is the codes writen by chunhan ************************************* *}
       
   206 
       
   207 section {* Arden's Lemma revised *}
       
   208 
       
   209 lemma arden_aux1:
       
   210   assumes a: "X \<subseteq> X ; A \<union> B"
       
   211   and     b: "[] \<notin> A"
       
   212   shows      "x \<in> X \<Longrightarrow> x \<in> B ; A\<star>"
       
   213 apply (induct x taking:length rule:measure_induct)
       
   214 apply (subgoal_tac "x \<in> X ; A \<union> B")
       
   215 defer
       
   216 using a
       
   217 apply (auto)[1]
       
   218 apply simp
       
   219 apply (erule disjE)
       
   220 defer
       
   221 apply (auto simp add:lang_seq_def) [1]
       
   222 apply (subgoal_tac "\<exists> x1 x2. x = x1 @ x2 \<and> x1 \<in> X \<and> x2 \<in> A")
       
   223 defer
       
   224 apply (auto simp add:lang_seq_def) [1]
       
   225 apply (erule exE | erule conjE)+
       
   226 apply simp
       
   227 apply (drule_tac x = x1 in spec)
       
   228 apply (simp)
       
   229 using b
       
   230 apply -
       
   231 apply (auto)[1]
       
   232 apply (subgoal_tac "x1 @ x2 \<in> (B ; A\<star>) ; A")
       
   233 defer
       
   234 apply (auto simp add:lang_seq_def)[1]
       
   235 by (metis Un_absorb1 lang_seq_assoc lang_seq_union(2) lang_star_double lang_star_simple mem_def sup1CI)
       
   236 
       
   237 theorem ardens_revised:
       
   238   assumes nemp: "[] \<notin> A"
       
   239   shows "(X = X ; A \<union> B) \<longleftrightarrow> (X = B ; A\<star>)"
       
   240 apply(rule iffI)
       
   241 defer
       
   242 apply(simp)
       
   243 apply(subst lang_star_cases')
       
   244 apply(subst lang_seq_union)
       
   245 apply(simp add: lang_seq_empty)
       
   246 apply(simp add: lang_seq_assoc)
       
   247 apply(auto)[1]
       
   248 proof -
       
   249   assume "X = X ; A \<union> B"
       
   250   then have as1: "X ; A \<union> B \<subseteq> X" and as2: "X \<subseteq> X ; A \<union> B" by simp_all
       
   251   from as1 have a: "X ; A \<subseteq> X" and b: "B \<subseteq> X" by simp_all
       
   252   from b have "B; A\<star> \<subseteq> X ; A\<star>" by (auto simp add: lang_seq_def)
       
   253   moreover
       
   254   from a have "X ; A\<star> \<subseteq> X" 
       
   255 
       
   256 by (rule lang_star_prop2)
       
   257   ultimately have f1: "B ; A\<star> \<subseteq> X" by simp
       
   258   from as2 nemp
       
   259   have f2: "X \<subseteq> B; A\<star>" using arden_aux1 by auto
       
   260   from f1 f2 show "X = B; A\<star>" by auto
       
   261 qed
       
   262 
       
   263 
       
   264 
       
   265 section {* equiv class' definition *}
       
   266 
       
   267 definition 
       
   268   equiv_str :: "string \<Rightarrow> string set \<Rightarrow> string \<Rightarrow> bool" ("_ \<equiv>_\<equiv> _" [100, 100, 100] 100)
       
   269 where
       
   270   "x \<equiv>Lang\<equiv> y \<longleftrightarrow> (\<forall>z. x @ z \<in> Lang \<longleftrightarrow> y @ z \<in> Lang)"
       
   271 
       
   272 definition
       
   273   equiv_class :: "string \<Rightarrow> (string set) \<Rightarrow> string set" ("\<lbrakk>_\<rbrakk>_" [100, 100] 100)
       
   274 where
       
   275   "\<lbrakk>x\<rbrakk>Lang \<equiv> {y. x \<equiv>Lang\<equiv> y}"
       
   276 
       
   277 text {* Chunhan modifies Q to Quo *}
       
   278 
       
   279 definition  
       
   280   quot :: "string set \<Rightarrow> string set \<Rightarrow> (string set) set" ("_ Quo _" [100, 100] 100)
       
   281 where
       
   282   "L1 Quo L2 \<equiv> { \<lbrakk>x\<rbrakk>L2 | x. x \<in> L1}" 
       
   283 
       
   284 
       
   285 lemma lang_eqs_union_of_eqcls: 
       
   286   "Lang = \<Union> {X. X \<in> (UNIV Quo Lang) \<and> (\<forall> x \<in> X. x \<in> Lang)}"
       
   287 proof
       
   288   show "Lang \<subseteq> \<Union>{X \<in> UNIV Quo Lang. \<forall>x\<in>X. x \<in> Lang}"
       
   289   proof
       
   290     fix x
       
   291     assume "x \<in> Lang"
       
   292     thus "x \<in> \<Union>{X \<in> UNIV Quo Lang. \<forall>x\<in>X. x \<in> Lang}"
       
   293     proof (simp add:quot_def)
       
   294       assume "(1)": "x \<in> Lang"
       
   295       show "\<exists>xa. (\<exists>x. xa = \<lbrakk>x\<rbrakk>Lang) \<and> (\<forall>x\<in>xa. x \<in> Lang) \<and> x \<in> xa" (is "\<exists>xa.?P xa")
       
   296       proof -
       
   297         have "?P (\<lbrakk>x\<rbrakk>Lang)" using "(1)"
       
   298           by (auto simp:equiv_class_def equiv_str_def dest: spec[where  x = "[]"])
       
   299         thus ?thesis by blast
       
   300       qed
       
   301     qed
       
   302   qed   
       
   303 next
       
   304   show "\<Union>{X \<in> UNIV Quo Lang. \<forall>x\<in>X. x \<in> Lang} \<subseteq> Lang"
       
   305     by auto
       
   306 qed
       
   307 
       
   308 lemma empty_notin_CS: "{} \<notin> UNIV Quo Lang"
       
   309 apply (clarsimp simp:quot_def equiv_class_def)
       
   310 by (rule_tac x = x in exI, auto simp:equiv_str_def)
       
   311 
       
   312 lemma no_two_cls_inters:
       
   313   "\<lbrakk>X \<in> UNIV Quo Lang; Y \<in> UNIV Quo Lang; X \<noteq> Y\<rbrakk> \<Longrightarrow> X \<inter> Y = {}"
       
   314 by (auto simp:quot_def equiv_class_def equiv_str_def)
       
   315 
       
   316 text {* equiv_class transition *}
       
   317 definition 
       
   318   CT :: "string set \<Rightarrow> char \<Rightarrow> string set \<Rightarrow> bool" ("_-_\<rightarrow>_" [99,99]99)
       
   319 where
       
   320   "X-c\<rightarrow>Y \<equiv> ((X;{[c]}) \<subseteq> Y)"
       
   321 
       
   322 types t_equa_rhs = "(string set \<times> rexp) set"
       
   323 
       
   324 types t_equa = "(string set \<times> t_equa_rhs)"
       
   325 
       
   326 types t_equas = "t_equa set"
       
   327 
       
   328 text {* 
       
   329   "empty_rhs" generates "\<lambda>" for init-state, just like "\<lambda>" for final states 
       
   330   in Brzozowski method. But if the init-state is "{[]}" ("\<lambda>" itself) then 
       
   331   empty set is returned, see definition of "equation_rhs" 
       
   332 *} 
       
   333 
       
   334 definition 
       
   335   empty_rhs :: "string set \<Rightarrow> t_equa_rhs"
       
   336 where
       
   337   "empty_rhs X \<equiv> if ([] \<in> X) then {({[]}, EMPTY)} else {}"
       
   338 
       
   339 definition 
       
   340   folds :: "('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> 'b \<Rightarrow> 'a set \<Rightarrow> 'b"
       
   341 where
       
   342   "folds f z S \<equiv> SOME x. fold_graph f z S x"
       
   343 
       
   344 definition 
       
   345   equation_rhs :: "(string set) set \<Rightarrow> string set \<Rightarrow> t_equa_rhs"
       
   346 where
       
   347   "equation_rhs CS X \<equiv> if (X = {[]}) then {({[]}, EMPTY)}
       
   348                          else {(S, folds ALT NULL {CHAR c| c. S-c\<rightarrow>X} )| S. S \<in> CS} \<union> empty_rhs X"
       
   349 
       
   350 definition 
       
   351   equations :: "(string set) set \<Rightarrow> t_equas"
       
   352 where
       
   353   "equations CS \<equiv> {(X, equation_rhs CS X) | X. X \<in> CS}"
       
   354 
       
   355 overloading L_rhs \<equiv> "L:: t_equa_rhs \<Rightarrow> string set"
       
   356 begin
       
   357 fun L_rhs:: "t_equa_rhs \<Rightarrow> string set"
       
   358 where
       
   359   "L_rhs rhs = {x. \<exists> X r. (X, r) \<in> rhs \<and> x \<in> X;(L r)}"
       
   360 end
       
   361 
       
   362 definition 
       
   363   distinct_rhs :: "t_equa_rhs \<Rightarrow> bool"
       
   364 where
       
   365   "distinct_rhs rhs \<equiv> \<forall> X reg\<^isub>1 reg\<^isub>2. (X, reg\<^isub>1) \<in> rhs \<and> (X, reg\<^isub>2) \<in> rhs \<longrightarrow> reg\<^isub>1 = reg\<^isub>2"
       
   366 
       
   367 definition
       
   368   distinct_equas_rhs :: "t_equas \<Rightarrow> bool"
       
   369 where
       
   370   "distinct_equas_rhs equas \<equiv> \<forall> X rhs. (X, rhs) \<in> equas \<longrightarrow> distinct_rhs rhs"
       
   371 
       
   372 definition 
       
   373   distinct_equas :: "t_equas \<Rightarrow> bool"
       
   374 where
       
   375   "distinct_equas equas \<equiv> \<forall> X rhs rhs'. (X, rhs) \<in> equas \<and> (X, rhs') \<in> equas \<longrightarrow> rhs = rhs'"
       
   376 
       
   377 definition 
       
   378   seq_rhs_r :: "t_equa_rhs \<Rightarrow> rexp \<Rightarrow> t_equa_rhs"
       
   379 where
       
   380   "seq_rhs_r rhs r \<equiv> (\<lambda>(X, reg). (X, SEQ reg r)) ` rhs"
       
   381 
       
   382 definition 
       
   383   del_x_paired :: "('a \<times> 'b) set \<Rightarrow> 'a \<Rightarrow> ('a \<times> 'b) set"
       
   384 where
       
   385   "del_x_paired S x \<equiv> S - {X. X \<in> S \<and> fst X = x}"
       
   386 
       
   387 definition
       
   388   arden_variate :: "string set \<Rightarrow> rexp \<Rightarrow> t_equa_rhs \<Rightarrow> t_equa_rhs"
       
   389 where
       
   390   "arden_variate X r rhs \<equiv> seq_rhs_r (del_x_paired rhs X) (STAR r)"
       
   391 
       
   392 definition
       
   393   no_EMPTY_rhs :: "t_equa_rhs \<Rightarrow> bool"
       
   394 where
       
   395   "no_EMPTY_rhs rhs \<equiv> \<forall> X r. (X, r) \<in> rhs \<and> X \<noteq> {[]} \<longrightarrow> [] \<notin> L r"
       
   396 
       
   397 definition 
       
   398   no_EMPTY_equas :: "t_equas \<Rightarrow> bool"
       
   399 where
       
   400   "no_EMPTY_equas equas \<equiv> \<forall> X rhs. (X, rhs) \<in> equas \<longrightarrow> no_EMPTY_rhs rhs"
       
   401 
       
   402 lemma fold_alt_null_eqs:
       
   403   "finite rS \<Longrightarrow> x \<in> L (folds ALT NULL rS) = (\<exists> r \<in> rS. x \<in> L r)"
       
   404 apply (simp add:folds_def)
       
   405 apply (rule someI2_ex)
       
   406 apply (erule finite_imp_fold_graph)
       
   407 apply (erule fold_graph.induct)
       
   408 by auto (*??? how do this be in Isar ?? *)
       
   409 
       
   410 lemma seq_rhs_r_prop1:
       
   411   "L (seq_rhs_r rhs r) = (L rhs);(L r)"
       
   412 apply (auto simp:seq_rhs_r_def image_def lang_seq_def)
       
   413 apply (rule_tac x = "s1 @ s1a" in exI, rule_tac x = "s2a" in exI, simp)
       
   414 apply (rule_tac x = a in exI, rule_tac x = b in exI, simp)
       
   415 apply (rule_tac x = s1 in exI, rule_tac x = s1a in exI, simp)
       
   416 apply (rule_tac x = X in exI, rule_tac x  = "SEQ ra r" in exI, simp)
       
   417 apply (rule conjI)
       
   418 apply (rule_tac x = "(X, ra)" in bexI, simp+) 
       
   419 apply (rule_tac x = s1a in exI, rule_tac x = "s2a @ s2" in exI, simp)
       
   420 apply (simp add:lang_seq_def)
       
   421 by (rule_tac x = s2a in exI, rule_tac x = s2 in exI, simp)
       
   422 
       
   423 lemma del_x_paired_prop1:  
       
   424   "\<lbrakk>distinct_rhs rhs; (X, r) \<in> rhs\<rbrakk> \<Longrightarrow> X ; L r \<union> L (del_x_paired rhs X) = L rhs"
       
   425   apply (simp add:del_x_paired_def)
       
   426   apply (simp add: distinct_rhs_def)
       
   427   apply(auto simp add: lang_seq_def)
       
   428   apply(metis)
       
   429   done
       
   430 
       
   431 lemma arden_variate_prop:
       
   432   assumes "(X, rx) \<in> rhs"
       
   433   shows "(\<forall> Y. Y \<noteq> X \<longrightarrow> (\<exists> r. (Y, r) \<in> rhs) = (\<exists> r. (Y, r) \<in> (arden_variate X rx rhs)))"
       
   434 proof (rule allI, rule impI)
       
   435   fix Y
       
   436   assume "(1)": "Y \<noteq> X"
       
   437   show "(\<exists>r. (Y, r) \<in> rhs) = (\<exists>r. (Y, r) \<in> arden_variate X rx rhs)"
       
   438   proof
       
   439     assume "(1_1)": "\<exists>r. (Y, r) \<in> rhs"
       
   440     show "\<exists>r. (Y, r) \<in> arden_variate X rx rhs" (is "\<exists>r. ?P r")
       
   441     proof -
       
   442       from "(1_1)" obtain r where "(Y, r) \<in> rhs" ..
       
   443       hence "?P (SEQ r (STAR rx))"
       
   444       proof (simp add:arden_variate_def image_def)
       
   445         have "(Y, r) \<in> rhs \<Longrightarrow> (Y, r) \<in> del_x_paired rhs X"
       
   446           by (auto simp:del_x_paired_def "(1)")
       
   447         thus "(Y, r) \<in> rhs \<Longrightarrow> (Y, SEQ r (STAR rx)) \<in> seq_rhs_r (del_x_paired rhs X) (STAR rx)"
       
   448           by (auto simp:seq_rhs_r_def)
       
   449       qed
       
   450       thus ?thesis by blast
       
   451     qed
       
   452   next
       
   453     assume "(2_1)": "\<exists>r. (Y, r) \<in> arden_variate X rx rhs"
       
   454     thus "\<exists>r. (Y, r) \<in> rhs" (is "\<exists> r. ?P r")
       
   455       by (auto simp:arden_variate_def del_x_paired_def seq_rhs_r_def image_def)
       
   456   qed
       
   457 qed
       
   458 
       
   459 text {*
       
   460   arden_variate_valid:  proves variation from 
       
   461   
       
   462    "X = X;r + Y;ry + \<dots>" to "X = Y;(SEQ ry (STAR r)) + \<dots>" 
       
   463 
       
   464   holds the law of "language of left equiv language of right" 
       
   465 *}
       
   466 lemma arden_variate_valid:
       
   467   assumes X_not_empty: "X \<noteq> {[]}"
       
   468   and     l_eq_r:   "X = L rhs"
       
   469   and     dist: "distinct_rhs rhs"
       
   470   and     no_empty: "no_EMPTY_rhs rhs"
       
   471   and     self_contained: "(X, r) \<in> rhs"
       
   472   shows   "X = L (arden_variate X r rhs)" 
       
   473 proof -
       
   474   have "[] \<notin> L r" using no_empty X_not_empty self_contained
       
   475     by (auto simp:no_EMPTY_rhs_def)
       
   476   hence ardens: "X = X;(L r) \<union> (L (del_x_paired rhs X)) \<longleftrightarrow> X = (L (del_x_paired rhs X)) ; (L r)\<star>" 
       
   477     by (rule ardens_revised)
       
   478   have del_x: "X = X ; L r \<union> L (del_x_paired rhs X) \<longleftrightarrow> X = L rhs" using dist l_eq_r self_contained
       
   479     by (auto dest!:del_x_paired_prop1)
       
   480   show ?thesis
       
   481   proof
       
   482     show "X \<subseteq> L (arden_variate X r rhs)"
       
   483     proof
       
   484       fix x
       
   485       assume "(1_1)": "x \<in> X" with l_eq_r ardens del_x
       
   486       show "x \<in> L (arden_variate X r rhs)" 
       
   487         by (simp add:arden_variate_def seq_rhs_r_prop1 del:L_rhs.simps)
       
   488     qed
       
   489   next
       
   490     show "L (arden_variate X r rhs) \<subseteq> X"
       
   491     proof
       
   492       fix x
       
   493       assume "(2_1)": "x \<in> L (arden_variate X r rhs)" with ardens del_x l_eq_r
       
   494       show "x \<in> X" 
       
   495         by (simp add:arden_variate_def seq_rhs_r_prop1 del:L_rhs.simps)
       
   496     qed
       
   497   qed
       
   498 qed
       
   499 
       
   500 text {* 
       
   501   merge_rhs {(x1, r1), (x2, r2}, (x4, r4), \<dots>} {(x1, r1'), (x3, r3'), \<dots>} = 
       
   502      {(x1, ALT r1 r1'}, (x2, r2), (x3, r3'), (x4, r4), \<dots>} *}  
       
   503 definition 
       
   504   merge_rhs :: "t_equa_rhs \<Rightarrow> t_equa_rhs \<Rightarrow> t_equa_rhs"
       
   505 where
       
   506   "merge_rhs rhs rhs' \<equiv> {(X, r). (\<exists> r1 r2. ((X,r1) \<in> rhs \<and> (X, r2) \<in> rhs') \<and> r = ALT r1 r2)  \<or>
       
   507                                  (\<exists> r1. (X, r1) \<in> rhs \<and> (\<not> (\<exists> r2. (X, r2) \<in> rhs')) \<and> r = r1) \<or>
       
   508                                  (\<exists> r2. (X, r2) \<in> rhs' \<and> (\<not> (\<exists> r1. (X, r1) \<in> rhs)) \<and> r = r2)    }"                                  
       
   509 
       
   510 
       
   511 text {* rhs_subst rhs X=xrhs r: substitude all occurence of X in rhs((X,r) \<in> rhs) with xrhs *}
       
   512 definition 
       
   513   rhs_subst :: "t_equa_rhs \<Rightarrow> string set \<Rightarrow> t_equa_rhs \<Rightarrow> rexp \<Rightarrow> t_equa_rhs"
       
   514 where
       
   515   "rhs_subst rhs X xrhs r \<equiv> merge_rhs (del_x_paired rhs X) (seq_rhs_r xrhs r)"
       
   516 
       
   517 definition 
       
   518   equas_subst_f :: "string set \<Rightarrow> t_equa_rhs \<Rightarrow> t_equa \<Rightarrow> t_equa"
       
   519 where
       
   520   "equas_subst_f X xrhs equa \<equiv> let (Y, rhs) = equa in
       
   521                                  if (\<exists> r. (X, r) \<in> rhs)
       
   522                                  then (Y, rhs_subst rhs X xrhs (SOME r. (X, r) \<in> rhs))
       
   523                                  else equa"
       
   524 
       
   525 definition
       
   526   equas_subst :: "t_equas \<Rightarrow> string set \<Rightarrow> t_equa_rhs \<Rightarrow> t_equas"
       
   527 where
       
   528   "equas_subst ES X xrhs \<equiv> del_x_paired (equas_subst_f X xrhs ` ES) X"
       
   529 
       
   530 lemma lang_seq_prop1:
       
   531  "x \<in> X ; L r \<Longrightarrow> x \<in> X ; (L r \<union> L r')"
       
   532 by (auto simp:lang_seq_def)
       
   533 
       
   534 lemma lang_seq_prop1':
       
   535   "x \<in> X; L r \<Longrightarrow> x \<in> X ; (L r' \<union> L r)"
       
   536 by (auto simp:lang_seq_def)
       
   537 
       
   538 lemma lang_seq_prop2:
       
   539   "x \<in> X; (L r \<union> L r') \<Longrightarrow> x \<in> X;L r \<or> x \<in> X;L r'"
       
   540 by (auto simp:lang_seq_def)
       
   541 
       
   542 lemma merge_rhs_prop1:
       
   543   shows "L (merge_rhs rhs rhs') = L rhs \<union> L rhs' "
       
   544 apply (auto simp add:merge_rhs_def dest!:lang_seq_prop2 intro:lang_seq_prop1)
       
   545 apply (rule_tac x = X in exI, rule_tac x = r1 in exI, simp)
       
   546 apply (case_tac "\<exists> r2. (X, r2) \<in> rhs'")
       
   547 apply (clarify, rule_tac x = X in exI, rule_tac x = "ALT r r2" in exI, simp add:lang_seq_prop1)
       
   548 apply (rule_tac x = X in exI, rule_tac x = r in exI, simp)
       
   549 apply (case_tac "\<exists> r1. (X, r1) \<in> rhs")
       
   550 apply (clarify, rule_tac x = X in exI, rule_tac x = "ALT r1 r" in exI, simp add:lang_seq_prop1')
       
   551 apply (rule_tac x = X in exI, rule_tac x = r in exI, simp)
       
   552 done
       
   553 
       
   554 lemma no_EMPTY_rhss_imp_merge_no_EMPTY:
       
   555   "\<lbrakk>no_EMPTY_rhs rhs; no_EMPTY_rhs rhs'\<rbrakk> \<Longrightarrow> no_EMPTY_rhs (merge_rhs rhs rhs')"
       
   556 apply (simp add:no_EMPTY_rhs_def merge_rhs_def)
       
   557 apply (clarify, (erule conjE | erule exE | erule disjE)+)
       
   558 by auto
       
   559 
       
   560 lemma distinct_rhs_prop:
       
   561   "\<lbrakk>distinct_rhs rhs; (X, r1) \<in> rhs; (X, r2) \<in> rhs\<rbrakk> \<Longrightarrow> r1 = r2"
       
   562 by (auto simp:distinct_rhs_def)
       
   563 
       
   564 lemma merge_rhs_prop2:
       
   565   assumes dist_rhs: "distinct_rhs rhs"
       
   566   and     dist_rhs':"distinct_rhs rhs'"
       
   567   shows "distinct_rhs (merge_rhs rhs rhs')"
       
   568 apply (auto simp:merge_rhs_def distinct_rhs_def)
       
   569 using dist_rhs
       
   570 apply (drule distinct_rhs_prop, simp+)
       
   571 using dist_rhs'
       
   572 apply (drule distinct_rhs_prop, simp+)
       
   573 using dist_rhs
       
   574 apply (drule distinct_rhs_prop, simp+)
       
   575 using dist_rhs'
       
   576 apply (drule distinct_rhs_prop, simp+)
       
   577 done
       
   578 
       
   579 lemma seq_rhs_r_holds_distinct: 
       
   580   "distinct_rhs rhs \<Longrightarrow> distinct_rhs (seq_rhs_r rhs r)"
       
   581 by (auto simp:distinct_rhs_def seq_rhs_r_def)
       
   582 
       
   583 lemma seq_rhs_r_prop0:
       
   584   assumes l_eq_r: "X = L xrhs"
       
   585   shows "L (seq_rhs_r xrhs r) = X ; L r "
       
   586 using l_eq_r
       
   587 by (auto simp only:seq_rhs_r_prop1)
       
   588 
       
   589 lemma rhs_subst_prop1:
       
   590   assumes l_eq_r: "X = L xrhs"
       
   591   and     dist:  "distinct_rhs rhs"
       
   592   shows "(X, r) \<in> rhs \<Longrightarrow> L rhs = L (rhs_subst rhs X xrhs r)"
       
   593 apply (simp add:rhs_subst_def merge_rhs_prop1 del:L_rhs.simps)
       
   594 using l_eq_r 
       
   595 apply (drule_tac r = r in seq_rhs_r_prop0, simp del:L_rhs.simps)
       
   596 using dist
       
   597 by (auto dest!:del_x_paired_prop1 simp del:L_rhs.simps)
       
   598 
       
   599 lemma del_x_paired_holds_distinct_rhs:
       
   600   "distinct_rhs rhs \<Longrightarrow> distinct_rhs (del_x_paired rhs x)"
       
   601 by (auto simp:distinct_rhs_def del_x_paired_def)
       
   602 
       
   603 lemma rhs_subst_holds_distinct_rhs:
       
   604   "\<lbrakk>distinct_rhs rhs; distinct_rhs xrhs\<rbrakk> \<Longrightarrow> distinct_rhs (rhs_subst rhs X xrhs r)"
       
   605 apply (drule_tac r = r and rhs = xrhs in seq_rhs_r_holds_distinct)
       
   606 apply (drule_tac x = X in del_x_paired_holds_distinct_rhs)
       
   607 by (auto dest:merge_rhs_prop2[where rhs = "del_x_paired rhs X"] simp:rhs_subst_def)
       
   608 
       
   609 section {* myhill-nerode theorem *}
       
   610 
       
   611 definition left_eq_cls :: "t_equas \<Rightarrow> (string set) set"
       
   612 where
       
   613   "left_eq_cls ES \<equiv> {X. \<exists> rhs. (X, rhs) \<in> ES} "
       
   614 
       
   615 definition right_eq_cls :: "t_equas \<Rightarrow> (string set) set"
       
   616 where
       
   617   "right_eq_cls ES \<equiv> {Y. \<exists> X rhs r. (X, rhs) \<in> ES \<and> (Y, r) \<in> rhs }"
       
   618 
       
   619 definition rhs_eq_cls :: "t_equa_rhs \<Rightarrow> (string set) set"
       
   620 where
       
   621   "rhs_eq_cls rhs \<equiv> {Y. \<exists> r. (Y, r) \<in> rhs}"
       
   622 
       
   623 definition ardenable :: "t_equa \<Rightarrow> bool"
       
   624 where
       
   625   "ardenable equa \<equiv> let (X, rhs) = equa in 
       
   626                       distinct_rhs rhs \<and> no_EMPTY_rhs rhs \<and> X = L rhs"
       
   627 
       
   628 text {*
       
   629   Inv: Invairance of the equation-system, during the decrease of the equation-system, Inv holds.
       
   630 *}
       
   631 definition Inv :: "string set \<Rightarrow> t_equas \<Rightarrow> bool"
       
   632 where
       
   633   "Inv X ES \<equiv> finite ES \<and> (\<exists> rhs. (X, rhs) \<in> ES) \<and> distinct_equas ES \<and> 
       
   634             (\<forall> X xrhs. (X, xrhs) \<in> ES \<longrightarrow> ardenable (X, xrhs) \<and> X \<noteq> {} \<and> rhs_eq_cls xrhs \<subseteq> insert {[]} (left_eq_cls ES))"
       
   635 
       
   636 text {*
       
   637   TCon: Termination Condition of the equation-system decreasion.
       
   638 *}
       
   639 definition TCon:: "'a set \<Rightarrow> bool"
       
   640 where
       
   641   "TCon ES \<equiv> card ES = 1"
       
   642 
       
   643 
       
   644 text {* 
       
   645   The following is a iteration principle, and is the main framework for the proof:
       
   646    1: We can form the initial equation-system using "equations" defined above, and prove it has invariance Inv by lemma "init_ES_satisfy_Inv";
       
   647    2: We can decrease the number of the equation-system using ardens_lemma_revised and substitution ("equas_subst", defined above), 
       
   648         and prove it holds the property "step" in "wf_iter" by lemma "iteration_step"
       
   649    and finally using property Inv and TCon to prove the myhill-nerode theorem
       
   650   
       
   651 *}
       
   652 lemma wf_iter [rule_format]: 
       
   653   fixes f
       
   654   assumes step: "\<And> e. \<lbrakk>P e; \<not> Q e\<rbrakk> \<Longrightarrow> (\<exists> e'. P e' \<and>  (f(e'), f(e)) \<in> less_than)"
       
   655   shows pe:     "P e \<longrightarrow> (\<exists> e'. P e' \<and>  Q e')"
       
   656 proof(induct e rule: wf_induct 
       
   657            [OF wf_inv_image[OF wf_less_than, where f = "f"]], clarify)
       
   658   fix x 
       
   659   assume h [rule_format]: 
       
   660     "\<forall>y. (y, x) \<in> inv_image less_than f \<longrightarrow> P y \<longrightarrow> (\<exists>e'. P e' \<and> Q e')"
       
   661     and px: "P x"
       
   662   show "\<exists>e'. P e' \<and> Q e'"
       
   663   proof(cases "Q x")
       
   664     assume "Q x" with px show ?thesis by blast
       
   665   next
       
   666     assume nq: "\<not> Q x"
       
   667     from step [OF px nq]
       
   668     obtain e' where pe': "P e'" and ltf: "(f e', f x) \<in> less_than" by auto
       
   669     show ?thesis
       
   670     proof(rule h)
       
   671       from ltf show "(e', x) \<in> inv_image less_than f" 
       
   672 	by (simp add:inv_image_def)
       
   673     next
       
   674       from pe' show "P e'" .
       
   675     qed
       
   676   qed
       
   677 qed
       
   678 
       
   679 
       
   680 text {* ******BEGIN: proving the initial equation-system satisfies Inv ****** *}
       
   681 
       
   682 lemma distinct_rhs_equations:
       
   683   "(X, xrhs) \<in> equations (UNIV Quo Lang) \<Longrightarrow> distinct_rhs xrhs"
       
   684 by (auto simp: equations_def equation_rhs_def distinct_rhs_def empty_rhs_def dest:no_two_cls_inters)
       
   685 
       
   686 lemma every_nonempty_eqclass_has_strings:
       
   687   "\<lbrakk>X \<in> (UNIV Quo Lang); X \<noteq> {[]}\<rbrakk> \<Longrightarrow> \<exists> clist. clist \<in> X \<and> clist \<noteq> []"
       
   688 by (auto simp:quot_def equiv_class_def equiv_str_def)
       
   689 
       
   690 lemma every_eqclass_is_derived_from_empty:
       
   691   assumes not_empty: "X \<noteq> {[]}"
       
   692   shows "X \<in> (UNIV Quo Lang) \<Longrightarrow> \<exists> clist. {[]};{clist} \<subseteq> X \<and> clist \<noteq> []"
       
   693 using not_empty
       
   694 apply (drule_tac every_nonempty_eqclass_has_strings, simp)
       
   695 by (auto intro:exI[where x = clist] simp:lang_seq_def)
       
   696 
       
   697 lemma equiv_str_in_CS:
       
   698   "\<lbrakk>clist\<rbrakk>Lang \<in> (UNIV Quo Lang)"
       
   699 by (auto simp:quot_def)
       
   700 
       
   701 lemma has_str_imp_defined_by_str:
       
   702   "\<lbrakk>str \<in> X; X \<in> UNIV Quo Lang\<rbrakk> \<Longrightarrow> X = \<lbrakk>str\<rbrakk>Lang"
       
   703 by (auto simp:quot_def equiv_class_def equiv_str_def)
       
   704 
       
   705 lemma every_eqclass_has_ascendent:
       
   706   assumes has_str: "clist @ [c] \<in> X"
       
   707   and     in_CS:   "X \<in> UNIV Quo Lang"
       
   708   shows "\<exists> Y. Y \<in> UNIV Quo Lang \<and> Y-c\<rightarrow>X \<and> clist \<in> Y" (is "\<exists> Y. ?P Y")
       
   709 proof -
       
   710   have "?P (\<lbrakk>clist\<rbrakk>Lang)" 
       
   711   proof -
       
   712     have "\<lbrakk>clist\<rbrakk>Lang \<in> UNIV Quo Lang"       
       
   713       by (simp add:quot_def, rule_tac x = clist in exI, simp)
       
   714     moreover have "\<lbrakk>clist\<rbrakk>Lang-c\<rightarrow>X" 
       
   715     proof -
       
   716       have "X = \<lbrakk>(clist @ [c])\<rbrakk>Lang" using has_str in_CS
       
   717         by (auto intro!:has_str_imp_defined_by_str)
       
   718       moreover have "\<forall> sl. sl \<in> \<lbrakk>clist\<rbrakk>Lang \<longrightarrow> sl @ [c] \<in> \<lbrakk>(clist @ [c])\<rbrakk>Lang"
       
   719         by (auto simp:equiv_class_def equiv_str_def)
       
   720       ultimately show ?thesis unfolding CT_def lang_seq_def
       
   721         by auto
       
   722     qed
       
   723     moreover have "clist \<in> \<lbrakk>clist\<rbrakk>Lang" 
       
   724       by (auto simp:equiv_str_def equiv_class_def)
       
   725     ultimately show "?P (\<lbrakk>clist\<rbrakk>Lang)" by simp
       
   726   qed
       
   727   thus ?thesis by blast
       
   728 qed
       
   729 
       
   730 lemma finite_charset_rS:
       
   731   "finite {CHAR c |c. Y-c\<rightarrow>X}"
       
   732 by (rule_tac A = UNIV and f = CHAR in finite_surj, auto)
       
   733 
       
   734 lemma l_eq_r_in_equations:
       
   735   assumes X_in_equas: "(X, xrhs) \<in> equations (UNIV Quo Lang)"
       
   736   shows "X = L xrhs"    
       
   737 proof (cases "X = {[]}")
       
   738   case True
       
   739   thus ?thesis using X_in_equas 
       
   740     by (simp add:equations_def equation_rhs_def lang_seq_def)
       
   741 next
       
   742   case False 
       
   743   show ?thesis
       
   744   proof 
       
   745     show "X \<subseteq> L xrhs"
       
   746     proof
       
   747       fix x
       
   748       assume "(1)": "x \<in> X"
       
   749       show "x \<in> L xrhs"          
       
   750       proof (cases "x = []")
       
   751         assume empty: "x = []"
       
   752         hence "x \<in> L (empty_rhs X)" using "(1)"
       
   753           by (auto simp:empty_rhs_def lang_seq_def)
       
   754         thus ?thesis using X_in_equas False empty "(1)" 
       
   755           unfolding equations_def equation_rhs_def by auto
       
   756       next
       
   757         assume not_empty: "x \<noteq> []"
       
   758         hence "\<exists> clist c. x = clist @ [c]" by (case_tac x rule:rev_cases, auto)
       
   759         then obtain clist c where decom: "x = clist @ [c]" by blast
       
   760         moreover have "\<And> Y. \<lbrakk>Y \<in> UNIV Quo Lang; Y-c\<rightarrow>X; clist \<in> Y\<rbrakk>
       
   761           \<Longrightarrow> [c] \<in> L (folds ALT NULL {CHAR c |c. Y-c\<rightarrow>X})"
       
   762         proof -
       
   763           fix Y
       
   764           assume Y_is_eq_cl: "Y \<in> UNIV Quo Lang"
       
   765             and Y_CT_X: "Y-c\<rightarrow>X"
       
   766             and clist_in_Y: "clist \<in> Y"
       
   767           with finite_charset_rS 
       
   768           show "[c] \<in> L (folds ALT NULL {CHAR c |c. Y-c\<rightarrow>X})"
       
   769             by (auto simp :fold_alt_null_eqs)
       
   770         qed
       
   771         hence "\<exists>Xa. Xa \<in> UNIV Quo Lang \<and> clist @ [c] \<in> Xa ; L (folds ALT NULL {CHAR c |c. Xa-c\<rightarrow>X})" 
       
   772           using X_in_equas False not_empty "(1)" decom
       
   773           by (auto dest!:every_eqclass_has_ascendent simp:equations_def equation_rhs_def lang_seq_def)
       
   774         then obtain Xa where 
       
   775           "Xa \<in> UNIV Quo Lang \<and> clist @ [c] \<in> Xa ; L (folds ALT NULL {CHAR c |c. Xa-c\<rightarrow>X})" by blast
       
   776         hence "x \<in> L {(S, folds ALT NULL {CHAR c |c. S-c\<rightarrow>X}) |S. S \<in> UNIV Quo Lang}" 
       
   777           using X_in_equas "(1)" decom
       
   778           by (auto simp add:equations_def equation_rhs_def intro!:exI[where x = Xa])
       
   779         thus "x \<in> L xrhs" using X_in_equas False not_empty unfolding equations_def equation_rhs_def
       
   780           by auto
       
   781       qed
       
   782     qed
       
   783   next
       
   784     show "L xrhs \<subseteq> X"
       
   785     proof
       
   786       fix x 
       
   787       assume "(2)": "x \<in> L xrhs"
       
   788       have "(2_1)": "\<And> s1 s2 r Xa. \<lbrakk>s1 \<in> Xa; s2 \<in> L (folds ALT NULL {CHAR c |c. Xa-c\<rightarrow>X})\<rbrakk> \<Longrightarrow> s1 @ s2 \<in> X"
       
   789         using finite_charset_rS
       
   790         by (auto simp:CT_def lang_seq_def fold_alt_null_eqs)
       
   791       have "(2_2)": "\<And> s1 s2 Xa r.\<lbrakk>s1 \<in> Xa; s2 \<in> L r; (Xa, r) \<in> empty_rhs X\<rbrakk> \<Longrightarrow> s1 @ s2 \<in> X"
       
   792         by (simp add:empty_rhs_def split:if_splits)
       
   793       show "x \<in> X" using X_in_equas False "(2)"         
       
   794         by (auto intro:"(2_1)" "(2_2)" simp:equations_def equation_rhs_def lang_seq_def)
       
   795     qed
       
   796   qed
       
   797 qed
       
   798 
       
   799 
       
   800 
       
   801 lemma no_EMPTY_equations:
       
   802   "(X, xrhs) \<in> equations CS \<Longrightarrow> no_EMPTY_rhs xrhs"
       
   803 apply (clarsimp simp add:equations_def equation_rhs_def)
       
   804 apply (simp add:no_EMPTY_rhs_def empty_rhs_def, auto)
       
   805 apply (subgoal_tac "finite {CHAR c |c. Xa-c\<rightarrow>X}", drule_tac x = "[]" in fold_alt_null_eqs, clarsimp, rule finite_charset_rS)+
       
   806 done
       
   807 
       
   808 lemma init_ES_satisfy_ardenable:
       
   809   "(X, xrhs) \<in> equations (UNIV Quo Lang)  \<Longrightarrow> ardenable (X, xrhs)"  
       
   810   unfolding ardenable_def
       
   811   by (auto intro:distinct_rhs_equations no_EMPTY_equations simp:l_eq_r_in_equations simp del:L_rhs.simps)
       
   812 
       
   813 lemma init_ES_satisfy_Inv:
       
   814   assumes finite_CS: "finite (UNIV Quo Lang)"
       
   815   and X_in_eq_cls: "X \<in> UNIV Quo Lang"
       
   816   shows "Inv X (equations (UNIV Quo Lang))"
       
   817 proof -
       
   818   have "finite (equations (UNIV Quo Lang))" using finite_CS
       
   819     by (auto simp:equations_def)    
       
   820   moreover have "\<exists>rhs. (X, rhs) \<in> equations (UNIV Quo Lang)" using X_in_eq_cls 
       
   821     by (simp add:equations_def)
       
   822   moreover have "distinct_equas (equations (UNIV Quo Lang))" 
       
   823     by (auto simp:distinct_equas_def equations_def)
       
   824   moreover have "\<forall>X xrhs. (X, xrhs) \<in> equations (UNIV Quo Lang) \<longrightarrow>
       
   825                  rhs_eq_cls xrhs \<subseteq> insert {[]} (left_eq_cls (equations (UNIV Quo Lang)))" 
       
   826     apply (simp add:left_eq_cls_def equations_def rhs_eq_cls_def equation_rhs_def)
       
   827     by (auto simp:empty_rhs_def split:if_splits)
       
   828   moreover have "\<forall>X xrhs. (X, xrhs) \<in> equations (UNIV Quo Lang) \<longrightarrow> X \<noteq> {}"
       
   829     by (clarsimp simp:equations_def empty_notin_CS intro:classical)
       
   830   moreover have "\<forall>X xrhs. (X, xrhs) \<in> equations (UNIV Quo Lang) \<longrightarrow> ardenable (X, xrhs)"
       
   831     by (auto intro!:init_ES_satisfy_ardenable)
       
   832   ultimately show ?thesis by (simp add:Inv_def)
       
   833 qed
       
   834 
       
   835 
       
   836 text {* *********** END: proving the initial equation-system satisfies Inv ******* *}
       
   837 
       
   838 
       
   839 text {* ****** BEGIN: proving every equation-system's iteration step satisfies Inv ***** *}
       
   840 
       
   841 lemma not_T_aux: "\<lbrakk>\<not> TCon (insert a A); x = a\<rbrakk>
       
   842        \<Longrightarrow> \<exists>y. x \<noteq> y \<and> y \<in> insert a A "
       
   843 apply (case_tac "insert a A = {a}")
       
   844 by (auto simp:TCon_def)
       
   845 
       
   846 lemma not_T_atleast_2[rule_format]:
       
   847   "finite S \<Longrightarrow> \<forall> x. x \<in> S \<and> (\<not> TCon S)\<longrightarrow> (\<exists> y. x \<noteq> y \<and> y \<in> S)"
       
   848 apply (erule finite.induct, simp)
       
   849 apply (clarify, case_tac "x = a")
       
   850 by (erule not_T_aux, auto)
       
   851 
       
   852 lemma exist_another_equa: 
       
   853   "\<lbrakk>\<not> TCon ES; finite ES; distinct_equas ES; (X, rhl) \<in> ES\<rbrakk> \<Longrightarrow> \<exists> Y yrhl. (Y, yrhl) \<in> ES \<and> X \<noteq> Y"
       
   854 apply (drule not_T_atleast_2, simp)
       
   855 apply (clarsimp simp:distinct_equas_def)
       
   856 apply (drule_tac x= X in spec, drule_tac x = rhl in spec, drule_tac x = b in spec)
       
   857 by auto
       
   858 
       
   859 lemma Inv_mono_with_lambda:
       
   860   assumes Inv_ES: "Inv X ES"
       
   861   and X_noteq_Y:  "X \<noteq> {[]}"
       
   862   shows "Inv X (ES - {({[]}, yrhs)})"
       
   863 proof -
       
   864   have "finite (ES - {({[]}, yrhs)})" using Inv_ES
       
   865     by (simp add:Inv_def)
       
   866   moreover have "\<exists>rhs. (X, rhs) \<in> ES - {({[]}, yrhs)}" using Inv_ES X_noteq_Y
       
   867     by (simp add:Inv_def)
       
   868   moreover have "distinct_equas (ES - {({[]}, yrhs)})" using Inv_ES X_noteq_Y
       
   869     apply (clarsimp simp:Inv_def distinct_equas_def)
       
   870     by (drule_tac x = Xa in spec, simp)    
       
   871   moreover have "\<forall>X xrhs.(X, xrhs) \<in> ES - {({[]}, yrhs)} \<longrightarrow>
       
   872                           ardenable (X, xrhs) \<and> X \<noteq> {}" using Inv_ES
       
   873     by (clarify, simp add:Inv_def)
       
   874   moreover 
       
   875   have "insert {[]} (left_eq_cls (ES - {({[]}, yrhs)})) = insert {[]} (left_eq_cls ES)"
       
   876     by (auto simp:left_eq_cls_def)
       
   877   hence "\<forall>X xrhs.(X, xrhs) \<in> ES - {({[]}, yrhs)} \<longrightarrow>
       
   878                           rhs_eq_cls xrhs \<subseteq> insert {[]} (left_eq_cls (ES - {({[]}, yrhs)}))"
       
   879     using Inv_ES by (auto simp:Inv_def)
       
   880   ultimately show ?thesis by (simp add:Inv_def)
       
   881 qed
       
   882 
       
   883 lemma non_empty_card_prop:
       
   884   "finite ES \<Longrightarrow> \<forall>e. e \<in> ES \<longrightarrow> card ES - Suc 0 < card ES"
       
   885 apply (erule finite.induct, simp)
       
   886 apply (case_tac[!] "a \<in> A")
       
   887 by (auto simp:insert_absorb)
       
   888 
       
   889 lemma ardenable_prop:
       
   890   assumes not_lambda: "Y \<noteq> {[]}"
       
   891   and ardable: "ardenable (Y, yrhs)"
       
   892   shows "\<exists> yrhs'. Y = L yrhs' \<and> distinct_rhs yrhs' \<and> rhs_eq_cls yrhs' = rhs_eq_cls yrhs - {Y}" (is "\<exists> yrhs'. ?P yrhs'")
       
   893 proof (cases "(\<exists> reg. (Y, reg) \<in> yrhs)")
       
   894   case True
       
   895   thus ?thesis 
       
   896   proof 
       
   897     fix reg
       
   898     assume self_contained: "(Y, reg) \<in> yrhs"
       
   899     show ?thesis 
       
   900     proof -
       
   901       have "?P (arden_variate Y reg yrhs)"
       
   902       proof -
       
   903         have "Y = L (arden_variate Y reg yrhs)" 
       
   904           using self_contained not_lambda ardable
       
   905           by (rule_tac arden_variate_valid, simp_all add:ardenable_def)
       
   906         moreover have "distinct_rhs (arden_variate Y reg yrhs)" 
       
   907           using ardable 
       
   908           by (auto simp:distinct_rhs_def arden_variate_def seq_rhs_r_def del_x_paired_def ardenable_def)
       
   909         moreover have "rhs_eq_cls (arden_variate Y reg yrhs) = rhs_eq_cls yrhs - {Y}"
       
   910         proof -
       
   911           have "\<And> rhs r. rhs_eq_cls (seq_rhs_r rhs r) = rhs_eq_cls rhs"
       
   912             apply (auto simp:rhs_eq_cls_def seq_rhs_r_def image_def)
       
   913             by (rule_tac x = "SEQ ra r" in exI, rule_tac x = "(x, ra)" in bexI, simp+)
       
   914           moreover have "\<And> rhs X. rhs_eq_cls (del_x_paired rhs X) = rhs_eq_cls rhs - {X}"
       
   915             by (auto simp:rhs_eq_cls_def del_x_paired_def)
       
   916           ultimately show ?thesis by (simp add:arden_variate_def)
       
   917         qed
       
   918         ultimately show ?thesis by simp
       
   919       qed
       
   920       thus ?thesis by (rule_tac x= "arden_variate Y reg yrhs" in exI, simp)
       
   921     qed
       
   922   qed
       
   923 next
       
   924   case False
       
   925   hence "(2)": "rhs_eq_cls yrhs - {Y} = rhs_eq_cls yrhs"
       
   926     by (auto simp:rhs_eq_cls_def)
       
   927   show ?thesis 
       
   928   proof -
       
   929     have "?P yrhs" using False ardable "(2)" 
       
   930       by (simp add:ardenable_def)      
       
   931     thus ?thesis by blast
       
   932   qed
       
   933 qed
       
   934 
       
   935 lemma equas_subst_f_del_no_other:
       
   936   assumes self_contained: "(Y, rhs) \<in> ES"
       
   937   shows "\<exists> rhs'. (Y, rhs') \<in> (equas_subst_f X xrhs ` ES)" (is "\<exists> rhs'. ?P rhs'")
       
   938 proof -
       
   939   have "\<exists> rhs'. equas_subst_f X xrhs (Y, rhs) = (Y, rhs')"
       
   940     by (auto simp:equas_subst_f_def)
       
   941   then obtain rhs' where "equas_subst_f X xrhs (Y, rhs) = (Y, rhs')" by blast
       
   942   hence "?P rhs'" unfolding image_def using self_contained
       
   943     by (auto intro:bexI[where x = "(Y, rhs)"])
       
   944   thus ?thesis by blast
       
   945 qed
       
   946 
       
   947 lemma del_x_paired_del_only_x: 
       
   948   "\<lbrakk>X \<noteq> Y; (X, rhs) \<in> ES\<rbrakk> \<Longrightarrow> (X, rhs) \<in> del_x_paired ES Y"
       
   949 by (auto simp:del_x_paired_def)
       
   950 
       
   951 lemma equas_subst_del_no_other:
       
   952  "\<lbrakk>(X, rhs) \<in> ES; X \<noteq> Y\<rbrakk> \<Longrightarrow> (\<exists>rhs. (X, rhs) \<in> equas_subst ES Y rhs')"
       
   953 unfolding equas_subst_def
       
   954 apply (drule_tac X = Y and xrhs = rhs' in equas_subst_f_del_no_other)
       
   955 by (erule exE, drule del_x_paired_del_only_x, auto)
       
   956 
       
   957 lemma equas_subst_holds_distinct:
       
   958   "distinct_equas ES \<Longrightarrow> distinct_equas (equas_subst ES Y rhs')"
       
   959 apply (clarsimp simp add:equas_subst_def distinct_equas_def del_x_paired_def equas_subst_f_def)
       
   960 by (auto split:if_splits)
       
   961 
       
   962 lemma del_x_paired_dels: 
       
   963   "(X, rhs) \<in> ES \<Longrightarrow> {Y. Y \<in> ES \<and> fst Y = X} \<inter> ES \<noteq> {}"
       
   964 by (auto)
       
   965 
       
   966 lemma del_x_paired_subset:
       
   967   "(X, rhs) \<in> ES \<Longrightarrow> ES - {Y. Y \<in> ES \<and> fst Y = X} \<subset> ES"
       
   968 apply (drule del_x_paired_dels)
       
   969 by auto
       
   970 
       
   971 lemma del_x_paired_card_less: 
       
   972   "\<lbrakk>finite ES; (X, rhs) \<in> ES\<rbrakk> \<Longrightarrow> card (del_x_paired ES X) < card ES"
       
   973 apply (simp add:del_x_paired_def)
       
   974 apply (drule del_x_paired_subset)
       
   975 by (auto intro:psubset_card_mono)
       
   976 
       
   977 lemma equas_subst_card_less:
       
   978   "\<lbrakk>finite ES; (Y, yrhs) \<in> ES\<rbrakk> \<Longrightarrow> card (equas_subst ES Y rhs') < card ES"
       
   979 apply (simp add:equas_subst_def)
       
   980 apply (frule_tac h = "equas_subst_f Y rhs'" in finite_imageI)
       
   981 apply (drule_tac f = "equas_subst_f Y rhs'" in Finite_Set.card_image_le)
       
   982 apply (drule_tac X = Y and xrhs = rhs' in equas_subst_f_del_no_other,erule exE)
       
   983 by (drule del_x_paired_card_less, auto)
       
   984 
       
   985 lemma equas_subst_holds_distinct_rhs:
       
   986   assumes   dist': "distinct_rhs yrhs'"
       
   987   and     history: "\<forall>X xrhs. (X, xrhs) \<in> ES \<longrightarrow> ardenable (X, xrhs)"
       
   988   and     X_in :  "(X, xrhs) \<in> equas_subst ES Y yrhs'"
       
   989   shows "distinct_rhs xrhs"
       
   990 using X_in history
       
   991 apply (clarsimp simp:equas_subst_def del_x_paired_def)
       
   992 apply (drule_tac x = a in spec, drule_tac x = b in spec)
       
   993 apply (simp add:ardenable_def equas_subst_f_def)
       
   994 by (auto intro:rhs_subst_holds_distinct_rhs simp:dist' split:if_splits)
       
   995 
       
   996 lemma r_no_EMPTY_imp_seq_rhs_r_no_EMPTY:
       
   997   "[] \<notin> L r \<Longrightarrow> no_EMPTY_rhs (seq_rhs_r rhs r)"
       
   998 by (auto simp:no_EMPTY_rhs_def seq_rhs_r_def lang_seq_def)
       
   999 
       
  1000 lemma del_x_paired_holds_no_EMPTY:
       
  1001   "no_EMPTY_rhs yrhs \<Longrightarrow> no_EMPTY_rhs (del_x_paired yrhs Y)"
       
  1002 by (auto simp:no_EMPTY_rhs_def del_x_paired_def)
       
  1003 
       
  1004 lemma rhs_subst_holds_no_EMPTY:
       
  1005   "\<lbrakk>no_EMPTY_rhs yrhs; (Y, r) \<in> yrhs; Y \<noteq> {[]}\<rbrakk> \<Longrightarrow> no_EMPTY_rhs (rhs_subst yrhs Y rhs' r)"
       
  1006 apply (auto simp:rhs_subst_def intro!:no_EMPTY_rhss_imp_merge_no_EMPTY r_no_EMPTY_imp_seq_rhs_r_no_EMPTY del_x_paired_holds_no_EMPTY)
       
  1007 by (auto simp:no_EMPTY_rhs_def)
       
  1008 
       
  1009 lemma equas_subst_holds_no_EMPTY:
       
  1010   assumes substor: "Y \<noteq> {[]}"
       
  1011   and history: "\<forall>X xrhs. (X, xrhs) \<in> ES \<longrightarrow> ardenable (X, xrhs)"
       
  1012   and X_in:"(X, xrhs) \<in> equas_subst ES Y yrhs'"
       
  1013   shows "no_EMPTY_rhs xrhs"
       
  1014 proof-
       
  1015   from X_in have "\<exists> (Z, zrhs) \<in> ES. (X, xrhs) = equas_subst_f Y yrhs' (Z, zrhs)"
       
  1016     by (auto simp add:equas_subst_def del_x_paired_def)
       
  1017   then obtain Z zrhs where Z_in: "(Z, zrhs) \<in> ES"
       
  1018                        and X_Z: "(X, xrhs) = equas_subst_f Y yrhs' (Z, zrhs)" by blast
       
  1019   hence dist_zrhs: "distinct_rhs zrhs" using history
       
  1020     by (auto simp:ardenable_def)
       
  1021   show ?thesis
       
  1022   proof (cases "\<exists> r. (Y, r) \<in> zrhs")
       
  1023     case True
       
  1024     then obtain r where Y_in_zrhs: "(Y, r) \<in> zrhs" ..
       
  1025     hence some: "(SOME r. (Y, r) \<in> zrhs) = r" using Z_in dist_zrhs
       
  1026       by (auto simp:distinct_rhs_def)
       
  1027     hence "no_EMPTY_rhs (rhs_subst zrhs Y yrhs' r)"
       
  1028       using substor Y_in_zrhs history Z_in
       
  1029       by (rule_tac rhs_subst_holds_no_EMPTY, auto simp:ardenable_def)
       
  1030     thus ?thesis using X_Z True some
       
  1031       by (simp add:equas_subst_def equas_subst_f_def)
       
  1032   next
       
  1033     case False
       
  1034     hence "(X, xrhs) = (Z, zrhs)" using Z_in X_Z
       
  1035       by (simp add:equas_subst_f_def)
       
  1036     thus ?thesis using history Z_in
       
  1037       by (auto simp:ardenable_def)
       
  1038   qed
       
  1039 qed
       
  1040 
       
  1041 lemma equas_subst_f_holds_left_eq_right:
       
  1042   assumes substor: "Y = L rhs'"
       
  1043   and     history: "\<forall>X xrhs. (X, xrhs) \<in> ES \<longrightarrow> distinct_rhs xrhs \<and> X = L xrhs"
       
  1044   and       subst: "(X, xrhs) = equas_subst_f Y rhs' (Z, zrhs)"
       
  1045   and     self_contained: "(Z, zrhs) \<in> ES"
       
  1046   shows "X = L xrhs"
       
  1047 proof (cases "\<exists> r. (Y, r) \<in> zrhs")
       
  1048   case True
       
  1049   from True obtain r where "(1)":"(Y, r) \<in> zrhs" ..
       
  1050   show ?thesis
       
  1051   proof -
       
  1052     from history self_contained
       
  1053     have dist: "distinct_rhs zrhs" by auto
       
  1054     hence "(SOME r. (Y, r) \<in> zrhs) = r" using self_contained "(1)"
       
  1055       using distinct_rhs_def by (auto intro:some_equality)
       
  1056     moreover have "L zrhs = L (rhs_subst zrhs Y rhs' r)" using substor dist "(1)" self_contained
       
  1057       by (rule_tac rhs_subst_prop1, auto simp:distinct_equas_rhs_def)
       
  1058     ultimately show ?thesis using subst history self_contained
       
  1059       by (auto simp:equas_subst_f_def split:if_splits)
       
  1060   qed
       
  1061 next
       
  1062   case False
       
  1063   thus ?thesis using history subst self_contained
       
  1064     by (auto simp:equas_subst_f_def)
       
  1065 qed
       
  1066 
       
  1067 lemma equas_subst_holds_left_eq_right:
       
  1068   assumes history: "\<forall>X xrhs. (X, xrhs) \<in> ES \<longrightarrow> ardenable (X, xrhs)"
       
  1069   and     substor: "Y = L rhs'"
       
  1070   and     X_in :  "(X, xrhs) \<in> equas_subst ES Y yrhs'"
       
  1071   shows "\<forall>X xrhs. (X, xrhs) \<in> equas_subst ES Y rhs' \<longrightarrow> X = L xrhs"
       
  1072 apply (clarsimp simp add:equas_subst_def del_x_paired_def)
       
  1073 using substor
       
  1074 apply (drule_tac equas_subst_f_holds_left_eq_right)
       
  1075 using history
       
  1076 by (auto simp:ardenable_def)
       
  1077 
       
  1078 lemma equas_subst_holds_ardenable:
       
  1079   assumes substor: "Y = L yrhs'"
       
  1080   and history: "\<forall>X xrhs. (X, xrhs) \<in> ES \<longrightarrow> ardenable (X, xrhs)"
       
  1081   and X_in:"(X, xrhs) \<in> equas_subst ES Y yrhs'"
       
  1082   and dist': "distinct_rhs yrhs'"
       
  1083   and not_lambda: "Y \<noteq> {[]}"
       
  1084   shows "ardenable (X, xrhs)"
       
  1085 proof -
       
  1086   have "distinct_rhs xrhs" using history X_in dist' 
       
  1087     by (auto dest:equas_subst_holds_distinct_rhs)
       
  1088   moreover have "no_EMPTY_rhs xrhs" using history X_in not_lambda
       
  1089     by (auto intro:equas_subst_holds_no_EMPTY)
       
  1090   moreover have "X = L xrhs" using history substor X_in
       
  1091   by (auto dest: equas_subst_holds_left_eq_right simp del:L_rhs.simps)
       
  1092   ultimately show ?thesis using ardenable_def by simp
       
  1093 qed
       
  1094 
       
  1095 lemma equas_subst_holds_cls_defined:
       
  1096   assumes         X_in: "(X, xrhs) \<in> equas_subst ES Y yrhs'"
       
  1097   and           Inv_ES: "Inv X' ES"
       
  1098   and            subst: "(Y, yrhs) \<in> ES"
       
  1099   and  cls_holds_but_Y: "rhs_eq_cls yrhs' = rhs_eq_cls yrhs - {Y}"
       
  1100   shows "rhs_eq_cls xrhs \<subseteq> insert {[]} (left_eq_cls (equas_subst ES Y yrhs'))"
       
  1101 proof-
       
  1102   have tac: "\<lbrakk> A \<subseteq> B; C \<subseteq> D; E \<subseteq> A \<union> B\<rbrakk> \<Longrightarrow> E \<subseteq> B \<union> D" by auto
       
  1103   from X_in have "\<exists> (Z, zrhs) \<in> ES. (X, xrhs) = equas_subst_f Y yrhs' (Z, zrhs)"
       
  1104     by (auto simp add:equas_subst_def del_x_paired_def)
       
  1105   then obtain Z zrhs where Z_in: "(Z, zrhs) \<in> ES"
       
  1106                        and X_Z: "(X, xrhs) = equas_subst_f Y yrhs' (Z, zrhs)" by blast
       
  1107   hence "rhs_eq_cls zrhs \<subseteq> insert {[]} (left_eq_cls ES)" using Inv_ES
       
  1108     by (auto simp:Inv_def)
       
  1109   moreover have "rhs_eq_cls yrhs' \<subseteq> insert {[]} (left_eq_cls ES) - {Y}" 
       
  1110     using Inv_ES subst cls_holds_but_Y
       
  1111     by (auto simp:Inv_def)
       
  1112   moreover have "rhs_eq_cls xrhs \<subseteq> rhs_eq_cls zrhs \<union> rhs_eq_cls yrhs' - {Y}"
       
  1113     using X_Z cls_holds_but_Y
       
  1114     apply (clarsimp simp add:equas_subst_f_def rhs_subst_def split:if_splits)
       
  1115     by (auto simp:rhs_eq_cls_def merge_rhs_def del_x_paired_def seq_rhs_r_def)
       
  1116   moreover have "left_eq_cls (equas_subst ES Y yrhs') = left_eq_cls ES - {Y}" using subst
       
  1117     by (auto simp: left_eq_cls_def equas_subst_def del_x_paired_def equas_subst_f_def
       
  1118              dest: equas_subst_f_del_no_other
       
  1119              split: if_splits)
       
  1120   ultimately show ?thesis by blast
       
  1121 qed
       
  1122 
       
  1123 lemma iteration_step: 
       
  1124   assumes Inv_ES: "Inv X ES"
       
  1125   and    not_T: "\<not> TCon ES"
       
  1126   shows "(\<exists> ES'. Inv X ES' \<and> (card ES', card ES) \<in> less_than)" 
       
  1127 proof -
       
  1128   from Inv_ES not_T have another: "\<exists>Y yrhs. (Y, yrhs) \<in> ES \<and> X \<noteq> Y" unfolding Inv_def
       
  1129     by (clarify, rule_tac exist_another_equa[where X = X], auto)
       
  1130   then obtain Y yrhs where subst: "(Y, yrhs) \<in> ES" and not_X: " X \<noteq> Y" by blast
       
  1131   show ?thesis (is "\<exists> ES'. ?P ES'")
       
  1132   proof (cases "Y = {[]}") 
       
  1133     case True
       
  1134       --"in this situation, we pick a \"\<lambda>\" equation, thus directly remove it from the equation-system"
       
  1135     have "?P (ES - {(Y, yrhs)})" 
       
  1136     proof 
       
  1137       show "Inv X (ES - {(Y, yrhs)})" using True not_X
       
  1138         by (simp add:Inv_ES Inv_mono_with_lambda)
       
  1139     next 
       
  1140       show "(card (ES - {(Y, yrhs)}), card ES) \<in> less_than" using Inv_ES subst
       
  1141         by (auto elim:non_empty_card_prop[rule_format] simp:Inv_def)
       
  1142     qed
       
  1143     thus ?thesis by blast
       
  1144   next
       
  1145     case False
       
  1146       --"in this situation, we pick a equation and using ardenable to get a 
       
  1147         rhs without itself in it, then use equas_subst to form a new equation-system"
       
  1148     hence "\<exists> yrhs'. Y = L yrhs' \<and> distinct_rhs yrhs' \<and> rhs_eq_cls yrhs' = rhs_eq_cls yrhs - {Y}" 
       
  1149       using subst Inv_ES
       
  1150       by (auto intro:ardenable_prop simp add:Inv_def simp del:L_rhs.simps)
       
  1151     then obtain yrhs' where Y'_l_eq_r: "Y = L yrhs'"
       
  1152       and dist_Y': "distinct_rhs yrhs'"
       
  1153       and cls_holds_but_Y: "rhs_eq_cls yrhs' = rhs_eq_cls yrhs - {Y}" by blast
       
  1154     hence "?P (equas_subst ES Y yrhs')"
       
  1155     proof -
       
  1156       have finite_del: "\<And> S x. finite S \<Longrightarrow> finite (del_x_paired S x)" 
       
  1157         apply (rule_tac A = "del_x_paired S x" in finite_subset)
       
  1158         by (auto simp:del_x_paired_def)
       
  1159       have "finite (equas_subst ES Y yrhs')" using Inv_ES 
       
  1160         by (auto intro!:finite_del simp:equas_subst_def Inv_def)
       
  1161       moreover have "\<exists>rhs. (X, rhs) \<in> equas_subst ES Y yrhs'" using Inv_ES not_X
       
  1162         by (auto intro:equas_subst_del_no_other simp:Inv_def)
       
  1163       moreover have "distinct_equas (equas_subst ES Y yrhs')" using Inv_ES
       
  1164         by (auto intro:equas_subst_holds_distinct simp:Inv_def)
       
  1165       moreover have "\<forall>X xrhs. (X, xrhs) \<in> equas_subst ES Y yrhs' \<longrightarrow> ardenable (X, xrhs)"
       
  1166         using Inv_ES dist_Y' False Y'_l_eq_r
       
  1167         apply (clarsimp simp:Inv_def)
       
  1168         by (rule equas_subst_holds_ardenable, simp_all)
       
  1169       moreover have "\<forall>X xrhs. (X, xrhs) \<in> equas_subst ES Y yrhs' \<longrightarrow> X \<noteq> {}" using Inv_ES
       
  1170         by (clarsimp simp:equas_subst_def Inv_def del_x_paired_def equas_subst_f_def split:if_splits, auto)
       
  1171       moreover have "\<forall>X xrhs. (X, xrhs) \<in> equas_subst ES Y yrhs' \<longrightarrow>
       
  1172                                rhs_eq_cls xrhs \<subseteq> insert {[]} (left_eq_cls (equas_subst ES Y yrhs'))"
       
  1173         using Inv_ES subst cls_holds_but_Y
       
  1174         apply (rule_tac impI | rule_tac allI)+
       
  1175         by (erule equas_subst_holds_cls_defined, auto)
       
  1176       moreover have "(card (equas_subst ES Y yrhs'), card ES) \<in> less_than"using Inv_ES subst
       
  1177         by (simp add:equas_subst_card_less Inv_def)
       
  1178       ultimately show "?P (equas_subst ES Y yrhs')" by (auto simp:Inv_def)      
       
  1179     qed
       
  1180     thus ?thesis by blast
       
  1181   qed
       
  1182 qed
       
  1183 
       
  1184 text {* ***** END: proving every equation-system's iteration step satisfies Inv ************** *}
       
  1185 
       
  1186 lemma iteration_conc: 
       
  1187   assumes history: "Inv X ES"
       
  1188   shows "\<exists> ES'. Inv X ES' \<and> TCon ES'" (is "\<exists> ES'. ?P ES'")
       
  1189 proof (cases "TCon ES")
       
  1190   case True
       
  1191   hence "?P ES" using history by simp
       
  1192   thus ?thesis by blast
       
  1193 next
       
  1194   case False  
       
  1195   thus ?thesis using history iteration_step
       
  1196     by (rule_tac f = card in wf_iter, simp_all)
       
  1197 qed
       
  1198 
       
  1199 lemma eqset_imp_iff': "A = B \<Longrightarrow> \<forall> x. x \<in> A \<longleftrightarrow> x \<in> B"
       
  1200 apply (auto simp:mem_def)
       
  1201 done
       
  1202 
       
  1203 lemma set_cases2:
       
  1204   "\<lbrakk>(A = {} \<Longrightarrow> R A); \<And> x. (A = {x}) \<Longrightarrow> R A; \<And> x y. \<lbrakk>x \<noteq> y; x \<in> A; y \<in> A\<rbrakk> \<Longrightarrow> R A\<rbrakk> \<Longrightarrow> R A"
       
  1205 apply (case_tac "A = {}", simp)
       
  1206 by (case_tac "\<exists> x. A = {x}", clarsimp, blast)
       
  1207 
       
  1208 lemma rhs_aux:"\<lbrakk>distinct_rhs rhs; {Y. \<exists>r. (Y, r) \<in> rhs} = {X}\<rbrakk> \<Longrightarrow> (\<exists>r. rhs = {(X, r)})"
       
  1209 apply (rule_tac A = rhs in set_cases2, simp)
       
  1210 apply (drule_tac x = X in eqset_imp_iff, clarsimp)
       
  1211 apply (drule eqset_imp_iff',clarsimp)
       
  1212 apply (frule_tac x = a in spec, drule_tac x = aa in spec)
       
  1213 by (auto simp:distinct_rhs_def)
       
  1214 
       
  1215 lemma every_eqcl_has_reg: 
       
  1216   assumes finite_CS: "finite (UNIV Quo Lang)"
       
  1217   and X_in_CS: "X \<in> (UNIV Quo Lang)"
       
  1218   shows "\<exists> (reg::rexp). L reg = X" (is "\<exists> r. ?E r")
       
  1219 proof-
       
  1220   have "\<exists>ES'. Inv X ES' \<and> TCon ES'" using finite_CS X_in_CS
       
  1221     by (auto intro:init_ES_satisfy_Inv iteration_conc)
       
  1222   then obtain ES' where Inv_ES': "Inv X ES'" 
       
  1223                    and  TCon_ES': "TCon ES'" by blast
       
  1224   from Inv_ES' TCon_ES' 
       
  1225   have "\<exists> rhs. ES' = {(X, rhs)}"
       
  1226     apply (clarsimp simp:Inv_def TCon_def)
       
  1227     apply (rule_tac x = rhs in exI)
       
  1228     by (auto dest!:card_Suc_Diff1 simp:card_eq_0_iff)  
       
  1229   then obtain rhs where ES'_single_equa: "ES' = {(X, rhs)}" ..
       
  1230   hence X_ardenable: "ardenable (X, rhs)" using Inv_ES'
       
  1231     by (simp add:Inv_def)
       
  1232   
       
  1233   from X_ardenable have X_l_eq_r: "X = L rhs"
       
  1234     by (simp add:ardenable_def)
       
  1235   hence rhs_not_empty: "rhs \<noteq> {}" using Inv_ES' ES'_single_equa
       
  1236     by (auto simp:Inv_def ardenable_def)
       
  1237   have rhs_eq_cls: "rhs_eq_cls rhs \<subseteq> {X, {[]}}"
       
  1238     using Inv_ES' ES'_single_equa
       
  1239     by (auto simp:Inv_def ardenable_def left_eq_cls_def)
       
  1240   have X_not_empty: "X \<noteq> {}" using Inv_ES' ES'_single_equa
       
  1241     by (auto simp:Inv_def)    
       
  1242   show ?thesis
       
  1243   proof (cases "X = {[]}")
       
  1244     case True
       
  1245     hence "?E EMPTY" by (simp)
       
  1246     thus ?thesis by blast
       
  1247   next
       
  1248     case False with  X_ardenable
       
  1249     have "\<exists> rhs'. X = L rhs' \<and> rhs_eq_cls rhs' = rhs_eq_cls rhs - {X} \<and> distinct_rhs rhs'"
       
  1250       by (drule_tac ardenable_prop, auto)
       
  1251     then obtain rhs' where X_eq_rhs': "X = L rhs'"
       
  1252       and rhs'_eq_cls: "rhs_eq_cls rhs' = rhs_eq_cls rhs - {X}" 
       
  1253       and rhs'_dist : "distinct_rhs rhs'" by blast
       
  1254     have "rhs_eq_cls rhs' \<subseteq> {{[]}}" using rhs_eq_cls False rhs'_eq_cls rhs_not_empty 
       
  1255       by blast
       
  1256     hence "rhs_eq_cls rhs' = {{[]}}" using X_not_empty X_eq_rhs'
       
  1257       by (auto simp:rhs_eq_cls_def)
       
  1258     hence "\<exists> r. rhs' = {({[]}, r)}" using rhs'_dist
       
  1259       by (auto intro:rhs_aux simp:rhs_eq_cls_def)
       
  1260     then obtain r where "rhs' = {({[]}, r)}" ..
       
  1261     hence "?E r" using X_eq_rhs' by (auto simp add:lang_seq_def)
       
  1262     thus ?thesis by blast     
       
  1263   qed
       
  1264 qed
       
  1265 
       
  1266 text {* definition of a regular language *}
       
  1267 
       
  1268 abbreviation
       
  1269   reg :: "string set => bool"
       
  1270 where
       
  1271   "reg L1 \<equiv> (\<exists>r::rexp. L r = L1)"
       
  1272 
       
  1273 theorem myhill_nerode: 
       
  1274   assumes finite_CS: "finite (UNIV Quo Lang)"
       
  1275   shows   "\<exists> (reg::rexp). Lang = L reg" (is "\<exists> r. ?P r")
       
  1276 proof -
       
  1277   have has_r_each: "\<forall>C\<in>{X \<in> UNIV Quo Lang. \<forall>x\<in>X. x \<in> Lang}. \<exists>(r::rexp). C = L r" using finite_CS
       
  1278     by (auto dest:every_eqcl_has_reg)  
       
  1279   have "\<exists> (rS::rexp set). finite rS \<and> 
       
  1280                           (\<forall> C \<in> {X \<in> UNIV Quo Lang. \<forall>x\<in>X. x \<in> Lang}. \<exists> r \<in> rS. C = L r) \<and> 
       
  1281                           (\<forall> r \<in> rS. \<exists> C \<in> {X \<in> UNIV Quo Lang. \<forall>x\<in>X. x \<in> Lang}. C = L r)" 
       
  1282        (is "\<exists> rS. ?Q rS")
       
  1283   proof-
       
  1284     have "\<And> C. C \<in> {X \<in> UNIV Quo Lang. \<forall>x\<in>X. x \<in> Lang} \<Longrightarrow> C = L (SOME (ra::rexp). C = L ra)"
       
  1285       using has_r_each
       
  1286       apply (erule_tac x = C in ballE, erule_tac exE)
       
  1287       by (rule_tac a = r in someI2, simp+)
       
  1288     hence "?Q ((\<lambda> C. SOME r. C = L r) ` {X \<in> UNIV Quo Lang. \<forall>x\<in>X. x \<in> Lang})" using has_r_each
       
  1289       using finite_CS by auto
       
  1290     thus ?thesis by blast    
       
  1291   qed
       
  1292   then obtain rS where finite_rS : "finite rS"
       
  1293     and has_r_each': "\<forall> C \<in> {X \<in> UNIV Quo Lang. \<forall>x\<in>X. x \<in> Lang}. \<exists> r \<in> (rS::rexp set). C = L r"
       
  1294     and has_cl_each: "\<forall> r \<in> (rS::rexp set). \<exists> C \<in> {X \<in> UNIV Quo Lang. \<forall>x\<in>X. x \<in> Lang}. C = L r" by blast
       
  1295   have "?P (folds ALT NULL rS)"
       
  1296   proof
       
  1297     show "Lang \<subseteq> L (folds ALT NULL rS)" using finite_rS lang_eqs_union_of_eqcls[of Lang] has_r_each'
       
  1298       apply (clarsimp simp:fold_alt_null_eqs) by blast
       
  1299   next 
       
  1300     show "L (folds ALT NULL rS) \<subseteq> Lang" using finite_rS lang_eqs_union_of_eqcls[of Lang] has_cl_each
       
  1301       by (clarsimp simp:fold_alt_null_eqs)
       
  1302   qed
       
  1303   thus ?thesis by blast
       
  1304 qed 
       
  1305 
       
  1306 
       
  1307 text {* tests by Christian *}
       
  1308 
       
  1309 (* Alternative definition for Quo *)
       
  1310 definition 
       
  1311   QUOT :: "string set \<Rightarrow> (string set) set"  
       
  1312 where
       
  1313   "QUOT Lang \<equiv> (\<Union>x. {\<lbrakk>x\<rbrakk>Lang})"
       
  1314 
       
  1315 lemma test: 
       
  1316   "UNIV Quo Lang = QUOT Lang"
       
  1317 by (auto simp add: quot_def QUOT_def)
       
  1318 
       
  1319 lemma test1:
       
  1320   assumes finite_CS: "finite (QUOT Lang)"
       
  1321   shows "reg Lang"
       
  1322 using finite_CS
       
  1323 unfolding test[symmetric]
       
  1324 by (auto dest: myhill_nerode)
       
  1325 
       
  1326 lemma cons_one: "x @ y \<in> {z} \<Longrightarrow> x @ y = z"
       
  1327 by simp
       
  1328 
       
  1329 lemma quot_lambda: "QUOT {[]} = {{[]}, UNIV - {[]}}"
       
  1330 proof 
       
  1331   show "QUOT {[]} \<subseteq> {{[]}, UNIV - {[]}}"
       
  1332   proof 
       
  1333     fix x 
       
  1334     assume in_quot: "x \<in> QUOT {[]}"
       
  1335     show "x \<in> {{[]}, UNIV - {[]}}"
       
  1336     proof -
       
  1337       from in_quot 
       
  1338       have "x = {[]} \<or> x = UNIV - {[]}"
       
  1339         unfolding QUOT_def equiv_class_def
       
  1340       proof 
       
  1341         fix xa
       
  1342         assume in_univ: "xa \<in> UNIV"
       
  1343            and in_eqiv: "x \<in> {{y. xa \<equiv>{[]}\<equiv> y}}"
       
  1344         show "x = {[]} \<or> x = UNIV - {[]}"
       
  1345         proof(cases "xa = []")
       
  1346           case True
       
  1347           hence "{y. xa \<equiv>{[]}\<equiv> y} = {[]}" using in_eqiv
       
  1348             by (auto simp add:equiv_str_def)
       
  1349           thus ?thesis using in_eqiv by (rule_tac disjI1, simp)
       
  1350         next
       
  1351           case False
       
  1352           hence "{y. xa \<equiv>{[]}\<equiv> y} = UNIV - {[]}" using in_eqiv
       
  1353             by (auto simp:equiv_str_def)
       
  1354           thus ?thesis using in_eqiv by (rule_tac disjI2, simp)
       
  1355         qed
       
  1356       qed
       
  1357       thus ?thesis by simp
       
  1358     qed
       
  1359   qed
       
  1360 next
       
  1361   show "{{[]}, UNIV - {[]}} \<subseteq> QUOT {[]}"
       
  1362   proof
       
  1363     fix x
       
  1364     assume in_res: "x \<in> {{[]}, (UNIV::string set) - {[]}}"
       
  1365     show "x \<in> (QUOT {[]})"
       
  1366     proof -
       
  1367       have "x = {[]} \<Longrightarrow> x \<in> QUOT {[]}"
       
  1368         apply (simp add:QUOT_def equiv_class_def equiv_str_def)
       
  1369         by (rule_tac x = "[]" in exI, auto)
       
  1370       moreover have "x = UNIV - {[]} \<Longrightarrow> x \<in> QUOT {[]}"
       
  1371         apply (simp add:QUOT_def equiv_class_def equiv_str_def)
       
  1372         by (rule_tac x = "''a''" in exI, auto)
       
  1373       ultimately show ?thesis using in_res by blast
       
  1374     qed
       
  1375   qed
       
  1376 qed
       
  1377 
       
  1378 lemma quot_single_aux: "\<lbrakk>x \<noteq> []; x \<noteq> [c]\<rbrakk> \<Longrightarrow> x @ z \<noteq> [c]"
       
  1379 by (induct x, auto)
       
  1380 
       
  1381 lemma quot_single: "\<And> (c::char). QUOT {[c]} = {{[]}, {[c]}, UNIV - {[], [c]}}"
       
  1382 proof - 
       
  1383   fix c::"char" 
       
  1384   have exist_another: "\<exists> a. a \<noteq> c" 
       
  1385     apply (case_tac "c = CHR ''a''")
       
  1386     apply (rule_tac x = "CHR ''b''" in exI, simp)
       
  1387     by (rule_tac x = "CHR ''a''" in exI, simp)  
       
  1388   show "QUOT {[c]} = {{[]}, {[c]}, UNIV - {[], [c]}}"
       
  1389   proof
       
  1390     show "QUOT {[c]} \<subseteq> {{[]},{[c]}, UNIV - {[], [c]}}"
       
  1391     proof 
       
  1392       fix x 
       
  1393       assume in_quot: "x \<in> QUOT {[c]}"
       
  1394       show "x \<in> {{[]}, {[c]}, UNIV - {[],[c]}}"
       
  1395       proof -
       
  1396         from in_quot 
       
  1397         have "x = {[]} \<or> x = {[c]} \<or> x = UNIV - {[],[c]}"
       
  1398           unfolding QUOT_def equiv_class_def
       
  1399         proof 
       
  1400           fix xa
       
  1401           assume in_eqiv: "x \<in> {{y. xa \<equiv>{[c]}\<equiv> y}}"
       
  1402           show "x = {[]} \<or> x = {[c]} \<or> x = UNIV - {[], [c]}"
       
  1403           proof-
       
  1404             have "xa = [] \<Longrightarrow> x = {[]}" using in_eqiv 
       
  1405               by (auto simp add:equiv_str_def)
       
  1406             moreover have "xa = [c] \<Longrightarrow> x = {[c]}"
       
  1407             proof -
       
  1408               have "xa = [c] \<Longrightarrow> {y. xa \<equiv>{[c]}\<equiv> y} = {[c]}" using in_eqiv
       
  1409                 apply (simp add:equiv_str_def)
       
  1410                 apply (rule set_ext, rule iffI, simp)
       
  1411                 apply (drule_tac x = "[]" in spec, auto)
       
  1412                 done   
       
  1413               thus "xa = [c] \<Longrightarrow> x = {[c]}" using in_eqiv by simp 
       
  1414             qed
       
  1415             moreover have "\<lbrakk>xa \<noteq> []; xa \<noteq> [c]\<rbrakk> \<Longrightarrow> x = UNIV - {[],[c]}"
       
  1416             proof -
       
  1417               have "\<lbrakk>xa \<noteq> []; xa \<noteq> [c]\<rbrakk> \<Longrightarrow> {y. xa \<equiv>{[c]}\<equiv> y} = UNIV - {[],[c]}" 
       
  1418                 apply (clarsimp simp add:equiv_str_def)
       
  1419                 apply (rule set_ext, rule iffI, simp)
       
  1420                 apply (rule conjI)
       
  1421                 apply (drule_tac x = "[c]" in spec, simp)
       
  1422                 apply (drule_tac x = "[]" in spec, simp)
       
  1423                 by (auto dest:quot_single_aux)
       
  1424               thus "\<lbrakk>xa \<noteq> []; xa \<noteq> [c]\<rbrakk> \<Longrightarrow> x = UNIV - {[],[c]}" using in_eqiv by simp
       
  1425             qed
       
  1426             ultimately show ?thesis by blast
       
  1427           qed
       
  1428         qed
       
  1429         thus ?thesis by simp
       
  1430       qed
       
  1431     qed
       
  1432   next
       
  1433     show "{{[]}, {[c]}, UNIV - {[],[c]}} \<subseteq> QUOT {[c]}"
       
  1434     proof
       
  1435       fix x
       
  1436       assume in_res: "x \<in> {{[]},{[c]}, (UNIV::string set) - {[],[c]}}"
       
  1437       show "x \<in> (QUOT {[c]})"
       
  1438       proof -
       
  1439         have "x = {[]} \<Longrightarrow> x \<in> QUOT {[c]}"
       
  1440           apply (simp add:QUOT_def equiv_class_def equiv_str_def)
       
  1441           by (rule_tac x = "[]" in exI, auto)
       
  1442         moreover have "x = {[c]} \<Longrightarrow> x \<in> QUOT {[c]}"
       
  1443           apply (simp add:QUOT_def equiv_class_def equiv_str_def)
       
  1444           apply (rule_tac x = "[c]" in exI, simp)
       
  1445           apply (rule set_ext, rule iffI, simp+)
       
  1446           by (drule_tac x = "[]" in spec, simp)
       
  1447         moreover have "x = UNIV - {[],[c]} \<Longrightarrow> x \<in> QUOT {[c]}"
       
  1448           using exist_another
       
  1449           apply (clarsimp simp add:QUOT_def equiv_class_def equiv_str_def)        
       
  1450           apply (rule_tac x = "[a]" in exI, simp)
       
  1451           apply (rule set_ext, rule iffI, simp)
       
  1452           apply (clarsimp simp:quot_single_aux, simp)
       
  1453           apply (rule conjI)
       
  1454           apply (drule_tac x = "[c]" in spec, simp)
       
  1455           by (drule_tac x = "[]" in spec, simp)     
       
  1456         ultimately show ?thesis using in_res by blast
       
  1457       qed
       
  1458     qed
       
  1459   qed
       
  1460 qed
       
  1461 
       
  1462 lemma eq_class_imp_eq_str:
       
  1463   "\<lbrakk>x\<rbrakk>lang = \<lbrakk>y\<rbrakk>lang \<Longrightarrow> x \<equiv>lang\<equiv> y"
       
  1464 by (auto simp:equiv_class_def equiv_str_def)
       
  1465 
       
  1466 lemma finite_tag_image: 
       
  1467   "finite (range tag) \<Longrightarrow> finite (((op `) tag) ` S)"
       
  1468 apply (rule_tac B = "Pow (tag ` UNIV)" in finite_subset)
       
  1469 by (auto simp add:image_def Pow_def)
       
  1470 
       
  1471 lemma str_inj_imps:
       
  1472   assumes str_inj: "\<And> m n. tag m = tag (n::string) \<Longrightarrow> m \<equiv>lang\<equiv> n"
       
  1473   shows "inj_on ((op `) tag) (QUOT lang)"
       
  1474 proof (clarsimp simp add:inj_on_def QUOT_def)
       
  1475   fix x y
       
  1476   assume eq_tag: "tag ` \<lbrakk>x\<rbrakk>lang = tag ` \<lbrakk>y\<rbrakk>lang"
       
  1477   show "\<lbrakk>x\<rbrakk>lang = \<lbrakk>y\<rbrakk>lang"
       
  1478   proof -
       
  1479     have aux1:"\<And>a b. a \<in> (\<lbrakk>b\<rbrakk>lang) \<Longrightarrow> (a \<equiv>lang\<equiv> b)"
       
  1480       by (simp add:equiv_class_def equiv_str_def)
       
  1481     have aux2: "\<And> A B f. \<lbrakk>f ` A = f ` B; A \<noteq> {}\<rbrakk> \<Longrightarrow> \<exists> a b. a \<in> A \<and> b \<in> B \<and> f a = f b"
       
  1482       by auto
       
  1483     have aux3: "\<And> a l. \<lbrakk>a\<rbrakk>l \<noteq> {}" 
       
  1484       by (auto simp:equiv_class_def equiv_str_def)
       
  1485     show ?thesis using eq_tag
       
  1486       apply (drule_tac aux2, simp add:aux3, clarsimp)
       
  1487       apply (drule_tac str_inj, (drule_tac aux1)+)
       
  1488       by (simp add:equiv_str_def equiv_class_def)
       
  1489   qed
       
  1490 qed
       
  1491 
       
  1492 definition tag_str_ALT :: "string set \<Rightarrow> string set \<Rightarrow> string \<Rightarrow> (string set \<times> string set)"
       
  1493 where
       
  1494   "tag_str_ALT L\<^isub>1 L\<^isub>2 x \<equiv> (\<lbrakk>x\<rbrakk>L\<^isub>1, \<lbrakk>x\<rbrakk>L\<^isub>2)"
       
  1495 
       
  1496 lemma tag_str_alt_range_finite:
       
  1497   assumes finite1: "finite (QUOT L\<^isub>1)"
       
  1498   and finite2: "finite (QUOT L\<^isub>2)"
       
  1499   shows "finite (range (tag_str_ALT L\<^isub>1 L\<^isub>2))"
       
  1500 proof -
       
  1501   have "{y. \<exists>x. y = (\<lbrakk>x\<rbrakk>L\<^isub>1, \<lbrakk>x\<rbrakk>L\<^isub>2)} \<subseteq> (QUOT L\<^isub>1) \<times> (QUOT L\<^isub>2)"
       
  1502     by (auto simp:QUOT_def)
       
  1503   thus ?thesis using finite1 finite2
       
  1504     by (auto simp: image_def tag_str_ALT_def UNION_def 
       
  1505             intro: finite_subset[where B = "(QUOT L\<^isub>1) \<times> (QUOT L\<^isub>2)"])
       
  1506 qed
       
  1507 
       
  1508 lemma tag_str_alt_inj:
       
  1509   "tag_str_ALT L\<^isub>1 L\<^isub>2 x = tag_str_ALT L\<^isub>1 L\<^isub>2 y \<Longrightarrow> x \<equiv>(L\<^isub>1 \<union> L\<^isub>2)\<equiv> y"
       
  1510 apply (simp add:tag_str_ALT_def equiv_class_def equiv_str_def)
       
  1511 by blast
       
  1512   
       
  1513 lemma quot_alt:
       
  1514   assumes finite1: "finite (QUOT L\<^isub>1)"
       
  1515   and finite2: "finite (QUOT L\<^isub>2)"
       
  1516   shows "finite (QUOT (L\<^isub>1 \<union> L\<^isub>2))"
       
  1517 proof (rule_tac f = "(op `) (tag_str_ALT L\<^isub>1 L\<^isub>2)" in finite_imageD)
       
  1518   show "finite (op ` (tag_str_ALT L\<^isub>1 L\<^isub>2) ` QUOT (L\<^isub>1 \<union> L\<^isub>2))"
       
  1519     using finite_tag_image tag_str_alt_range_finite finite1 finite2
       
  1520     by auto
       
  1521 next
       
  1522   show "inj_on (op ` (tag_str_ALT L\<^isub>1 L\<^isub>2)) (QUOT (L\<^isub>1 \<union> L\<^isub>2))"
       
  1523     apply (rule_tac str_inj_imps)
       
  1524     by (erule_tac tag_str_alt_inj)
       
  1525 qed
       
  1526 
       
  1527 (* list_diff:: list substract, once different return tailer *)
       
  1528 fun list_diff :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list" (infix "-" 51)
       
  1529 where
       
  1530   "list_diff []  xs = []" |
       
  1531   "list_diff (x#xs) [] = x#xs" |
       
  1532   "list_diff (x#xs) (y#ys) = (if x = y then list_diff xs ys else (x#xs))"
       
  1533 
       
  1534 lemma [simp]: "(x @ y) - x = y"
       
  1535 apply (induct x)
       
  1536 by (case_tac y, simp+)
       
  1537 
       
  1538 lemma [simp]: "x - x = []"
       
  1539 by (induct x, auto)
       
  1540 
       
  1541 lemma [simp]: "x = xa @ y \<Longrightarrow> x - xa = y "
       
  1542 by (induct x, auto)
       
  1543 
       
  1544 lemma [simp]: "x - [] = x"
       
  1545 by (induct x, auto)
       
  1546 
       
  1547 lemma [simp]: "xa \<le> x \<Longrightarrow> (x @ y) - xa = (x - xa) @ y"
       
  1548 by (auto elim:prefixE)
       
  1549 
       
  1550 definition tag_str_SEQ:: "string set \<Rightarrow> string set \<Rightarrow> string \<Rightarrow> (string set \<times> string set set)"
       
  1551 where
       
  1552   "tag_str_SEQ L\<^isub>1 L\<^isub>2 x \<equiv> if (\<exists> xa \<le> x. xa \<in> L\<^isub>1)
       
  1553                          then (\<lbrakk>x\<rbrakk>L\<^isub>1, {\<lbrakk>(x - xa)\<rbrakk>L\<^isub>2 | xa.  xa \<le> x \<and> xa \<in> L\<^isub>1})
       
  1554                          else (\<lbrakk>x\<rbrakk>L\<^isub>1, {})"
       
  1555 
       
  1556 lemma tag_seq_eq_E:
       
  1557   "tag_str_SEQ L\<^isub>1 L\<^isub>2 x = tag_str_SEQ L\<^isub>1 L\<^isub>2 y \<Longrightarrow>
       
  1558    ((\<exists> xa \<le> x. xa \<in> L\<^isub>1) \<and> \<lbrakk>x\<rbrakk>L\<^isub>1 = \<lbrakk>y\<rbrakk>L\<^isub>1 \<and> 
       
  1559     {\<lbrakk>(x - xa)\<rbrakk>L\<^isub>2 | xa. xa \<le> x \<and> xa \<in> L\<^isub>1} = {\<lbrakk>(y - ya)\<rbrakk>L\<^isub>2 | ya. ya \<le> y \<and> ya \<in> L\<^isub>1} ) \<or>
       
  1560    ((\<forall> xa \<le> x. xa \<notin> L\<^isub>1) \<and> \<lbrakk>x\<rbrakk>L\<^isub>1 = \<lbrakk>y\<rbrakk>L\<^isub>1)"
       
  1561 by (simp add:tag_str_SEQ_def split:if_splits, blast)
       
  1562 
       
  1563 lemma tag_str_seq_range_finite:
       
  1564   assumes finite1: "finite (QUOT L\<^isub>1)"
       
  1565   and finite2: "finite (QUOT L\<^isub>2)"
       
  1566   shows "finite (range (tag_str_SEQ L\<^isub>1 L\<^isub>2))"
       
  1567 proof -
       
  1568   have "(range (tag_str_SEQ L\<^isub>1 L\<^isub>2)) \<subseteq> (QUOT L\<^isub>1) \<times> (Pow (QUOT L\<^isub>2))"
       
  1569     by (auto simp:image_def tag_str_SEQ_def QUOT_def)
       
  1570   thus ?thesis using finite1 finite2 
       
  1571     by (rule_tac B = "(QUOT L\<^isub>1) \<times> (Pow (QUOT L\<^isub>2))" in finite_subset, auto)
       
  1572 qed
       
  1573   
       
  1574 lemma app_in_seq_decom[rule_format]:
       
  1575   "\<forall> x. x @ z \<in> L\<^isub>1 ; L\<^isub>2 \<longrightarrow> (\<exists> xa \<le> x. xa \<in> L\<^isub>1 \<and> (x - xa) @ z \<in> L\<^isub>2) \<or> 
       
  1576                             (\<exists> za \<le> z. (x @ za) \<in> L\<^isub>1 \<and> (z - za) \<in> L\<^isub>2)"
       
  1577 apply (induct z)
       
  1578 apply (simp, rule allI, rule impI, rule disjI1)
       
  1579 apply (clarsimp simp add:lang_seq_def)
       
  1580 apply (rule_tac x = s1 in exI, simp)
       
  1581 apply (rule allI | rule impI)+
       
  1582 apply (drule_tac x = "x @ [a]" in spec, simp)
       
  1583 apply (erule exE | erule conjE | erule disjE)+
       
  1584 apply (rule disjI2, rule_tac x = "[a]" in exI, simp)
       
  1585 apply (rule disjI1, rule_tac x = xa in exI, simp) 
       
  1586 apply (erule exE | erule conjE)+
       
  1587 apply (rule disjI2, rule_tac x = "a # za" in exI, simp)
       
  1588 done
       
  1589 
       
  1590 lemma tag_str_seq_inj:
       
  1591   assumes tag_eq: "tag_str_SEQ L\<^isub>1 L\<^isub>2 x = tag_str_SEQ L\<^isub>1 L\<^isub>2 y"
       
  1592   shows "(x::string) \<equiv>(L\<^isub>1 ; L\<^isub>2)\<equiv> y"
       
  1593 proof -
       
  1594   have aux: "\<And> x y z. \<lbrakk>tag_str_SEQ L\<^isub>1 L\<^isub>2 x = tag_str_SEQ L\<^isub>1 L\<^isub>2 y; x @ z \<in> L\<^isub>1 ; L\<^isub>2\<rbrakk> 
       
  1595                        \<Longrightarrow> y @ z \<in> L\<^isub>1 ; L\<^isub>2"
       
  1596   proof (drule app_in_seq_decom, erule disjE)
       
  1597     fix x y z
       
  1598     assume tag_eq: "tag_str_SEQ L\<^isub>1 L\<^isub>2 x = tag_str_SEQ L\<^isub>1 L\<^isub>2 y"
       
  1599       and x_gets_l2: "\<exists>xa\<le>x. xa \<in> L\<^isub>1 \<and> (x - xa) @ z \<in> L\<^isub>2"
       
  1600     from x_gets_l2 have "\<exists> xa \<le> x. xa \<in> L\<^isub>1" by blast
       
  1601     hence xy_l2:"{\<lbrakk>(x - xa)\<rbrakk>L\<^isub>2 | xa. xa \<le> x \<and> xa \<in> L\<^isub>1} = {\<lbrakk>(y - ya)\<rbrakk>L\<^isub>2 | ya. ya \<le> y \<and> ya \<in> L\<^isub>1}"
       
  1602       using tag_eq tag_seq_eq_E by blast
       
  1603     from x_gets_l2 obtain xa where xa_le_x: "xa \<le> x"
       
  1604                                and xa_in_l1: "xa \<in> L\<^isub>1"
       
  1605                                and rest_in_l2: "(x - xa) @ z \<in> L\<^isub>2" by blast
       
  1606     hence "\<exists> ya. \<lbrakk>(x - xa)\<rbrakk>L\<^isub>2 = \<lbrakk>(y - ya)\<rbrakk>L\<^isub>2 \<and> ya \<le> y \<and> ya \<in> L\<^isub>1" using xy_l2 by auto
       
  1607     then obtain ya where ya_le_x: "ya \<le> y"
       
  1608                      and ya_in_l1: "ya \<in> L\<^isub>1"
       
  1609                      and rest_eq: "\<lbrakk>(x - xa)\<rbrakk>L\<^isub>2 = \<lbrakk>(y - ya)\<rbrakk>L\<^isub>2" by blast
       
  1610     from rest_eq rest_in_l2 have "(y - ya) @ z \<in> L\<^isub>2" 
       
  1611       by (auto simp:equiv_class_def equiv_str_def)
       
  1612     hence "ya @ ((y - ya) @ z) \<in> L\<^isub>1 ; L\<^isub>2" using ya_in_l1
       
  1613       by (auto simp:lang_seq_def)
       
  1614     thus "y @ z \<in> L\<^isub>1 ; L\<^isub>2" using ya_le_x 
       
  1615       by (erule_tac prefixE, simp)
       
  1616   next
       
  1617     fix x y z
       
  1618     assume tag_eq: "tag_str_SEQ L\<^isub>1 L\<^isub>2 x = tag_str_SEQ L\<^isub>1 L\<^isub>2 y"
       
  1619       and x_gets_l1: "\<exists>za\<le>z. x @ za \<in> L\<^isub>1 \<and> z - za \<in> L\<^isub>2"
       
  1620     from tag_eq tag_seq_eq_E have x_y_eq: "\<lbrakk>x\<rbrakk>L\<^isub>1 = \<lbrakk>y\<rbrakk>L\<^isub>1" by blast
       
  1621     from x_gets_l1 obtain za where za_le_z: "za \<le> z"
       
  1622                                and x_za_in_l1: "(x @ za) \<in> L\<^isub>1"
       
  1623                                and rest_in_l2: "z - za \<in> L\<^isub>2" by blast
       
  1624     from x_y_eq x_za_in_l1 have y_za_in_l1: "y @ za \<in> L\<^isub>1"
       
  1625       by (auto simp:equiv_class_def equiv_str_def)
       
  1626     hence "(y @ za) @ (z - za) \<in> L\<^isub>1 ; L\<^isub>2" using rest_in_l2
       
  1627       apply (simp add:lang_seq_def)
       
  1628       by (rule_tac x = "y @ za" in exI, rule_tac x = "z - za" in exI, simp)
       
  1629     thus "y @ z \<in> L\<^isub>1 ; L\<^isub>2" using za_le_z
       
  1630       by (erule_tac prefixE, simp)
       
  1631   qed
       
  1632   show ?thesis using tag_eq
       
  1633     apply (simp add:equiv_str_def)
       
  1634     by (auto intro:aux)
       
  1635 qed
       
  1636 
       
  1637 lemma quot_seq: 
       
  1638   assumes finite1: "finite (QUOT L\<^isub>1)"
       
  1639   and finite2: "finite (QUOT L\<^isub>2)"
       
  1640   shows "finite (QUOT (L\<^isub>1;L\<^isub>2))"
       
  1641 proof (rule_tac f = "(op `) (tag_str_SEQ L\<^isub>1 L\<^isub>2)" in finite_imageD)
       
  1642   show "finite (op ` (tag_str_SEQ L\<^isub>1 L\<^isub>2) ` QUOT (L\<^isub>1 ; L\<^isub>2))"
       
  1643     using finite_tag_image tag_str_seq_range_finite finite1 finite2
       
  1644     by auto
       
  1645 next
       
  1646   show "inj_on (op ` (tag_str_SEQ L\<^isub>1 L\<^isub>2)) (QUOT (L\<^isub>1 ; L\<^isub>2))"
       
  1647     apply (rule_tac str_inj_imps)
       
  1648     by (erule_tac tag_str_seq_inj)
       
  1649 qed
       
  1650 
       
  1651 (****************** the STAR case ************************)
       
  1652 
       
  1653 lemma app_eq_elim[rule_format]:
       
  1654   "\<And> a. \<forall> b x y. a @ b = x @ y \<longrightarrow> (\<exists> aa ab. a = aa @ ab \<and> x = aa \<and> y = ab @ b) \<or>
       
  1655                                    (\<exists> ba bb. b = ba @ bb \<and> x = a @ ba \<and> y = bb \<and> ba \<noteq> [])"
       
  1656   apply (induct_tac a rule:List.induct, simp)
       
  1657   apply (rule allI | rule impI)+
       
  1658   by (case_tac x, auto)
       
  1659 
       
  1660 definition tag_str_STAR:: "string set \<Rightarrow> string \<Rightarrow> string set set"
       
  1661 where
       
  1662   "tag_str_STAR L\<^isub>1 x \<equiv> if (x = []) 
       
  1663                        then {}
       
  1664                        else {\<lbrakk>x\<^isub>2\<rbrakk>L\<^isub>1 | x\<^isub>1 x\<^isub>2. x =  x\<^isub>1 @ x\<^isub>2 \<and> x\<^isub>1 \<in> L\<^isub>1\<star> \<and> x\<^isub>2 \<noteq> []}"
       
  1665 
       
  1666 lemma tag_str_star_range_finite:
       
  1667   assumes finite1: "finite (QUOT L\<^isub>1)"
       
  1668   shows "finite (range (tag_str_STAR L\<^isub>1))"
       
  1669 proof -
       
  1670   have "range (tag_str_STAR L\<^isub>1) \<subseteq> Pow (QUOT L\<^isub>1)"
       
  1671     by (auto simp:image_def tag_str_STAR_def QUOT_def)
       
  1672   thus ?thesis using finite1
       
  1673     by (rule_tac B = "Pow (QUOT L\<^isub>1)" in finite_subset, auto)
       
  1674 qed
       
  1675 
       
  1676 lemma star_prop[rule_format]: "x \<in> lang\<star> \<Longrightarrow> \<forall> y. y \<in> lang\<star> \<longrightarrow> x @ y \<in> lang\<star>"
       
  1677 by (erule Star.induct, auto)
       
  1678 
       
  1679 lemma star_prop2: "y \<in> lang \<Longrightarrow> y \<in> lang\<star>"
       
  1680 by (drule step[of y lang "[]"], auto simp:start)
       
  1681 
       
  1682 lemma star_prop3[rule_format]: "x \<in> lang\<star> \<Longrightarrow> \<forall>y . y \<in> lang \<longrightarrow> x @ y \<in> lang\<star>"
       
  1683 by (erule Star.induct, auto intro:star_prop2)
       
  1684 
       
  1685 lemma postfix_prop: "y >>= (x @ y) \<Longrightarrow> x = []"
       
  1686 by (erule postfixE, induct x arbitrary:y, auto)
       
  1687 
       
  1688 lemma inj_aux:
       
  1689   "\<lbrakk>(m @ z) \<in> L\<^isub>1\<star>; m \<equiv>L\<^isub>1\<equiv> yb; xa @ m = x; xa \<in> L\<^isub>1\<star>; m \<noteq> [];
       
  1690     \<forall> xa xb. x = xa @ xb \<and> xa \<in> L\<^isub>1\<star> \<and> xb \<noteq> [] \<and> xb @ z \<in> L\<^isub>1\<star> \<longrightarrow> xb >>= m\<rbrakk> 
       
  1691   \<Longrightarrow> (yb @ z) \<in> L\<^isub>1\<star>"
       
  1692 proof- 
       
  1693   have "\<And>s. s \<in> L\<^isub>1\<star> \<Longrightarrow> \<forall> m z yb. (s = m @ z \<and> m \<equiv>L\<^isub>1\<equiv> yb \<and> x = xa @ m \<and> xa \<in> L\<^isub>1\<star> \<and> m \<noteq> [] \<and>  
       
  1694     (\<forall> xa xb. x = xa @ xb \<and> xa \<in> L\<^isub>1\<star> \<and> xb \<noteq> [] \<and> xb @ z \<in> L\<^isub>1\<star> \<longrightarrow> xb >>= m) \<longrightarrow> (yb @ z) \<in> L\<^isub>1\<star>)"    
       
  1695     apply (erule Star.induct, simp)
       
  1696     apply (rule allI | rule impI | erule conjE)+
       
  1697     apply (drule app_eq_elim)
       
  1698     apply (erule disjE | erule exE | erule conjE)+
       
  1699     apply simp
       
  1700     apply (simp (no_asm) only:append_assoc[THEN sym])
       
  1701     apply (rule step) 
       
  1702     apply (simp add:equiv_str_def)
       
  1703     apply simp
       
  1704 
       
  1705     apply (erule exE | erule conjE)+    
       
  1706     apply (rotate_tac 3)
       
  1707     apply (frule_tac x = "xa @ s1" in spec)
       
  1708     apply (rotate_tac 12)
       
  1709     apply (drule_tac x = ba in spec)
       
  1710     apply (erule impE)
       
  1711     apply ( simp add:star_prop3)
       
  1712     apply (simp)
       
  1713     apply (drule postfix_prop)
       
  1714     apply simp
       
  1715     done
       
  1716   thus "\<lbrakk>(m @ z) \<in> L\<^isub>1\<star>; m \<equiv>L\<^isub>1\<equiv> yb; xa @ m = x; xa \<in> L\<^isub>1\<star>; m \<noteq> [];
       
  1717          \<forall> xa xb. x = xa @ xb \<and> xa \<in> L\<^isub>1\<star> \<and> xb \<noteq> [] \<and> xb @ z \<in> L\<^isub>1\<star> \<longrightarrow> xb >>= m\<rbrakk> 
       
  1718         \<Longrightarrow> (yb @ z) \<in> L\<^isub>1\<star>" by blast
       
  1719 qed
       
  1720 
       
  1721 
       
  1722 lemma min_postfix_exists[rule_format]:
       
  1723   "finite A \<Longrightarrow> A \<noteq> {} \<and> (\<forall> a \<in> A. \<forall> b \<in> A. ((b >>= a) \<or> (a >>= b))) 
       
  1724                 \<longrightarrow> (\<exists> min. (min \<in> A \<and> (\<forall> a \<in> A. a >>= min)))"
       
  1725 apply (erule finite.induct)
       
  1726 apply simp
       
  1727 apply simp
       
  1728 apply (case_tac "A = {}")
       
  1729 apply simp
       
  1730 apply clarsimp
       
  1731 apply (case_tac "a >>= min")
       
  1732 apply (rule_tac x = min in exI, simp)
       
  1733 apply (rule_tac x = a in exI, simp)
       
  1734 apply clarify
       
  1735 apply (rotate_tac 5)
       
  1736 apply (erule_tac x = aa in ballE) defer apply simp
       
  1737 apply (erule_tac ys = min in postfix_trans)
       
  1738 apply (erule_tac x = min in ballE) 
       
  1739 by simp+
       
  1740 
       
  1741 lemma tag_str_star_inj:
       
  1742   "tag_str_STAR L\<^isub>1 x = tag_str_STAR L\<^isub>1 (y::string) \<Longrightarrow> x \<equiv>L\<^isub>1\<star>\<equiv> y"
       
  1743 proof -
       
  1744   have aux: "\<And> x y z. \<lbrakk>tag_str_STAR L\<^isub>1 x = tag_str_STAR L\<^isub>1 y; x @ z \<in> L\<^isub>1\<star>\<rbrakk> \<Longrightarrow> y @ z \<in> L\<^isub>1\<star>"
       
  1745   proof-
       
  1746     fix x y z
       
  1747     assume tag_eq: "tag_str_STAR L\<^isub>1 x = tag_str_STAR L\<^isub>1 y"
       
  1748       and x_z: "x @ z \<in> L\<^isub>1\<star>"
       
  1749     show "y @ z \<in> L\<^isub>1\<star>"
       
  1750     proof (cases "x = []")
       
  1751       case True
       
  1752       with tag_eq have "y = []" by (simp add:tag_str_STAR_def split:if_splits, blast)
       
  1753       thus ?thesis using x_z True by simp
       
  1754     next
       
  1755       case False
       
  1756       hence not_empty: "{xb. \<exists> xa. x = xa @ xb \<and> xa \<in> L\<^isub>1\<star> \<and> xb \<noteq> [] \<and> xb @ z \<in> L\<^isub>1\<star>} \<noteq> {}" using x_z
       
  1757         by (simp, rule_tac x = x in exI, rule_tac x = "[]" in exI, simp add:start)
       
  1758       have finite_set: "finite {xb. \<exists> xa. x = xa @ xb \<and> xa \<in> L\<^isub>1\<star> \<and> xb \<noteq> [] \<and> xb @ z \<in> L\<^isub>1\<star>}"
       
  1759         apply (rule_tac B = "{xb. \<exists> xa. x = xa @ xb}" in finite_subset)
       
  1760         apply auto
       
  1761         apply (induct x, simp)
       
  1762         apply (subgoal_tac "{xb. \<exists>xa. a # x = xa @ xb} = insert (a # x) {xb. \<exists>xa. x = xa @ xb}")
       
  1763         apply auto
       
  1764         by (case_tac xaa, simp+)
       
  1765       have comparable: "\<forall> a \<in> {xb. \<exists> xa. x = xa @ xb \<and> xa \<in> L\<^isub>1\<star> \<and> xb \<noteq> [] \<and> xb @ z \<in> L\<^isub>1\<star>}. 
       
  1766                         \<forall> b \<in> {xb. \<exists> xa. x = xa @ xb \<and> xa \<in> L\<^isub>1\<star> \<and> xb \<noteq> [] \<and> xb @ z \<in> L\<^isub>1\<star>}.
       
  1767                           ((b >>= a) \<or> (a >>= b))"
       
  1768         by (auto simp:postfix_def, drule app_eq_elim, blast)
       
  1769       hence "\<exists> min. min \<in> {xb. \<exists> xa. x = xa @ xb \<and> xa \<in> L\<^isub>1\<star> \<and> xb \<noteq> [] \<and> xb @ z \<in> L\<^isub>1\<star>} 
       
  1770                 \<and> (\<forall> xa xb. x = xa @ xb \<and> xa \<in> L\<^isub>1\<star> \<and> xb \<noteq> [] \<and> xb @ z \<in> L\<^isub>1\<star> \<longrightarrow> xb >>= min)"
       
  1771         using finite_set not_empty comparable
       
  1772         apply (drule_tac min_postfix_exists, simp)
       
  1773         by (erule exE, rule_tac x = min in exI, auto)
       
  1774       then obtain min xa where x_decom: "x = xa @ min \<and> xa \<in> L\<^isub>1\<star>"
       
  1775         and min_not_empty: "min \<noteq> []"
       
  1776         and min_z_in_star: "min @ z \<in> L\<^isub>1\<star>"
       
  1777         and is_min: "\<forall> xa xb. x = xa @ xb \<and> xa \<in> L\<^isub>1\<star> \<and> xb \<noteq> [] \<and> xb @ z \<in> L\<^isub>1\<star> \<longrightarrow> xb >>= min"  by blast
       
  1778       from x_decom min_not_empty have "\<lbrakk>min\<rbrakk>L\<^isub>1 \<in> tag_str_STAR L\<^isub>1 x"  by (auto simp:tag_str_STAR_def)
       
  1779       hence "\<exists> yb. \<lbrakk>yb\<rbrakk>L\<^isub>1 \<in> tag_str_STAR L\<^isub>1 y \<and> \<lbrakk>min\<rbrakk>L\<^isub>1 = \<lbrakk>yb\<rbrakk>L\<^isub>1" using tag_eq by auto
       
  1780       hence "\<exists> ya yb. y = ya @ yb \<and> ya \<in> L\<^isub>1\<star> \<and> min \<equiv>L\<^isub>1\<equiv> yb \<and> yb \<noteq> [] " 
       
  1781         by (simp add:tag_str_STAR_def equiv_class_def equiv_str_def split:if_splits, blast)        
       
  1782       then obtain ya yb where y_decom: "y = ya @ yb"
       
  1783                           and ya_in_star: "ya \<in> L\<^isub>1\<star>"
       
  1784                           and yb_not_empty: "yb \<noteq> []"
       
  1785                           and min_yb_eq: "min \<equiv>L\<^isub>1\<equiv> yb"  by blast
       
  1786       from min_z_in_star min_yb_eq min_not_empty is_min x_decom
       
  1787       have "yb @ z \<in> L\<^isub>1\<star>"
       
  1788         by (rule_tac x = x and xa = xa in inj_aux, simp+)
       
  1789       thus ?thesis using ya_in_star y_decom
       
  1790         by (auto dest:star_prop)        
       
  1791     qed
       
  1792   qed
       
  1793   show "tag_str_STAR L\<^isub>1 x = tag_str_STAR L\<^isub>1 (y::string) \<Longrightarrow> x \<equiv>L\<^isub>1\<star>\<equiv> y"
       
  1794     by (auto intro:aux simp:equiv_str_def)
       
  1795 qed
       
  1796 
       
  1797 lemma quot_star:  
       
  1798   assumes finite1: "finite (QUOT L\<^isub>1)"
       
  1799   shows "finite (QUOT (L\<^isub>1\<star>))"
       
  1800 proof (rule_tac f = "(op `) (tag_str_STAR L\<^isub>1)" in finite_imageD)
       
  1801   show "finite (op ` (tag_str_STAR L\<^isub>1) ` QUOT (L\<^isub>1\<star>))"
       
  1802     using finite_tag_image tag_str_star_range_finite finite1
       
  1803     by auto
       
  1804 next
       
  1805   show "inj_on (op ` (tag_str_STAR L\<^isub>1)) (QUOT (L\<^isub>1\<star>))"
       
  1806     apply (rule_tac str_inj_imps)
       
  1807     by (erule_tac tag_str_star_inj)
       
  1808 qed
       
  1809 
       
  1810 lemma other_direction:
       
  1811   "Lang = L (r::rexp) \<Longrightarrow> finite (QUOT Lang)"
       
  1812 apply (induct arbitrary:Lang rule:rexp.induct)
       
  1813 apply (simp add:QUOT_def equiv_class_def equiv_str_def)
       
  1814 by (simp_all add:quot_lambda quot_single quot_seq quot_alt quot_star)  
       
  1815 
       
  1816 end