149
|
1 |
theory Closure
|
|
2 |
imports Myhill_2
|
|
3 |
begin
|
|
4 |
|
|
5 |
section {* Closure properties of regular languages *}
|
|
6 |
|
|
7 |
abbreviation
|
|
8 |
regular :: "lang \<Rightarrow> bool"
|
|
9 |
where
|
|
10 |
"regular A \<equiv> \<exists>r::rexp. A = L r"
|
|
11 |
|
|
12 |
|
|
13 |
lemma closure_union[intro]:
|
|
14 |
assumes "regular A" "regular B"
|
|
15 |
shows "regular (A \<union> B)"
|
|
16 |
proof -
|
|
17 |
from assms obtain r1 r2::rexp where "L r1 = A" "L r2 = B" by auto
|
|
18 |
then have "A \<union> B = L (ALT r1 r2)" by simp
|
|
19 |
then show "regular (A \<union> B)" by blast
|
|
20 |
qed
|
|
21 |
|
|
22 |
lemma closure_seq[intro]:
|
|
23 |
assumes "regular A" "regular B"
|
|
24 |
shows "regular (A ;; B)"
|
|
25 |
proof -
|
|
26 |
from assms obtain r1 r2::rexp where "L r1 = A" "L r2 = B" by auto
|
|
27 |
then have "A ;; B = L (SEQ r1 r2)" by simp
|
|
28 |
then show "regular (A ;; B)" by blast
|
|
29 |
qed
|
|
30 |
|
|
31 |
lemma closure_star[intro]:
|
|
32 |
assumes "regular A"
|
|
33 |
shows "regular (A\<star>)"
|
|
34 |
proof -
|
|
35 |
from assms obtain r::rexp where "L r = A" by auto
|
|
36 |
then have "A\<star> = L (STAR r)" by simp
|
|
37 |
then show "regular (A\<star>)" by blast
|
|
38 |
qed
|
|
39 |
|
|
40 |
lemma closure_complement[intro]:
|
|
41 |
assumes "regular A"
|
|
42 |
shows "regular (- A)"
|
|
43 |
proof -
|
|
44 |
from assms have "finite (UNIV // \<approx>A)" by (simp add: Myhill_Nerode)
|
|
45 |
then have "finite (UNIV // \<approx>(-A))" by (simp add: str_eq_rel_def)
|
|
46 |
then show "regular (- A)" by (simp add: Myhill_Nerode)
|
|
47 |
qed
|
|
48 |
|
|
49 |
lemma closure_difference[intro]:
|
|
50 |
assumes "regular A" "regular B"
|
|
51 |
shows "regular (A - B)"
|
|
52 |
proof -
|
|
53 |
have "A - B = - (- A \<union> B)" by blast
|
|
54 |
moreover
|
|
55 |
have "regular (- (- A \<union> B))"
|
|
56 |
using assms by blast
|
|
57 |
ultimately show "regular (A - B)" by simp
|
|
58 |
qed
|
|
59 |
|
|
60 |
lemma closure_intersection[intro]:
|
|
61 |
assumes "regular A" "regular B"
|
|
62 |
shows "regular (A \<inter> B)"
|
|
63 |
proof -
|
|
64 |
have "A \<inter> B = - (- A \<union> - B)" by blast
|
|
65 |
moreover
|
|
66 |
have "regular (- (- A \<union> - B))"
|
|
67 |
using assms by blast
|
|
68 |
ultimately show "regular (A \<inter> B)" by simp
|
|
69 |
qed
|
|
70 |
|
|
71 |
|
|
72 |
text {* closure under string reversal *}
|
|
73 |
|
|
74 |
fun
|
|
75 |
Rev :: "rexp \<Rightarrow> rexp"
|
|
76 |
where
|
|
77 |
"Rev NULL = NULL"
|
|
78 |
| "Rev EMPTY = EMPTY"
|
|
79 |
| "Rev (CHAR c) = CHAR c"
|
|
80 |
| "Rev (ALT r1 r2) = ALT (Rev r1) (Rev r2)"
|
|
81 |
| "Rev (SEQ r1 r2) = SEQ (Rev r2) (Rev r1)"
|
|
82 |
| "Rev (STAR r) = STAR (Rev r)"
|
|
83 |
|
|
84 |
lemma rev_Seq:
|
|
85 |
"(rev ` A) ;; (rev ` B) = rev ` (B ;; A)"
|
|
86 |
unfolding Seq_def image_def
|
|
87 |
apply(auto)
|
|
88 |
apply(rule_tac x="xb @ xa" in exI)
|
|
89 |
apply(auto)
|
|
90 |
done
|
|
91 |
|
|
92 |
lemma rev_Star1:
|
|
93 |
assumes a: "s \<in> (rev ` A)\<star>"
|
|
94 |
shows "s \<in> rev ` (A\<star>)"
|
|
95 |
using a
|
|
96 |
proof(induct rule: star_induct)
|
|
97 |
case (step s1 s2)
|
|
98 |
have inj: "inj (rev::string \<Rightarrow> string)" unfolding inj_on_def by auto
|
|
99 |
have "s1 \<in> rev ` A" "s2 \<in> rev ` (A\<star>)" by fact+
|
|
100 |
then obtain x1 x2 where "x1 \<in> A" "x2 \<in> A\<star>" and eqs: "s1 = rev x1" "s2 = rev x2" by auto
|
|
101 |
then have "x1 \<in> A\<star>" "x2 \<in> A\<star>" by (auto intro: star_intro2)
|
|
102 |
then have "x2 @ x1 \<in> A\<star>" by (auto intro: star_intro1)
|
|
103 |
then have "rev (x2 @ x1) \<in> rev ` A\<star>" using inj by (simp only: inj_image_mem_iff)
|
|
104 |
then show "s1 @ s2 \<in> rev ` A\<star>" using eqs by simp
|
|
105 |
qed (auto)
|
|
106 |
|
|
107 |
lemma rev_Star2:
|
|
108 |
assumes a: "s \<in> A\<star>"
|
|
109 |
shows "rev s \<in> (rev ` A)\<star>"
|
|
110 |
using a
|
|
111 |
proof(induct rule: star_induct)
|
|
112 |
case (step s1 s2)
|
|
113 |
have inj: "inj (rev::string \<Rightarrow> string)" unfolding inj_on_def by auto
|
|
114 |
have "s1 \<in> A"by fact
|
|
115 |
then have "rev s1 \<in> rev ` A" using inj by (simp only: inj_image_mem_iff)
|
|
116 |
then have "rev s1 \<in> (rev ` A)\<star>" by (auto intro: star_intro2)
|
|
117 |
moreover
|
|
118 |
have "rev s2 \<in> (rev ` A)\<star>" by fact
|
|
119 |
ultimately show "rev (s1 @ s2) \<in> (rev ` A)\<star>" by (auto intro: star_intro1)
|
|
120 |
qed (auto)
|
|
121 |
|
|
122 |
lemma rev_Star:
|
|
123 |
"(rev ` A)\<star> = rev ` (A\<star>)"
|
|
124 |
using rev_Star1 rev_Star2 by auto
|
|
125 |
|
|
126 |
lemma rev_lang:
|
|
127 |
"L (Rev r) = rev ` (L r)"
|
|
128 |
by (induct r) (simp_all add: rev_Star rev_Seq image_Un)
|
|
129 |
|
|
130 |
lemma closure_reversal[intro]:
|
|
131 |
assumes "regular A"
|
|
132 |
shows "regular (rev ` A)"
|
|
133 |
proof -
|
|
134 |
from assms obtain r::rexp where "L r = A" by auto
|
|
135 |
then have "L (Rev r) = rev ` A" by (simp add: rev_lang)
|
|
136 |
then show "regular (rev` A)" by blast
|
|
137 |
qed
|
|
138 |
|
|
139 |
|
|
140 |
end |