# HG changeset patch # User zhang # Date 1296215531 0 # Node ID 7aa6c20e6d311d94aa0757cb5dcf2e17845c1c39 # Parent 5a7e02dcd3d59d3bb948a99a2210d8b253436b2d More improvement diff -r 5a7e02dcd3d5 -r 7aa6c20e6d31 Myhill.thy --- a/Myhill.thy Thu Jan 27 17:37:20 2011 +0000 +++ b/Myhill.thy Fri Jan 28 11:52:11 2011 +0000 @@ -13,46 +13,51 @@ *} definition - str_eq :: "string \ lang \ string \ bool" ("_ \_ _") + str_eq ("_ \_ _") where "x \Lang y \ (x, y) \ (\Lang)" text {* - The very basic scheme to show the finiteness of the partion generated by a language @{text "Lang"} - is by attaching a tag to every string. The set of tags are carfully choosen to be finite so that - the range of tagging function is finite. If it can be proved that strings with the same tag - are equivlent with respect @{text "Lang"}, then the partition given rise by @{text "Lang"} must be finite. - The detailed argjument for this is formalized by the following lemma @{text "tag_finite_imageD"}. - The basic idea is using lemma @{thm [source] "finite_imageD"} - from standard library: - \[ - @{thm "finite_imageD" [no_vars]} - \] - which says: if the image of injective function @{text "f"} over set @{text "A"} is - finite, then @{text "A"} must be finte. - *} + The basic idea to show the finiteness of the partition induced by relation @{text "\Lang"} + is to attach a tag @{text "tag(x)"} to every string @{text "x"}, the set of tags are carfully + choosen, so that the range of tagging function @{text "tag"} (denoted @{text "range(tag)"}) is finite. + If strings with the same tag are equivlent with respect @{text "\Lang"}, + i.e. @{text "tag(x) = tag(y) \ x \Lang y"} (this property is named `injectivity' in the following), + then it can be proved that: the partition given rise by @{text "(\Lang)"} is finite. + + There are two arguments for this. The first goes as the following: + \begin{enumerate} + \item First, the tagging function @{text "tag"} induces an equivalent relation @{text "(=tag=)"} + (defiintion of @{text "f_eq_rel"} and lemma @{text "equiv_f_eq_rel"}). + \item It is shown that: if the range of @{text "tag"} is finite, + the partition given rise by @{text "(=tag=)"} is finite (lemma @{text "finite_eq_f_rel"}). + \item It is proved that if equivalent relation @{text "R1"} is more refined than @{text "R2"} + (expressed as @{text "R1 \ R2"}), + and the partition induced by @{text "R1"} is finite, then the partition induced by @{text "R2"} + is finite as well (lemma @{text "refined_partition_finite"}). + \item The injectivity assumption @{text "tag(x) = tag(y) \ x \Lang y"} implies that + @{text "(=tag=)"} is more refined than @{text "(\Lang)"}. + \item Combining the points above, we have: the partition induced by language @{text "Lang"} + is finite (lemma @{text "tag_finite_imageD"}). + \end{enumerate} +*} - +definition + f_eq_rel ("=_=") +where + "(=f=) = {(x, y) | x y. f x = f y}" -(* I am trying to reduce the following proof to even simpler principles. But not yet succeed. *) -definition - f_eq_rel ("\_") -where - "\(f::'a \ 'b) = {(x, y) | x y. f x = f y}" - -thm finite.induct +lemma equiv_f_eq_rel:"equiv UNIV (=f=)" + by (auto simp:equiv_def f_eq_rel_def refl_on_def sym_def trans_def) lemma finite_range_image: "finite (range f) \ finite (f ` A)" by (rule_tac B = "{y. \x. y = f x}" in finite_subset, auto simp:image_def) -lemma "equiv UNIV (\f)" - by (auto simp:equiv_def f_eq_rel_def refl_on_def sym_def trans_def) - -lemma +lemma finite_eq_f_rel: assumes rng_fnt: "finite (range tag)" - shows "finite (UNIV // (\tag))" + shows "finite (UNIV // (=tag=))" proof - - let "?f" = "op ` tag" and ?A = "(UNIV // (\tag))" + let "?f" = "op ` tag" and ?A = "(UNIV // (=tag=))" show ?thesis proof (rule_tac f = "?f" and A = ?A in finite_imageD) -- {* @@ -68,7 +73,7 @@ qed next -- {* - The injectivity of @{text "f"}-image is a consequence of the definition of @{text "\tag"} + The injectivity of @{text "f"}-image is a consequence of the definition of @{text "(=tag=)"}: *} show "inj_on ?f ?A" proof- @@ -79,8 +84,10 @@ have "X = Y" proof - from X_in Y_in tag_eq - obtain x y where x_in: "x \ X" and y_in: "y \ Y" and eq_tg: "tag x = tag y" - unfolding quotient_def Image_def str_eq_rel_def str_eq_def image_def f_eq_rel_def + obtain x y + where x_in: "x \ X" and y_in: "y \ Y" and eq_tg: "tag x = tag y" + unfolding quotient_def Image_def str_eq_rel_def + str_eq_def image_def f_eq_rel_def apply simp by blast with X_in Y_in show ?thesis by (auto simp:quotient_def str_eq_rel_def str_eq_def f_eq_rel_def) @@ -90,23 +97,114 @@ qed qed +lemma finite_image_finite: "\\ x \ A. f x \ B; finite B\ \ finite (f ` A)" + by (rule finite_subset [of _ B], auto) -(* -lemma finite_range_image: "finite (range f) \ finite (f ` A)" - by (rule_tac B = "{y. \x. y = f x}" in finite_subset, auto simp:image_def) -*) +lemma refined_partition_finite: + fixes R1 R2 A + assumes fnt: "finite (A // R1)" + and refined: "R1 \ R2" + and eq1: "equiv A R1" and eq2: "equiv A R2" + shows "finite (A // R2)" +proof - + let ?f = "\ X. {R1 `` {x} | x. x \ X}" + and ?A = "(A // R2)" and ?B = "(A // R1)" + show ?thesis + proof(rule_tac f = ?f and A = ?A in finite_imageD) + show "finite (?f ` ?A)" + proof(rule finite_subset [of _ "Pow ?B"]) + from fnt show "finite (Pow (A // R1))" by simp + next + from eq2 + show " ?f ` A // R2 \ Pow ?B" + apply (unfold image_def Pow_def quotient_def, auto) + by (rule_tac x = xb in bexI, simp, + unfold equiv_def sym_def refl_on_def, blast) + qed + next + show "inj_on ?f ?A" + proof - + { fix X Y + assume X_in: "X \ ?A" and Y_in: "Y \ ?A" + and eq_f: "?f X = ?f Y" (is "?L = ?R") + have "X = Y" using X_in + proof(rule quotientE) + fix x + assume "X = R2 `` {x}" and "x \ A" with eq2 + have x_in: "x \ X" + by (unfold equiv_def quotient_def refl_on_def, auto) + with eq_f have "R1 `` {x} \ ?R" by auto + then obtain y where + y_in: "y \ Y" and eq_r: "R1 `` {x} = R1 ``{y}" by auto + have "(x, y) \ R1" + proof - + from x_in X_in y_in Y_in eq2 + have "x \ A" and "y \ A" + by (unfold equiv_def quotient_def refl_on_def, auto) + from eq_equiv_class_iff [OF eq1 this] and eq_r + show ?thesis by simp + qed + with refined have xy_r2: "(x, y) \ R2" by auto + from quotient_eqI [OF eq2 X_in Y_in x_in y_in this] + show ?thesis . + qed + } thus ?thesis by (auto simp:inj_on_def) + qed + qed +qed + +lemma equiv_lang_eq: "equiv UNIV (\Lang)" + apply (unfold equiv_def str_eq_rel_def sym_def refl_on_def trans_def) + by blast lemma tag_finite_imageD: - fixes L :: "lang" + fixes tag assumes rng_fnt: "finite (range tag)" - -- {* Suppose the range of tagging fucntion @{text "tag"} is finite. *} - and same_tag_eqvt: "\ m n. tag m = tag n \ m \L n" + -- {* Suppose the rang of tagging fucntion @{text "tag"} is finite. *} + and same_tag_eqvt: "\ m n. tag m = tag (n::string) \ m \Lang n" -- {* And strings with same tag are equivalent *} - shows "finite (UNIV // \L)" - -- {* Then the partition generated by @{text "\L"} is finite. *} + shows "finite (UNIV // (\Lang))" +proof - + let ?R1 = "(=tag=)" + show ?thesis + proof(rule_tac refined_partition_finite [of _ ?R1]) + from finite_eq_f_rel [OF rng_fnt] + show "finite (UNIV // =tag=)" . + next + from same_tag_eqvt + show "(=tag=) \ (\Lang)" + by (auto simp:f_eq_rel_def str_eq_def) + next + from equiv_f_eq_rel + show "equiv UNIV (=tag=)" by blast + next + from equiv_lang_eq + show "equiv UNIV (\Lang)" by blast + qed +qed + +text {* + A more concise, but less intelligible argument for @{text "tag_finite_imageD"} + is given as the following. The basic idea is still using standard library + lemma @{thm [source] "finite_imageD"}: + \[ + @{thm "finite_imageD" [no_vars]} + \] + which says: if the image of injective function @{text "f"} over set @{text "A"} is + finite, then @{text "A"} must be finte, as we did in the lemmas above. + *} + +lemma + fixes tag + assumes rng_fnt: "finite (range tag)" + -- {* Suppose the rang of tagging fucntion @{text "tag"} is finite. *} + and same_tag_eqvt: "\ m n. tag m = tag (n::string) \ m \Lang n" + -- {* And strings with same tag are equivalent *} + shows "finite (UNIV // (\Lang))" + -- {* Then the partition generated by @{text "(\Lang)"} is finite. *} proof - -- {* The particular @{text "f"} and @{text "A"} used in @{thm [source] "finite_imageD"} are:*} - let "?f" = "op ` tag" and ?A = "(UNIV // \L)" + let "?f" = "op ` tag" and ?A = "(UNIV // \Lang)" show ?thesis proof (rule_tac f = "?f" and A = ?A in finite_imageD) -- {* @@ -136,7 +234,7 @@ obtain x y where x_in: "x \ X" and y_in: "y \ Y" and eq_tg: "tag x = tag y" unfolding quotient_def Image_def str_eq_rel_def str_eq_def image_def apply simp by blast - from same_tag_eqvt [OF eq_tg] have "x \L y" . + from same_tag_eqvt [OF eq_tg] have "x \Lang y" . with X_in Y_in x_in y_in show ?thesis by (auto simp:quotient_def str_eq_rel_def str_eq_def) qed @@ -148,33 +246,18 @@ subsection {* Lemmas for basic cases *} text {* - The the final result of this direction is in @{text "rexp_imp_finite"}, - which is an induction on the structure of regular expressions. There is one - case for each regular expression operator. For basic operators such as - @{const NULL}, @{const EMPTY}, @{const CHAR}, the finiteness of their - language partition can be established directly with no need of tagging. - This section contains several technical lemma for these base cases. - - The inductive cases involve operators @{const ALT}, @{const SEQ} and @{const - STAR}. Tagging functions need to be defined individually for each of - them. There will be one dedicated section for each of these cases, and each - section goes virtually the same way: gives definition of the tagging - function and prove that strings with the same tag are equivalent. -*} + The the final result of this direction is in @{text "easier_direction"}, which + is an induction on the structure of regular expressions. There is one case + for each regular expression operator. For basic operators such as @{text "NULL, EMPTY, CHAR c"}, + the finiteness of their language partition can be established directly with no need + of taggiing. This section contains several technical lemma for these base cases. -subsection {* The case for @{const "NULL"} *} - -lemma quot_null_eq: - shows "(UNIV // \{}) = ({UNIV}::lang set)" - unfolding quotient_def Image_def str_eq_rel_def by auto - -lemma quot_null_finiteI [intro]: - shows "finite ((UNIV // \{})::lang set)" -unfolding quot_null_eq by simp - - -subsection {* The case for @{const "EMPTY"} *} - + The inductive cases involve operators @{text "ALT, SEQ"} and @{text "STAR"}. + Tagging functions need to be defined individually for each of them. There will be one + dedicated section for each of these cases, and each section goes virtually the same way: + gives definition of the tagging function and prove that strings + with the same tag are equivalent. + *} lemma quot_empty_subset: "UNIV // (\{[]}) \ {{[]}, UNIV - {[]}}" @@ -183,25 +266,18 @@ assume "x \ UNIV // \{[]}" then obtain y where h: "x = {z. (y, z) \ \{[]}}" unfolding quotient_def Image_def by blast - show "x \ {{[]}, UNIV - {[]}}" + show "x \ {{[]}, UNIV - {[]}}" proof (cases "y = []") case True with h - have "x = {[]}" by (auto simp: str_eq_rel_def) + have "x = {[]}" by (auto simp:str_eq_rel_def) thus ?thesis by simp next case False with h - have "x = UNIV - {[]}" by (auto simp: str_eq_rel_def) + have "x = UNIV - {[]}" by (auto simp:str_eq_rel_def) thus ?thesis by simp qed qed -lemma quot_empty_finiteI [intro]: - shows "finite (UNIV // (\{[]}))" -by (rule finite_subset[OF quot_empty_subset]) (simp) - - -subsection {* The case for @{const "CHAR"} *} - lemma quot_char_subset: "UNIV // (\{[c]}) \ {{[]},{[c]}, UNIV - {[], [c]}}" proof @@ -227,18 +303,17 @@ qed qed -lemma quot_char_finiteI [intro]: - shows "finite (UNIV // (\{[c]}))" -by (rule finite_subset[OF quot_char_subset]) (simp) - - -subsection {* The case for @{const SEQ}*} +subsection {* The case for @{text "SEQ"}*} definition - tag_str_SEQ :: "lang \ lang \ string \ (lang \ lang set)" -where - "tag_str_SEQ L1 L2 = (\x. (\L1 `` {x}, {(\L2 `` {x - xa}) | xa. xa \ x \ xa \ L1}))" + "tag_str_SEQ L\<^isub>1 L\<^isub>2 x \ + ((\L\<^isub>1) `` {x}, {(\L\<^isub>2) `` {x - xa}| xa. xa \ x \ xa \ L\<^isub>1})" +lemma tag_str_seq_range_finite: + "\finite (UNIV // \L\<^isub>1); finite (UNIV // \L\<^isub>2)\ + \ finite (range (tag_str_SEQ L\<^isub>1 L\<^isub>2))" +apply (rule_tac B = "(UNIV // \L\<^isub>1) \ (Pow (UNIV // \L\<^isub>2))" in finite_subset) +by (auto simp:tag_str_SEQ_def Image_def quotient_def split:if_splits) lemma append_seq_elim: assumes "x @ y \ L\<^isub>1 ;; L\<^isub>2" @@ -306,71 +381,52 @@ qed } thus "tag_str_SEQ L\<^isub>1 L\<^isub>2 m = tag_str_SEQ L\<^isub>1 L\<^isub>2 n \ m \(L\<^isub>1 ;; L\<^isub>2) n" by (auto simp add: str_eq_def str_eq_rel_def) -qed +qed -lemma quot_seq_finiteI [intro]: - fixes L1 L2::"lang" - assumes fin1: "finite (UNIV // \L1)" - and fin2: "finite (UNIV // \L2)" - shows "finite (UNIV // \(L1 ;; L2))" -proof (rule_tac tag = "tag_str_SEQ L1 L2" in tag_finite_imageD) - show "\x y. tag_str_SEQ L1 L2 x = tag_str_SEQ L1 L2 y \ x \(L1 ;; L2) y" - by (rule tag_str_SEQ_injI) -next - have *: "finite ((UNIV // \L1) \ (Pow (UNIV // \L2)))" - using fin1 fin2 by auto - show "finite (range (tag_str_SEQ L1 L2))" - unfolding tag_str_SEQ_def - apply(rule finite_subset[OF _ *]) - unfolding quotient_def - by auto -qed +lemma quot_seq_finiteI: + "\finite (UNIV // \L\<^isub>1); finite (UNIV // \L\<^isub>2)\ + \ finite (UNIV // \(L\<^isub>1 ;; L\<^isub>2))" + apply (rule_tac tag = "tag_str_SEQ L\<^isub>1 L\<^isub>2" in tag_finite_imageD) + by (auto intro:tag_str_SEQ_injI elim:tag_str_seq_range_finite) - -subsection {* The case for @{const ALT} *} +subsection {* The case for @{text "ALT"} *} definition - tag_str_ALT :: "lang \ lang \ string \ (lang \ lang)" -where - "tag_str_ALT L1 L2 = (\x. (\L1 `` {x}, \L2 `` {x}))" - + "tag_str_ALT L\<^isub>1 L\<^isub>2 (x::string) \ ((\L\<^isub>1) `` {x}, (\L\<^isub>2) `` {x})" -lemma quot_union_finiteI [intro]: - fixes L1 L2::"lang" - assumes finite1: "finite (UNIV // \L1)" - and finite2: "finite (UNIV // \L2)" - shows "finite (UNIV // \(L1 \ L2))" -proof (rule_tac tag = "tag_str_ALT L1 L2" in tag_finite_imageD) - show "\x y. tag_str_ALT L1 L2 x = tag_str_ALT L1 L2 y \ x \(L1 \ L2) y" - unfolding tag_str_ALT_def - unfolding str_eq_def - unfolding Image_def - unfolding str_eq_rel_def - by auto +lemma quot_union_finiteI: + assumes finite1: "finite (UNIV // \(L\<^isub>1::string set))" + and finite2: "finite (UNIV // \L\<^isub>2)" + shows "finite (UNIV // \(L\<^isub>1 \ L\<^isub>2))" +proof (rule_tac tag = "tag_str_ALT L\<^isub>1 L\<^isub>2" in tag_finite_imageD) + show "\m n. tag_str_ALT L\<^isub>1 L\<^isub>2 m = tag_str_ALT L\<^isub>1 L\<^isub>2 n \ m \(L\<^isub>1 \ L\<^isub>2) n" + unfolding tag_str_ALT_def str_eq_def Image_def str_eq_rel_def by auto next - have *: "finite ((UNIV // \L1) \ (UNIV // \L2))" - using finite1 finite2 by auto - show "finite (range (tag_str_ALT L1 L2))" - unfolding tag_str_ALT_def - apply(rule finite_subset[OF _ *]) - unfolding quotient_def - by auto + show "finite (range (tag_str_ALT L\<^isub>1 L\<^isub>2))" using finite1 finite2 + apply (rule_tac B = "(UNIV // \L\<^isub>1) \ (UNIV // \L\<^isub>2)" in finite_subset) + by (auto simp:tag_str_ALT_def Image_def quotient_def) qed -subsection {* The case for @{const "STAR"} *} +subsection {* + The case for @{text "STAR"} + *} text {* This turned out to be the trickiest case. - *} (* I will make some illustrations for it. *) + Any string @{text "x"} in language @{text "L\<^isub>1\"}, + can be splited into a prefix @{text "xa \ L\<^isub>1\"} and a suffix @{text "x - xa \ L\<^isub>1"}. + For one such @{text "x"}, there can be many such splits. The tagging of @{text "x"} is then + defined by collecting the @{text "L\<^isub>1"}-state of the suffixes from every possible split. + *} + +(* I will make some illustrations for it. *) definition - tag_str_STAR :: "lang \ string \ lang set" -where - "tag_str_STAR L1 = (\x. {\L1 `` {x - xa} | xa. xa < x \ xa \ L1\})" + "tag_str_STAR L\<^isub>1 x \ {(\L\<^isub>1) `` {x - xa} | xa. xa < x \ xa \ L\<^isub>1\}" - -lemma finite_set_has_max: - "\finite A; A \ {}\ \ (\ max \ A. \ a \ A. f a <= (f max :: nat))" +text {* A technical lemma. *} +lemma finite_set_has_max: "\finite A; A \ {}\ \ + (\ max \ A. \ a \ A. f a <= (f max :: nat))" proof (induct rule:finite.induct) case emptyI thus ?case by simp next @@ -394,24 +450,62 @@ qed qed + +text {* Technical lemma. *} lemma finite_strict_prefix_set: "finite {xa. xa < (x::string)}" apply (induct x rule:rev_induct, simp) apply (subgoal_tac "{xa. xa < xs @ [x]} = {xa. xa < xs} \ {xs}") by (auto simp:strict_prefix_def) +text {* + The following lemma @{text "tag_str_star_range_finite"} establishes the range finiteness + of the tagging function. + *} +lemma tag_str_star_range_finite: + "finite (UNIV // \L\<^isub>1) \ finite (range (tag_str_STAR L\<^isub>1))" +apply (rule_tac B = "Pow (UNIV // \L\<^isub>1)" in finite_subset) +by (auto simp:tag_str_STAR_def Image_def + quotient_def split:if_splits) + +text {* + The following lemma @{text "tag_str_STAR_injI"} establishes the injectivity of + the tagging function for case @{text "STAR"}. + *} + lemma tag_str_STAR_injI: - "tag_str_STAR L\<^isub>1 m = tag_str_STAR L\<^isub>1 n \ m \(L\<^isub>1\) n" + fixes v w + assumes eq_tag: "tag_str_STAR L\<^isub>1 v = tag_str_STAR L\<^isub>1 w" + shows "(v::string) \(L\<^isub>1\) w" proof- + -- {* + \begin{minipage}{0.9\textwidth} + According to the definition of @{text "\Lang"}, + proving @{text "v \(L\<^isub>1\) w"} amounts to + showing: for any string @{text "u"}, + if @{text "v @ u \ (L\<^isub>1\)"} then @{text "w @ u \ (L\<^isub>1\)"} and vice versa. + The reasoning pattern for both directions are the same, as derived + in the following: + \end{minipage} + *} { fix x y z - assume xz_in_star: "x @ z \ L\<^isub>1\" - and tag_xy: "tag_str_STAR L\<^isub>1 x = tag_str_STAR L\<^isub>1 y" + assume xz_in_star: "x @ z \ L\<^isub>1\" + and tag_xy: "tag_str_STAR L\<^isub>1 x = tag_str_STAR L\<^isub>1 y" have "y @ z \ L\<^isub>1\" proof(cases "x = []") + -- {* + The degenerated case when @{text "x"} is a null string is easy to prove: + *} case True with tag_xy have "y = []" by (auto simp:tag_str_STAR_def strict_prefix_def) thus ?thesis using xz_in_star True by simp next + -- {* + \begin{minipage}{0.9\textwidth} + The case when @{text "x"} is not null, and + @{text "x @ z"} is in @{text "L\<^isub>1\"}, + \end{minipage} + *} case False obtain x_max where h1: "x_max < x" @@ -478,36 +572,163 @@ qed with h5 h6 show ?thesis by (drule_tac star_intro1, auto simp:strict_prefix_def elim:prefixE) - qed - } thus "tag_str_STAR L\<^isub>1 m = tag_str_STAR L\<^isub>1 n \ m \(L\<^isub>1\) n" - by (auto simp add:str_eq_def str_eq_rel_def) + qed + } + -- {* By instantiating the reasoning pattern just derived for both directions:*} + from this [OF _ eq_tag] and this [OF _ eq_tag [THEN sym]] + -- {* The thesis is proved as a trival consequence: *} + show ?thesis by (unfold str_eq_def str_eq_rel_def, blast) qed -lemma quot_star_finiteI [intro]: - fixes L1::"lang" - assumes finite1: "finite (UNIV // \L1)" - shows "finite (UNIV // \(L1\))" -proof (rule_tac tag = "tag_str_STAR L1" in tag_finite_imageD) - show "\x y. tag_str_STAR L1 x = tag_str_STAR L1 y \ x \(L1\) y" - by (rule tag_str_STAR_injI) +lemma quot_star_finiteI: + "finite (UNIV // \L\<^isub>1) \ finite (UNIV // \(L\<^isub>1\))" + apply (rule_tac tag = "tag_str_STAR L\<^isub>1" in tag_finite_imageD) + by (auto intro:tag_str_STAR_injI elim:tag_str_star_range_finite) + +subsection {* + The main lemma + *} + +lemma easier_direction: + "Lang = L (r::rexp) \ finite (UNIV // (\Lang))" +proof (induct arbitrary:Lang rule:rexp.induct) + case NULL + have "UNIV // (\{}) \ {UNIV} " + by (auto simp:quotient_def str_eq_rel_def str_eq_def) + with prems show "?case" by (auto intro:finite_subset) +next + case EMPTY + have "UNIV // (\{[]}) \ {{[]}, UNIV - {[]}}" + by (rule quot_empty_subset) + with prems show ?case by (auto intro:finite_subset) next - have *: "finite (Pow (UNIV // \L1))" - using finite1 by auto - show "finite (range (tag_str_STAR L1))" - unfolding tag_str_STAR_def - apply(rule finite_subset[OF _ *]) - unfolding quotient_def - by auto -qed - - -subsection {* The main lemma *} - -lemma rexp_imp_finite: - fixes r::"rexp" - shows "finite (UNIV // \(L r))" -by (induct r) (auto) - + case (CHAR c) + have "UNIV // (\{[c]}) \ {{[]},{[c]}, UNIV - {[], [c]}}" + by (rule quot_char_subset) + with prems show ?case by (auto intro:finite_subset) +next + case (SEQ r\<^isub>1 r\<^isub>2) + have "\finite (UNIV // \(L r\<^isub>1)); finite (UNIV // \(L r\<^isub>2))\ + \ finite (UNIV // \(L r\<^isub>1 ;; L r\<^isub>2))" + by (erule quot_seq_finiteI, simp) + with prems show ?case by simp +next + case (ALT r\<^isub>1 r\<^isub>2) + have "\finite (UNIV // \(L r\<^isub>1)); finite (UNIV // \(L r\<^isub>2))\ + \ finite (UNIV // \(L r\<^isub>1 \ L r\<^isub>2))" + by (erule quot_union_finiteI, simp) + with prems show ?case by simp +next + case (STAR r) + have "finite (UNIV // \(L r)) + \ finite (UNIV // \((L r)\))" + by (erule quot_star_finiteI) + with prems show ?case by simp +qed end +(* +lemma refined_quotient_union_eq: + assumes refined: "R1 \ R2" + and eq1: "equiv A R1" and eq2: "equiv A R2" + and y_in: "y \ A" + shows "\{R1 `` {x} | x. x \ (R2 `` {y})} = R2 `` {y}" +proof + show "\{R1 `` {x} |x. x \ R2 `` {y}} \ R2 `` {y}" (is "?L \ ?R") + proof - + { fix z + assume zl: "z \ ?L" and nzr: "z \ ?R" + have "False" + proof - + from zl and eq1 eq2 and y_in + obtain x where xy2: "(x, y) \ R2" and zx1: "(z, x) \ R1" + by (simp only:equiv_def sym_def, blast) + have "(z, y) \ R2" + proof - + from zx1 and refined have "(z, x) \ R2" by blast + moreover from xy2 have "(x, y) \ R2" . + ultimately show ?thesis using eq2 + by (simp only:equiv_def, unfold trans_def, blast) + qed + with nzr eq2 show ?thesis by (auto simp:equiv_def sym_def) + qed + } thus ?thesis by blast + qed +next + show "R2 `` {y} \ \{R1 `` {x} |x. x \ R2 `` {y}}" (is "?L \ ?R") + proof + fix x + assume x_in: "x \ ?L" + with eq1 eq2 have "x \ R1 `` {x}" + by (unfold equiv_def refl_on_def, auto) + with x_in show "x \ ?R" by auto + qed +qed +*) + +(* +lemma refined_partition_finite: + fixes R1 R2 A + assumes fnt: "finite (A // R1)" + and refined: "R1 \ R2" + and eq1: "equiv A R1" and eq2: "equiv A R2" + shows "finite (A // R2)" +proof - + let ?f = "\ X. {R1 `` {x} | x. x \ X}" + and ?A = "(A // R2)" and ?B = "(A // R1)" + show ?thesis + proof(rule_tac f = ?f and A = ?A in finite_imageD) + show "finite (?f ` ?A)" + proof(rule finite_subset [of _ "Pow ?B"]) + from fnt show "finite (Pow (A // R1))" by simp + next + from eq2 + show " ?f ` A // R2 \ Pow ?B" + apply (unfold image_def Pow_def quotient_def, auto) + by (rule_tac x = xb in bexI, simp, + unfold equiv_def sym_def refl_on_def, blast) + qed + next + show "inj_on ?f ?A" + proof - + { fix X Y + assume X_in: "X \ ?A" and Y_in: "Y \ ?A" + and eq_f: "?f X = ?f Y" (is "?L = ?R") + hence "X = Y" + proof - + from X_in eq2 + obtain x + where x_in: "x \ A" + and eq_x: "X = R2 `` {x}" (is "X = ?X") + by (unfold quotient_def equiv_def refl_on_def, auto) + from Y_in eq2 obtain y + where y_in: "y \ A" + and eq_y: "Y = R2 `` {y}" (is "Y = ?Y") + by (unfold quotient_def equiv_def refl_on_def, auto) + have "?X = ?Y" + proof - + from eq_f have "\ ?L = \ ?R" by auto + moreover have "\ ?L = ?X" + proof - + from eq_x have "\ ?L = \{R1 `` {x} |x. x \ ?X}" by simp + also from refined_quotient_union_eq [OF refined eq1 eq2 x_in] + have "\ = ?X" . + finally show ?thesis . + qed + moreover have "\ ?R = ?Y" + proof - + from eq_y have "\ ?R = \{R1 `` {y} |y. y \ ?Y}" by simp + also from refined_quotient_union_eq [OF refined eq1 eq2 y_in] + have "\ = ?Y" . + finally show ?thesis . + qed + ultimately show ?thesis by simp + qed + with eq_x eq_y show ?thesis by auto + qed + } thus ?thesis by (auto simp:inj_on_def) + qed + qed +qed +*)