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