# HG changeset patch # User urbanc # Date 1296406797 0 # Node ID 32bff8310071469ffbc758045526b3bd0cde9279 # Parent 59936c012addbc9c838bcdf55363662f9eac618d revised proof of Ardens lemma diff -r 59936c012add -r 32bff8310071 Myhill_1.thy --- a/Myhill_1.thy Sun Jan 30 12:22:07 2011 +0000 +++ b/Myhill_1.thy Sun Jan 30 16:59:57 2011 +0000 @@ -32,11 +32,14 @@ Sequential composition of two languages @{text "L1"} and @{text "L2"} *} -definition Seq :: "lang \ lang \ lang" ("_ ;; _" [100,100] 100) +definition Seq :: "lang \ lang \ lang" (infixr ";;" 100) where "L1 ;; L2 = {s1 @ s2 | s1 s2. s1 \ L1 \ s2 \ L2}" -text {* Transitive closure of language @{text "L"}. *} +text {* + Transitive closure of language @{text "L"}. +*} + inductive_set Star :: "lang \ lang" ("_\" [101] 102) for L @@ -44,23 +47,35 @@ start[intro]: "[] \ L\" | step[intro]: "\s1 \ L; s2 \ L\\ \ s1@s2 \ L\" -text {* Some properties of operator @{text ";;"}.*} +text {* Some properties of operator @{text ";;"}. *} -lemma seq_union_distrib: - "(A \ B) ;; C = (A ;; C) \ (B ;; C)" -by (auto simp:Seq_def) +lemma seq_union_distrib_right: + shows "(A \ B) ;; C = (A ;; C) \ (B ;; C)" +unfolding Seq_def by auto + +lemma seq_union_distrib_left: + shows "C ;; (A \ B) = (C ;; A) \ (C ;; B)" +unfolding Seq_def by auto lemma seq_intro: "\x \ A; y \ B\ \ x @ y \ A ;; B " by (auto simp:Seq_def) lemma seq_assoc: - "(A ;; B) ;; C = A ;; (B ;; C)" -apply(auto simp:Seq_def) -apply blast + shows "(A ;; B) ;; C = A ;; (B ;; C)" +unfolding Seq_def +apply(auto) +apply(blast) by (metis append_assoc) -lemma star_intro1[rule_format]: "x \ lang\ \ \ y. y \ lang\ \ x @ y \ lang\" +lemma seq_empty [simp]: + shows "A ;; {[]} = A" + and "{[]} ;; A = A" +by (simp_all add: Seq_def) + + +lemma star_intro1[rule_format]: + "x \ lang\ \ \ y. y \ lang\ \ x @ y \ lang\" by (erule Star.induct, auto) lemma star_intro2: "y \ lang \ y \ lang\" @@ -74,13 +89,176 @@ "\x \ lang\; x \ []\ \(\ a b. x = a @ b \ a \ [] \ a \ lang \ b \ lang\)" by (induct x rule: Star.induct, simp, blast) -lemma star_decom': - "\x \ lang\; x \ []\ \ \a b. x = a @ b \ a \ lang\ \ b \ lang" -apply (induct x rule:Star.induct, simp) -apply (case_tac "s2 = []") -apply (rule_tac x = "[]" in exI, rule_tac x = s1 in exI, simp add:start) -apply (simp, (erule exE| erule conjE)+) -by (rule_tac x = "s1 @ a" in exI, rule_tac x = b in exI, simp add:step) +lemma lang_star_cases: + shows "L\ = {[]} \ L ;; L\" +proof + { fix x + have "x \ L\ \ x \ {[]} \ L ;; L\" + unfolding Seq_def + by (induct rule: Star.induct) (auto) + } + then show "L\ \ {[]} \ L ;; L\" by auto +next + show "{[]} \ L ;; L\ \ L\" + unfolding Seq_def by auto +qed + +fun + pow :: "lang \ nat \ lang" (infixl "\" 100) +where + "A \ 0 = {[]}" +| "A \ (Suc n) = A ;; (A \ n)" + +lemma star_pow_eq: + shows "A\ = (\n. A \ n)" +proof - + { fix n x + assume "x \ (A \ n)" + then have "x \ A\" + by (induct n arbitrary: x) (auto simp add: Seq_def) + } + moreover + { fix x + assume "x \ A\" + then have "\n. x \ A \ n" + proof (induct rule: Star.induct) + case start + have "[] \ A \ 0" by auto + then show "\n. [] \ A \ n" by blast + next + case (step s1 s2) + have "s1 \ A" by fact + moreover + have "\n. s2 \ A \ n" by fact + then obtain n where "s2 \ A \ n" by blast + ultimately + have "s1 @ s2 \ A \ (Suc n)" by (auto simp add: Seq_def) + then show "\n. s1 @ s2 \ A \ n" by blast + qed + } + ultimately show "A\ = (\n. A \ n)" by auto +qed + +lemma + shows seq_Union_left: "B ;; (\n. A \ n) = (\n. B ;; (A \ n))" + and seq_Union_right: "(\n. A \ n) ;; B = (\n. (A \ n) ;; B)" +unfolding Seq_def by auto + +lemma seq_pow_comm: + shows "A ;; (A \ n) = (A \ n) ;; A" +by (induct n) (simp_all add: seq_assoc[symmetric]) + +lemma seq_star_comm: + shows "A ;; A\ = A\ ;; A" +unfolding star_pow_eq +unfolding seq_Union_left +unfolding seq_pow_comm +unfolding seq_Union_right +by simp + +text {* Two lemmas about the length of strings in @{text "A \ n"} *} + +lemma pow_length: + assumes a: "[] \ A" + and b: "s \ A \ Suc n" + shows "n < length s" +using b +proof (induct n arbitrary: s) + case 0 + have "s \ A \ Suc 0" by fact + with a have "s \ []" by auto + then show "0 < length s" by auto +next + case (Suc n) + have ih: "\s. s \ A \ Suc n \ n < length s" by fact + have "s \ A \ Suc (Suc n)" by fact + then obtain s1 s2 where eq: "s = s1 @ s2" and *: "s1 \ A" and **: "s2 \ A \ Suc n" + by (auto simp add: Seq_def) + from ih ** have "n < length s2" by simp + moreover have "0 < length s1" using * a by auto + ultimately show "Suc n < length s" unfolding eq + by (simp only: length_append) +qed + +lemma seq_pow_length: + assumes a: "[] \ A" + and b: "s \ B ;; (A \ Suc n)" + shows "n < length s" +proof - + from b obtain s1 s2 where eq: "s = s1 @ s2" and *: "s2 \ A \ Suc n" + unfolding Seq_def by auto + from * have " n < length s2" by (rule pow_length[OF a]) + then show "n < length s" using eq by simp +qed + + +section {* A slightly modified version of Arden's lemma *} + +text {* + Arden's lemma expressed at the level of languages, rather + than the level of regular expression. +*} + + +lemma ardens_helper: + assumes eq: "X = X ;; A \ B" + shows "X = X ;; (A \ Suc n) \ (\m\{0..n}. B ;; (A \ m))" +proof (induct n) + case 0 + show "X = X ;; (A \ Suc 0) \ (\(m::nat)\{0..0}. B ;; (A \ m))" + using eq by simp +next + case (Suc n) + have ih: "X = X ;; (A \ Suc n) \ (\m\{0..n}. B ;; (A \ m))" by fact + also have "\ = (X ;; A \ B) ;; (A \ Suc n) \ (\m\{0..n}. B ;; (A \ m))" using eq by simp + also have "\ = X ;; (A \ Suc (Suc n)) \ (B ;; (A \ Suc n)) \ (\m\{0..n}. B ;; (A \ m))" + by (simp add: seq_union_distrib_right seq_assoc) + also have "\ = X ;; (A \ Suc (Suc n)) \ (\m\{0..Suc n}. B ;; (A \ m))" + by (auto simp add: le_Suc_eq) + finally show "X = X ;; (A \ Suc (Suc n)) \ (\m\{0..Suc n}. B ;; (A \ m))" . +qed + +theorem ardens_revised: + assumes nemp: "[] \ A" + shows "X = X ;; A \ B \ X = B ;; A\" +proof + assume eq: "X = B ;; A\" + have "A\ = {[]} \ A\ ;; A" + unfolding seq_star_comm[symmetric] + by (rule lang_star_cases) + then have "B ;; A\ = B ;; ({[]} \ A\ ;; A)" + unfolding Seq_def by simp + also have "\ = B \ B ;; (A\ ;; A)" + unfolding seq_union_distrib_left by simp + also have "\ = B \ (B ;; A\) ;; A" + by (simp only: seq_assoc) + finally show "X = X ;; A \ B" + using eq by blast +next + assume eq: "X = X ;; A \ B" + { fix n::nat + have "B ;; (A \ n) \ X" using ardens_helper[OF eq, of "n"] by auto } + then have "B ;; A\ \ X" unfolding star_pow_eq Seq_def + by (auto simp add: UNION_def) + moreover + { fix s::string + obtain k where "k = length s" by auto + then have not_in: "s \ X ;; (A \ Suc k)" + using seq_pow_length[OF nemp] by blast + assume "s \ X" + then have "s \ X ;; (A \ Suc k) \ (\m\{0..k}. B ;; (A \ m))" + using ardens_helper[OF eq, of "k"] by auto + then have "s \ (\m\{0..k}. B ;; (A \ m))" using not_in by auto + moreover + have "(\m\{0..k}. B ;; (A \ m)) \ (\n. B ;; (A \ n))" by auto + ultimately + have "s \ B ;; A\" unfolding star_pow_eq seq_Union_left + by auto } + then have "X \ B ;; A\" by auto + ultimately + show "X = B ;; A\" by simp +qed + text {* The syntax of regular expressions is defined by the datatype @{text "rexp"}. *} @@ -117,6 +295,29 @@ | "L_rexp (STAR r) = (L_rexp r)\" end +text {* + To obtain equational system out of finite set of equivalent classes, a fold operation + on finite set @{text "folds"} is defined. The use of @{text "SOME"} makes @{text "fold"} + more robust than the @{text "fold"} in Isabelle library. The expression @{text "folds f"} + makes sense when @{text "f"} is not @{text "associative"} and @{text "commutitive"}, + while @{text "fold f"} does not. +*} + +definition + folds :: "('a \ 'b \ 'b) \ 'b \ 'a set \ 'b" +where + "folds f z S \ SOME x. fold_graph f z S x" + +text {* + The following lemma assures that the arbitrary choice made by the @{text "SOME"} in @{text "folds"} + does not affect the @{text "L"}-value of the resultant regular expression. + *} +lemma folds_alt_simp [simp]: + "finite rs \ L (folds ALT NULL rs) = \ (L ` rs)" +apply (rule set_eq_intro, simp add:folds_def) +apply (rule someI2_ex, erule finite_imp_fold_graph) +by (erule fold_graph.induct, auto) + (* Just a technical lemma. *) lemma [simp]: shows "(x, y) \ {(x, y). P x y} \ P x y" @@ -160,98 +361,6 @@ section {* Direction @{text "finite partition \ regular language"}*} -subsection {* - Ardens lemma - *} -text {* Ardens lemma expressed at the level of language, rather than the level of regular expression. *} - -theorem ardens_revised: - assumes nemp: "[] \ A" - shows "(X = X ;; A \ B) \ (X = B ;; A\)" -proof - assume eq: "X = B ;; A\" - have "A\ = {[]} \ A\ ;; A" - by (auto simp:Seq_def star_intro3 star_decom') - then have "B ;; A\ = B ;; ({[]} \ A\ ;; A)" - unfolding Seq_def by simp - also have "\ = B \ B ;; (A\ ;; A)" - unfolding Seq_def by auto - also have "\ = B \ (B ;; A\) ;; A" - by (simp only:seq_assoc) - finally show "X = X ;; A \ B" - using eq by blast -next - assume eq': "X = X ;; A \ B" - hence c1': "\ x. x \ B \ x \ X" - and c2': "\ x y. \x \ X; y \ A\ \ x @ y \ X" - using Seq_def by auto - show "X = B ;; A\" - proof - show "B ;; A\ \ X" - proof- - { fix x y - have "\y \ A\; x \ X\ \ x @ y \ X " - apply (induct arbitrary:x rule:Star.induct, simp) - by (auto simp only:append_assoc[THEN sym] dest:c2') - } thus ?thesis using c1' by (auto simp:Seq_def) - qed - next - show "X \ B ;; A\" - proof- - { fix x - have "x \ X \ x \ B ;; A\" - proof (induct x taking:length rule:measure_induct) - fix z - assume hyps: - "\y. length y < length z \ y \ X \ y \ B ;; A\" - and z_in: "z \ X" - show "z \ B ;; A\" - proof (cases "z \ B") - case True thus ?thesis by (auto simp:Seq_def start) - next - case False hence "z \ X ;; A" using eq' z_in by auto - then obtain za zb where za_in: "za \ X" - and zab: "z = za @ zb \ zb \ A" and zbne: "zb \ []" - using nemp unfolding Seq_def by blast - from zbne zab have "length za < length z" by auto - with za_in hyps have "za \ B ;; A\" by blast - hence "za @ zb \ B ;; A\" using zab - by (clarsimp simp:Seq_def, blast dest:star_intro3) - thus ?thesis using zab by simp - qed - qed - } thus ?thesis by blast - qed - qed -qed - -subsection {* - Defintions peculiar to this direction - *} - -text {* - To obtain equational system out of finite set of equivalent classes, a fold operation - on finite set @{text "folds"} is defined. The use of @{text "SOME"} makes @{text "fold"} - more robust than the @{text "fold"} in Isabelle library. The expression @{text "folds f"} - makes sense when @{text "f"} is not @{text "associative"} and @{text "commutitive"}, - while @{text "fold f"} does not. -*} - -definition - folds :: "('a \ 'b \ 'b) \ 'b \ 'a set \ 'b" -where - "folds f z S \ SOME x. fold_graph f z S x" - -text {* - The following lemma assures that the arbitrary choice made by the @{text "SOME"} in @{text "folds"} - does not affect the @{text "L"}-value of the resultant regular expression. - *} -lemma folds_alt_simp [simp]: - "finite rs \ L (folds ALT NULL rs) = \ (L ` rs)" -apply (rule set_eq_intro, simp add:folds_def) -apply (rule someI2_ex, erule finite_imp_fold_graph) -by (erule fold_graph.induct, auto) - text {* The relationship between equivalent classes can be described by an equational system. @@ -756,7 +865,7 @@ qed moreover have "L (arden_variate X rhs) = (B ;; A\)" (is "?L = ?R") by (simp only:arden_variate_def L_rhs_union_distrib lang_of_append_rhs - B_def A_def b_def L_rexp.simps seq_union_distrib) + B_def A_def b_def L_rexp.simps seq_union_distrib_left) ultimately show ?thesis by simp qed diff -r 59936c012add -r 32bff8310071 Paper/Paper.thy --- a/Paper/Paper.thy Sun Jan 30 12:22:07 2011 +0000 +++ b/Paper/Paper.thy Sun Jan 30 16:59:57 2011 +0000 @@ -6,7 +6,11 @@ declare [[show_question_marks = false]] notation (latex output) - str_eq_rel ("\\<^bsub>_\<^esub>") + str_eq_rel ("\\<^bsub>_\<^esub>") and + Seq (infixr "\" 100) and + Star ("_\<^bsup>\\<^esup>") and + pow ("_\<^bsup>_\<^esup>" [100, 100] 100) and + Suc ("_+1" [100] 100) (*>*) @@ -16,6 +20,45 @@ *} +section {* Preliminaries *} + +text {* + A central technique in our proof is the solution of equational systems + involving regular expressions. For this we will use the following ``reverse'' + version of Arden's lemma. + + \begin{lemma}[Reverse Arden's Lemma]\mbox{}\\ + If @{thm (prem 1) ardens_revised} then + @{thm (lhs) ardens_revised} has the unique solution + @{thm (rhs) ardens_revised}. + \end{lemma} + + \begin{proof} + For right-to-left direction we assume @{thm (rhs) ardens_revised} and show + @{thm (lhs) ardens_revised}. From Lemma ??? we have @{term "A\ = {[]} \ A ;; A\"}, + which is equal to @{term "A\ = {[]} \ A\ ;; A"}. Adding @{text B} to both + sides gives @{term "B ;; A\ = B ;; ({[]} \ A\ ;; A)"}, whose right-hand side + is @{term "B \ (B ;; A\) ;; A"}. This completes this direction. + + For the other direction we assume @{thm (lhs) ardens_revised}. By a simple induction + on @{text n}, we can show the property + + \begin{center} + @{text "(*)"}\hspace{5mm} @{thm (concl) ardens_helper} + \end{center} + + \noindent + Using this property we can show that @{term "B ;; (A \ n) \ X"} holds for + all @{text n}. From this we can infer @{term "B ;; A\ \ X"} using Lemma ???. + The inclusion in the other direction we establishing by assuming a string @{text s} + with length @{text k} is element in @{text X}. Since @{thm (prem 1) ardens_revised} + we know that @{term "s \ X ;; (A \ Suc k)"} as its length is only @{text k}. + From @{text "(*)"} it follows that + @{term s} must be element in @{term "(\m\{0..k}. B ;; (A \ m))"}. This in turn + implies that @{term s} is in @{term "(\n. B ;; (A \ n))"}. Using Lemma ??? this + is equal to @{term "B ;; A\"}, as we needed to show.\qed + \end{proof} +*} section {* Regular expressions have finitely many partitions *} @@ -27,7 +70,7 @@ \begin{proof} By induction on the structure of @{text r}. The cases for @{const NULL}, @{const EMPTY} - and @{const CHAR} are starightforward, because we can easily establish + and @{const CHAR} are straightforward, because we can easily establish \begin{center} \begin{tabular}{l} diff -r 59936c012add -r 32bff8310071 tphols-2011/myhill.pdf Binary file tphols-2011/myhill.pdf has changed