# HG changeset patch # User urbanc # Date 1287489065 0 # Node ID 074d9a4b2bc9466f775eb36f438ed9c8f8dbf420 # Parent f20f391b21faa6677c3d6bbf4a49e8a6fb62e6a4 added a file about the easy closure properties of regular sets (the difficult parts, like complement, are missing) diff -r f20f391b21fa -r 074d9a4b2bc9 Closure.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Closure.thy Tue Oct 19 11:51:05 2010 +0000 @@ -0,0 +1,223 @@ +theory "RegSet" + imports "Main" +begin + + +text {* Sequential composition of sets *} + +definition + lang_seq :: "string set \ string set \ string set" ("_ ; _" [100,100] 100) +where + "L1 ; L2 = {s1@s2 | s1 s2. s1 \ L1 \ s2 \ L2}" + + +section {* Kleene star for sets *} + +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\" + + +text {* A standard property of star *} + +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_cases2: + shows "[] \ L \ L\ - {[]} = L ; L\" +by (subst lang_star_cases) + (simp add: lang_seq_def) + + +section {* Regular Expressions *} + +datatype rexp = + NULL +| EMPTY +| CHAR char +| SEQ rexp rexp +| ALT rexp rexp +| STAR rexp + + +section {* Semantics of Regular Expressions *} + +fun + L :: "rexp \ string set" +where + "L (NULL) = {}" +| "L (EMPTY) = {[]}" +| "L (CHAR c) = {[c]}" +| "L (SEQ r1 r2) = (L r1) ; (L r2)" +| "L (ALT r1 r2) = (L r1) \ (L r2)" +| "L (STAR r) = (L r)\" + +abbreviation + CUNIV :: "string set" +where + "CUNIV \ (\x. [x]) ` (UNIV::char set)" + +lemma CUNIV_star_minus: + "(CUNIV\ - {[c]}) = {[]} \ (CUNIV - {[c]}; (CUNIV\))" +apply(subst lang_star_cases) +apply(simp add: lang_seq_def) +oops + + +lemma string_in_CUNIV: + shows "s \ CUNIV\" +proof (induct s) + case Nil + show "[] \ CUNIV\" by (rule start) +next + case (Cons c s) + have "[c] \ CUNIV" by simp + moreover + have "s \ CUNIV\" by fact + ultimately have "[c] @ s \ CUNIV\" by (rule step) + then show "c # s \ CUNIV\" by simp +qed + +lemma UNIV_CUNIV_star: + shows "UNIV = CUNIV\" +using string_in_CUNIV +by (auto) + +abbreviation + reg :: "string set => bool" +where + "reg L1 \ (\r. L r = L1)" + +lemma reg_null [intro]: + shows "reg {}" +by (metis L.simps(1)) + +lemma reg_empty [intro]: + shows "reg {[]}" +by (metis L.simps(2)) + +lemma reg_star [intro]: + shows "reg L1 \ reg (L1\)" +by (metis L.simps(6)) + +lemma reg_seq [intro]: + assumes a: "reg L1" "reg L2" + shows "reg (L1 ; L2)" +using a +by (metis L.simps(4)) + +lemma reg_union [intro]: + assumes a: "reg L1" "reg L2" + shows "reg (L1 \ L2)" +using a +by (metis L.simps(5)) + +lemma reg_string [intro]: + fixes s::string + shows "reg {s}" +proof (induct s) + case Nil + show "reg {[]}" by (rule reg_empty) +next + case (Cons c s) + have "reg {s}" by fact + then obtain r where "L r = {s}" by auto + then have "L (SEQ (CHAR c) r) = {[c]} ; {s}" by simp + also have "\ = {c # s}" by (simp add: lang_seq_def) + finally show "reg {c # s}" by blast +qed + +lemma reg_finite [intro]: + assumes a: "finite L1" + shows "reg L1" +using a +proof(induct) + case empty + show "reg {}" by (rule reg_null) +next + case (insert s S) + have "reg {s}" by (rule reg_string) + moreover + have "reg S" by fact + ultimately have "reg ({s} \ S)" by (rule reg_union) + then show "reg (insert s S)" by simp +qed + +lemma reg_cuniv [intro]: + shows "reg (CUNIV)" +by (rule reg_finite) (auto) + +lemma reg_univ: + shows "reg (UNIV::string set)" +proof - + have "reg CUNIV" by (rule reg_cuniv) + then have "reg (CUNIV\)" by (rule reg_star) + then show "reg UNIV" by (simp add: UNIV_CUNIV_star) +qed + +lemma reg_finite_subset: + assumes a: "finite L1" + and b: "reg L1" "L2 \ L1" + shows "reg L2" +using a b +apply(induct arbitrary: L2) +apply(simp add: reg_empty) +oops + + +lemma reg_not: + shows "reg (UNIV - L r)" +proof (induct r) + case NULL + have "reg UNIV" by (rule reg_univ) + then show "reg (UNIV - L NULL)" by simp +next + case EMPTY + have "[] \ CUNIV" by auto + moreover + have "reg (CUNIV; CUNIV\)" by auto + ultimately have "reg (CUNIV\ - {[]})" + using lang_star_cases2 by simp + then show "reg (UNIV - L EMPTY)" by (simp add: UNIV_CUNIV_star) +next + case (CHAR c) + then show "?case" + apply(simp) + +using reg_UNIV +apply(simp) +apply(simp add: char_star2[symmetric]) +apply(rule reg_seq) +apply(rule reg_cuniv) +apply(rule reg_star) +apply(rule reg_cuniv) +oops + + + +end + + + + + + + + + + diff -r f20f391b21fa -r 074d9a4b2bc9 Matcher.thy --- a/Matcher.thy Thu Oct 07 05:30:21 2010 +0000 +++ b/Matcher.thy Tue Oct 19 11:51:05 2010 +0000 @@ -68,7 +68,7 @@ where "der c (NULL) = NULL" | "der c (EMPTY) = NULL" -| "der c (CHAR c') = (if c=c' then EMPTY else NULL)" +| "der c (CHAR c') = (if c = c' then EMPTY else NULL)" | "der c (ALT r1 r2) = ALT (der c r1) (der c r2)" | "der c (SEQ r1 r2) = ALT (SEQ (der c r1) r2) (if nullable r1 then der c r2 else NULL)" | "der c (STAR r) = SEQ (der c r) (STAR r)" @@ -77,7 +77,7 @@ derivative :: "string \ rexp \ rexp" where "derivative [] r = r" -| "derivative (c#s) r = derivative s (der c r)" +| "derivative (c # s) r = derivative s (der c r)" fun matches :: "rexp \ string \ bool" @@ -92,29 +92,29 @@ by (induct r) (auto) lemma der_correctness: - shows "s \ L (der c r) \ c#s \ L r" + shows "s \ L (der c r) \ c # s \ L r" proof (induct r arbitrary: s) case (SEQ r1 r2 s) - have ih1: "\s. s \ L (der c r1) \ c#s \ L r1" by fact - have ih2: "\s. s \ L (der c r2) \ c#s \ L r2" by fact - show "s \ L (der c (SEQ r1 r2)) \ c#s \ L (SEQ r1 r2)" + have ih1: "\s. s \ L (der c r1) \ c # s \ L r1" by fact + have ih2: "\s. s \ L (der c r2) \ c # s \ L r2" by fact + show "s \ L (der c (SEQ r1 r2)) \ c # s \ L (SEQ r1 r2)" using ih1 ih2 by (auto simp add: nullable_correctness Cons_eq_append_conv) next case (STAR r s) - have ih: "\s. s \ L (der c r) \ c#s \ L r" by fact - show "s \ L (der c (STAR r)) \ c#s \ L (STAR r)" + have ih: "\s. s \ L (der c r) \ c # s \ L r" by fact + show "s \ L (der c (STAR r)) \ c # s \ L (STAR r)" proof assume "s \ L (der c (STAR r))" then have "s \ L (der c r) ; L r\" by simp - then have "c#s \ L r ; (L r)\" + then have "c # s \ L r ; (L r)\" by (auto simp add: ih Cons_eq_append_conv) - then have "c#s \ (L r)\" using lang_star_cases by auto - then show "c#s \ L (STAR r)" by simp + then have "c # s \ (L r)\" using lang_star_cases by auto + then show "c # s \ L (STAR r)" by simp next - assume "c#s \ L (STAR r)" - then have "c#s \ (L r)\" by simp + assume "c # s \ L (STAR r)" + then have "c # s \ (L r)\" by simp then have "s \ L (der c r); (L r)\" - by (induct x\"c#s" rule: Star.induct) + by (induct x\"c # s" rule: Star.induct) (auto simp add: ih append_eq_Cons_conv) then show "s \ L (der c (STAR r))" by simp qed @@ -141,14 +141,14 @@ match :: "rexp list \ string \ bool" where "match [] [] = True" -| "match [] (c#s) = False" -| "match (NULL#rs) s = False" -| "match (EMPTY#rs) s = match rs s" -| "match (CHAR c#rs) [] = False" -| "match (CHAR c#rs) (d#s) = (if c = d then match rs s else False)" -| "match (ALT r1 r2#rs) s = (match (r1#rs) s \ match (r2#rs) s)" -| "match (SEQ r1 r2#rs) s = match (r1#r2#rs) s" -| "match (STAR r#rs) s = (match rs s \ match (r#(STAR r)#rs) s)" +| "match [] (c # s) = False" +| "match (NULL # rs) s = False" +| "match (EMPTY # rs) s = match rs s" +| "match (CHAR c # rs) [] = False" +| "match (CHAR c # rs) (d # s) = (if c = d then match rs s else False)" +| "match (ALT r1 r2 # rs) s = (match (r1 # rs) s \ match (r2 # rs) s)" +| "match (SEQ r1 r2 # rs) s = match (r1 # r2 # rs) s" +| "match (STAR r # rs) s = (match rs s \ match (r # (STAR r) # rs) s)" apply(pat_completeness) apply(auto) done