diff -r b794db0b79db -r b1258b7d2789 MyhillNerode.thy --- a/MyhillNerode.thy Fri Jun 03 13:59:21 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1816 +0,0 @@ -theory MyhillNerode - imports "Main" "List_Prefix" -begin - -text {* sequential composition of languages *} - -definition - lang_seq :: "string set \ string set \ string set" ("_ ; _" [100,100] 100) -where - "L1 ; L2 = {s1 @ s2 | s1 s2. s1 \ L1 \ s2 \ L2}" - -lemma lang_seq_empty: - shows "{[]} ; L = L" - and "L ; {[]} = L" -unfolding lang_seq_def by auto - -lemma lang_seq_null: - shows "{} ; L = {}" - and "L ; {} = {}" -unfolding lang_seq_def by auto - -lemma lang_seq_append: - assumes a: "s1 \ L1" - and b: "s2 \ L2" - shows "s1@s2 \ L1 ; L2" -unfolding lang_seq_def -using a b by auto - -lemma lang_seq_union: - shows "(L1 \ L2); L3 = (L1; L3) \ (L2; L3)" - and "L1; (L2 \ L3) = (L1; L2) \ (L1; L3)" -unfolding lang_seq_def by auto - -lemma lang_seq_assoc: - shows "(L1 ; L2) ; L3 = L1 ; (L2 ; L3)" -unfolding lang_seq_def -apply(auto) -apply(metis) -by (metis append_assoc) - - -section {* Kleene star for languages defined as least fixed point *} - -inductive_set - Star :: "string set \ string set" ("_\" [101] 102) - for L :: "string set" -where - start[intro]: "[] \ L\" -| step[intro]: "\s1 \ L; s2 \ L\\ \ s1@s2 \ L\" - -lemma lang_star_empty: - shows "{}\ = {[]}" -by (auto elim: Star.cases) - -lemma lang_star_cases: - shows "L\ = {[]} \ L ; L\" -proof - { fix x - have "x \ L\ \ x \ {[]} \ L ; L\" - unfolding lang_seq_def - by (induct rule: Star.induct) (auto) - } - then show "L\ \ {[]} \ L ; L\" by auto -next - show "{[]} \ L ; L\ \ L\" - unfolding lang_seq_def by auto -qed - -lemma lang_star_cases': - shows "L\ = {[]} \ L\ ; L" -proof - { fix x - have "x \ L\ \ x \ {[]} \ L\ ; L" - unfolding lang_seq_def - apply (induct rule: Star.induct) - apply simp - apply simp - apply (erule disjE) - apply (auto)[1] - apply (erule exE | erule conjE)+ - apply (rule disjI2) - apply (rule_tac x = "s1 @ s1a" in exI) - by auto - } - then show "L\ \ {[]} \ L\ ; L" by auto -next - show "{[]} \ L\ ; L \ L\" - unfolding lang_seq_def - apply auto - apply (erule Star.induct) - apply auto - apply (drule step[of _ _ "[]"]) - by (auto intro:start) -qed - -lemma lang_star_simple: - shows "L \ L\" -by (subst lang_star_cases) - (auto simp only: lang_seq_def) - -lemma lang_star_prop0_aux: - "s2 \ L\ \ \ s1. s1 \ L \ (\ s3 s4. s3 \ L\ \ s4 \ L \ s1 @ s2 = s3 @ s4)" -apply (erule Star.induct) -apply (clarify, rule_tac x = "[]" in exI, rule_tac x = s1 in exI, simp add:start) -apply (clarify, drule_tac x = s1 in spec) -apply (drule mp, simp, clarify) -apply (rule_tac x = "s1a @ s3" in exI, rule_tac x = s4 in exI) -by auto - -lemma lang_star_prop0: - "\s1 \ L; s2 \ L\\ \ \ s3 s4. s3 \ L\ \ s4 \ L \ s1 @ s2 = s3 @ s4" -by (auto dest:lang_star_prop0_aux) - -lemma lang_star_prop1: - assumes asm: "L1; L2 \ L2" - shows "L1\; L2 \ L2" -proof - - { fix s1 s2 - assume minor: "s2 \ L2" - assume major: "s1 \ L1\" - then have "s1@s2 \ L2" - proof(induct rule: Star.induct) - case start - show "[]@s2 \ L2" using minor by simp - next - case (step s1 s1') - have "s1 \ L1" by fact - moreover - have "s1'@s2 \ L2" by fact - ultimately have "s1@(s1'@s2) \ L1; L2" by (auto simp add: lang_seq_def) - with asm have "s1@(s1'@s2) \ L2" by auto - then show "(s1@s1')@s2 \ L2" by simp - qed - } - then show "L1\; L2 \ L2" by (auto simp add: lang_seq_def) -qed - -lemma lang_star_prop2_aux: - "s2 \ L2\ \ \ s1. s1 \ L1 \ L1 ; L2 \ L1 \ s1 @ s2 \ L1" -apply (erule Star.induct, simp) -apply (clarify, drule_tac x = "s1a @ s1" in spec) -by (auto simp:lang_seq_def) - -lemma lang_star_prop2: - "L1; L2 \ L1 \ L1 ; L2\ \ L1" -by (auto dest!:lang_star_prop2_aux simp:lang_seq_def) - -lemma lang_star_seq_subseteq: - shows "L ; L\ \ L\" -using lang_star_cases by blast - -lemma lang_star_double: - shows "L\; L\ = L\" -proof - show "L\ ; L\ \ L\" - using lang_star_prop1 lang_star_seq_subseteq by blast -next - have "L\ \ L\ \ L\; (L; L\)" by auto - also have "\ = L\;{[]} \ L\; (L; L\)" by (simp add: lang_seq_empty) - also have "\ = L\; ({[]} \ L; L\)" by (simp only: lang_seq_union) - also have "\ = L\; L\" using lang_star_cases by simp - finally show "L\ \ L\ ; L\" by simp -qed - -lemma lang_star_seq_subseteq': - shows "L\; L \ L\" -proof - - have "L \ L\" by (rule lang_star_simple) - then have "L\; L \ L\; L\" by (auto simp add: lang_seq_def) - then show "L\; L \ L\" using lang_star_double by blast -qed - -lemma - shows "L\ \ L\\" -by (rule lang_star_simple) - - -section {* regular expressions *} - -datatype rexp = - NULL -| EMPTY -| CHAR char -| SEQ rexp rexp -| ALT rexp rexp -| STAR rexp - - -consts L:: "'a \ string set" - -overloading L_rexp \ "L:: rexp \ string set" -begin -fun - L_rexp :: "rexp \ string set" -where - "L_rexp (NULL) = {}" - | "L_rexp (EMPTY) = {[]}" - | "L_rexp (CHAR c) = {[c]}" - | "L_rexp (SEQ r1 r2) = (L_rexp r1) ; (L_rexp r2)" - | "L_rexp (ALT r1 r2) = (L_rexp r1) \ (L_rexp r2)" - | "L_rexp (STAR r) = (L_rexp r)\" -end - - -text{* ************ now is the codes writen by chunhan ************************************* *} - -section {* Arden's Lemma revised *} - -lemma arden_aux1: - assumes a: "X \ X ; A \ B" - and b: "[] \ A" - shows "x \ X \ x \ B ; A\" -apply (induct x taking:length rule:measure_induct) -apply (subgoal_tac "x \ X ; A \ B") -defer -using a -apply (auto)[1] -apply simp -apply (erule disjE) -defer -apply (auto simp add:lang_seq_def) [1] -apply (subgoal_tac "\ x1 x2. x = x1 @ x2 \ x1 \ X \ x2 \ A") -defer -apply (auto simp add:lang_seq_def) [1] -apply (erule exE | erule conjE)+ -apply simp -apply (drule_tac x = x1 in spec) -apply (simp) -using b -apply - -apply (auto)[1] -apply (subgoal_tac "x1 @ x2 \ (B ; A\) ; A") -defer -apply (auto simp add:lang_seq_def)[1] -by (metis Un_absorb1 lang_seq_assoc lang_seq_union(2) lang_star_double lang_star_simple mem_def sup1CI) - -theorem ardens_revised: - assumes nemp: "[] \ A" - shows "(X = X ; A \ B) \ (X = B ; A\)" -apply(rule iffI) -defer -apply(simp) -apply(subst lang_star_cases') -apply(subst lang_seq_union) -apply(simp add: lang_seq_empty) -apply(simp add: lang_seq_assoc) -apply(auto)[1] -proof - - assume "X = X ; A \ B" - then have as1: "X ; A \ B \ X" and as2: "X \ X ; A \ B" by simp_all - from as1 have a: "X ; A \ X" and b: "B \ X" by simp_all - from b have "B; A\ \ X ; A\" by (auto simp add: lang_seq_def) - moreover - from a have "X ; A\ \ X" - -by (rule lang_star_prop2) - ultimately have f1: "B ; A\ \ X" by simp - from as2 nemp - have f2: "X \ B; A\" using arden_aux1 by auto - from f1 f2 show "X = B; A\" by auto -qed - - - -section {* equiv class' definition *} - -definition - equiv_str :: "string \ string set \ string \ bool" ("_ \_\ _" [100, 100, 100] 100) -where - "x \Lang\ y \ (\z. x @ z \ Lang \ y @ z \ Lang)" - -definition - equiv_class :: "string \ (string set) \ string set" ("\_\_" [100, 100] 100) -where - "\x\Lang \ {y. x \Lang\ y}" - -text {* Chunhan modifies Q to Quo *} - -definition - quot :: "string set \ string set \ (string set) set" ("_ Quo _" [100, 100] 100) -where - "L1 Quo L2 \ { \x\L2 | x. x \ L1}" - - -lemma lang_eqs_union_of_eqcls: - "Lang = \ {X. X \ (UNIV Quo Lang) \ (\ x \ X. x \ Lang)}" -proof - show "Lang \ \{X \ UNIV Quo Lang. \x\X. x \ Lang}" - proof - fix x - assume "x \ Lang" - thus "x \ \{X \ UNIV Quo Lang. \x\X. x \ Lang}" - proof (simp add:quot_def) - assume "(1)": "x \ Lang" - show "\xa. (\x. xa = \x\Lang) \ (\x\xa. x \ Lang) \ x \ xa" (is "\xa.?P xa") - proof - - have "?P (\x\Lang)" using "(1)" - by (auto simp:equiv_class_def equiv_str_def dest: spec[where x = "[]"]) - thus ?thesis by blast - qed - qed - qed -next - show "\{X \ UNIV Quo Lang. \x\X. x \ Lang} \ Lang" - by auto -qed - -lemma empty_notin_CS: "{} \ UNIV Quo Lang" -apply (clarsimp simp:quot_def equiv_class_def) -by (rule_tac x = x in exI, auto simp:equiv_str_def) - -lemma no_two_cls_inters: - "\X \ UNIV Quo Lang; Y \ UNIV Quo Lang; X \ Y\ \ X \ Y = {}" -by (auto simp:quot_def equiv_class_def equiv_str_def) - -text {* equiv_class transition *} -definition - CT :: "string set \ char \ string set \ bool" ("_-_\_" [99,99]99) -where - "X-c\Y \ ((X;{[c]}) \ Y)" - -types t_equa_rhs = "(string set \ rexp) set" - -types t_equa = "(string set \ t_equa_rhs)" - -types t_equas = "t_equa set" - -text {* - "empty_rhs" generates "\" for init-state, just like "\" for final states - in Brzozowski method. But if the init-state is "{[]}" ("\" itself) then - empty set is returned, see definition of "equation_rhs" -*} - -definition - empty_rhs :: "string set \ t_equa_rhs" -where - "empty_rhs X \ if ([] \ X) then {({[]}, EMPTY)} else {}" - -definition - folds :: "('a \ 'b \ 'b) \ 'b \ 'a set \ 'b" -where - "folds f z S \ SOME x. fold_graph f z S x" - -definition - equation_rhs :: "(string set) set \ string set \ t_equa_rhs" -where - "equation_rhs CS X \ if (X = {[]}) then {({[]}, EMPTY)} - else {(S, folds ALT NULL {CHAR c| c. S-c\X} )| S. S \ CS} \ empty_rhs X" - -definition - equations :: "(string set) set \ t_equas" -where - "equations CS \ {(X, equation_rhs CS X) | X. X \ CS}" - -overloading L_rhs \ "L:: t_equa_rhs \ string set" -begin -fun L_rhs:: "t_equa_rhs \ string set" -where - "L_rhs rhs = {x. \ X r. (X, r) \ rhs \ x \ X;(L r)}" -end - -definition - distinct_rhs :: "t_equa_rhs \ bool" -where - "distinct_rhs rhs \ \ X reg\<^isub>1 reg\<^isub>2. (X, reg\<^isub>1) \ rhs \ (X, reg\<^isub>2) \ rhs \ reg\<^isub>1 = reg\<^isub>2" - -definition - distinct_equas_rhs :: "t_equas \ bool" -where - "distinct_equas_rhs equas \ \ X rhs. (X, rhs) \ equas \ distinct_rhs rhs" - -definition - distinct_equas :: "t_equas \ bool" -where - "distinct_equas equas \ \ X rhs rhs'. (X, rhs) \ equas \ (X, rhs') \ equas \ rhs = rhs'" - -definition - seq_rhs_r :: "t_equa_rhs \ rexp \ t_equa_rhs" -where - "seq_rhs_r rhs r \ (\(X, reg). (X, SEQ reg r)) ` rhs" - -definition - del_x_paired :: "('a \ 'b) set \ 'a \ ('a \ 'b) set" -where - "del_x_paired S x \ S - {X. X \ S \ fst X = x}" - -definition - arden_variate :: "string set \ rexp \ t_equa_rhs \ t_equa_rhs" -where - "arden_variate X r rhs \ seq_rhs_r (del_x_paired rhs X) (STAR r)" - -definition - no_EMPTY_rhs :: "t_equa_rhs \ bool" -where - "no_EMPTY_rhs rhs \ \ X r. (X, r) \ rhs \ X \ {[]} \ [] \ L r" - -definition - no_EMPTY_equas :: "t_equas \ bool" -where - "no_EMPTY_equas equas \ \ X rhs. (X, rhs) \ equas \ no_EMPTY_rhs rhs" - -lemma fold_alt_null_eqs: - "finite rS \ x \ L (folds ALT NULL rS) = (\ r \ rS. x \ L r)" -apply (simp add:folds_def) -apply (rule someI2_ex) -apply (erule finite_imp_fold_graph) -apply (erule fold_graph.induct) -by auto (*??? how do this be in Isar ?? *) - -lemma seq_rhs_r_prop1: - "L (seq_rhs_r rhs r) = (L rhs);(L r)" -apply (auto simp:seq_rhs_r_def image_def lang_seq_def) -apply (rule_tac x = "s1 @ s1a" in exI, rule_tac x = "s2a" in exI, simp) -apply (rule_tac x = a in exI, rule_tac x = b in exI, simp) -apply (rule_tac x = s1 in exI, rule_tac x = s1a in exI, simp) -apply (rule_tac x = X in exI, rule_tac x = "SEQ ra r" in exI, simp) -apply (rule conjI) -apply (rule_tac x = "(X, ra)" in bexI, simp+) -apply (rule_tac x = s1a in exI, rule_tac x = "s2a @ s2" in exI, simp) -apply (simp add:lang_seq_def) -by (rule_tac x = s2a in exI, rule_tac x = s2 in exI, simp) - -lemma del_x_paired_prop1: - "\distinct_rhs rhs; (X, r) \ rhs\ \ X ; L r \ L (del_x_paired rhs X) = L rhs" - apply (simp add:del_x_paired_def) - apply (simp add: distinct_rhs_def) - apply(auto simp add: lang_seq_def) - apply(metis) - done - -lemma arden_variate_prop: - assumes "(X, rx) \ rhs" - shows "(\ Y. Y \ X \ (\ r. (Y, r) \ rhs) = (\ r. (Y, r) \ (arden_variate X rx rhs)))" -proof (rule allI, rule impI) - fix Y - assume "(1)": "Y \ X" - show "(\r. (Y, r) \ rhs) = (\r. (Y, r) \ arden_variate X rx rhs)" - proof - assume "(1_1)": "\r. (Y, r) \ rhs" - show "\r. (Y, r) \ arden_variate X rx rhs" (is "\r. ?P r") - proof - - from "(1_1)" obtain r where "(Y, r) \ rhs" .. - hence "?P (SEQ r (STAR rx))" - proof (simp add:arden_variate_def image_def) - have "(Y, r) \ rhs \ (Y, r) \ del_x_paired rhs X" - by (auto simp:del_x_paired_def "(1)") - thus "(Y, r) \ rhs \ (Y, SEQ r (STAR rx)) \ seq_rhs_r (del_x_paired rhs X) (STAR rx)" - by (auto simp:seq_rhs_r_def) - qed - thus ?thesis by blast - qed - next - assume "(2_1)": "\r. (Y, r) \ arden_variate X rx rhs" - thus "\r. (Y, r) \ rhs" (is "\ r. ?P r") - by (auto simp:arden_variate_def del_x_paired_def seq_rhs_r_def image_def) - qed -qed - -text {* - arden_variate_valid: proves variation from - - "X = X;r + Y;ry + \" to "X = Y;(SEQ ry (STAR r)) + \" - - holds the law of "language of left equiv language of right" -*} -lemma arden_variate_valid: - assumes X_not_empty: "X \ {[]}" - and l_eq_r: "X = L rhs" - and dist: "distinct_rhs rhs" - and no_empty: "no_EMPTY_rhs rhs" - and self_contained: "(X, r) \ rhs" - shows "X = L (arden_variate X r rhs)" -proof - - have "[] \ L r" using no_empty X_not_empty self_contained - by (auto simp:no_EMPTY_rhs_def) - hence ardens: "X = X;(L r) \ (L (del_x_paired rhs X)) \ X = (L (del_x_paired rhs X)) ; (L r)\" - by (rule ardens_revised) - have del_x: "X = X ; L r \ L (del_x_paired rhs X) \ X = L rhs" using dist l_eq_r self_contained - by (auto dest!:del_x_paired_prop1) - show ?thesis - proof - show "X \ L (arden_variate X r rhs)" - proof - fix x - assume "(1_1)": "x \ X" with l_eq_r ardens del_x - show "x \ L (arden_variate X r rhs)" - by (simp add:arden_variate_def seq_rhs_r_prop1 del:L_rhs.simps) - qed - next - show "L (arden_variate X r rhs) \ X" - proof - fix x - assume "(2_1)": "x \ L (arden_variate X r rhs)" with ardens del_x l_eq_r - show "x \ X" - by (simp add:arden_variate_def seq_rhs_r_prop1 del:L_rhs.simps) - qed - qed -qed - -text {* - merge_rhs {(x1, r1), (x2, r2}, (x4, r4), \} {(x1, r1'), (x3, r3'), \} = - {(x1, ALT r1 r1'}, (x2, r2), (x3, r3'), (x4, r4), \} *} -definition - merge_rhs :: "t_equa_rhs \ t_equa_rhs \ t_equa_rhs" -where - "merge_rhs rhs rhs' \ {(X, r). (\ r1 r2. ((X,r1) \ rhs \ (X, r2) \ rhs') \ r = ALT r1 r2) \ - (\ r1. (X, r1) \ rhs \ (\ (\ r2. (X, r2) \ rhs')) \ r = r1) \ - (\ r2. (X, r2) \ rhs' \ (\ (\ r1. (X, r1) \ rhs)) \ r = r2) }" - - -text {* rhs_subst rhs X=xrhs r: substitude all occurence of X in rhs((X,r) \ rhs) with xrhs *} -definition - rhs_subst :: "t_equa_rhs \ string set \ t_equa_rhs \ rexp \ t_equa_rhs" -where - "rhs_subst rhs X xrhs r \ merge_rhs (del_x_paired rhs X) (seq_rhs_r xrhs r)" - -definition - equas_subst_f :: "string set \ t_equa_rhs \ t_equa \ t_equa" -where - "equas_subst_f X xrhs equa \ let (Y, rhs) = equa in - if (\ r. (X, r) \ rhs) - then (Y, rhs_subst rhs X xrhs (SOME r. (X, r) \ rhs)) - else equa" - -definition - equas_subst :: "t_equas \ string set \ t_equa_rhs \ t_equas" -where - "equas_subst ES X xrhs \ del_x_paired (equas_subst_f X xrhs ` ES) X" - -lemma lang_seq_prop1: - "x \ X ; L r \ x \ X ; (L r \ L r')" -by (auto simp:lang_seq_def) - -lemma lang_seq_prop1': - "x \ X; L r \ x \ X ; (L r' \ L r)" -by (auto simp:lang_seq_def) - -lemma lang_seq_prop2: - "x \ X; (L r \ L r') \ x \ X;L r \ x \ X;L r'" -by (auto simp:lang_seq_def) - -lemma merge_rhs_prop1: - shows "L (merge_rhs rhs rhs') = L rhs \ L rhs' " -apply (auto simp add:merge_rhs_def dest!:lang_seq_prop2 intro:lang_seq_prop1) -apply (rule_tac x = X in exI, rule_tac x = r1 in exI, simp) -apply (case_tac "\ r2. (X, r2) \ rhs'") -apply (clarify, rule_tac x = X in exI, rule_tac x = "ALT r r2" in exI, simp add:lang_seq_prop1) -apply (rule_tac x = X in exI, rule_tac x = r in exI, simp) -apply (case_tac "\ r1. (X, r1) \ rhs") -apply (clarify, rule_tac x = X in exI, rule_tac x = "ALT r1 r" in exI, simp add:lang_seq_prop1') -apply (rule_tac x = X in exI, rule_tac x = r in exI, simp) -done - -lemma no_EMPTY_rhss_imp_merge_no_EMPTY: - "\no_EMPTY_rhs rhs; no_EMPTY_rhs rhs'\ \ no_EMPTY_rhs (merge_rhs rhs rhs')" -apply (simp add:no_EMPTY_rhs_def merge_rhs_def) -apply (clarify, (erule conjE | erule exE | erule disjE)+) -by auto - -lemma distinct_rhs_prop: - "\distinct_rhs rhs; (X, r1) \ rhs; (X, r2) \ rhs\ \ r1 = r2" -by (auto simp:distinct_rhs_def) - -lemma merge_rhs_prop2: - assumes dist_rhs: "distinct_rhs rhs" - and dist_rhs':"distinct_rhs rhs'" - shows "distinct_rhs (merge_rhs rhs rhs')" -apply (auto simp:merge_rhs_def distinct_rhs_def) -using dist_rhs -apply (drule distinct_rhs_prop, simp+) -using dist_rhs' -apply (drule distinct_rhs_prop, simp+) -using dist_rhs -apply (drule distinct_rhs_prop, simp+) -using dist_rhs' -apply (drule distinct_rhs_prop, simp+) -done - -lemma seq_rhs_r_holds_distinct: - "distinct_rhs rhs \ distinct_rhs (seq_rhs_r rhs r)" -by (auto simp:distinct_rhs_def seq_rhs_r_def) - -lemma seq_rhs_r_prop0: - assumes l_eq_r: "X = L xrhs" - shows "L (seq_rhs_r xrhs r) = X ; L r " -using l_eq_r -by (auto simp only:seq_rhs_r_prop1) - -lemma rhs_subst_prop1: - assumes l_eq_r: "X = L xrhs" - and dist: "distinct_rhs rhs" - shows "(X, r) \ rhs \ L rhs = L (rhs_subst rhs X xrhs r)" -apply (simp add:rhs_subst_def merge_rhs_prop1 del:L_rhs.simps) -using l_eq_r -apply (drule_tac r = r in seq_rhs_r_prop0, simp del:L_rhs.simps) -using dist -by (auto dest!:del_x_paired_prop1 simp del:L_rhs.simps) - -lemma del_x_paired_holds_distinct_rhs: - "distinct_rhs rhs \ distinct_rhs (del_x_paired rhs x)" -by (auto simp:distinct_rhs_def del_x_paired_def) - -lemma rhs_subst_holds_distinct_rhs: - "\distinct_rhs rhs; distinct_rhs xrhs\ \ distinct_rhs (rhs_subst rhs X xrhs r)" -apply (drule_tac r = r and rhs = xrhs in seq_rhs_r_holds_distinct) -apply (drule_tac x = X in del_x_paired_holds_distinct_rhs) -by (auto dest:merge_rhs_prop2[where rhs = "del_x_paired rhs X"] simp:rhs_subst_def) - -section {* myhill-nerode theorem *} - -definition left_eq_cls :: "t_equas \ (string set) set" -where - "left_eq_cls ES \ {X. \ rhs. (X, rhs) \ ES} " - -definition right_eq_cls :: "t_equas \ (string set) set" -where - "right_eq_cls ES \ {Y. \ X rhs r. (X, rhs) \ ES \ (Y, r) \ rhs }" - -definition rhs_eq_cls :: "t_equa_rhs \ (string set) set" -where - "rhs_eq_cls rhs \ {Y. \ r. (Y, r) \ rhs}" - -definition ardenable :: "t_equa \ bool" -where - "ardenable equa \ let (X, rhs) = equa in - distinct_rhs rhs \ no_EMPTY_rhs rhs \ X = L rhs" - -text {* - Inv: Invairance of the equation-system, during the decrease of the equation-system, Inv holds. -*} -definition Inv :: "string set \ t_equas \ bool" -where - "Inv X ES \ finite ES \ (\ rhs. (X, rhs) \ ES) \ distinct_equas ES \ - (\ X xrhs. (X, xrhs) \ ES \ ardenable (X, xrhs) \ X \ {} \ rhs_eq_cls xrhs \ insert {[]} (left_eq_cls ES))" - -text {* - TCon: Termination Condition of the equation-system decreasion. -*} -definition TCon:: "'a set \ bool" -where - "TCon ES \ card ES = 1" - - -text {* - The following is a iteration principle, and is the main framework for the proof: - 1: We can form the initial equation-system using "equations" defined above, and prove it has invariance Inv by lemma "init_ES_satisfy_Inv"; - 2: We can decrease the number of the equation-system using ardens_lemma_revised and substitution ("equas_subst", defined above), - and prove it holds the property "step" in "wf_iter" by lemma "iteration_step" - and finally using property Inv and TCon to prove the myhill-nerode theorem - -*} -lemma wf_iter [rule_format]: - fixes f - assumes step: "\ e. \P e; \ Q e\ \ (\ e'. P e' \ (f(e'), f(e)) \ less_than)" - shows pe: "P e \ (\ e'. P e' \ Q e')" -proof(induct e rule: wf_induct - [OF wf_inv_image[OF wf_less_than, where f = "f"]], clarify) - fix x - assume h [rule_format]: - "\y. (y, x) \ inv_image less_than f \ P y \ (\e'. P e' \ Q e')" - and px: "P x" - show "\e'. P e' \ Q e'" - proof(cases "Q x") - assume "Q x" with px show ?thesis by blast - next - assume nq: "\ Q x" - from step [OF px nq] - obtain e' where pe': "P e'" and ltf: "(f e', f x) \ less_than" by auto - show ?thesis - proof(rule h) - from ltf show "(e', x) \ inv_image less_than f" - by (simp add:inv_image_def) - next - from pe' show "P e'" . - qed - qed -qed - - -text {* ******BEGIN: proving the initial equation-system satisfies Inv ****** *} - -lemma distinct_rhs_equations: - "(X, xrhs) \ equations (UNIV Quo Lang) \ distinct_rhs xrhs" -by (auto simp: equations_def equation_rhs_def distinct_rhs_def empty_rhs_def dest:no_two_cls_inters) - -lemma every_nonempty_eqclass_has_strings: - "\X \ (UNIV Quo Lang); X \ {[]}\ \ \ clist. clist \ X \ clist \ []" -by (auto simp:quot_def equiv_class_def equiv_str_def) - -lemma every_eqclass_is_derived_from_empty: - assumes not_empty: "X \ {[]}" - shows "X \ (UNIV Quo Lang) \ \ clist. {[]};{clist} \ X \ clist \ []" -using not_empty -apply (drule_tac every_nonempty_eqclass_has_strings, simp) -by (auto intro:exI[where x = clist] simp:lang_seq_def) - -lemma equiv_str_in_CS: - "\clist\Lang \ (UNIV Quo Lang)" -by (auto simp:quot_def) - -lemma has_str_imp_defined_by_str: - "\str \ X; X \ UNIV Quo Lang\ \ X = \str\Lang" -by (auto simp:quot_def equiv_class_def equiv_str_def) - -lemma every_eqclass_has_ascendent: - assumes has_str: "clist @ [c] \ X" - and in_CS: "X \ UNIV Quo Lang" - shows "\ Y. Y \ UNIV Quo Lang \ Y-c\X \ clist \ Y" (is "\ Y. ?P Y") -proof - - have "?P (\clist\Lang)" - proof - - have "\clist\Lang \ UNIV Quo Lang" - by (simp add:quot_def, rule_tac x = clist in exI, simp) - moreover have "\clist\Lang-c\X" - proof - - have "X = \(clist @ [c])\Lang" using has_str in_CS - by (auto intro!:has_str_imp_defined_by_str) - moreover have "\ sl. sl \ \clist\Lang \ sl @ [c] \ \(clist @ [c])\Lang" - by (auto simp:equiv_class_def equiv_str_def) - ultimately show ?thesis unfolding CT_def lang_seq_def - by auto - qed - moreover have "clist \ \clist\Lang" - by (auto simp:equiv_str_def equiv_class_def) - ultimately show "?P (\clist\Lang)" by simp - qed - thus ?thesis by blast -qed - -lemma finite_charset_rS: - "finite {CHAR c |c. Y-c\X}" -by (rule_tac A = UNIV and f = CHAR in finite_surj, auto) - -lemma l_eq_r_in_equations: - assumes X_in_equas: "(X, xrhs) \ equations (UNIV Quo Lang)" - shows "X = L xrhs" -proof (cases "X = {[]}") - case True - thus ?thesis using X_in_equas - by (simp add:equations_def equation_rhs_def lang_seq_def) -next - case False - show ?thesis - proof - show "X \ L xrhs" - proof - fix x - assume "(1)": "x \ X" - show "x \ L xrhs" - proof (cases "x = []") - assume empty: "x = []" - hence "x \ L (empty_rhs X)" using "(1)" - by (auto simp:empty_rhs_def lang_seq_def) - thus ?thesis using X_in_equas False empty "(1)" - unfolding equations_def equation_rhs_def by auto - next - assume not_empty: "x \ []" - hence "\ clist c. x = clist @ [c]" by (case_tac x rule:rev_cases, auto) - then obtain clist c where decom: "x = clist @ [c]" by blast - moreover have "\ Y. \Y \ UNIV Quo Lang; Y-c\X; clist \ Y\ - \ [c] \ L (folds ALT NULL {CHAR c |c. Y-c\X})" - proof - - fix Y - assume Y_is_eq_cl: "Y \ UNIV Quo Lang" - and Y_CT_X: "Y-c\X" - and clist_in_Y: "clist \ Y" - with finite_charset_rS - show "[c] \ L (folds ALT NULL {CHAR c |c. Y-c\X})" - by (auto simp :fold_alt_null_eqs) - qed - hence "\Xa. Xa \ UNIV Quo Lang \ clist @ [c] \ Xa ; L (folds ALT NULL {CHAR c |c. Xa-c\X})" - using X_in_equas False not_empty "(1)" decom - by (auto dest!:every_eqclass_has_ascendent simp:equations_def equation_rhs_def lang_seq_def) - then obtain Xa where - "Xa \ UNIV Quo Lang \ clist @ [c] \ Xa ; L (folds ALT NULL {CHAR c |c. Xa-c\X})" by blast - hence "x \ L {(S, folds ALT NULL {CHAR c |c. S-c\X}) |S. S \ UNIV Quo Lang}" - using X_in_equas "(1)" decom - by (auto simp add:equations_def equation_rhs_def intro!:exI[where x = Xa]) - thus "x \ L xrhs" using X_in_equas False not_empty unfolding equations_def equation_rhs_def - by auto - qed - qed - next - show "L xrhs \ X" - proof - fix x - assume "(2)": "x \ L xrhs" - have "(2_1)": "\ s1 s2 r Xa. \s1 \ Xa; s2 \ L (folds ALT NULL {CHAR c |c. Xa-c\X})\ \ s1 @ s2 \ X" - using finite_charset_rS - by (auto simp:CT_def lang_seq_def fold_alt_null_eqs) - have "(2_2)": "\ s1 s2 Xa r.\s1 \ Xa; s2 \ L r; (Xa, r) \ empty_rhs X\ \ s1 @ s2 \ X" - by (simp add:empty_rhs_def split:if_splits) - show "x \ X" using X_in_equas False "(2)" - by (auto intro:"(2_1)" "(2_2)" simp:equations_def equation_rhs_def lang_seq_def) - qed - qed -qed - - - -lemma no_EMPTY_equations: - "(X, xrhs) \ equations CS \ no_EMPTY_rhs xrhs" -apply (clarsimp simp add:equations_def equation_rhs_def) -apply (simp add:no_EMPTY_rhs_def empty_rhs_def, auto) -apply (subgoal_tac "finite {CHAR c |c. Xa-c\X}", drule_tac x = "[]" in fold_alt_null_eqs, clarsimp, rule finite_charset_rS)+ -done - -lemma init_ES_satisfy_ardenable: - "(X, xrhs) \ equations (UNIV Quo Lang) \ ardenable (X, xrhs)" - unfolding ardenable_def - by (auto intro:distinct_rhs_equations no_EMPTY_equations simp:l_eq_r_in_equations simp del:L_rhs.simps) - -lemma init_ES_satisfy_Inv: - assumes finite_CS: "finite (UNIV Quo Lang)" - and X_in_eq_cls: "X \ UNIV Quo Lang" - shows "Inv X (equations (UNIV Quo Lang))" -proof - - have "finite (equations (UNIV Quo Lang))" using finite_CS - by (auto simp:equations_def) - moreover have "\rhs. (X, rhs) \ equations (UNIV Quo Lang)" using X_in_eq_cls - by (simp add:equations_def) - moreover have "distinct_equas (equations (UNIV Quo Lang))" - by (auto simp:distinct_equas_def equations_def) - moreover have "\X xrhs. (X, xrhs) \ equations (UNIV Quo Lang) \ - rhs_eq_cls xrhs \ insert {[]} (left_eq_cls (equations (UNIV Quo Lang)))" - apply (simp add:left_eq_cls_def equations_def rhs_eq_cls_def equation_rhs_def) - by (auto simp:empty_rhs_def split:if_splits) - moreover have "\X xrhs. (X, xrhs) \ equations (UNIV Quo Lang) \ X \ {}" - by (clarsimp simp:equations_def empty_notin_CS intro:classical) - moreover have "\X xrhs. (X, xrhs) \ equations (UNIV Quo Lang) \ ardenable (X, xrhs)" - by (auto intro!:init_ES_satisfy_ardenable) - ultimately show ?thesis by (simp add:Inv_def) -qed - - -text {* *********** END: proving the initial equation-system satisfies Inv ******* *} - - -text {* ****** BEGIN: proving every equation-system's iteration step satisfies Inv ***** *} - -lemma not_T_aux: "\\ TCon (insert a A); x = a\ - \ \y. x \ y \ y \ insert a A " -apply (case_tac "insert a A = {a}") -by (auto simp:TCon_def) - -lemma not_T_atleast_2[rule_format]: - "finite S \ \ x. x \ S \ (\ TCon S)\ (\ y. x \ y \ y \ S)" -apply (erule finite.induct, simp) -apply (clarify, case_tac "x = a") -by (erule not_T_aux, auto) - -lemma exist_another_equa: - "\\ TCon ES; finite ES; distinct_equas ES; (X, rhl) \ ES\ \ \ Y yrhl. (Y, yrhl) \ ES \ X \ Y" -apply (drule not_T_atleast_2, simp) -apply (clarsimp simp:distinct_equas_def) -apply (drule_tac x= X in spec, drule_tac x = rhl in spec, drule_tac x = b in spec) -by auto - -lemma Inv_mono_with_lambda: - assumes Inv_ES: "Inv X ES" - and X_noteq_Y: "X \ {[]}" - shows "Inv X (ES - {({[]}, yrhs)})" -proof - - have "finite (ES - {({[]}, yrhs)})" using Inv_ES - by (simp add:Inv_def) - moreover have "\rhs. (X, rhs) \ ES - {({[]}, yrhs)}" using Inv_ES X_noteq_Y - by (simp add:Inv_def) - moreover have "distinct_equas (ES - {({[]}, yrhs)})" using Inv_ES X_noteq_Y - apply (clarsimp simp:Inv_def distinct_equas_def) - by (drule_tac x = Xa in spec, simp) - moreover have "\X xrhs.(X, xrhs) \ ES - {({[]}, yrhs)} \ - ardenable (X, xrhs) \ X \ {}" using Inv_ES - by (clarify, simp add:Inv_def) - moreover - have "insert {[]} (left_eq_cls (ES - {({[]}, yrhs)})) = insert {[]} (left_eq_cls ES)" - by (auto simp:left_eq_cls_def) - hence "\X xrhs.(X, xrhs) \ ES - {({[]}, yrhs)} \ - rhs_eq_cls xrhs \ insert {[]} (left_eq_cls (ES - {({[]}, yrhs)}))" - using Inv_ES by (auto simp:Inv_def) - ultimately show ?thesis by (simp add:Inv_def) -qed - -lemma non_empty_card_prop: - "finite ES \ \e. e \ ES \ card ES - Suc 0 < card ES" -apply (erule finite.induct, simp) -apply (case_tac[!] "a \ A") -by (auto simp:insert_absorb) - -lemma ardenable_prop: - assumes not_lambda: "Y \ {[]}" - and ardable: "ardenable (Y, yrhs)" - shows "\ yrhs'. Y = L yrhs' \ distinct_rhs yrhs' \ rhs_eq_cls yrhs' = rhs_eq_cls yrhs - {Y}" (is "\ yrhs'. ?P yrhs'") -proof (cases "(\ reg. (Y, reg) \ yrhs)") - case True - thus ?thesis - proof - fix reg - assume self_contained: "(Y, reg) \ yrhs" - show ?thesis - proof - - have "?P (arden_variate Y reg yrhs)" - proof - - have "Y = L (arden_variate Y reg yrhs)" - using self_contained not_lambda ardable - by (rule_tac arden_variate_valid, simp_all add:ardenable_def) - moreover have "distinct_rhs (arden_variate Y reg yrhs)" - using ardable - by (auto simp:distinct_rhs_def arden_variate_def seq_rhs_r_def del_x_paired_def ardenable_def) - moreover have "rhs_eq_cls (arden_variate Y reg yrhs) = rhs_eq_cls yrhs - {Y}" - proof - - have "\ rhs r. rhs_eq_cls (seq_rhs_r rhs r) = rhs_eq_cls rhs" - apply (auto simp:rhs_eq_cls_def seq_rhs_r_def image_def) - by (rule_tac x = "SEQ ra r" in exI, rule_tac x = "(x, ra)" in bexI, simp+) - moreover have "\ rhs X. rhs_eq_cls (del_x_paired rhs X) = rhs_eq_cls rhs - {X}" - by (auto simp:rhs_eq_cls_def del_x_paired_def) - ultimately show ?thesis by (simp add:arden_variate_def) - qed - ultimately show ?thesis by simp - qed - thus ?thesis by (rule_tac x= "arden_variate Y reg yrhs" in exI, simp) - qed - qed -next - case False - hence "(2)": "rhs_eq_cls yrhs - {Y} = rhs_eq_cls yrhs" - by (auto simp:rhs_eq_cls_def) - show ?thesis - proof - - have "?P yrhs" using False ardable "(2)" - by (simp add:ardenable_def) - thus ?thesis by blast - qed -qed - -lemma equas_subst_f_del_no_other: - assumes self_contained: "(Y, rhs) \ ES" - shows "\ rhs'. (Y, rhs') \ (equas_subst_f X xrhs ` ES)" (is "\ rhs'. ?P rhs'") -proof - - have "\ rhs'. equas_subst_f X xrhs (Y, rhs) = (Y, rhs')" - by (auto simp:equas_subst_f_def) - then obtain rhs' where "equas_subst_f X xrhs (Y, rhs) = (Y, rhs')" by blast - hence "?P rhs'" unfolding image_def using self_contained - by (auto intro:bexI[where x = "(Y, rhs)"]) - thus ?thesis by blast -qed - -lemma del_x_paired_del_only_x: - "\X \ Y; (X, rhs) \ ES\ \ (X, rhs) \ del_x_paired ES Y" -by (auto simp:del_x_paired_def) - -lemma equas_subst_del_no_other: - "\(X, rhs) \ ES; X \ Y\ \ (\rhs. (X, rhs) \ equas_subst ES Y rhs')" -unfolding equas_subst_def -apply (drule_tac X = Y and xrhs = rhs' in equas_subst_f_del_no_other) -by (erule exE, drule del_x_paired_del_only_x, auto) - -lemma equas_subst_holds_distinct: - "distinct_equas ES \ distinct_equas (equas_subst ES Y rhs')" -apply (clarsimp simp add:equas_subst_def distinct_equas_def del_x_paired_def equas_subst_f_def) -by (auto split:if_splits) - -lemma del_x_paired_dels: - "(X, rhs) \ ES \ {Y. Y \ ES \ fst Y = X} \ ES \ {}" -by (auto) - -lemma del_x_paired_subset: - "(X, rhs) \ ES \ ES - {Y. Y \ ES \ fst Y = X} \ ES" -apply (drule del_x_paired_dels) -by auto - -lemma del_x_paired_card_less: - "\finite ES; (X, rhs) \ ES\ \ card (del_x_paired ES X) < card ES" -apply (simp add:del_x_paired_def) -apply (drule del_x_paired_subset) -by (auto intro:psubset_card_mono) - -lemma equas_subst_card_less: - "\finite ES; (Y, yrhs) \ ES\ \ card (equas_subst ES Y rhs') < card ES" -apply (simp add:equas_subst_def) -apply (frule_tac h = "equas_subst_f Y rhs'" in finite_imageI) -apply (drule_tac f = "equas_subst_f Y rhs'" in Finite_Set.card_image_le) -apply (drule_tac X = Y and xrhs = rhs' in equas_subst_f_del_no_other,erule exE) -by (drule del_x_paired_card_less, auto) - -lemma equas_subst_holds_distinct_rhs: - assumes dist': "distinct_rhs yrhs'" - and history: "\X xrhs. (X, xrhs) \ ES \ ardenable (X, xrhs)" - and X_in : "(X, xrhs) \ equas_subst ES Y yrhs'" - shows "distinct_rhs xrhs" -using X_in history -apply (clarsimp simp:equas_subst_def del_x_paired_def) -apply (drule_tac x = a in spec, drule_tac x = b in spec) -apply (simp add:ardenable_def equas_subst_f_def) -by (auto intro:rhs_subst_holds_distinct_rhs simp:dist' split:if_splits) - -lemma r_no_EMPTY_imp_seq_rhs_r_no_EMPTY: - "[] \ L r \ no_EMPTY_rhs (seq_rhs_r rhs r)" -by (auto simp:no_EMPTY_rhs_def seq_rhs_r_def lang_seq_def) - -lemma del_x_paired_holds_no_EMPTY: - "no_EMPTY_rhs yrhs \ no_EMPTY_rhs (del_x_paired yrhs Y)" -by (auto simp:no_EMPTY_rhs_def del_x_paired_def) - -lemma rhs_subst_holds_no_EMPTY: - "\no_EMPTY_rhs yrhs; (Y, r) \ yrhs; Y \ {[]}\ \ no_EMPTY_rhs (rhs_subst yrhs Y rhs' r)" -apply (auto simp:rhs_subst_def intro!:no_EMPTY_rhss_imp_merge_no_EMPTY r_no_EMPTY_imp_seq_rhs_r_no_EMPTY del_x_paired_holds_no_EMPTY) -by (auto simp:no_EMPTY_rhs_def) - -lemma equas_subst_holds_no_EMPTY: - assumes substor: "Y \ {[]}" - and history: "\X xrhs. (X, xrhs) \ ES \ ardenable (X, xrhs)" - and X_in:"(X, xrhs) \ equas_subst ES Y yrhs'" - shows "no_EMPTY_rhs xrhs" -proof- - from X_in have "\ (Z, zrhs) \ ES. (X, xrhs) = equas_subst_f Y yrhs' (Z, zrhs)" - by (auto simp add:equas_subst_def del_x_paired_def) - then obtain Z zrhs where Z_in: "(Z, zrhs) \ ES" - and X_Z: "(X, xrhs) = equas_subst_f Y yrhs' (Z, zrhs)" by blast - hence dist_zrhs: "distinct_rhs zrhs" using history - by (auto simp:ardenable_def) - show ?thesis - proof (cases "\ r. (Y, r) \ zrhs") - case True - then obtain r where Y_in_zrhs: "(Y, r) \ zrhs" .. - hence some: "(SOME r. (Y, r) \ zrhs) = r" using Z_in dist_zrhs - by (auto simp:distinct_rhs_def) - hence "no_EMPTY_rhs (rhs_subst zrhs Y yrhs' r)" - using substor Y_in_zrhs history Z_in - by (rule_tac rhs_subst_holds_no_EMPTY, auto simp:ardenable_def) - thus ?thesis using X_Z True some - by (simp add:equas_subst_def equas_subst_f_def) - next - case False - hence "(X, xrhs) = (Z, zrhs)" using Z_in X_Z - by (simp add:equas_subst_f_def) - thus ?thesis using history Z_in - by (auto simp:ardenable_def) - qed -qed - -lemma equas_subst_f_holds_left_eq_right: - assumes substor: "Y = L rhs'" - and history: "\X xrhs. (X, xrhs) \ ES \ distinct_rhs xrhs \ X = L xrhs" - and subst: "(X, xrhs) = equas_subst_f Y rhs' (Z, zrhs)" - and self_contained: "(Z, zrhs) \ ES" - shows "X = L xrhs" -proof (cases "\ r. (Y, r) \ zrhs") - case True - from True obtain r where "(1)":"(Y, r) \ zrhs" .. - show ?thesis - proof - - from history self_contained - have dist: "distinct_rhs zrhs" by auto - hence "(SOME r. (Y, r) \ zrhs) = r" using self_contained "(1)" - using distinct_rhs_def by (auto intro:some_equality) - moreover have "L zrhs = L (rhs_subst zrhs Y rhs' r)" using substor dist "(1)" self_contained - by (rule_tac rhs_subst_prop1, auto simp:distinct_equas_rhs_def) - ultimately show ?thesis using subst history self_contained - by (auto simp:equas_subst_f_def split:if_splits) - qed -next - case False - thus ?thesis using history subst self_contained - by (auto simp:equas_subst_f_def) -qed - -lemma equas_subst_holds_left_eq_right: - assumes history: "\X xrhs. (X, xrhs) \ ES \ ardenable (X, xrhs)" - and substor: "Y = L rhs'" - and X_in : "(X, xrhs) \ equas_subst ES Y yrhs'" - shows "\X xrhs. (X, xrhs) \ equas_subst ES Y rhs' \ X = L xrhs" -apply (clarsimp simp add:equas_subst_def del_x_paired_def) -using substor -apply (drule_tac equas_subst_f_holds_left_eq_right) -using history -by (auto simp:ardenable_def) - -lemma equas_subst_holds_ardenable: - assumes substor: "Y = L yrhs'" - and history: "\X xrhs. (X, xrhs) \ ES \ ardenable (X, xrhs)" - and X_in:"(X, xrhs) \ equas_subst ES Y yrhs'" - and dist': "distinct_rhs yrhs'" - and not_lambda: "Y \ {[]}" - shows "ardenable (X, xrhs)" -proof - - have "distinct_rhs xrhs" using history X_in dist' - by (auto dest:equas_subst_holds_distinct_rhs) - moreover have "no_EMPTY_rhs xrhs" using history X_in not_lambda - by (auto intro:equas_subst_holds_no_EMPTY) - moreover have "X = L xrhs" using history substor X_in - by (auto dest: equas_subst_holds_left_eq_right simp del:L_rhs.simps) - ultimately show ?thesis using ardenable_def by simp -qed - -lemma equas_subst_holds_cls_defined: - assumes X_in: "(X, xrhs) \ equas_subst ES Y yrhs'" - and Inv_ES: "Inv X' ES" - and subst: "(Y, yrhs) \ ES" - and cls_holds_but_Y: "rhs_eq_cls yrhs' = rhs_eq_cls yrhs - {Y}" - shows "rhs_eq_cls xrhs \ insert {[]} (left_eq_cls (equas_subst ES Y yrhs'))" -proof- - have tac: "\ A \ B; C \ D; E \ A \ B\ \ E \ B \ D" by auto - from X_in have "\ (Z, zrhs) \ ES. (X, xrhs) = equas_subst_f Y yrhs' (Z, zrhs)" - by (auto simp add:equas_subst_def del_x_paired_def) - then obtain Z zrhs where Z_in: "(Z, zrhs) \ ES" - and X_Z: "(X, xrhs) = equas_subst_f Y yrhs' (Z, zrhs)" by blast - hence "rhs_eq_cls zrhs \ insert {[]} (left_eq_cls ES)" using Inv_ES - by (auto simp:Inv_def) - moreover have "rhs_eq_cls yrhs' \ insert {[]} (left_eq_cls ES) - {Y}" - using Inv_ES subst cls_holds_but_Y - by (auto simp:Inv_def) - moreover have "rhs_eq_cls xrhs \ rhs_eq_cls zrhs \ rhs_eq_cls yrhs' - {Y}" - using X_Z cls_holds_but_Y - apply (clarsimp simp add:equas_subst_f_def rhs_subst_def split:if_splits) - by (auto simp:rhs_eq_cls_def merge_rhs_def del_x_paired_def seq_rhs_r_def) - moreover have "left_eq_cls (equas_subst ES Y yrhs') = left_eq_cls ES - {Y}" using subst - by (auto simp: left_eq_cls_def equas_subst_def del_x_paired_def equas_subst_f_def - dest: equas_subst_f_del_no_other - split: if_splits) - ultimately show ?thesis by blast -qed - -lemma iteration_step: - assumes Inv_ES: "Inv X ES" - and not_T: "\ TCon ES" - shows "(\ ES'. Inv X ES' \ (card ES', card ES) \ less_than)" -proof - - from Inv_ES not_T have another: "\Y yrhs. (Y, yrhs) \ ES \ X \ Y" unfolding Inv_def - by (clarify, rule_tac exist_another_equa[where X = X], auto) - then obtain Y yrhs where subst: "(Y, yrhs) \ ES" and not_X: " X \ Y" by blast - show ?thesis (is "\ ES'. ?P ES'") - proof (cases "Y = {[]}") - case True - --"in this situation, we pick a \"\\" equation, thus directly remove it from the equation-system" - have "?P (ES - {(Y, yrhs)})" - proof - show "Inv X (ES - {(Y, yrhs)})" using True not_X - by (simp add:Inv_ES Inv_mono_with_lambda) - next - show "(card (ES - {(Y, yrhs)}), card ES) \ less_than" using Inv_ES subst - by (auto elim:non_empty_card_prop[rule_format] simp:Inv_def) - qed - thus ?thesis by blast - next - case False - --"in this situation, we pick a equation and using ardenable to get a - rhs without itself in it, then use equas_subst to form a new equation-system" - hence "\ yrhs'. Y = L yrhs' \ distinct_rhs yrhs' \ rhs_eq_cls yrhs' = rhs_eq_cls yrhs - {Y}" - using subst Inv_ES - by (auto intro:ardenable_prop simp add:Inv_def simp del:L_rhs.simps) - then obtain yrhs' where Y'_l_eq_r: "Y = L yrhs'" - and dist_Y': "distinct_rhs yrhs'" - and cls_holds_but_Y: "rhs_eq_cls yrhs' = rhs_eq_cls yrhs - {Y}" by blast - hence "?P (equas_subst ES Y yrhs')" - proof - - have finite_del: "\ S x. finite S \ finite (del_x_paired S x)" - apply (rule_tac A = "del_x_paired S x" in finite_subset) - by (auto simp:del_x_paired_def) - have "finite (equas_subst ES Y yrhs')" using Inv_ES - by (auto intro!:finite_del simp:equas_subst_def Inv_def) - moreover have "\rhs. (X, rhs) \ equas_subst ES Y yrhs'" using Inv_ES not_X - by (auto intro:equas_subst_del_no_other simp:Inv_def) - moreover have "distinct_equas (equas_subst ES Y yrhs')" using Inv_ES - by (auto intro:equas_subst_holds_distinct simp:Inv_def) - moreover have "\X xrhs. (X, xrhs) \ equas_subst ES Y yrhs' \ ardenable (X, xrhs)" - using Inv_ES dist_Y' False Y'_l_eq_r - apply (clarsimp simp:Inv_def) - by (rule equas_subst_holds_ardenable, simp_all) - moreover have "\X xrhs. (X, xrhs) \ equas_subst ES Y yrhs' \ X \ {}" using Inv_ES - by (clarsimp simp:equas_subst_def Inv_def del_x_paired_def equas_subst_f_def split:if_splits, auto) - moreover have "\X xrhs. (X, xrhs) \ equas_subst ES Y yrhs' \ - rhs_eq_cls xrhs \ insert {[]} (left_eq_cls (equas_subst ES Y yrhs'))" - using Inv_ES subst cls_holds_but_Y - apply (rule_tac impI | rule_tac allI)+ - by (erule equas_subst_holds_cls_defined, auto) - moreover have "(card (equas_subst ES Y yrhs'), card ES) \ less_than"using Inv_ES subst - by (simp add:equas_subst_card_less Inv_def) - ultimately show "?P (equas_subst ES Y yrhs')" by (auto simp:Inv_def) - qed - thus ?thesis by blast - qed -qed - -text {* ***** END: proving every equation-system's iteration step satisfies Inv ************** *} - -lemma iteration_conc: - assumes history: "Inv X ES" - shows "\ ES'. Inv X ES' \ TCon ES'" (is "\ ES'. ?P ES'") -proof (cases "TCon ES") - case True - hence "?P ES" using history by simp - thus ?thesis by blast -next - case False - thus ?thesis using history iteration_step - by (rule_tac f = card in wf_iter, simp_all) -qed - -lemma eqset_imp_iff': "A = B \ \ x. x \ A \ x \ B" -apply (auto simp:mem_def) -done - -lemma set_cases2: - "\(A = {} \ R A); \ x. (A = {x}) \ R A; \ x y. \x \ y; x \ A; y \ A\ \ R A\ \ R A" -apply (case_tac "A = {}", simp) -by (case_tac "\ x. A = {x}", clarsimp, blast) - -lemma rhs_aux:"\distinct_rhs rhs; {Y. \r. (Y, r) \ rhs} = {X}\ \ (\r. rhs = {(X, r)})" -apply (rule_tac A = rhs in set_cases2, simp) -apply (drule_tac x = X in eqset_imp_iff, clarsimp) -apply (drule eqset_imp_iff',clarsimp) -apply (frule_tac x = a in spec, drule_tac x = aa in spec) -by (auto simp:distinct_rhs_def) - -lemma every_eqcl_has_reg: - assumes finite_CS: "finite (UNIV Quo Lang)" - and X_in_CS: "X \ (UNIV Quo Lang)" - shows "\ (reg::rexp). L reg = X" (is "\ r. ?E r") -proof- - have "\ES'. Inv X ES' \ TCon ES'" using finite_CS X_in_CS - by (auto intro:init_ES_satisfy_Inv iteration_conc) - then obtain ES' where Inv_ES': "Inv X ES'" - and TCon_ES': "TCon ES'" by blast - from Inv_ES' TCon_ES' - have "\ rhs. ES' = {(X, rhs)}" - apply (clarsimp simp:Inv_def TCon_def) - apply (rule_tac x = rhs in exI) - by (auto dest!:card_Suc_Diff1 simp:card_eq_0_iff) - then obtain rhs where ES'_single_equa: "ES' = {(X, rhs)}" .. - hence X_ardenable: "ardenable (X, rhs)" using Inv_ES' - by (simp add:Inv_def) - - from X_ardenable have X_l_eq_r: "X = L rhs" - by (simp add:ardenable_def) - hence rhs_not_empty: "rhs \ {}" using Inv_ES' ES'_single_equa - by (auto simp:Inv_def ardenable_def) - have rhs_eq_cls: "rhs_eq_cls rhs \ {X, {[]}}" - using Inv_ES' ES'_single_equa - by (auto simp:Inv_def ardenable_def left_eq_cls_def) - have X_not_empty: "X \ {}" using Inv_ES' ES'_single_equa - by (auto simp:Inv_def) - show ?thesis - proof (cases "X = {[]}") - case True - hence "?E EMPTY" by (simp) - thus ?thesis by blast - next - case False with X_ardenable - have "\ rhs'. X = L rhs' \ rhs_eq_cls rhs' = rhs_eq_cls rhs - {X} \ distinct_rhs rhs'" - by (drule_tac ardenable_prop, auto) - then obtain rhs' where X_eq_rhs': "X = L rhs'" - and rhs'_eq_cls: "rhs_eq_cls rhs' = rhs_eq_cls rhs - {X}" - and rhs'_dist : "distinct_rhs rhs'" by blast - have "rhs_eq_cls rhs' \ {{[]}}" using rhs_eq_cls False rhs'_eq_cls rhs_not_empty - by blast - hence "rhs_eq_cls rhs' = {{[]}}" using X_not_empty X_eq_rhs' - by (auto simp:rhs_eq_cls_def) - hence "\ r. rhs' = {({[]}, r)}" using rhs'_dist - by (auto intro:rhs_aux simp:rhs_eq_cls_def) - then obtain r where "rhs' = {({[]}, r)}" .. - hence "?E r" using X_eq_rhs' by (auto simp add:lang_seq_def) - thus ?thesis by blast - qed -qed - -text {* definition of a regular language *} - -abbreviation - reg :: "string set => bool" -where - "reg L1 \ (\r::rexp. L r = L1)" - -theorem myhill_nerode: - assumes finite_CS: "finite (UNIV Quo Lang)" - shows "\ (reg::rexp). Lang = L reg" (is "\ r. ?P r") -proof - - have has_r_each: "\C\{X \ UNIV Quo Lang. \x\X. x \ Lang}. \(r::rexp). C = L r" using finite_CS - by (auto dest:every_eqcl_has_reg) - have "\ (rS::rexp set). finite rS \ - (\ C \ {X \ UNIV Quo Lang. \x\X. x \ Lang}. \ r \ rS. C = L r) \ - (\ r \ rS. \ C \ {X \ UNIV Quo Lang. \x\X. x \ Lang}. C = L r)" - (is "\ rS. ?Q rS") - proof- - have "\ C. C \ {X \ UNIV Quo Lang. \x\X. x \ Lang} \ C = L (SOME (ra::rexp). C = L ra)" - using has_r_each - apply (erule_tac x = C in ballE, erule_tac exE) - by (rule_tac a = r in someI2, simp+) - hence "?Q ((\ C. SOME r. C = L r) ` {X \ UNIV Quo Lang. \x\X. x \ Lang})" using has_r_each - using finite_CS by auto - thus ?thesis by blast - qed - then obtain rS where finite_rS : "finite rS" - and has_r_each': "\ C \ {X \ UNIV Quo Lang. \x\X. x \ Lang}. \ r \ (rS::rexp set). C = L r" - and has_cl_each: "\ r \ (rS::rexp set). \ C \ {X \ UNIV Quo Lang. \x\X. x \ Lang}. C = L r" by blast - have "?P (folds ALT NULL rS)" - proof - show "Lang \ L (folds ALT NULL rS)" using finite_rS lang_eqs_union_of_eqcls[of Lang] has_r_each' - apply (clarsimp simp:fold_alt_null_eqs) by blast - next - show "L (folds ALT NULL rS) \ Lang" using finite_rS lang_eqs_union_of_eqcls[of Lang] has_cl_each - by (clarsimp simp:fold_alt_null_eqs) - qed - thus ?thesis by blast -qed - - -text {* tests by Christian *} - -(* Alternative definition for Quo *) -definition - QUOT :: "string set \ (string set) set" -where - "QUOT Lang \ (\x. {\x\Lang})" - -lemma test: - "UNIV Quo Lang = QUOT Lang" -by (auto simp add: quot_def QUOT_def) - -lemma test1: - assumes finite_CS: "finite (QUOT Lang)" - shows "reg Lang" -using finite_CS -unfolding test[symmetric] -by (auto dest: myhill_nerode) - -lemma cons_one: "x @ y \ {z} \ x @ y = z" -by simp - -lemma quot_lambda: "QUOT {[]} = {{[]}, UNIV - {[]}}" -proof - show "QUOT {[]} \ {{[]}, UNIV - {[]}}" - proof - fix x - assume in_quot: "x \ QUOT {[]}" - show "x \ {{[]}, UNIV - {[]}}" - proof - - from in_quot - have "x = {[]} \ x = UNIV - {[]}" - unfolding QUOT_def equiv_class_def - proof - fix xa - assume in_univ: "xa \ UNIV" - and in_eqiv: "x \ {{y. xa \{[]}\ y}}" - show "x = {[]} \ x = UNIV - {[]}" - proof(cases "xa = []") - case True - hence "{y. xa \{[]}\ y} = {[]}" using in_eqiv - by (auto simp add:equiv_str_def) - thus ?thesis using in_eqiv by (rule_tac disjI1, simp) - next - case False - hence "{y. xa \{[]}\ y} = UNIV - {[]}" using in_eqiv - by (auto simp:equiv_str_def) - thus ?thesis using in_eqiv by (rule_tac disjI2, simp) - qed - qed - thus ?thesis by simp - qed - qed -next - show "{{[]}, UNIV - {[]}} \ QUOT {[]}" - proof - fix x - assume in_res: "x \ {{[]}, (UNIV::string set) - {[]}}" - show "x \ (QUOT {[]})" - proof - - have "x = {[]} \ x \ QUOT {[]}" - apply (simp add:QUOT_def equiv_class_def equiv_str_def) - by (rule_tac x = "[]" in exI, auto) - moreover have "x = UNIV - {[]} \ x \ QUOT {[]}" - apply (simp add:QUOT_def equiv_class_def equiv_str_def) - by (rule_tac x = "''a''" in exI, auto) - ultimately show ?thesis using in_res by blast - qed - qed -qed - -lemma quot_single_aux: "\x \ []; x \ [c]\ \ x @ z \ [c]" -by (induct x, auto) - -lemma quot_single: "\ (c::char). QUOT {[c]} = {{[]}, {[c]}, UNIV - {[], [c]}}" -proof - - fix c::"char" - have exist_another: "\ a. a \ c" - apply (case_tac "c = CHR ''a''") - apply (rule_tac x = "CHR ''b''" in exI, simp) - by (rule_tac x = "CHR ''a''" in exI, simp) - show "QUOT {[c]} = {{[]}, {[c]}, UNIV - {[], [c]}}" - proof - show "QUOT {[c]} \ {{[]},{[c]}, UNIV - {[], [c]}}" - proof - fix x - assume in_quot: "x \ QUOT {[c]}" - show "x \ {{[]}, {[c]}, UNIV - {[],[c]}}" - proof - - from in_quot - have "x = {[]} \ x = {[c]} \ x = UNIV - {[],[c]}" - unfolding QUOT_def equiv_class_def - proof - fix xa - assume in_eqiv: "x \ {{y. xa \{[c]}\ y}}" - show "x = {[]} \ x = {[c]} \ x = UNIV - {[], [c]}" - proof- - have "xa = [] \ x = {[]}" using in_eqiv - by (auto simp add:equiv_str_def) - moreover have "xa = [c] \ x = {[c]}" - proof - - have "xa = [c] \ {y. xa \{[c]}\ y} = {[c]}" using in_eqiv - apply (simp add:equiv_str_def) - apply (rule set_ext, rule iffI, simp) - apply (drule_tac x = "[]" in spec, auto) - done - thus "xa = [c] \ x = {[c]}" using in_eqiv by simp - qed - moreover have "\xa \ []; xa \ [c]\ \ x = UNIV - {[],[c]}" - proof - - have "\xa \ []; xa \ [c]\ \ {y. xa \{[c]}\ y} = UNIV - {[],[c]}" - apply (clarsimp simp add:equiv_str_def) - apply (rule set_ext, rule iffI, simp) - apply (rule conjI) - apply (drule_tac x = "[c]" in spec, simp) - apply (drule_tac x = "[]" in spec, simp) - by (auto dest:quot_single_aux) - thus "\xa \ []; xa \ [c]\ \ x = UNIV - {[],[c]}" using in_eqiv by simp - qed - ultimately show ?thesis by blast - qed - qed - thus ?thesis by simp - qed - qed - next - show "{{[]}, {[c]}, UNIV - {[],[c]}} \ QUOT {[c]}" - proof - fix x - assume in_res: "x \ {{[]},{[c]}, (UNIV::string set) - {[],[c]}}" - show "x \ (QUOT {[c]})" - proof - - have "x = {[]} \ x \ QUOT {[c]}" - apply (simp add:QUOT_def equiv_class_def equiv_str_def) - by (rule_tac x = "[]" in exI, auto) - moreover have "x = {[c]} \ x \ QUOT {[c]}" - apply (simp add:QUOT_def equiv_class_def equiv_str_def) - apply (rule_tac x = "[c]" in exI, simp) - apply (rule set_ext, rule iffI, simp+) - by (drule_tac x = "[]" in spec, simp) - moreover have "x = UNIV - {[],[c]} \ x \ QUOT {[c]}" - using exist_another - apply (clarsimp simp add:QUOT_def equiv_class_def equiv_str_def) - apply (rule_tac x = "[a]" in exI, simp) - apply (rule set_ext, rule iffI, simp) - apply (clarsimp simp:quot_single_aux, simp) - apply (rule conjI) - apply (drule_tac x = "[c]" in spec, simp) - by (drule_tac x = "[]" in spec, simp) - ultimately show ?thesis using in_res by blast - qed - qed - qed -qed - -lemma eq_class_imp_eq_str: - "\x\lang = \y\lang \ x \lang\ y" -by (auto simp:equiv_class_def equiv_str_def) - -lemma finite_tag_image: - "finite (range tag) \ finite (((op `) tag) ` S)" -apply (rule_tac B = "Pow (tag ` UNIV)" in finite_subset) -by (auto simp add:image_def Pow_def) - -lemma str_inj_imps: - assumes str_inj: "\ m n. tag m = tag (n::string) \ m \lang\ n" - shows "inj_on ((op `) tag) (QUOT lang)" -proof (clarsimp simp add:inj_on_def QUOT_def) - fix x y - assume eq_tag: "tag ` \x\lang = tag ` \y\lang" - show "\x\lang = \y\lang" - proof - - have aux1:"\a b. a \ (\b\lang) \ (a \lang\ b)" - by (simp add:equiv_class_def equiv_str_def) - have aux2: "\ A B f. \f ` A = f ` B; A \ {}\ \ \ a b. a \ A \ b \ B \ f a = f b" - by auto - have aux3: "\ a l. \a\l \ {}" - by (auto simp:equiv_class_def equiv_str_def) - show ?thesis using eq_tag - apply (drule_tac aux2, simp add:aux3, clarsimp) - apply (drule_tac str_inj, (drule_tac aux1)+) - by (simp add:equiv_str_def equiv_class_def) - qed -qed - -definition tag_str_ALT :: "string set \ string set \ string \ (string set \ string set)" -where - "tag_str_ALT L\<^isub>1 L\<^isub>2 x \ (\x\L\<^isub>1, \x\L\<^isub>2)" - -lemma tag_str_alt_range_finite: - assumes finite1: "finite (QUOT L\<^isub>1)" - and finite2: "finite (QUOT L\<^isub>2)" - shows "finite (range (tag_str_ALT L\<^isub>1 L\<^isub>2))" -proof - - have "{y. \x. y = (\x\L\<^isub>1, \x\L\<^isub>2)} \ (QUOT L\<^isub>1) \ (QUOT L\<^isub>2)" - by (auto simp:QUOT_def) - thus ?thesis using finite1 finite2 - by (auto simp: image_def tag_str_ALT_def UNION_def - intro: finite_subset[where B = "(QUOT L\<^isub>1) \ (QUOT L\<^isub>2)"]) -qed - -lemma tag_str_alt_inj: - "tag_str_ALT L\<^isub>1 L\<^isub>2 x = tag_str_ALT L\<^isub>1 L\<^isub>2 y \ x \(L\<^isub>1 \ L\<^isub>2)\ y" -apply (simp add:tag_str_ALT_def equiv_class_def equiv_str_def) -by blast - -lemma quot_alt: - assumes finite1: "finite (QUOT L\<^isub>1)" - and finite2: "finite (QUOT L\<^isub>2)" - shows "finite (QUOT (L\<^isub>1 \ L\<^isub>2))" -proof (rule_tac f = "(op `) (tag_str_ALT L\<^isub>1 L\<^isub>2)" in finite_imageD) - show "finite (op ` (tag_str_ALT L\<^isub>1 L\<^isub>2) ` QUOT (L\<^isub>1 \ L\<^isub>2))" - using finite_tag_image tag_str_alt_range_finite finite1 finite2 - by auto -next - show "inj_on (op ` (tag_str_ALT L\<^isub>1 L\<^isub>2)) (QUOT (L\<^isub>1 \ L\<^isub>2))" - apply (rule_tac str_inj_imps) - by (erule_tac tag_str_alt_inj) -qed - -(* list_diff:: list substract, once different return tailer *) -fun list_diff :: "'a list \ 'a list \ 'a list" (infix "-" 51) -where - "list_diff [] xs = []" | - "list_diff (x#xs) [] = x#xs" | - "list_diff (x#xs) (y#ys) = (if x = y then list_diff xs ys else (x#xs))" - -lemma [simp]: "(x @ y) - x = y" -apply (induct x) -by (case_tac y, simp+) - -lemma [simp]: "x - x = []" -by (induct x, auto) - -lemma [simp]: "x = xa @ y \ x - xa = y " -by (induct x, auto) - -lemma [simp]: "x - [] = x" -by (induct x, auto) - -lemma [simp]: "xa \ x \ (x @ y) - xa = (x - xa) @ y" -by (auto elim:prefixE) - -definition tag_str_SEQ:: "string set \ string set \ string \ (string set \ string set set)" -where - "tag_str_SEQ L\<^isub>1 L\<^isub>2 x \ if (\ xa \ x. xa \ L\<^isub>1) - then (\x\L\<^isub>1, {\(x - xa)\L\<^isub>2 | xa. xa \ x \ xa \ L\<^isub>1}) - else (\x\L\<^isub>1, {})" - -lemma tag_seq_eq_E: - "tag_str_SEQ L\<^isub>1 L\<^isub>2 x = tag_str_SEQ L\<^isub>1 L\<^isub>2 y \ - ((\ xa \ x. xa \ L\<^isub>1) \ \x\L\<^isub>1 = \y\L\<^isub>1 \ - {\(x - xa)\L\<^isub>2 | xa. xa \ x \ xa \ L\<^isub>1} = {\(y - ya)\L\<^isub>2 | ya. ya \ y \ ya \ L\<^isub>1} ) \ - ((\ xa \ x. xa \ L\<^isub>1) \ \x\L\<^isub>1 = \y\L\<^isub>1)" -by (simp add:tag_str_SEQ_def split:if_splits, blast) - -lemma tag_str_seq_range_finite: - assumes finite1: "finite (QUOT L\<^isub>1)" - and finite2: "finite (QUOT L\<^isub>2)" - shows "finite (range (tag_str_SEQ L\<^isub>1 L\<^isub>2))" -proof - - have "(range (tag_str_SEQ L\<^isub>1 L\<^isub>2)) \ (QUOT L\<^isub>1) \ (Pow (QUOT L\<^isub>2))" - by (auto simp:image_def tag_str_SEQ_def QUOT_def) - thus ?thesis using finite1 finite2 - by (rule_tac B = "(QUOT L\<^isub>1) \ (Pow (QUOT L\<^isub>2))" in finite_subset, auto) -qed - -lemma app_in_seq_decom[rule_format]: - "\ x. x @ z \ L\<^isub>1 ; L\<^isub>2 \ (\ xa \ x. xa \ L\<^isub>1 \ (x - xa) @ z \ L\<^isub>2) \ - (\ za \ z. (x @ za) \ L\<^isub>1 \ (z - za) \ L\<^isub>2)" -apply (induct z) -apply (simp, rule allI, rule impI, rule disjI1) -apply (clarsimp simp add:lang_seq_def) -apply (rule_tac x = s1 in exI, simp) -apply (rule allI | rule impI)+ -apply (drule_tac x = "x @ [a]" in spec, simp) -apply (erule exE | erule conjE | erule disjE)+ -apply (rule disjI2, rule_tac x = "[a]" in exI, simp) -apply (rule disjI1, rule_tac x = xa in exI, simp) -apply (erule exE | erule conjE)+ -apply (rule disjI2, rule_tac x = "a # za" in exI, simp) -done - -lemma tag_str_seq_inj: - assumes tag_eq: "tag_str_SEQ L\<^isub>1 L\<^isub>2 x = tag_str_SEQ L\<^isub>1 L\<^isub>2 y" - shows "(x::string) \(L\<^isub>1 ; L\<^isub>2)\ y" -proof - - have aux: "\ x y z. \tag_str_SEQ L\<^isub>1 L\<^isub>2 x = tag_str_SEQ L\<^isub>1 L\<^isub>2 y; x @ z \ L\<^isub>1 ; L\<^isub>2\ - \ y @ z \ L\<^isub>1 ; L\<^isub>2" - proof (drule app_in_seq_decom, erule disjE) - fix x y z - assume tag_eq: "tag_str_SEQ L\<^isub>1 L\<^isub>2 x = tag_str_SEQ L\<^isub>1 L\<^isub>2 y" - and x_gets_l2: "\xa\x. xa \ L\<^isub>1 \ (x - xa) @ z \ L\<^isub>2" - from x_gets_l2 have "\ xa \ x. xa \ L\<^isub>1" by blast - hence xy_l2:"{\(x - xa)\L\<^isub>2 | xa. xa \ x \ xa \ L\<^isub>1} = {\(y - ya)\L\<^isub>2 | ya. ya \ y \ ya \ L\<^isub>1}" - using tag_eq tag_seq_eq_E by blast - from x_gets_l2 obtain xa where xa_le_x: "xa \ x" - and xa_in_l1: "xa \ L\<^isub>1" - and rest_in_l2: "(x - xa) @ z \ L\<^isub>2" by blast - hence "\ ya. \(x - xa)\L\<^isub>2 = \(y - ya)\L\<^isub>2 \ ya \ y \ ya \ L\<^isub>1" using xy_l2 by auto - then obtain ya where ya_le_x: "ya \ y" - and ya_in_l1: "ya \ L\<^isub>1" - and rest_eq: "\(x - xa)\L\<^isub>2 = \(y - ya)\L\<^isub>2" by blast - from rest_eq rest_in_l2 have "(y - ya) @ z \ L\<^isub>2" - by (auto simp:equiv_class_def equiv_str_def) - hence "ya @ ((y - ya) @ z) \ L\<^isub>1 ; L\<^isub>2" using ya_in_l1 - by (auto simp:lang_seq_def) - thus "y @ z \ L\<^isub>1 ; L\<^isub>2" using ya_le_x - by (erule_tac prefixE, simp) - next - fix x y z - assume tag_eq: "tag_str_SEQ L\<^isub>1 L\<^isub>2 x = tag_str_SEQ L\<^isub>1 L\<^isub>2 y" - and x_gets_l1: "\za\z. x @ za \ L\<^isub>1 \ z - za \ L\<^isub>2" - from tag_eq tag_seq_eq_E have x_y_eq: "\x\L\<^isub>1 = \y\L\<^isub>1" by blast - from x_gets_l1 obtain za where za_le_z: "za \ z" - and x_za_in_l1: "(x @ za) \ L\<^isub>1" - and rest_in_l2: "z - za \ L\<^isub>2" by blast - from x_y_eq x_za_in_l1 have y_za_in_l1: "y @ za \ L\<^isub>1" - by (auto simp:equiv_class_def equiv_str_def) - hence "(y @ za) @ (z - za) \ L\<^isub>1 ; L\<^isub>2" using rest_in_l2 - apply (simp add:lang_seq_def) - by (rule_tac x = "y @ za" in exI, rule_tac x = "z - za" in exI, simp) - thus "y @ z \ L\<^isub>1 ; L\<^isub>2" using za_le_z - by (erule_tac prefixE, simp) - qed - show ?thesis using tag_eq - apply (simp add:equiv_str_def) - by (auto intro:aux) -qed - -lemma quot_seq: - assumes finite1: "finite (QUOT L\<^isub>1)" - and finite2: "finite (QUOT L\<^isub>2)" - shows "finite (QUOT (L\<^isub>1;L\<^isub>2))" -proof (rule_tac f = "(op `) (tag_str_SEQ L\<^isub>1 L\<^isub>2)" in finite_imageD) - show "finite (op ` (tag_str_SEQ L\<^isub>1 L\<^isub>2) ` QUOT (L\<^isub>1 ; L\<^isub>2))" - using finite_tag_image tag_str_seq_range_finite finite1 finite2 - by auto -next - show "inj_on (op ` (tag_str_SEQ L\<^isub>1 L\<^isub>2)) (QUOT (L\<^isub>1 ; L\<^isub>2))" - apply (rule_tac str_inj_imps) - by (erule_tac tag_str_seq_inj) -qed - -(****************** the STAR case ************************) - -lemma app_eq_elim[rule_format]: - "\ a. \ b x y. a @ b = x @ y \ (\ aa ab. a = aa @ ab \ x = aa \ y = ab @ b) \ - (\ ba bb. b = ba @ bb \ x = a @ ba \ y = bb \ ba \ [])" - apply (induct_tac a rule:List.induct, simp) - apply (rule allI | rule impI)+ - by (case_tac x, auto) - -definition tag_str_STAR:: "string set \ string \ string set set" -where - "tag_str_STAR L\<^isub>1 x \ if (x = []) - then {} - else {\x\<^isub>2\L\<^isub>1 | x\<^isub>1 x\<^isub>2. x = x\<^isub>1 @ x\<^isub>2 \ x\<^isub>1 \ L\<^isub>1\ \ x\<^isub>2 \ []}" - -lemma tag_str_star_range_finite: - assumes finite1: "finite (QUOT L\<^isub>1)" - shows "finite (range (tag_str_STAR L\<^isub>1))" -proof - - have "range (tag_str_STAR L\<^isub>1) \ Pow (QUOT L\<^isub>1)" - by (auto simp:image_def tag_str_STAR_def QUOT_def) - thus ?thesis using finite1 - by (rule_tac B = "Pow (QUOT L\<^isub>1)" in finite_subset, auto) -qed - -lemma star_prop[rule_format]: "x \ lang\ \ \ y. y \ lang\ \ x @ y \ lang\" -by (erule Star.induct, auto) - -lemma star_prop2: "y \ lang \ y \ lang\" -by (drule step[of y lang "[]"], auto simp:start) - -lemma star_prop3[rule_format]: "x \ lang\ \ \y . y \ lang \ x @ y \ lang\" -by (erule Star.induct, auto intro:star_prop2) - -lemma postfix_prop: "y >>= (x @ y) \ x = []" -by (erule postfixE, induct x arbitrary:y, auto) - -lemma inj_aux: - "\(m @ z) \ L\<^isub>1\; m \L\<^isub>1\ yb; xa @ m = x; xa \ L\<^isub>1\; m \ []; - \ xa xb. x = xa @ xb \ xa \ L\<^isub>1\ \ xb \ [] \ xb @ z \ L\<^isub>1\ \ xb >>= m\ - \ (yb @ z) \ L\<^isub>1\" -proof- - have "\s. s \ L\<^isub>1\ \ \ m z yb. (s = m @ z \ m \L\<^isub>1\ yb \ x = xa @ m \ xa \ L\<^isub>1\ \ m \ [] \ - (\ xa xb. x = xa @ xb \ xa \ L\<^isub>1\ \ xb \ [] \ xb @ z \ L\<^isub>1\ \ xb >>= m) \ (yb @ z) \ L\<^isub>1\)" - apply (erule Star.induct, simp) - apply (rule allI | rule impI | erule conjE)+ - apply (drule app_eq_elim) - apply (erule disjE | erule exE | erule conjE)+ - apply simp - apply (simp (no_asm) only:append_assoc[THEN sym]) - apply (rule step) - apply (simp add:equiv_str_def) - apply simp - - apply (erule exE | erule conjE)+ - apply (rotate_tac 3) - apply (frule_tac x = "xa @ s1" in spec) - apply (rotate_tac 12) - apply (drule_tac x = ba in spec) - apply (erule impE) - apply ( simp add:star_prop3) - apply (simp) - apply (drule postfix_prop) - apply simp - done - thus "\(m @ z) \ L\<^isub>1\; m \L\<^isub>1\ yb; xa @ m = x; xa \ L\<^isub>1\; m \ []; - \ xa xb. x = xa @ xb \ xa \ L\<^isub>1\ \ xb \ [] \ xb @ z \ L\<^isub>1\ \ xb >>= m\ - \ (yb @ z) \ L\<^isub>1\" by blast -qed - - -lemma min_postfix_exists[rule_format]: - "finite A \ A \ {} \ (\ a \ A. \ b \ A. ((b >>= a) \ (a >>= b))) - \ (\ min. (min \ A \ (\ a \ A. a >>= min)))" -apply (erule finite.induct) -apply simp -apply simp -apply (case_tac "A = {}") -apply simp -apply clarsimp -apply (case_tac "a >>= min") -apply (rule_tac x = min in exI, simp) -apply (rule_tac x = a in exI, simp) -apply clarify -apply (rotate_tac 5) -apply (erule_tac x = aa in ballE) defer apply simp -apply (erule_tac ys = min in postfix_trans) -apply (erule_tac x = min in ballE) -by simp+ - -lemma tag_str_star_inj: - "tag_str_STAR L\<^isub>1 x = tag_str_STAR L\<^isub>1 (y::string) \ x \L\<^isub>1\\ y" -proof - - have aux: "\ x y z. \tag_str_STAR L\<^isub>1 x = tag_str_STAR L\<^isub>1 y; x @ z \ L\<^isub>1\\ \ y @ z \ L\<^isub>1\" - proof- - fix x y z - assume tag_eq: "tag_str_STAR L\<^isub>1 x = tag_str_STAR L\<^isub>1 y" - and x_z: "x @ z \ L\<^isub>1\" - show "y @ z \ L\<^isub>1\" - proof (cases "x = []") - case True - with tag_eq have "y = []" by (simp add:tag_str_STAR_def split:if_splits, blast) - thus ?thesis using x_z True by simp - next - case False - hence not_empty: "{xb. \ xa. x = xa @ xb \ xa \ L\<^isub>1\ \ xb \ [] \ xb @ z \ L\<^isub>1\} \ {}" using x_z - by (simp, rule_tac x = x in exI, rule_tac x = "[]" in exI, simp add:start) - have finite_set: "finite {xb. \ xa. x = xa @ xb \ xa \ L\<^isub>1\ \ xb \ [] \ xb @ z \ L\<^isub>1\}" - apply (rule_tac B = "{xb. \ xa. x = xa @ xb}" in finite_subset) - apply auto - apply (induct x, simp) - apply (subgoal_tac "{xb. \xa. a # x = xa @ xb} = insert (a # x) {xb. \xa. x = xa @ xb}") - apply auto - by (case_tac xaa, simp+) - have comparable: "\ a \ {xb. \ xa. x = xa @ xb \ xa \ L\<^isub>1\ \ xb \ [] \ xb @ z \ L\<^isub>1\}. - \ b \ {xb. \ xa. x = xa @ xb \ xa \ L\<^isub>1\ \ xb \ [] \ xb @ z \ L\<^isub>1\}. - ((b >>= a) \ (a >>= b))" - by (auto simp:postfix_def, drule app_eq_elim, blast) - hence "\ min. min \ {xb. \ xa. x = xa @ xb \ xa \ L\<^isub>1\ \ xb \ [] \ xb @ z \ L\<^isub>1\} - \ (\ xa xb. x = xa @ xb \ xa \ L\<^isub>1\ \ xb \ [] \ xb @ z \ L\<^isub>1\ \ xb >>= min)" - using finite_set not_empty comparable - apply (drule_tac min_postfix_exists, simp) - by (erule exE, rule_tac x = min in exI, auto) - then obtain min xa where x_decom: "x = xa @ min \ xa \ L\<^isub>1\" - and min_not_empty: "min \ []" - and min_z_in_star: "min @ z \ L\<^isub>1\" - and is_min: "\ xa xb. x = xa @ xb \ xa \ L\<^isub>1\ \ xb \ [] \ xb @ z \ L\<^isub>1\ \ xb >>= min" by blast - from x_decom min_not_empty have "\min\L\<^isub>1 \ tag_str_STAR L\<^isub>1 x" by (auto simp:tag_str_STAR_def) - hence "\ yb. \yb\L\<^isub>1 \ tag_str_STAR L\<^isub>1 y \ \min\L\<^isub>1 = \yb\L\<^isub>1" using tag_eq by auto - hence "\ ya yb. y = ya @ yb \ ya \ L\<^isub>1\ \ min \L\<^isub>1\ yb \ yb \ [] " - by (simp add:tag_str_STAR_def equiv_class_def equiv_str_def split:if_splits, blast) - then obtain ya yb where y_decom: "y = ya @ yb" - and ya_in_star: "ya \ L\<^isub>1\" - and yb_not_empty: "yb \ []" - and min_yb_eq: "min \L\<^isub>1\ yb" by blast - from min_z_in_star min_yb_eq min_not_empty is_min x_decom - have "yb @ z \ L\<^isub>1\" - by (rule_tac x = x and xa = xa in inj_aux, simp+) - thus ?thesis using ya_in_star y_decom - by (auto dest:star_prop) - qed - qed - show "tag_str_STAR L\<^isub>1 x = tag_str_STAR L\<^isub>1 (y::string) \ x \L\<^isub>1\\ y" - by (auto intro:aux simp:equiv_str_def) -qed - -lemma quot_star: - assumes finite1: "finite (QUOT L\<^isub>1)" - shows "finite (QUOT (L\<^isub>1\))" -proof (rule_tac f = "(op `) (tag_str_STAR L\<^isub>1)" in finite_imageD) - show "finite (op ` (tag_str_STAR L\<^isub>1) ` QUOT (L\<^isub>1\))" - using finite_tag_image tag_str_star_range_finite finite1 - by auto -next - show "inj_on (op ` (tag_str_STAR L\<^isub>1)) (QUOT (L\<^isub>1\))" - apply (rule_tac str_inj_imps) - by (erule_tac tag_str_star_inj) -qed - -lemma other_direction: - "Lang = L (r::rexp) \ finite (QUOT Lang)" -apply (induct arbitrary:Lang rule:rexp.induct) -apply (simp add:QUOT_def equiv_class_def equiv_str_def) -by (simp_all add:quot_lambda quot_single quot_seq quot_alt quot_star) - -end