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