89 } thus ?thesis unfolding inj_on_def by auto |
88 } thus ?thesis unfolding inj_on_def by auto |
90 qed |
89 qed |
91 qed |
90 qed |
92 qed |
91 qed |
93 |
92 |
94 *) |
93 |
95 |
94 (* |
96 lemma finite_range_image: "finite (range f) \<Longrightarrow> finite (f ` A)" |
95 lemma finite_range_image: "finite (range f) \<Longrightarrow> finite (f ` A)" |
97 by (rule_tac B = "{y. \<exists>x. y = f x}" in finite_subset, auto simp:image_def) |
96 by (rule_tac B = "{y. \<exists>x. y = f x}" in finite_subset, auto simp:image_def) |
|
97 *) |
98 |
98 |
99 lemma tag_finite_imageD: |
99 lemma tag_finite_imageD: |
100 fixes tag |
100 fixes L :: "lang" |
101 assumes rng_fnt: "finite (range tag)" |
101 assumes rng_fnt: "finite (range tag)" |
102 -- {* Suppose the rang of tagging fucntion @{text "tag"} is finite. *} |
102 -- {* Suppose the range of tagging fucntion @{text "tag"} is finite. *} |
103 and same_tag_eqvt: "\<And> m n. tag m = tag (n::string) \<Longrightarrow> m \<approx>lang n" |
103 and same_tag_eqvt: "\<And> m n. tag m = tag n \<Longrightarrow> m \<approx>L n" |
104 -- {* And strings with same tag are equivalent *} |
104 -- {* And strings with same tag are equivalent *} |
105 shows "finite (UNIV // (\<approx>lang))" |
105 shows "finite (UNIV // \<approx>L)" |
106 -- {* Then the partition generated by @{text "(\<approx>lang)"} is finite. *} |
106 -- {* Then the partition generated by @{text "\<approx>L"} is finite. *} |
107 proof - |
107 proof - |
108 -- {* The particular @{text "f"} and @{text "A"} used in @{thm [source] "finite_imageD"} are:*} |
108 -- {* The particular @{text "f"} and @{text "A"} used in @{thm [source] "finite_imageD"} are:*} |
109 let "?f" = "op ` tag" and ?A = "(UNIV // \<approx>lang)" |
109 let "?f" = "op ` tag" and ?A = "(UNIV // \<approx>L)" |
110 show ?thesis |
110 show ?thesis |
111 proof (rule_tac f = "?f" and A = ?A in finite_imageD) |
111 proof (rule_tac f = "?f" and A = ?A in finite_imageD) |
112 -- {* |
112 -- {* |
113 The finiteness of @{text "f"}-image is a simple consequence of assumption @{text "rng_fnt"}: |
113 The finiteness of @{text "f"}-image is a simple consequence of assumption @{text "rng_fnt"}: |
114 *} |
114 *} |
146 qed |
146 qed |
147 |
147 |
148 subsection {* Lemmas for basic cases *} |
148 subsection {* Lemmas for basic cases *} |
149 |
149 |
150 text {* |
150 text {* |
151 The the final result of this direction is in @{text "easier_direction"}, which |
151 The the final result of this direction is in @{text "rexp_imp_finite"}, |
152 is an induction on the structure of regular expressions. There is one case |
152 which is an induction on the structure of regular expressions. There is one |
153 for each regular expression operator. For basic operators such as @{text "NULL, EMPTY, CHAR c"}, |
153 case for each regular expression operator. For basic operators such as |
154 the finiteness of their language partition can be established directly with no need |
154 @{const NULL}, @{const EMPTY}, @{const CHAR}, the finiteness of their |
155 of taggiing. This section contains several technical lemma for these base cases. |
155 language partition can be established directly with no need of tagging. |
156 |
156 This section contains several technical lemma for these base cases. |
157 The inductive cases involve operators @{text "ALT, SEQ"} and @{text "STAR"}. |
157 |
158 Tagging functions need to be defined individually for each of them. There will be one |
158 The inductive cases involve operators @{const ALT}, @{const SEQ} and @{const |
159 dedicated section for each of these cases, and each section goes virtually the same way: |
159 STAR}. Tagging functions need to be defined individually for each of |
160 gives definition of the tagging function and prove that strings |
160 them. There will be one dedicated section for each of these cases, and each |
161 with the same tag are equivalent. |
161 section goes virtually the same way: gives definition of the tagging |
162 *} |
162 function and prove that strings with the same tag are equivalent. |
|
163 *} |
|
164 |
|
165 subsection {* The case for @{const "NULL"} *} |
|
166 |
|
167 lemma quot_null_eq: |
|
168 shows "(UNIV // \<approx>{}) = ({UNIV}::lang set)" |
|
169 unfolding quotient_def Image_def str_eq_rel_def by auto |
|
170 |
|
171 lemma quot_null_finiteI [intro]: |
|
172 shows "finite ((UNIV // \<approx>{})::lang set)" |
|
173 unfolding quot_null_eq by simp |
|
174 |
|
175 |
|
176 subsection {* The case for @{const "EMPTY"} *} |
|
177 |
163 |
178 |
164 lemma quot_empty_subset: |
179 lemma quot_empty_subset: |
165 "UNIV // (\<approx>{[]}) \<subseteq> {{[]}, UNIV - {[]}}" |
180 "UNIV // (\<approx>{[]}) \<subseteq> {{[]}, UNIV - {[]}}" |
166 proof |
181 proof |
167 fix x |
182 fix x |
168 assume "x \<in> UNIV // \<approx>{[]}" |
183 assume "x \<in> UNIV // \<approx>{[]}" |
169 then obtain y where h: "x = {z. (y, z) \<in> \<approx>{[]}}" |
184 then obtain y where h: "x = {z. (y, z) \<in> \<approx>{[]}}" |
170 unfolding quotient_def Image_def by blast |
185 unfolding quotient_def Image_def by blast |
171 show "x \<in> {{[]}, UNIV - {[]}}" |
186 show "x \<in> {{[]}, UNIV - {[]}}" |
172 proof (cases "y = []") |
187 proof (cases "y = []") |
173 case True with h |
188 case True with h |
174 have "x = {[]}" by (auto simp:str_eq_rel_def) |
189 have "x = {[]}" by (auto simp: str_eq_rel_def) |
175 thus ?thesis by simp |
190 thus ?thesis by simp |
176 next |
191 next |
177 case False with h |
192 case False with h |
178 have "x = UNIV - {[]}" by (auto simp:str_eq_rel_def) |
193 have "x = UNIV - {[]}" by (auto simp: str_eq_rel_def) |
179 thus ?thesis by simp |
194 thus ?thesis by simp |
180 qed |
195 qed |
181 qed |
196 qed |
|
197 |
|
198 lemma quot_empty_finiteI [intro]: |
|
199 shows "finite (UNIV // (\<approx>{[]}))" |
|
200 by (rule finite_subset[OF quot_empty_subset]) (simp) |
|
201 |
|
202 |
|
203 subsection {* The case for @{const "CHAR"} *} |
182 |
204 |
183 lemma quot_char_subset: |
205 lemma quot_char_subset: |
184 "UNIV // (\<approx>{[c]}) \<subseteq> {{[]},{[c]}, UNIV - {[], [c]}}" |
206 "UNIV // (\<approx>{[c]}) \<subseteq> {{[]},{[c]}, UNIV - {[], [c]}}" |
185 proof |
207 proof |
186 fix x |
208 fix x |
203 by (auto simp add:str_eq_rel_def) |
225 by (auto simp add:str_eq_rel_def) |
204 } ultimately show ?thesis by blast |
226 } ultimately show ?thesis by blast |
205 qed |
227 qed |
206 qed |
228 qed |
207 |
229 |
208 subsection {* The case for @{text "SEQ"}*} |
230 lemma quot_char_finiteI [intro]: |
|
231 shows "finite (UNIV // (\<approx>{[c]}))" |
|
232 by (rule finite_subset[OF quot_char_subset]) (simp) |
|
233 |
|
234 |
|
235 subsection {* The case for @{const SEQ}*} |
209 |
236 |
210 definition |
237 definition |
211 "tag_str_SEQ L\<^isub>1 L\<^isub>2 x \<equiv> |
238 tag_str_SEQ :: "lang \<Rightarrow> lang \<Rightarrow> string \<Rightarrow> (lang \<times> lang set)" |
212 ((\<approx>L\<^isub>1) `` {x}, {(\<approx>L\<^isub>2) `` {x - xa}| xa. xa \<le> x \<and> xa \<in> L\<^isub>1})" |
239 where |
213 |
240 "tag_str_SEQ L1 L2 = (\<lambda>x. (\<approx>L1 `` {x}, {(\<approx>L2 `` {x - xa}) | xa. xa \<le> x \<and> xa \<in> L1}))" |
214 lemma tag_str_seq_range_finite: |
241 |
215 "\<lbrakk>finite (UNIV // \<approx>L\<^isub>1); finite (UNIV // \<approx>L\<^isub>2)\<rbrakk> |
|
216 \<Longrightarrow> finite (range (tag_str_SEQ L\<^isub>1 L\<^isub>2))" |
|
217 apply (rule_tac B = "(UNIV // \<approx>L\<^isub>1) \<times> (Pow (UNIV // \<approx>L\<^isub>2))" in finite_subset) |
|
218 by (auto simp:tag_str_SEQ_def Image_def quotient_def split:if_splits) |
|
219 |
242 |
220 lemma append_seq_elim: |
243 lemma append_seq_elim: |
221 assumes "x @ y \<in> L\<^isub>1 ;; L\<^isub>2" |
244 assumes "x @ y \<in> L\<^isub>1 ;; L\<^isub>2" |
222 shows "(\<exists> xa \<le> x. xa \<in> L\<^isub>1 \<and> (x - xa) @ y \<in> L\<^isub>2) \<or> |
245 shows "(\<exists> xa \<le> x. xa \<in> L\<^isub>1 \<and> (x - xa) @ y \<in> L\<^isub>2) \<or> |
223 (\<exists> ya \<le> y. (x @ ya) \<in> L\<^isub>1 \<and> (y - ya) \<in> L\<^isub>2)" |
246 (\<exists> ya \<le> y. (x @ ya) \<in> L\<^isub>1 \<and> (y - ya) \<in> L\<^isub>2)" |
281 } |
304 } |
282 ultimately show ?thesis by blast |
305 ultimately show ?thesis by blast |
283 qed |
306 qed |
284 } thus "tag_str_SEQ L\<^isub>1 L\<^isub>2 m = tag_str_SEQ L\<^isub>1 L\<^isub>2 n \<Longrightarrow> m \<approx>(L\<^isub>1 ;; L\<^isub>2) n" |
307 } thus "tag_str_SEQ L\<^isub>1 L\<^isub>2 m = tag_str_SEQ L\<^isub>1 L\<^isub>2 n \<Longrightarrow> m \<approx>(L\<^isub>1 ;; L\<^isub>2) n" |
285 by (auto simp add: str_eq_def str_eq_rel_def) |
308 by (auto simp add: str_eq_def str_eq_rel_def) |
286 qed |
309 qed |
287 |
310 |
288 lemma quot_seq_finiteI: |
311 lemma quot_seq_finiteI [intro]: |
289 "\<lbrakk>finite (UNIV // \<approx>L\<^isub>1); finite (UNIV // \<approx>L\<^isub>2)\<rbrakk> |
312 fixes L1 L2::"lang" |
290 \<Longrightarrow> finite (UNIV // \<approx>(L\<^isub>1 ;; L\<^isub>2))" |
313 assumes fin1: "finite (UNIV // \<approx>L1)" |
291 apply (rule_tac tag = "tag_str_SEQ L\<^isub>1 L\<^isub>2" in tag_finite_imageD) |
314 and fin2: "finite (UNIV // \<approx>L2)" |
292 by (auto intro:tag_str_SEQ_injI elim:tag_str_seq_range_finite) |
315 shows "finite (UNIV // \<approx>(L1 ;; L2))" |
293 |
316 proof (rule_tac tag = "tag_str_SEQ L1 L2" in tag_finite_imageD) |
294 subsection {* The case for @{text "ALT"} *} |
317 show "\<And>x y. tag_str_SEQ L1 L2 x = tag_str_SEQ L1 L2 y \<Longrightarrow> x \<approx>(L1 ;; L2) y" |
|
318 by (rule tag_str_SEQ_injI) |
|
319 next |
|
320 have *: "finite ((UNIV // \<approx>L1) \<times> (Pow (UNIV // \<approx>L2)))" |
|
321 using fin1 fin2 by auto |
|
322 show "finite (range (tag_str_SEQ L1 L2))" |
|
323 unfolding tag_str_SEQ_def |
|
324 apply(rule finite_subset[OF _ *]) |
|
325 unfolding quotient_def |
|
326 by auto |
|
327 qed |
|
328 |
|
329 |
|
330 subsection {* The case for @{const ALT} *} |
295 |
331 |
296 definition |
332 definition |
297 "tag_str_ALT L\<^isub>1 L\<^isub>2 (x::string) \<equiv> ((\<approx>L\<^isub>1) `` {x}, (\<approx>L\<^isub>2) `` {x})" |
333 tag_str_ALT :: "lang \<Rightarrow> lang \<Rightarrow> string \<Rightarrow> (lang \<times> lang)" |
298 |
334 where |
299 lemma quot_union_finiteI: |
335 "tag_str_ALT L1 L2 = (\<lambda>x. (\<approx>L1 `` {x}, \<approx>L2 `` {x}))" |
300 assumes finite1: "finite (UNIV // \<approx>(L\<^isub>1::string set))" |
336 |
301 and finite2: "finite (UNIV // \<approx>L\<^isub>2)" |
337 |
302 shows "finite (UNIV // \<approx>(L\<^isub>1 \<union> L\<^isub>2))" |
338 lemma quot_union_finiteI [intro]: |
303 proof (rule_tac tag = "tag_str_ALT L\<^isub>1 L\<^isub>2" in tag_finite_imageD) |
339 fixes L1 L2::"lang" |
304 show "\<And>m n. tag_str_ALT L\<^isub>1 L\<^isub>2 m = tag_str_ALT L\<^isub>1 L\<^isub>2 n \<Longrightarrow> m \<approx>(L\<^isub>1 \<union> L\<^isub>2) n" |
340 assumes finite1: "finite (UNIV // \<approx>L1)" |
305 unfolding tag_str_ALT_def str_eq_def Image_def str_eq_rel_def by auto |
341 and finite2: "finite (UNIV // \<approx>L2)" |
|
342 shows "finite (UNIV // \<approx>(L1 \<union> L2))" |
|
343 proof (rule_tac tag = "tag_str_ALT L1 L2" in tag_finite_imageD) |
|
344 show "\<And>x y. tag_str_ALT L1 L2 x = tag_str_ALT L1 L2 y \<Longrightarrow> x \<approx>(L1 \<union> L2) y" |
|
345 unfolding tag_str_ALT_def |
|
346 unfolding str_eq_def |
|
347 unfolding Image_def |
|
348 unfolding str_eq_rel_def |
|
349 by auto |
306 next |
350 next |
307 show "finite (range (tag_str_ALT L\<^isub>1 L\<^isub>2))" using finite1 finite2 |
351 have *: "finite ((UNIV // \<approx>L1) \<times> (UNIV // \<approx>L2))" |
308 apply (rule_tac B = "(UNIV // \<approx>L\<^isub>1) \<times> (UNIV // \<approx>L\<^isub>2)" in finite_subset) |
352 using finite1 finite2 by auto |
309 by (auto simp:tag_str_ALT_def Image_def quotient_def) |
353 show "finite (range (tag_str_ALT L1 L2))" |
310 qed |
354 unfolding tag_str_ALT_def |
311 |
355 apply(rule finite_subset[OF _ *]) |
312 subsection {* |
356 unfolding quotient_def |
313 The case for @{text "STAR"} |
357 by auto |
314 *} |
358 qed |
|
359 |
|
360 subsection {* The case for @{const "STAR"} *} |
315 |
361 |
316 text {* |
362 text {* |
317 This turned out to be the trickiest case. |
363 This turned out to be the trickiest case. |
318 *} (* I will make some illustrations for it. *) |
364 *} (* I will make some illustrations for it. *) |
319 |
365 |
320 definition |
366 definition |
321 "tag_str_STAR L\<^isub>1 x \<equiv> {(\<approx>L\<^isub>1) `` {x - xa} | xa. xa < x \<and> xa \<in> L\<^isub>1\<star>}" |
367 tag_str_STAR :: "lang \<Rightarrow> string \<Rightarrow> lang set" |
322 |
368 where |
323 lemma finite_set_has_max: "\<lbrakk>finite A; A \<noteq> {}\<rbrakk> \<Longrightarrow> |
369 "tag_str_STAR L1 = (\<lambda>x. {\<approx>L1 `` {x - xa} | xa. xa < x \<and> xa \<in> L1\<star>})" |
324 (\<exists> max \<in> A. \<forall> a \<in> A. f a <= (f max :: nat))" |
370 |
|
371 |
|
372 lemma finite_set_has_max: |
|
373 "\<lbrakk>finite A; A \<noteq> {}\<rbrakk> \<Longrightarrow> (\<exists> max \<in> A. \<forall> a \<in> A. f a <= (f max :: nat))" |
325 proof (induct rule:finite.induct) |
374 proof (induct rule:finite.induct) |
326 case emptyI thus ?case by simp |
375 case emptyI thus ?case by simp |
327 next |
376 next |
328 case (insertI A a) |
377 case (insertI A a) |
329 show ?case |
378 show ?case |
347 |
396 |
348 lemma finite_strict_prefix_set: "finite {xa. xa < (x::string)}" |
397 lemma finite_strict_prefix_set: "finite {xa. xa < (x::string)}" |
349 apply (induct x rule:rev_induct, simp) |
398 apply (induct x rule:rev_induct, simp) |
350 apply (subgoal_tac "{xa. xa < xs @ [x]} = {xa. xa < xs} \<union> {xs}") |
399 apply (subgoal_tac "{xa. xa < xs @ [x]} = {xa. xa < xs} \<union> {xs}") |
351 by (auto simp:strict_prefix_def) |
400 by (auto simp:strict_prefix_def) |
352 |
|
353 |
|
354 lemma tag_str_star_range_finite: |
|
355 "finite (UNIV // \<approx>L\<^isub>1) \<Longrightarrow> finite (range (tag_str_STAR L\<^isub>1))" |
|
356 apply (rule_tac B = "Pow (UNIV // \<approx>L\<^isub>1)" in finite_subset) |
|
357 by (auto simp:tag_str_STAR_def Image_def |
|
358 quotient_def split:if_splits) |
|
359 |
401 |
360 lemma tag_str_STAR_injI: |
402 lemma tag_str_STAR_injI: |
361 "tag_str_STAR L\<^isub>1 m = tag_str_STAR L\<^isub>1 n \<Longrightarrow> m \<approx>(L\<^isub>1\<star>) n" |
403 "tag_str_STAR L\<^isub>1 m = tag_str_STAR L\<^isub>1 n \<Longrightarrow> m \<approx>(L\<^isub>1\<star>) n" |
362 proof- |
404 proof- |
363 { fix x y z |
405 { fix x y z |
439 qed |
481 qed |
440 } thus "tag_str_STAR L\<^isub>1 m = tag_str_STAR L\<^isub>1 n \<Longrightarrow> m \<approx>(L\<^isub>1\<star>) n" |
482 } thus "tag_str_STAR L\<^isub>1 m = tag_str_STAR L\<^isub>1 n \<Longrightarrow> m \<approx>(L\<^isub>1\<star>) n" |
441 by (auto simp add:str_eq_def str_eq_rel_def) |
483 by (auto simp add:str_eq_def str_eq_rel_def) |
442 qed |
484 qed |
443 |
485 |
444 lemma quot_star_finiteI: |
486 lemma quot_star_finiteI [intro]: |
445 "finite (UNIV // \<approx>L\<^isub>1) \<Longrightarrow> finite (UNIV // \<approx>(L\<^isub>1\<star>))" |
487 fixes L1::"lang" |
446 apply (rule_tac tag = "tag_str_STAR L\<^isub>1" in tag_finite_imageD) |
488 assumes finite1: "finite (UNIV // \<approx>L1)" |
447 by (auto intro:tag_str_STAR_injI elim:tag_str_star_range_finite) |
489 shows "finite (UNIV // \<approx>(L1\<star>))" |
448 |
490 proof (rule_tac tag = "tag_str_STAR L1" in tag_finite_imageD) |
449 subsection {* |
491 show "\<And>x y. tag_str_STAR L1 x = tag_str_STAR L1 y \<Longrightarrow> x \<approx>(L1\<star>) y" |
450 The main lemma |
492 by (rule tag_str_STAR_injI) |
451 *} |
|
452 |
|
453 lemma easier_directio\<nu>: |
|
454 "Lang = L (r::rexp) \<Longrightarrow> finite (UNIV // (\<approx>Lang))" |
|
455 proof (induct arbitrary:Lang rule:rexp.induct) |
|
456 case NULL |
|
457 have "UNIV // (\<approx>{}) \<subseteq> {UNIV} " |
|
458 by (auto simp:quotient_def str_eq_rel_def str_eq_def) |
|
459 with prems show "?case" by (auto intro:finite_subset) |
|
460 next |
493 next |
461 case EMPTY |
494 have *: "finite (Pow (UNIV // \<approx>L1))" |
462 have "UNIV // (\<approx>{[]}) \<subseteq> {{[]}, UNIV - {[]}}" |
495 using finite1 by auto |
463 by (rule quot_empty_subset) |
496 show "finite (range (tag_str_STAR L1))" |
464 with prems show ?case by (auto intro:finite_subset) |
497 unfolding tag_str_STAR_def |
465 next |
498 apply(rule finite_subset[OF _ *]) |
466 case (CHAR c) |
499 unfolding quotient_def |
467 have "UNIV // (\<approx>{[c]}) \<subseteq> {{[]},{[c]}, UNIV - {[], [c]}}" |
500 by auto |
468 by (rule quot_char_subset) |
501 qed |
469 with prems show ?case by (auto intro:finite_subset) |
502 |
470 next |
503 |
471 case (SEQ r\<^isub>1 r\<^isub>2) |
504 subsection {* The main lemma *} |
472 have "\<lbrakk>finite (UNIV // \<approx>(L r\<^isub>1)); finite (UNIV // \<approx>(L r\<^isub>2))\<rbrakk> |
505 |
473 \<Longrightarrow> finite (UNIV // \<approx>(L r\<^isub>1 ;; L r\<^isub>2))" |
506 lemma rexp_imp_finite: |
474 by (erule quot_seq_finiteI, simp) |
507 fixes r::"rexp" |
475 with prems show ?case by simp |
508 shows "finite (UNIV // \<approx>(L r))" |
476 next |
509 by (induct r) (auto) |
477 case (ALT r\<^isub>1 r\<^isub>2) |
510 |
478 have "\<lbrakk>finite (UNIV // \<approx>(L r\<^isub>1)); finite (UNIV // \<approx>(L r\<^isub>2))\<rbrakk> |
|
479 \<Longrightarrow> finite (UNIV // \<approx>(L r\<^isub>1 \<union> L r\<^isub>2))" |
|
480 by (erule quot_union_finiteI, simp) |
|
481 with prems show ?case by simp |
|
482 next |
|
483 case (STAR r) |
|
484 have "finite (UNIV // \<approx>(L r)) |
|
485 \<Longrightarrow> finite (UNIV // \<approx>((L r)\<star>))" |
|
486 by (erule quot_star_finiteI) |
|
487 with prems show ?case by simp |
|
488 qed |
|
489 |
511 |
490 end |
512 end |
491 |
513 |