diff -r b794db0b79db -r b1258b7d2789 Regular_Set.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Regular_Set.thy Mon Jul 25 13:33:38 2011 +0000 @@ -0,0 +1,348 @@ +(* Author: Tobias Nipkow, Alex Krauss *) + +header "Regular sets" + +theory Regular_Set +imports Main +begin + +type_synonym 'a lang = "'a list set" + +definition conc :: "'a lang \ 'a lang \ 'a lang" (infixr "@@" 75) where +"A @@ B = {xs@ys | xs ys. xs:A & ys:B}" + +overloading lang_pow == "compow :: nat \ 'a lang \ 'a lang" +begin + primrec lang_pow :: "nat \ 'a lang \ 'a lang" where + "lang_pow 0 A = {[]}" | + "lang_pow (Suc n) A = A @@ (lang_pow n A)" +end + +definition star :: "'a lang \ 'a lang" where +"star A = (\n. A ^^ n)" + + + +definition deriv :: "'a \ 'a lang \ 'a lang" +where "deriv x L = { xs. x#xs \ L }" + + +coinductive bisimilar :: "'a list set \ 'a list set \ bool" where +"([] \ K \ [] \ L) + \ (\x. bisimilar (deriv x K) (deriv x L)) + \ bisimilar K L" + + +subsection{* @{term "op @@"} *} + +lemma concI[simp,intro]: "u : A \ v : B \ u@v : A @@ B" +by (auto simp add: conc_def) + +lemma concE[elim]: +assumes "w \ A @@ B" +obtains u v where "u \ A" "v \ B" "w = u@v" +using assms by (auto simp: conc_def) + +lemma conc_mono: "A \ C \ B \ D \ A @@ B \ C @@ D" +by (auto simp: conc_def) + +lemma conc_empty[simp]: shows "{} @@ A = {}" and "A @@ {} = {}" +by auto + +lemma conc_epsilon[simp]: shows "{[]} @@ A = A" and "A @@ {[]} = A" +by (simp_all add:conc_def) + +lemma conc_assoc: "(A @@ B) @@ C = A @@ (B @@ C)" +by (auto elim!: concE) (simp only: append_assoc[symmetric] concI) + +lemma conc_Un_distrib: +shows "A @@ (B \ C) = A @@ B \ A @@ C" +and "(A \ B) @@ C = A @@ C \ B @@ C" +by auto + +lemma conc_UNION_distrib: +shows "A @@ UNION I M = UNION I (%i. A @@ M i)" +and "UNION I M @@ A = UNION I (%i. M i @@ A)" +by auto + + +subsection{* @{term "A ^^ n"} *} + +lemma lang_pow_add: "A ^^ (n + m) = A ^^ n @@ A ^^ m" +by (induct n) (auto simp: conc_assoc) + +lemma lang_pow_empty: "{} ^^ n = (if n = 0 then {[]} else {})" +by (induct n) auto + +lemma lang_pow_empty_Suc[simp]: "({}::'a lang) ^^ Suc n = {}" +by (simp add: lang_pow_empty) + + +lemma length_lang_pow_ub: + "ALL w : A. length w \ k \ w : A^^n \ length w \ k*n" +by(induct n arbitrary: w) (fastsimp simp: conc_def)+ + +lemma length_lang_pow_lb: + "ALL w : A. length w \ k \ w : A^^n \ length w \ k*n" +by(induct n arbitrary: w) (fastsimp simp: conc_def)+ + + +subsection{* @{const star} *} + +lemma star_if_lang_pow[simp]: "w : A ^^ n \ w : star A" +by (auto simp: star_def) + +lemma Nil_in_star[iff]: "[] : star A" +proof (rule star_if_lang_pow) + show "[] : A ^^ 0" by simp +qed + +lemma star_if_lang[simp]: assumes "w : A" shows "w : star A" +proof (rule star_if_lang_pow) + show "w : A ^^ 1" using `w : A` by simp +qed + +lemma append_in_starI[simp]: +assumes "u : star A" and "v : star A" shows "u@v : star A" +proof - + from `u : star A` obtain m where "u : A ^^ m" by (auto simp: star_def) + moreover + from `v : star A` obtain n where "v : A ^^ n" by (auto simp: star_def) + ultimately have "u@v : A ^^ (m+n)" by (simp add: lang_pow_add) + thus ?thesis by simp +qed + +lemma conc_star_star: "star A @@ star A = star A" +by (auto simp: conc_def) + +lemma star_induct[consumes 1, case_names Nil append, induct set: star]: +assumes "w : star A" + and "P []" + and step: "!!u v. u : A \ v : star A \ P v \ P (u@v)" +shows "P w" +proof - + { fix n have "w : A ^^ n \ P w" + by (induct n arbitrary: w) (auto intro: `P []` step star_if_lang_pow) } + with `w : star A` show "P w" by (auto simp: star_def) +qed + +lemma star_empty[simp]: "star {} = {[]}" +by (auto elim: star_induct) + +lemma star_epsilon[simp]: "star {[]} = {[]}" +by (auto elim: star_induct) + +lemma star_idemp[simp]: "star (star A) = star A" +by (auto elim: star_induct) + +lemma star_unfold_left: "star A = A @@ star A \ {[]}" (is "?L = ?R") +proof + show "?L \ ?R" by (rule, erule star_induct) auto +qed auto + +lemma concat_in_star: "set ws \ A \ concat ws : star A" +by (induct ws) simp_all + +lemma in_star_iff_concat: + "w : star A = (EX ws. set ws \ A & w = concat ws)" + (is "_ = (EX ws. ?R w ws)") +proof + assume "w : star A" thus "EX ws. ?R w ws" + proof induct + case Nil have "?R [] []" by simp + thus ?case .. + next + case (append u v) + moreover + then obtain ws where "set ws \ A \ v = concat ws" by blast + ultimately have "?R (u@v) (u#ws)" by auto + thus ?case .. + qed +next + assume "EX us. ?R w us" thus "w : star A" + by (auto simp: concat_in_star) +qed + +lemma star_conv_concat: "star A = {concat ws|ws. set ws \ A}" +by (fastsimp simp: in_star_iff_concat) + +lemma star_insert_eps[simp]: "star (insert [] A) = star(A)" +proof- + { fix us + have "set us \ insert [] A \ EX vs. concat us = concat vs \ set vs \ A" + (is "?P \ EX vs. ?Q vs") + proof + let ?vs = "filter (%u. u \ []) us" + show "?P \ ?Q ?vs" by (induct us) auto + qed + } thus ?thesis by (auto simp: star_conv_concat) +qed + +lemma Arden: +assumes "[] \ A" and "X = A @@ X \ B" +shows "X = star A @@ B" +proof - + { fix n have "X = A^^(n+1)@@X \ (\i\n. A^^i@@B)" + proof(induct n) + case 0 show ?case using `X = A @@ X \ B` by simp + next + case (Suc n) + have "X = A@@X Un B" by(rule assms(2)) + also have "\ = A@@(A^^(n+1)@@X \ (\i\n. A^^i@@B)) Un B" + by(subst Suc)(rule refl) + also have "\ = A^^(n+2)@@X \ (\i\n. A^^(i+1)@@B) Un B" + by(simp add:conc_UNION_distrib conc_assoc conc_Un_distrib) + also have "\ = A^^(n+2)@@X \ (UN i : {1..n+1}. A^^i@@B) \ B" + by(subst UN_le_add_shift)(rule refl) + also have "\ = A^^(n+2)@@X \ (UN i : {1..n+1}. A^^i@@B) \ A^^0@@B" + by(simp) + also have "\ = A^^(n+2)@@X \ (\i\n+1. A^^i@@B)" + by(auto simp: UN_le_eq_Un0) + finally show ?case by simp + qed + } note 1 = this + { fix w assume "w : X" + let ?n = "size w" + from `[] \ A` have "ALL u : A. length u \ 1" + by (metis Suc_eq_plus1 add_leD2 le_0_eq length_0_conv not_less_eq_eq) + hence "ALL u : A^^(?n+1). length u \ ?n+1" + by (metis length_lang_pow_lb nat_mult_1) + hence "ALL u : A^^(?n+1)@@X. length u \ ?n+1" + by(auto simp only: conc_def length_append) + hence "w \ A^^(?n+1)@@X" by auto + hence "w : star A @@ B" using `w : X` 1[of ?n] + by(auto simp add: star_def conc_UNION_distrib) + } moreover + { fix w assume "w : star A @@ B" + hence "EX n. w : A^^n @@ B" by(auto simp: conc_def star_def) + hence "w : X" using 1 by blast + } ultimately show ?thesis by blast +qed + +subsection{* @{const deriv} *} + +lemma deriv_empty[simp]: "deriv a {} = {}" +and deriv_epsilon[simp]: "deriv a {[]} = {}" +and deriv_char[simp]: "deriv a {[b]} = (if a = b then {[]} else {})" +and deriv_union[simp]: "deriv a (A \ B) = deriv a A \ deriv a B" +by (auto simp: deriv_def) + +lemma deriv_conc_subset: +"deriv a A @@ B \ deriv a (A @@ B)" (is "?L \ ?R") +proof + fix w assume "w \ ?L" + then obtain u v where "w = u @ v" "a # u \ A" "v \ B" + by (auto simp: deriv_def) + then have "a # w \ A @@ B" + by (auto intro: concI[of "a # u", simplified]) + thus "w \ ?R" by (auto simp: deriv_def) +qed + +lemma deriv_conc1: +assumes "[] \ A" +shows "deriv a (A @@ B) = deriv a A @@ B" (is "?L = ?R") +proof + show "?L \ ?R" + proof + fix w assume "w \ ?L" + then have "a # w \ A @@ B" by (simp add: deriv_def) + then obtain x y + where aw: "a # w = x @ y" "x \ A" "y \ B" by auto + with `[] \ A` obtain x' where "x = a # x'" + by (cases x) auto + with aw have "w = x' @ y" "x' \ deriv a A" + by (auto simp: deriv_def) + with `y \ B` show "w \ ?R" by simp + qed + show "?R \ ?L" by (fact deriv_conc_subset) +qed + +lemma deriv_conc2: +assumes "[] \ A" +shows "deriv a (A @@ B) = deriv a A @@ B \ deriv a B" +(is "?L = ?R") +proof + show "?L \ ?R" + proof + fix w assume "w \ ?L" + then have "a # w \ A @@ B" by (simp add: deriv_def) + then obtain x y + where aw: "a # w = x @ y" "x \ A" "y \ B" by auto + show "w \ ?R" + proof (cases x) + case Nil + with aw have "w \ deriv a B" by (auto simp: deriv_def) + thus ?thesis .. + next + case (Cons b x') + with aw have "w = x' @ y" "x' \ deriv a A" + by (auto simp: deriv_def) + with `y \ B` show "w \ ?R" by simp + qed + qed + + from concI[OF `[] \ A`, simplified] + have "B \ A @@ B" .. + then have "deriv a B \ deriv a (A @@ B)" by (auto simp: deriv_def) + with deriv_conc_subset[of a A B] + show "?R \ ?L" by auto +qed + +lemma wlog_no_eps: +assumes PB: "\B. [] \ B \ P B" +assumes preserved: "\A. P A \ P (insert [] A)" +shows "P A" +proof - + let ?B = "A - {[]}" + have "P ?B" by (rule PB) auto + thus "P A" + proof cases + assume "[] \ A" + then have "(insert [] ?B) = A" by auto + with preserved[OF `P ?B`] + show ?thesis by simp + qed auto +qed + +lemma deriv_insert_eps[simp]: +"deriv a (insert [] A) = deriv a A" +by (auto simp: deriv_def) + +lemma deriv_star[simp]: "deriv a (star A) = deriv a A @@ star A" +proof (induct A rule: wlog_no_eps) + fix B :: "'a list set" assume "[] \ B" + thus "deriv a (star B) = deriv a B @@ star B" + by (subst star_unfold_left) (simp add: deriv_conc1) +qed auto + + +subsection{* @{const bisimilar} *} + +lemma equal_if_bisimilar: +assumes "bisimilar K L" shows "K = L" +proof (rule set_eqI) + fix w + from `bisimilar K L` show "w \ K \ w \ L" + proof (induct w arbitrary: K L) + case Nil thus ?case by (auto elim: bisimilar.cases) + next + case (Cons a w K L) + from `bisimilar K L` have "bisimilar (deriv a K) (deriv a L)" + by (auto elim: bisimilar.cases) + then have "w \ deriv a K \ w \ deriv a L" by (rule Cons(1)) + thus ?case by (auto simp: deriv_def) + qed +qed + +lemma language_coinduct: +fixes R (infixl "\" 50) +assumes "K \ L" +assumes "\K L. K \ L \ ([] \ K \ [] \ L)" +assumes "\K L x. K \ L \ deriv x K \ deriv x L" +shows "K = L" +apply (rule equal_if_bisimilar) +apply (rule bisimilar.coinduct[of R, OF `K \ L`]) +apply (auto simp: assms) +done + +end