|
1 theory RegExp |
|
2 imports "Main" |
|
3 begin |
|
4 |
|
5 text {* sequential composition of languages *} |
|
6 |
|
7 definition |
|
8 lang_seq :: "string set \<Rightarrow> string set \<Rightarrow> string set" ("_ ; _" [100,100] 100) |
|
9 where |
|
10 "L1 ; L2 = {s1@s2 | s1 s2. s1 \<in> L1 \<and> s2 \<in> L2}" |
|
11 |
|
12 lemma lang_seq_empty: |
|
13 shows "{[]} ; L = L" |
|
14 and "L ; {[]} = L" |
|
15 unfolding lang_seq_def by auto |
|
16 |
|
17 lemma lang_seq_null: |
|
18 shows "{} ; L = {}" |
|
19 and "L ; {} = {}" |
|
20 unfolding lang_seq_def by auto |
|
21 |
|
22 lemma lang_seq_append: |
|
23 assumes a: "s1 \<in> L1" |
|
24 and b: "s2 \<in> L2" |
|
25 shows "s1@s2 \<in> L1 ; L2" |
|
26 unfolding lang_seq_def |
|
27 using a b by auto |
|
28 |
|
29 lemma lang_seq_union: |
|
30 shows "(L1 \<union> L2); L3 = (L1; L3) \<union> (L2; L3)" |
|
31 and "L1; (L2 \<union> L3) = (L1; L2) \<union> (L1; L3)" |
|
32 unfolding lang_seq_def by auto |
|
33 |
|
34 lemma lang_seq_assoc: |
|
35 shows "(L1 ; L2) ; L3 = L1 ; (L2 ; L3)" |
|
36 by (simp add: lang_seq_def Collect_def mem_def expand_fun_eq) |
|
37 (metis append_assoc) |
|
38 |
|
39 lemma lang_seq_minus: |
|
40 shows "(L1; L2) - {[]} = |
|
41 (if [] \<in> L1 then L2 - {[]} else {}) \<union> |
|
42 (if [] \<in> L2 then L1 - {[]} else {}) \<union> ((L1 - {[]}); (L2 - {[]}))" |
|
43 apply(auto simp add: lang_seq_def) |
|
44 apply(metis mem_def self_append_conv) |
|
45 apply(metis mem_def self_append_conv2) |
|
46 apply(metis mem_def self_append_conv2) |
|
47 apply(metis mem_def self_append_conv) |
|
48 done |
|
49 |
|
50 section {* Kleene star for languages defined as least fixed point *} |
|
51 |
|
52 inductive_set |
|
53 Star :: "string set \<Rightarrow> string set" ("_\<star>" [101] 102) |
|
54 for L :: "string set" |
|
55 where |
|
56 start[intro]: "[] \<in> L\<star>" |
|
57 | step[intro]: "\<lbrakk>s1 \<in> L; s2 \<in> L\<star>\<rbrakk> \<Longrightarrow> s1@s2 \<in> L\<star>" |
|
58 |
|
59 lemma lang_star_empty: |
|
60 shows "{}\<star> = {[]}" |
|
61 by (auto elim: Star.cases) |
|
62 |
|
63 lemma lang_star_cases: |
|
64 shows "L\<star> = {[]} \<union> L ; L\<star>" |
|
65 proof |
|
66 { fix x |
|
67 have "x \<in> L\<star> \<Longrightarrow> x \<in> {[]} \<union> L ; L\<star>" |
|
68 unfolding lang_seq_def |
|
69 by (induct rule: Star.induct) (auto) |
|
70 } |
|
71 then show "L\<star> \<subseteq> {[]} \<union> L ; L\<star>" by auto |
|
72 next |
|
73 show "{[]} \<union> L ; L\<star> \<subseteq> L\<star>" |
|
74 unfolding lang_seq_def by auto |
|
75 qed |
|
76 |
|
77 lemma lang_star_cases': |
|
78 shows "L\<star> = {[]} \<union> L\<star> ; L" |
|
79 proof |
|
80 { fix x |
|
81 have "x \<in> L\<star> \<Longrightarrow> x \<in> {[]} \<union> L\<star> ; L" |
|
82 unfolding lang_seq_def |
|
83 apply (induct rule: Star.induct) |
|
84 apply simp |
|
85 apply simp |
|
86 apply (erule disjE) |
|
87 apply (auto)[1] |
|
88 apply (erule exE | erule conjE)+ |
|
89 apply (rule disjI2) |
|
90 apply (rule_tac x = "s1 @ s1a" in exI) |
|
91 by auto |
|
92 } |
|
93 then show "L\<star> \<subseteq> {[]} \<union> L\<star> ; L" by auto |
|
94 next |
|
95 show "{[]} \<union> L\<star> ; L \<subseteq> L\<star>" |
|
96 unfolding lang_seq_def |
|
97 apply auto |
|
98 apply (erule Star.induct) |
|
99 apply auto |
|
100 apply (drule step[of _ _ "[]"]) |
|
101 by (auto intro:start) |
|
102 qed |
|
103 |
|
104 lemma lang_star_simple: |
|
105 shows "L \<subseteq> L\<star>" |
|
106 by (subst lang_star_cases) |
|
107 (auto simp only: lang_seq_def) |
|
108 |
|
109 lemma lang_star_prop0_aux: |
|
110 "s2 \<in> L\<star> \<Longrightarrow> \<forall> s1. s1 \<in> L \<longrightarrow> (\<exists> s3 s4. s3 \<in> L\<star> \<and> s4 \<in> L \<and> s1 @ s2 = s3 @ s4)" |
|
111 apply (erule Star.induct) |
|
112 apply (clarify, rule_tac x = "[]" in exI, rule_tac x = s1 in exI, simp add:start) |
|
113 apply (clarify, drule_tac x = s1 in spec) |
|
114 apply (drule mp, simp, clarify) |
|
115 apply (rule_tac x = "s1a @ s3" in exI, rule_tac x = s4 in exI) |
|
116 by auto |
|
117 |
|
118 lemma lang_star_prop0: |
|
119 "\<lbrakk>s1 \<in> L; s2 \<in> L\<star>\<rbrakk> \<Longrightarrow> \<exists> s3 s4. s3 \<in> L\<star> \<and> s4 \<in> L \<and> s1 @ s2 = s3 @ s4" |
|
120 by (auto dest:lang_star_prop0_aux) |
|
121 |
|
122 lemma lang_star_prop1: |
|
123 assumes asm: "L1; L2 \<subseteq> L2" |
|
124 shows "L1\<star>; L2 \<subseteq> L2" |
|
125 proof - |
|
126 { fix s1 s2 |
|
127 assume minor: "s2 \<in> L2" |
|
128 assume major: "s1 \<in> L1\<star>" |
|
129 then have "s1@s2 \<in> L2" |
|
130 proof(induct rule: Star.induct) |
|
131 case start |
|
132 show "[]@s2 \<in> L2" using minor by simp |
|
133 next |
|
134 case (step s1 s1') |
|
135 have "s1 \<in> L1" by fact |
|
136 moreover |
|
137 have "s1'@s2 \<in> L2" by fact |
|
138 ultimately have "s1@(s1'@s2) \<in> L1; L2" by (auto simp add: lang_seq_def) |
|
139 with asm have "s1@(s1'@s2) \<in> L2" by auto |
|
140 then show "(s1@s1')@s2 \<in> L2" by simp |
|
141 qed |
|
142 } |
|
143 then show "L1\<star>; L2 \<subseteq> L2" by (auto simp add: lang_seq_def) |
|
144 qed |
|
145 |
|
146 lemma lang_star_prop2_aux: |
|
147 "s2 \<in> L2\<star> \<Longrightarrow> \<forall> s1. s1 \<in> L1 \<and> L1 ; L2 \<subseteq> L1 \<longrightarrow> s1 @ s2 \<in> L1" |
|
148 apply (erule Star.induct, simp) |
|
149 apply (clarify, drule_tac x = "s1a @ s1" in spec) |
|
150 by (auto simp:lang_seq_def) |
|
151 |
|
152 lemma lang_star_prop2: |
|
153 "L1; L2 \<subseteq> L1 \<Longrightarrow> L1 ; L2\<star> \<subseteq> L1" |
|
154 by (auto dest!:lang_star_prop2_aux simp:lang_seq_def) |
|
155 |
|
156 lemma lang_star_seq_subseteq: |
|
157 shows "L ; L\<star> \<subseteq> L\<star>" |
|
158 using lang_star_cases by blast |
|
159 |
|
160 lemma lang_star_double: |
|
161 shows "L\<star>; L\<star> = L\<star>" |
|
162 proof |
|
163 show "L\<star> ; L\<star> \<subseteq> L\<star>" |
|
164 using lang_star_prop1 lang_star_seq_subseteq by blast |
|
165 next |
|
166 have "L\<star> \<subseteq> L\<star> \<union> L\<star>; (L; L\<star>)" by auto |
|
167 also have "\<dots> = L\<star>;{[]} \<union> L\<star>; (L; L\<star>)" by (simp add: lang_seq_empty) |
|
168 also have "\<dots> = L\<star>; ({[]} \<union> L; L\<star>)" by (simp only: lang_seq_union) |
|
169 also have "\<dots> = L\<star>; L\<star>" using lang_star_cases by simp |
|
170 finally show "L\<star> \<subseteq> L\<star> ; L\<star>" by simp |
|
171 qed |
|
172 |
|
173 lemma lang_star_seq_subseteq': |
|
174 shows "L\<star>; L \<subseteq> L\<star>" |
|
175 proof - |
|
176 have "L \<subseteq> L\<star>" by (rule lang_star_simple) |
|
177 then have "L\<star>; L \<subseteq> L\<star>; L\<star>" by (auto simp add: lang_seq_def) |
|
178 then show "L\<star>; L \<subseteq> L\<star>" using lang_star_double by blast |
|
179 qed |
|
180 |
|
181 lemma |
|
182 shows "L\<star> \<subseteq> L\<star>\<star>" |
|
183 by (rule lang_star_simple) |
|
184 |
|
185 section {* tricky section *} |
|
186 |
|
187 lemma k1: |
|
188 assumes b: "s \<in> L\<star>" |
|
189 and a: "s \<noteq> []" |
|
190 shows "s \<in> (L - {[]}); L\<star>" |
|
191 using b a |
|
192 apply(induct rule: Star.induct) |
|
193 apply(simp) |
|
194 apply(case_tac "s1=[]") |
|
195 apply(simp) |
|
196 apply(simp add: lang_seq_def) |
|
197 apply(blast) |
|
198 done |
|
199 |
|
200 section {* (relies on lemma k1) *} |
|
201 |
|
202 lemma zzz: |
|
203 shows "{s. c#s \<in> L1\<star>} = {s. c#s \<in> L1} ; (L1\<star>)" |
|
204 apply(auto simp add: lang_seq_def Cons_eq_append_conv) |
|
205 apply(drule k1) |
|
206 apply(auto)[1] |
|
207 apply(auto simp add: lang_seq_def)[1] |
|
208 apply(rule_tac x="tl s1" in exI) |
|
209 apply(rule_tac x="s2" in exI) |
|
210 apply(auto)[1] |
|
211 apply(auto simp add: Cons_eq_append_conv)[2] |
|
212 apply(drule lang_seq_append) |
|
213 apply(assumption) |
|
214 apply(rotate_tac 1) |
|
215 apply(drule rev_subsetD) |
|
216 apply(rule lang_star_seq_subseteq) |
|
217 apply(simp) |
|
218 done |
|
219 |
|
220 |
|
221 |
|
222 section {* regular expressions *} |
|
223 |
|
224 datatype rexp = |
|
225 NULL |
|
226 | EMPTY |
|
227 | CHAR char |
|
228 | SEQ rexp rexp |
|
229 | ALT rexp rexp |
|
230 | STAR rexp |
|
231 |
|
232 |
|
233 consts L:: "'a \<Rightarrow> string set" |
|
234 |
|
235 fun |
|
236 L_rexp :: "rexp \<Rightarrow> string set" |
|
237 where |
|
238 "L_rexp (NULL) = {}" |
|
239 | "L_rexp (EMPTY) = {[]}" |
|
240 | "L_rexp (CHAR c) = {[c]}" |
|
241 | "L_rexp (SEQ r1 r2) = (L_rexp r1) ; (L_rexp r2)" |
|
242 | "L_rexp (ALT r1 r2) = (L_rexp r1) \<union> (L_rexp r2)" |
|
243 | "L_rexp (STAR r) = (L_rexp r)\<star>" |
|
244 |
|
245 defs (overloaded) |
|
246 l_rexp_abs: "L rexp \<equiv> L_rexp rexp" |
|
247 |
|
248 declare L_rexp.simps [simp del] L_rexp.simps [folded l_rexp_abs, simp add] |
|
249 |
|
250 definition |
|
251 Ls :: "rexp set \<Rightarrow> string set" |
|
252 where |
|
253 "Ls R = (\<Union>r\<in>R. (L r))" |
|
254 |
|
255 lemma Ls_union: |
|
256 "Ls (R1 \<union> R2) = (Ls R1) \<union> (Ls R2)" |
|
257 unfolding Ls_def by auto |
|
258 |
|
259 text {* helper function for termination proofs *} |
|
260 fun |
|
261 Left :: "rexp \<Rightarrow> rexp" |
|
262 where |
|
263 "Left (SEQ r1 r2) = r1" |
|
264 |
|
265 text {* dagger function *} |
|
266 |
|
267 function |
|
268 dagger :: "rexp \<Rightarrow> char \<Rightarrow> rexp list" ("_ \<dagger> _") |
|
269 where |
|
270 c1: "(NULL \<dagger> c) = []" |
|
271 | c2: "(EMPTY) \<dagger> c = []" |
|
272 | c3: "(CHAR c') \<dagger> c = (if c = c' then [EMPTY] else [])" |
|
273 | c4: "(ALT r1 r2) \<dagger> c = r1 \<dagger> c @ r2 \<dagger> c" |
|
274 | c5: "(SEQ NULL r2) \<dagger> c = []" |
|
275 | c6: "(SEQ EMPTY r2) \<dagger> c = r2 \<dagger> c" |
|
276 | c7: "(SEQ (CHAR c') r2) \<dagger> c = (if c = c' then [r2] else [])" |
|
277 | c8: "(SEQ (SEQ r11 r12) r2) \<dagger> c = (SEQ r11 (SEQ r12 r2)) \<dagger> c" |
|
278 | c9: "(SEQ (ALT r11 r12) r2) \<dagger> c = (SEQ r11 r2) \<dagger> c @ (SEQ r12 r2) \<dagger> c" |
|
279 | c10: "(SEQ (STAR r1) r2) \<dagger> c = r2 \<dagger> c @ [SEQ r' (SEQ (STAR r1) r2). r' \<leftarrow> r1 \<dagger> c]" |
|
280 | c11: "(STAR r) \<dagger> c = [SEQ r' (STAR r) . r' \<leftarrow> r \<dagger> c]" |
|
281 by (pat_completeness) (auto) |
|
282 |
|
283 termination dagger |
|
284 by (relation "measures [\<lambda>(r, c). size r, \<lambda>(r, c). size (Left r)]") (simp_all) |
|
285 |
|
286 lemma dagger_correctness: |
|
287 "Ls (set r \<dagger> c) = {s. c#s \<in> L r}" |
|
288 proof (induct rule: dagger.induct) |
|
289 case (1 c) |
|
290 show "Ls (set NULL \<dagger> c) = {s. c#s \<in> L NULL}" by (simp add: Ls_def) |
|
291 next |
|
292 case (2 c) |
|
293 show "Ls (set EMPTY \<dagger> c) = {s. c#s \<in> L EMPTY}" by (simp add: Ls_def) |
|
294 next |
|
295 case (3 c' c) |
|
296 show "Ls (set CHAR c' \<dagger> c) = {s. c#s \<in> L (CHAR c')}" by (simp add: Ls_def) |
|
297 next |
|
298 case (4 r1 r2 c) |
|
299 have ih1: "Ls (set r1 \<dagger> c) = {s. c#s \<in> L r1}" by fact |
|
300 have ih2: "Ls (set r2 \<dagger> c) = {s. c#s \<in> L r2}" by fact |
|
301 show "Ls (set ALT r1 r2 \<dagger> c) = {s. c#s \<in> L (ALT r1 r2)}" |
|
302 by (simp add: Ls_union ih1 ih2 Collect_disj_eq) |
|
303 next |
|
304 case (5 r2 c) |
|
305 show "Ls (set SEQ NULL r2 \<dagger> c) = {s. c#s \<in> L (SEQ NULL r2)}" by (simp add: Ls_def lang_seq_null) |
|
306 next |
|
307 case (6 r2 c) |
|
308 have ih: "Ls (set r2 \<dagger> c) = {s. c#s \<in> L r2}" by fact |
|
309 show "Ls (set SEQ EMPTY r2 \<dagger> c) = {s. c#s \<in> L (SEQ EMPTY r2)}" |
|
310 by (simp add: ih lang_seq_empty) |
|
311 next |
|
312 case (7 c' r2 c) |
|
313 show "Ls (set SEQ (CHAR c') r2 \<dagger> c) = {s. c#s \<in> L (SEQ (CHAR c') r2)}" |
|
314 by (simp add: Ls_def lang_seq_def) |
|
315 next |
|
316 case (8 r11 r12 r2 c) |
|
317 have ih: "Ls (set SEQ r11 (SEQ r12 r2) \<dagger> c) = {s. c#s \<in> L (SEQ r11 (SEQ r12 r2))}" by fact |
|
318 show "Ls (set SEQ (SEQ r11 r12) r2 \<dagger> c) = {s. c#s \<in> L (SEQ (SEQ r11 r12) r2)}" |
|
319 by (simp add: ih lang_seq_assoc) |
|
320 next |
|
321 case (9 r11 r12 r2 c) |
|
322 have ih1: "Ls (set SEQ r11 r2 \<dagger> c) = {s. c#s \<in> L (SEQ r11 r2)}" by fact |
|
323 have ih2: "Ls (set SEQ r12 r2 \<dagger> c) = {s. c#s \<in> L (SEQ r12 r2)}" by fact |
|
324 show "Ls (set SEQ (ALT r11 r12) r2 \<dagger> c) = {s. c#s \<in> L (SEQ (ALT r11 r12) r2)}" |
|
325 by (simp add: Ls_union ih1 ih2 lang_seq_union Collect_disj_eq) |
|
326 next |
|
327 case (10 r1 r2 c) |
|
328 have ih2: "Ls (set r2 \<dagger> c) = {s. c#s \<in> L r2}" by fact |
|
329 have ih1: "Ls (set r1 \<dagger> c) = {s. c#s \<in> L r1}" by fact |
|
330 have "Ls (set SEQ (STAR r1) r2 \<dagger> c) = Ls (set r2 \<dagger> c) \<union> (Ls (set r1 \<dagger> c); ((L r1)\<star> ; L r2))" |
|
331 by (auto simp add: lang_seq_def Ls_def) |
|
332 also have "\<dots> = {s. c#s \<in> L r2} \<union> ({s. c#s \<in> L r1} ; ((L r1)\<star> ; L r2))" using ih1 ih2 by simp |
|
333 also have "\<dots> = {s. c#s \<in> L r2} \<union> ({s. c#s \<in> L r1} ; (L r1)\<star>) ; L r2" by (simp add: lang_seq_assoc) |
|
334 also have "\<dots> = {s. c#s \<in> L r2} \<union> {s. c#s \<in> (L r1)\<star>} ; L r2" by (simp add: zzz) |
|
335 also have "\<dots> = {s. c#s \<in> L r2} \<union> {s. c#s \<in> (L r1)\<star> ; L r2}" |
|
336 by (auto simp add: lang_seq_def Cons_eq_append_conv) |
|
337 also have "\<dots> = {s. c#s \<in> (L r1)\<star> ; L r2}" |
|
338 by (force simp add: lang_seq_def) |
|
339 finally show "Ls (set SEQ (STAR r1) r2 \<dagger> c) = {s. c#s \<in> L (SEQ (STAR r1) r2)}" by simp |
|
340 next |
|
341 case (11 r c) |
|
342 have ih: "Ls (set r \<dagger> c) = {s. c#s \<in> L r}" by fact |
|
343 have "Ls (set (STAR r) \<dagger> c) = Ls (set r \<dagger> c) ; (L r)\<star>" |
|
344 by (auto simp add: lang_seq_def Ls_def) |
|
345 also have "\<dots> = {s. c#s \<in> L r} ; (L r)\<star>" using ih by simp |
|
346 also have "\<dots> = {s. c#s \<in> (L r)\<star>}" using zzz by simp |
|
347 finally show "Ls (set (STAR r) \<dagger> c) = {s. c#s \<in> L (STAR r)}" by simp |
|
348 qed |
|
349 |
|
350 |
|
351 text {* matcher function (based on the "list"-dagger function) *} |
|
352 fun |
|
353 first_True :: "bool list \<Rightarrow> bool" |
|
354 where |
|
355 "first_True [] = False" |
|
356 | "first_True (x#xs) = (if x then True else first_True xs)" |
|
357 |
|
358 lemma not_first_True[simp]: |
|
359 shows "(\<not>(first_True xs)) = (\<forall>x \<in> set xs. \<not>x)" |
|
360 by (induct xs) (auto) |
|
361 |
|
362 lemma first_True: |
|
363 shows "(first_True xs) = (\<exists>x \<in> set xs. x)" |
|
364 by (induct xs) (auto) |
|
365 |
|
366 text {* matcher function *} |
|
367 |
|
368 function |
|
369 matcher :: "rexp \<Rightarrow> string \<Rightarrow> bool" ("_ ! _") |
|
370 where |
|
371 "NULL ! s = False" |
|
372 | "EMPTY ! s = (s =[])" |
|
373 | "CHAR c ! s = (s = [c])" |
|
374 | "ALT r1 r2 ! s = (r1 ! s \<or> r2 ! s)" |
|
375 | "STAR r ! [] = True" |
|
376 | "STAR r ! c#s = first_True [SEQ (r') (STAR r) ! s. r' \<leftarrow> r \<dagger> c]" |
|
377 | "SEQ r1 r2 ! [] = (r1 ! [] \<and> r2 ! [])" |
|
378 | "SEQ NULL r2 ! (c#s) = False" |
|
379 | "SEQ EMPTY r2 ! (c#s) = (r2 ! c#s)" |
|
380 | "SEQ (CHAR c') r2 ! (c#s) = (if c'=c then r2 ! s else False)" |
|
381 | "SEQ (SEQ r11 r12) r2 ! (c#s) = (SEQ r11 (SEQ r12 r2) ! c#s)" |
|
382 | "SEQ (ALT r11 r12) r2 ! (c#s) = ((SEQ r11 r2) ! (c#s) \<or> (SEQ r12 r2) ! (c#s))" |
|
383 | "SEQ (STAR r1) r2 ! (c#s) = (r2 ! (c#s) \<or> first_True [SEQ r' (SEQ (STAR r1) r2) ! s. r' \<leftarrow> r1 \<dagger> c])" |
|
384 by (pat_completeness) (auto) |
|
385 |
|
386 termination matcher |
|
387 by(relation "measures [\<lambda>(r,s). length s, \<lambda>(r,s). size r, \<lambda>(r,s). size (Left r)]") (simp_all) |
|
388 |
|
389 text {* positive correctness of the matcher *} |
|
390 lemma matcher1: |
|
391 shows "r ! s \<Longrightarrow> s \<in> L r" |
|
392 proof (induct rule: matcher.induct) |
|
393 case (1 s) |
|
394 have "NULL ! s" by fact |
|
395 then show "s \<in> L NULL" by simp |
|
396 next |
|
397 case (2 s) |
|
398 have "EMPTY ! s" by fact |
|
399 then show "s \<in> L EMPTY" by simp |
|
400 next |
|
401 case (3 c s) |
|
402 have "CHAR c ! s" by fact |
|
403 then show "s \<in> L (CHAR c)" by simp |
|
404 next |
|
405 case (4 r1 r2 s) |
|
406 have ih1: "r1 ! s \<Longrightarrow> s \<in> L r1" by fact |
|
407 have ih2: "r2 ! s \<Longrightarrow> s \<in> L r2" by fact |
|
408 have "ALT r1 r2 ! s" by fact |
|
409 with ih1 ih2 show "s \<in> L (ALT r1 r2)" by auto |
|
410 next |
|
411 case (5 r) |
|
412 have "STAR r ! []" by fact |
|
413 then show "[] \<in> L (STAR r)" by auto |
|
414 next |
|
415 case (6 r c s) |
|
416 have ih1: "\<And>rx. \<lbrakk>rx \<in> set r \<dagger> c; SEQ rx (STAR r) ! s\<rbrakk> \<Longrightarrow> s \<in> L (SEQ rx (STAR r))" by fact |
|
417 have as: "STAR r ! c#s" by fact |
|
418 then obtain r' where imp1: "r' \<in> set r \<dagger> c" and imp2: "SEQ r' (STAR r) ! s" |
|
419 by (auto simp add: first_True) |
|
420 from imp2 imp1 have "s \<in> L (SEQ r' (STAR r))" using ih1 by simp |
|
421 then have "s \<in> L r' ; (L r)\<star>" by simp |
|
422 then have "s \<in> Ls (set r \<dagger> c) ; (L r)\<star>" using imp1 by (auto simp add: Ls_def lang_seq_def) |
|
423 then have "s \<in> {s. c#s \<in> L r} ; (L r)\<star>" by (auto simp add: dagger_correctness) |
|
424 then have "s \<in> {s. c#s \<in> (L r)\<star>}" by (simp add: zzz) |
|
425 then have "c#s \<in> {[c]}; {s. c#s \<in> (L r)\<star>}" by (auto simp add: lang_seq_def) |
|
426 then have "c#s \<in> (L r)\<star>" by (auto simp add: lang_seq_def) |
|
427 then show "c#s \<in> L (STAR r)" by simp |
|
428 next |
|
429 case (7 r1 r2) |
|
430 have ih1: "r1 ! [] \<Longrightarrow> [] \<in> L r1" by fact |
|
431 have ih2: "r2 ! [] \<Longrightarrow> [] \<in> L r2" by fact |
|
432 have as: "SEQ r1 r2 ! []" by fact |
|
433 then have "r1 ! [] \<and> r2 ! []" by simp |
|
434 then show "[] \<in> L (SEQ r1 r2)" using ih1 ih2 by (simp add: lang_seq_def) |
|
435 next |
|
436 case (8 r2 c s) |
|
437 have "SEQ NULL r2 ! c#s" by fact |
|
438 then show "c#s \<in> L (SEQ NULL r2)" by simp |
|
439 next |
|
440 case (9 r2 c s) |
|
441 have ih1: "r2 ! c#s \<Longrightarrow> c#s \<in> L r2" by fact |
|
442 have "SEQ EMPTY r2 ! c#s" by fact |
|
443 then show "c#s \<in> L (SEQ EMPTY r2)" using ih1 by (simp add: lang_seq_def) |
|
444 next |
|
445 case (10 c' r2 c s) |
|
446 have ih1: "\<lbrakk>c' = c; r2 ! s\<rbrakk> \<Longrightarrow> s \<in> L r2" by fact |
|
447 have "SEQ (CHAR c') r2 ! c#s" by fact |
|
448 then show "c#s \<in> L (SEQ (CHAR c') r2)" |
|
449 using ih1 by (auto simp add: lang_seq_def split: if_splits) |
|
450 next |
|
451 case (11 r11 r12 r2 c s) |
|
452 have ih1: "SEQ r11 (SEQ r12 r2) ! c#s \<Longrightarrow> c#s \<in> L (SEQ r11 (SEQ r12 r2))" by fact |
|
453 have "SEQ (SEQ r11 r12) r2 ! c#s" by fact |
|
454 then have "c#s \<in> L (SEQ r11 (SEQ r12 r2))" using ih1 by simp |
|
455 then show "c#s \<in> L (SEQ (SEQ r11 r12) r2)" by (simp add: lang_seq_assoc) |
|
456 next |
|
457 case (12 r11 r12 r2 c s) |
|
458 have ih1: "SEQ r11 r2 ! c#s \<Longrightarrow> c#s \<in> L (SEQ r11 r2)" by fact |
|
459 have ih2: "SEQ r12 r2 ! c#s \<Longrightarrow> c#s \<in> L (SEQ r12 r2)" by fact |
|
460 have "SEQ (ALT r11 r12) r2 ! c#s" by fact |
|
461 then show "c#s \<in> L (SEQ (ALT r11 r12) r2)" |
|
462 using ih1 ih2 by (auto simp add: lang_seq_union) |
|
463 next |
|
464 case (13 r1 r2 c s) |
|
465 have ih1: "r2 ! c#s \<Longrightarrow> c#s \<in> L r2" by fact |
|
466 have ih2: "\<And>r'. \<lbrakk>r' \<in> set r1 \<dagger> c; SEQ r' (SEQ (STAR r1) r2) ! s\<rbrakk> \<Longrightarrow> |
|
467 s \<in> L (SEQ r' (SEQ (STAR r1) r2))" by fact |
|
468 have "SEQ (STAR r1) r2 ! c#s" by fact |
|
469 then have "(r2 ! c#s) \<or> (\<exists>r' \<in> set r1 \<dagger> c. SEQ r' (SEQ (STAR r1) r2) ! s)" by (auto simp add: first_True) |
|
470 moreover |
|
471 { assume "r2 ! c#s" |
|
472 with ih1 have "c#s \<in> L r2" by simp |
|
473 then have "c # s \<in> L r1\<star> ; L r2" |
|
474 by (auto simp add: lang_seq_def) |
|
475 then have "c#s \<in> L (SEQ (STAR r1) r2)" by simp |
|
476 } |
|
477 moreover |
|
478 { assume "\<exists>r' \<in> set r1 \<dagger> c. SEQ r' (SEQ (STAR r1) r2) ! s" |
|
479 then obtain r' where imp1: "r' \<in> set r1 \<dagger> c" and imp2: "SEQ r' (SEQ (STAR r1) r2) ! s" by blast |
|
480 from imp2 imp1 have "s \<in> L (SEQ r' (SEQ (STAR r1) r2))" using ih2 by simp |
|
481 then have "s \<in> L r' ; ((L r1)\<star> ; L r2)" by simp |
|
482 then have "s \<in> Ls (set r1 \<dagger> c) ; ((L r1)\<star> ; L r2)" using imp1 by (auto simp add: Ls_def lang_seq_def) |
|
483 then have "s \<in> {s. c#s \<in> L r1} ; ((L r1)\<star> ; L r2)" by (simp add: dagger_correctness) |
|
484 then have "s \<in> ({s. c#s \<in> L r1} ; (L r1)\<star>) ; L r2" by (simp add: lang_seq_assoc) |
|
485 then have "s \<in> {s. c#s \<in> (L r1)\<star>} ; L r2" by (simp add: zzz) |
|
486 then have "c#s \<in> {[c]}; ({s. c#s \<in> (L r1)\<star>}; L r2)" by (auto simp add: lang_seq_def) |
|
487 then have "c#s \<in> ({[c]}; {s. c#s \<in> (L r1)\<star>}) ; L r2" by (simp add: lang_seq_assoc) |
|
488 then have "c#s \<in> (L r1)\<star>; L r2" by (auto simp add: lang_seq_def) |
|
489 then have "c#s \<in> L (SEQ (STAR r1) r2)" by simp |
|
490 } |
|
491 ultimately show "c#s \<in> L (SEQ (STAR r1) r2)" by blast |
|
492 qed |
|
493 |
|
494 text {* negative correctness of the matcher *} |
|
495 lemma matcher2: |
|
496 shows "\<not> r ! s \<Longrightarrow> s \<notin> L r" |
|
497 proof (induct rule: matcher.induct) |
|
498 case (1 s) |
|
499 have "\<not> NULL ! s" by fact |
|
500 then show "s \<notin> L NULL" by simp |
|
501 next |
|
502 case (2 s) |
|
503 have "\<not> EMPTY ! s" by fact |
|
504 then show "s \<notin> L EMPTY" by simp |
|
505 next |
|
506 case (3 c s) |
|
507 have "\<not> CHAR c ! s" by fact |
|
508 then show "s \<notin> L (CHAR c)" by simp |
|
509 next |
|
510 case (4 r1 r2 s) |
|
511 have ih2: "\<not> r1 ! s \<Longrightarrow> s \<notin> L r1" by fact |
|
512 have ih4: "\<not> r2 ! s \<Longrightarrow> s \<notin> L r2" by fact |
|
513 have "\<not> ALT r1 r2 ! s" by fact |
|
514 then show "s \<notin> L (ALT r1 r2)" by (simp add: ih2 ih4) |
|
515 next |
|
516 case (5 r) |
|
517 have "\<not> STAR r ! []" by fact |
|
518 then show "[] \<notin> L (STAR r)" by simp |
|
519 next |
|
520 case (6 r c s) |
|
521 have ih: "\<And>rx. \<lbrakk>rx \<in> set r \<dagger> c; \<not>SEQ rx (STAR r) ! s\<rbrakk> \<Longrightarrow> s \<notin> L (SEQ rx (STAR r))" by fact |
|
522 have as: "\<not> STAR r ! c#s" by fact |
|
523 then have "\<forall>r'\<in> set r \<dagger> c. \<not> (SEQ r' (STAR r) ! s)" by simp |
|
524 then have "\<forall>r'\<in> set r \<dagger> c. s \<notin> L (SEQ r' (STAR r))" using ih by auto |
|
525 then have "\<forall>r'\<in> set r \<dagger> c. s \<notin> L r' ; ((L r)\<star>)" by simp |
|
526 then have "s \<notin> (Ls (set r \<dagger> c)) ; ((L r)\<star>)" by (auto simp add: Ls_def lang_seq_def) |
|
527 then have "s \<notin> {s. c#s \<in> L r} ; ((L r)\<star>)" by (simp add: dagger_correctness) |
|
528 then have "s \<notin> {s. c#s \<in> (L r)\<star>}" by (simp add: zzz) |
|
529 then have "c#s \<notin> {[c]} ; {s. c#s \<in> (L r)\<star>}" by (auto simp add: lang_seq_assoc lang_seq_def) |
|
530 then have "c#s \<notin> (L r)\<star>" by (simp add: lang_seq_def) |
|
531 then show "c#s \<notin> L (STAR r)" by simp |
|
532 next |
|
533 case (7 r1 r2) |
|
534 have ih2: "\<not> r1 ! [] \<Longrightarrow> [] \<notin> L r1" by fact |
|
535 have ih4: "\<not> r2 ! [] \<Longrightarrow> [] \<notin> L r2" by fact |
|
536 have "\<not> SEQ r1 r2 ! []" by fact |
|
537 then have "\<not> r1 ! [] \<or> \<not> r2 ! []" by simp |
|
538 then show "[] \<notin> L (SEQ r1 r2)" using ih2 ih4 |
|
539 by (auto simp add: lang_seq_def) |
|
540 next |
|
541 case (8 r2 c s) |
|
542 have "\<not> SEQ NULL r2 ! c#s" by fact |
|
543 then show "c#s \<notin> L (SEQ NULL r2)" by (simp add: lang_seq_null) |
|
544 next |
|
545 case (9 r2 c s) |
|
546 have ih1: "\<not> r2 ! c#s \<Longrightarrow> c#s \<notin> L r2" by fact |
|
547 have "\<not> SEQ EMPTY r2 ! c#s" by fact |
|
548 then show "c#s \<notin> L (SEQ EMPTY r2)" |
|
549 using ih1 by (simp add: lang_seq_def) |
|
550 next |
|
551 case (10 c' r2 c s) |
|
552 have ih2: "\<lbrakk>c' = c; \<not>r2 ! s\<rbrakk> \<Longrightarrow> s \<notin> L r2" by fact |
|
553 have "\<not> SEQ (CHAR c') r2 ! c#s" by fact |
|
554 then show "c#s \<notin> L (SEQ (CHAR c') r2)" |
|
555 using ih2 by (auto simp add: lang_seq_def) |
|
556 next |
|
557 case (11 r11 r12 r2 c s) |
|
558 have ih2: "\<not> SEQ r11 (SEQ r12 r2) ! c#s \<Longrightarrow> c#s \<notin> L (SEQ r11 (SEQ r12 r2))" by fact |
|
559 have "\<not> SEQ (SEQ r11 r12) r2 ! c#s" by fact |
|
560 then show "c#s \<notin> L (SEQ (SEQ r11 r12) r2)" |
|
561 using ih2 by (auto simp add: lang_seq_def) |
|
562 next |
|
563 case (12 r11 r12 r2 c s) |
|
564 have ih2: "\<not> SEQ r11 r2 ! c#s \<Longrightarrow> c#s \<notin> L (SEQ r11 r2)" by fact |
|
565 have ih4: "\<not> SEQ r12 r2 ! c#s \<Longrightarrow> c#s \<notin> L (SEQ r12 r2)" by fact |
|
566 have "\<not> SEQ (ALT r11 r12) r2 ! c#s" by fact |
|
567 then show " c#s \<notin> L (SEQ (ALT r11 r12) r2)" |
|
568 using ih2 ih4 by (simp add: lang_seq_union) |
|
569 next |
|
570 case (13 r1 r2 c s) |
|
571 have ih1: "\<not>r2 ! c#s \<Longrightarrow> c#s \<notin> L r2" by fact |
|
572 have ih2: "\<And>rx. \<lbrakk>rx \<in> set r1 \<dagger> c; \<not> SEQ rx (SEQ (STAR r1) r2) ! s\<rbrakk> |
|
573 \<Longrightarrow> s \<notin> L (SEQ rx (SEQ (STAR r1) r2))" by fact |
|
574 have as: "\<not> SEQ (STAR r1) r2 ! c#s" by fact |
|
575 then have as1: "\<not>r2 ! c#s" and as2: "\<forall>r1'\<in>set r1 \<dagger> c. \<not> SEQ r1' (SEQ (STAR r1) r2) ! s" by simp_all |
|
576 from as1 have bs1: "c#s \<notin> L r2" using ih1 by simp |
|
577 from as2 have "\<forall>r1'\<in>set r1 \<dagger> c. \<not> SEQ r1' (SEQ (STAR r1) r2) ! s" by simp |
|
578 then have "\<forall>r1'\<in>set r1 \<dagger> c. s \<notin> L (SEQ r1' (SEQ (STAR r1) r2))" using ih2 by simp |
|
579 then have "\<forall>r1'\<in>set r1 \<dagger> c. s \<notin> L r1'; ((L r1)\<star>; L r2)" by simp |
|
580 then have "s \<notin> (Ls (set r1 \<dagger> c)) ; ((L r1)\<star>; L r2)" by (auto simp add: Ls_def lang_seq_def) |
|
581 then have "s \<notin> {s. c#s \<in> L r1} ; ((L r1)\<star>; L r2)" by (simp add: dagger_correctness) |
|
582 then have "s \<notin> ({s. c#s \<in> L r1} ; (L r1)\<star>); L r2" by (simp add: lang_seq_assoc) |
|
583 then have "s \<notin> {s. c#s \<in> (L r1)\<star>}; L r2" by (simp add: zzz) |
|
584 then have "c#s \<notin> {[c]}; ({s. c#s \<in> (L r1)\<star>}; L r2)" by (auto simp add: lang_seq_def) |
|
585 then have "c#s \<notin> (L r1)\<star>; L r2" using bs1 by (auto simp add: lang_seq_def Cons_eq_append_conv) |
|
586 then show "c#s \<notin> L (SEQ (STAR r1) r2)" by simp |
|
587 qed |
|
588 |
|
589 section {* Questions *} |
|
590 |
|
591 text {* |
|
592 - Why was the key lemma k1 omitted; is there an easy, non-induction |
|
593 way for obtaining this property? |
|
594 - Why was False included in the definition of the STAR-clause in |
|
595 the matcher? Has this something to do with executing the code? |
|
596 |
|
597 *} |
|
598 |
|
599 section {* Code *} |
|
600 |
|
601 export_code dagger in SML module_name Dagger file - |
|
602 export_code matcher in SML module_name Dagger file - |
|
603 |
|
604 section {* Examples *} |
|
605 |
|
606 text {* since now everything is based on lists, the evaluation is quite fast *} |
|
607 |
|
608 value "NULL ! []" |
|
609 value "(CHAR (CHR ''a'')) ! [CHR ''a'']" |
|
610 value "((CHAR a) ! [a,a])" |
|
611 value "(STAR (CHAR a)) ! []" |
|
612 value "(STAR (CHAR a)) ! [a,a]" |
|
613 value "(SEQ (CHAR (CHR ''a'')) (SEQ (STAR (CHAR (CHR ''b''))) (CHAR (CHR ''c'')))) ! ''abbbbc''" |
|
614 value "(SEQ (CHAR (CHR ''a'')) (SEQ (STAR (CHAR (CHR ''b''))) (CHAR (CHR ''c'')))) ! ''abbcbbc''" |
|
615 |
|
616 section {* Slind et al's matcher based on derivatives *} |
|
617 |
|
618 fun |
|
619 nullable :: "rexp \<Rightarrow> bool" |
|
620 where |
|
621 "nullable (NULL) = False" |
|
622 | "nullable (EMPTY) = True" |
|
623 | "nullable (CHAR c) = False" |
|
624 | "nullable (ALT r1 r2) = ((nullable r1) \<or> (nullable r2))" |
|
625 | "nullable (SEQ r1 r2) = ((nullable r1) \<and> (nullable r2))" |
|
626 | "nullable (STAR r) = True" |
|
627 |
|
628 lemma nullable: |
|
629 shows "([] \<in> L r) = nullable r" |
|
630 by (induct r) |
|
631 (auto simp add: lang_seq_def) |
|
632 |
|
633 fun |
|
634 der :: "char \<Rightarrow> rexp \<Rightarrow> rexp" |
|
635 where |
|
636 "der c (NULL) = NULL" |
|
637 | "der c (EMPTY) = NULL" |
|
638 | "der c (CHAR c') = (if c=c' then EMPTY else NULL)" |
|
639 | "der c (ALT r1 r2) = ALT (der c r1) (der c r2)" |
|
640 | "der c (SEQ r1 r2) = ALT (SEQ (der c r1) r2) (if nullable r1 then der c r2 else NULL)" |
|
641 | "der c (STAR r) = SEQ (der c r) (STAR r)" |
|
642 |
|
643 lemma k2: |
|
644 assumes b: "s \<in> L1\<star>" |
|
645 and a: "s \<noteq> []" |
|
646 shows "s \<in> (L1; (L1\<star>))" |
|
647 using b a |
|
648 apply(induct rule: Star.induct) |
|
649 apply(simp) |
|
650 apply(case_tac "s1=[]") |
|
651 apply(simp) |
|
652 apply(simp add: lang_seq_def) |
|
653 apply(blast) |
|
654 done |
|
655 |
|
656 |
|
657 lemma der_correctness: |
|
658 shows "(s \<in> L (der c r)) = ((c#s) \<in> L r)" |
|
659 proof (induct r arbitrary: s) |
|
660 case (NULL s) |
|
661 show "(s \<in> L (der c NULL)) = (c#s \<in> L NULL)" by simp |
|
662 next |
|
663 case (EMPTY s) |
|
664 show "(s \<in> L (der c EMPTY)) = (c#s \<in> L EMPTY)" by simp |
|
665 next |
|
666 case (CHAR c' s) |
|
667 show "(s \<in> L (der c (CHAR c'))) = (c#s \<in> L (CHAR c'))" by simp |
|
668 next |
|
669 case (SEQ r1 r2 s) |
|
670 have ih1: "\<And>s. (s \<in> L (der c r1)) = (c#s \<in> L r1)" by fact |
|
671 have ih2: "\<And>s. (s \<in> L (der c r2)) = (c#s \<in> L r2)" by fact |
|
672 show "(s \<in> L (der c (SEQ r1 r2))) = (c#s \<in> L (SEQ r1 r2))" |
|
673 using ih1 ih2 |
|
674 by (auto simp add: nullable[symmetric] lang_seq_def Cons_eq_append_conv) |
|
675 next |
|
676 case (ALT r1 r2 s) |
|
677 have ih1: "\<And>s. (s \<in> L (der c r1)) = (c#s \<in> L r1)" by fact |
|
678 have ih2: "\<And>s. (s \<in> L (der c r2)) = (c#s \<in> L r2)" by fact |
|
679 show "(s \<in> L (der c (ALT r1 r2))) = (c#s \<in> L (ALT r1 r2))" |
|
680 using ih1 ih2 by (auto simp add: lang_seq_def) |
|
681 next |
|
682 case (STAR r s) |
|
683 have ih1: "\<And>s. (s \<in> L (der c r)) = (c#s \<in> L r)" by fact |
|
684 show "(s \<in> L (der c (STAR r))) = (c#s \<in> L (STAR r))" |
|
685 using ih1 |
|
686 apply(simp) |
|
687 apply(auto simp add: lang_seq_def) |
|
688 apply(drule lang_seq_append) |
|
689 apply(assumption) |
|
690 apply(simp) |
|
691 apply(subst lang_star_cases) |
|
692 apply(simp) |
|
693 thm k1 |
|
694 apply(drule k2) |
|
695 apply(simp) |
|
696 apply(simp add: lang_seq_def) |
|
697 apply(erule exE)+ |
|
698 apply(erule conjE)+ |
|
699 apply(auto simp add: lang_seq_def Cons_eq_append_conv) |
|
700 apply(drule k1) |
|
701 apply(simp) |
|
702 apply(simp add: lang_seq_def) |
|
703 apply(erule exE)+ |
|
704 apply(erule conjE)+ |
|
705 apply(auto simp add: lang_seq_def Cons_eq_append_conv) |
|
706 done |
|
707 qed |
|
708 |
|
709 fun |
|
710 derivative :: "string \<Rightarrow> rexp \<Rightarrow> rexp" |
|
711 where |
|
712 "derivative [] r = r" |
|
713 | "derivative (c#s) r = derivative s (der c r)" |
|
714 |
|
715 fun |
|
716 slind_matcher :: "rexp \<Rightarrow> string \<Rightarrow> bool" |
|
717 where |
|
718 "slind_matcher r s = nullable (derivative s r)" |
|
719 |
|
720 lemma slind_matcher: |
|
721 shows "slind_matcher r s = (s \<in> L r)" |
|
722 by (induct s arbitrary: r) |
|
723 (auto simp add: nullable der_correctness) |
|
724 |
|
725 export_code slind_matcher in SML module_name Slind file - |
|
726 |
|
727 |
|
728 (* ******************************************** now is the codes writen by chunhan ************************************* *) |
|
729 |
|
730 section {* Arden's Lemma revised *} |
|
731 |
|
732 lemma arden_aux1: |
|
733 assumes a: "X \<subseteq> X ; A \<union> B" |
|
734 and b: "[] \<notin> A" |
|
735 shows "x \<in> X \<Longrightarrow> x \<in> B ; A\<star>" |
|
736 apply (induct x taking:length rule:measure_induct) |
|
737 apply (subgoal_tac "x \<in> X ; A \<union> B") |
|
738 defer |
|
739 using a |
|
740 apply (auto)[1] |
|
741 apply simp |
|
742 apply (erule disjE) |
|
743 defer |
|
744 apply (auto simp add:lang_seq_def) [1] |
|
745 apply (subgoal_tac "\<exists> x1 x2. x = x1 @ x2 \<and> x1 \<in> X \<and> x2 \<in> A") |
|
746 defer |
|
747 apply (auto simp add:lang_seq_def) [1] |
|
748 apply (erule exE | erule conjE)+ |
|
749 apply simp |
|
750 apply (drule_tac x = x1 in spec) |
|
751 apply (simp) |
|
752 using b |
|
753 apply - |
|
754 apply (auto)[1] |
|
755 apply (subgoal_tac "x1 @ x2 \<in> (B ; A\<star>) ; A") |
|
756 defer |
|
757 apply (auto simp add:lang_seq_def)[1] |
|
758 by (metis Un_absorb1 lang_seq_assoc lang_seq_union(2) lang_star_double lang_star_simple mem_def sup1CI) |
|
759 |
|
760 theorem ardens_revised: |
|
761 assumes nemp: "[] \<notin> A" |
|
762 shows "(X = X ; A \<union> B) \<longleftrightarrow> (X = B ; A\<star>)" |
|
763 apply(rule iffI) |
|
764 defer |
|
765 apply(simp) |
|
766 apply(subst lang_star_cases') |
|
767 apply(subst lang_seq_union) |
|
768 apply(simp add: lang_seq_empty) |
|
769 apply(simp add: lang_seq_assoc) |
|
770 apply(auto)[1] |
|
771 proof - |
|
772 assume "X = X ; A \<union> B" |
|
773 then have as1: "X ; A \<union> B \<subseteq> X" and as2: "X \<subseteq> X ; A \<union> B" by simp_all |
|
774 from as1 have a: "X ; A \<subseteq> X" and b: "B \<subseteq> X" by simp_all |
|
775 from b have "B; A\<star> \<subseteq> X ; A\<star>" by (auto simp add: lang_seq_def) |
|
776 moreover |
|
777 from a have "X ; A\<star> \<subseteq> X" |
|
778 |
|
779 by (rule lang_star_prop2) |
|
780 ultimately have f1: "B ; A\<star> \<subseteq> X" by simp |
|
781 from as2 nemp |
|
782 have f2: "X \<subseteq> B; A\<star>" using arden_aux1 by auto |
|
783 from f1 f2 show "X = B; A\<star>" by auto |
|
784 qed |
|
785 |
|
786 section {* equiv class' definition *} |
|
787 |
|
788 definition |
|
789 equiv_str :: "string \<Rightarrow> string set \<Rightarrow> string \<Rightarrow> bool" ("_ \<equiv>_\<equiv> _" [100, 100, 100] 100) |
|
790 where |
|
791 "x \<equiv>L'\<equiv> y \<longleftrightarrow> (\<forall>z. x@z \<in> L' \<longleftrightarrow> y@z \<in> L')" |
|
792 |
|
793 definition |
|
794 equiv_class :: "string \<Rightarrow> (string set) \<Rightarrow> string set" ("\<lbrakk>_\<rbrakk>_" [100, 100] 100) |
|
795 where |
|
796 "\<lbrakk>x\<rbrakk>L' \<equiv> {y. x \<equiv>L'\<equiv> y}" |
|
797 |
|
798 text {* Chunhan modifies Q to Quo *} |
|
799 definition |
|
800 quot :: "string set \<Rightarrow> (string set) \<Rightarrow> (string set) set" ("_ Quo _" [100, 100] 100) |
|
801 where |
|
802 "L' Quo R \<equiv> { \<lbrakk>x\<rbrakk>R | x. x \<in> L'}" |
|
803 |
|
804 lemma lang_eqs_union_of_eqcls: |
|
805 "Lang = \<Union> {X. X \<in> (UNIV Quo Lang) \<and> (\<forall> x \<in> X. x \<in> Lang)}" |
|
806 proof |
|
807 show "Lang \<subseteq> \<Union>{X \<in> UNIV Quo Lang. \<forall>x\<in>X. x \<in> Lang}" |
|
808 proof |
|
809 fix x |
|
810 assume "x \<in> Lang" |
|
811 thus "x \<in> \<Union>{X \<in> UNIV Quo Lang. \<forall>x\<in>X. x \<in> Lang}" |
|
812 proof (simp add:quot_def) |
|
813 assume "(1)": "x \<in> Lang" |
|
814 show "\<exists>xa. (\<exists>x. xa = \<lbrakk>x\<rbrakk>Lang) \<and> (\<forall>x\<in>xa. x \<in> Lang) \<and> x \<in> xa" (is "\<exists>xa.?P xa") |
|
815 proof - |
|
816 have "?P (\<lbrakk>x\<rbrakk>Lang)" using "(1)" |
|
817 by (auto simp:equiv_class_def equiv_str_def dest: spec[where x = "[]"]) |
|
818 thus ?thesis by blast |
|
819 qed |
|
820 qed |
|
821 qed |
|
822 next |
|
823 show "\<Union>{X \<in> UNIV Quo Lang. \<forall>x\<in>X. x \<in> Lang} \<subseteq> Lang" |
|
824 by auto |
|
825 qed |
|
826 |
|
827 lemma empty_notin_CS: "{} \<notin> UNIV Quo Lang" |
|
828 apply (clarsimp simp:quot_def equiv_class_def) |
|
829 by (rule_tac x = x in exI, auto simp:equiv_str_def) |
|
830 |
|
831 lemma no_two_cls_inters: |
|
832 "\<lbrakk>X \<in> UNIV Quo Lang; Y \<in> UNIV Quo Lang; X \<noteq> Y\<rbrakk> \<Longrightarrow> X \<inter> Y = {}" |
|
833 by (auto simp:quot_def equiv_class_def equiv_str_def) |
|
834 |
|
835 text {* equiv_class transition *} |
|
836 definition |
|
837 CT :: "string set \<Rightarrow> char \<Rightarrow> string set \<Rightarrow> bool" ("_-_\<rightarrow>_" [99,99]99) |
|
838 where |
|
839 "X-c\<rightarrow>Y \<equiv> ((X;{[c]}) \<subseteq> Y)" |
|
840 |
|
841 types t_equa_rhs = "(string set \<times> rexp) set" |
|
842 |
|
843 types t_equa = "(string set \<times> t_equa_rhs)" |
|
844 |
|
845 types t_equas = "t_equa set" |
|
846 |
|
847 text {* "empty_rhs" generates "\<lambda>" for init-state, just like "\<lambda>" for final states in Brzozowski method. |
|
848 But if the init-state is "{[]}" ("\<lambda>" itself) then empty set is returned, see definition of "equation_rhs" *} |
|
849 definition |
|
850 empty_rhs :: "string set \<Rightarrow> t_equa_rhs" |
|
851 where |
|
852 "empty_rhs X \<equiv> if ([] \<in> X) then {({[]}, EMPTY)} else {}" |
|
853 |
|
854 definition |
|
855 folds :: "('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> 'b \<Rightarrow> 'a set \<Rightarrow> 'b" |
|
856 where |
|
857 "folds f z S \<equiv> SOME x. fold_graph f z S x" |
|
858 |
|
859 definition |
|
860 equation_rhs :: "(string set) set \<Rightarrow> string set \<Rightarrow> t_equa_rhs" |
|
861 where |
|
862 "equation_rhs CS X \<equiv> if (X = {[]}) then {({[]}, EMPTY)} |
|
863 else {(S, folds ALT NULL {CHAR c| c. S-c\<rightarrow>X} )| S. S \<in> CS} \<union> empty_rhs X" |
|
864 |
|
865 definition |
|
866 equations :: "(string set) set \<Rightarrow> t_equas" |
|
867 where |
|
868 "equations CS \<equiv> {(X, equation_rhs CS X) | X. X \<in> CS}" |
|
869 |
|
870 definition |
|
871 L_rhs :: "t_equa_rhs \<Rightarrow> string set" |
|
872 where |
|
873 "L_rhs rhs \<equiv> {x. \<exists> X r. (X, r) \<in> rhs \<and> x \<in> X;(L r)}" |
|
874 |
|
875 defs (overloaded) |
|
876 l_rhs_abs: "L rhs \<equiv> L_rhs rhs" |
|
877 |
|
878 lemmas L_def = L_rhs_def [folded l_rhs_abs] L_rexp.simps (* ??? is this OK ?? *) |
|
879 |
|
880 definition |
|
881 distinct_rhs :: "t_equa_rhs \<Rightarrow> bool" |
|
882 where |
|
883 "distinct_rhs rhs \<equiv> \<forall> X reg\<^isub>1 reg\<^isub>2. (X, reg\<^isub>1) \<in> rhs \<and> (X, reg\<^isub>2) \<in> rhs \<longrightarrow> reg\<^isub>1 = reg\<^isub>2" |
|
884 |
|
885 definition |
|
886 distinct_equas_rhs :: "t_equas \<Rightarrow> bool" |
|
887 where |
|
888 "distinct_equas_rhs equas \<equiv> \<forall> X rhs. (X, rhs) \<in> equas \<longrightarrow> distinct_rhs rhs" |
|
889 |
|
890 definition |
|
891 distinct_equas :: "t_equas \<Rightarrow> bool" |
|
892 where |
|
893 "distinct_equas equas \<equiv> \<forall> X rhs rhs'. (X, rhs) \<in> equas \<and> (X, rhs') \<in> equas \<longrightarrow> rhs = rhs'" |
|
894 |
|
895 definition |
|
896 seq_rhs_r :: "t_equa_rhs \<Rightarrow> rexp \<Rightarrow> t_equa_rhs" |
|
897 where |
|
898 "seq_rhs_r rhs r \<equiv> (\<lambda>(X, reg). (X, SEQ reg r)) ` rhs" |
|
899 |
|
900 definition |
|
901 del_x_paired :: "('a \<times> 'b) set \<Rightarrow> 'a \<Rightarrow> ('a \<times> 'b) set" |
|
902 where |
|
903 "del_x_paired S x \<equiv> S - {X. X \<in> S \<and> fst X = x}" |
|
904 |
|
905 definition |
|
906 arden_variate :: "string set \<Rightarrow> rexp \<Rightarrow> t_equa_rhs \<Rightarrow> t_equa_rhs" |
|
907 where |
|
908 "arden_variate X r rhs \<equiv> seq_rhs_r (del_x_paired rhs X) (STAR r)" |
|
909 |
|
910 definition |
|
911 no_EMPTY_rhs :: "t_equa_rhs \<Rightarrow> bool" |
|
912 where |
|
913 "no_EMPTY_rhs rhs \<equiv> \<forall> X r. (X, r) \<in> rhs \<and> X \<noteq> {[]} \<longrightarrow> [] \<notin> L r" |
|
914 |
|
915 definition |
|
916 no_EMPTY_equas :: "t_equas \<Rightarrow> bool" |
|
917 where |
|
918 "no_EMPTY_equas equas \<equiv> \<forall> X rhs. (X, rhs) \<in> equas \<longrightarrow> no_EMPTY_rhs rhs" |
|
919 |
|
920 lemma fold_alt_null_eqs: |
|
921 "finite rS \<Longrightarrow> x \<in> L (folds ALT NULL rS) = (\<exists> r \<in> rS. x \<in> L r)" |
|
922 apply (simp add:folds_def) |
|
923 apply (rule someI2_ex) |
|
924 apply (erule finite_imp_fold_graph) |
|
925 apply (erule fold_graph.induct) |
|
926 by auto (*??? how do this be in Isar ?? *) |
|
927 |
|
928 lemma seq_rhs_r_prop1: |
|
929 "L (seq_rhs_r rhs r) = (L rhs);(L r)" |
|
930 apply (rule set_ext, rule iffI) |
|
931 apply (auto simp:L_def seq_rhs_r_def image_def lang_seq_def) |
|
932 apply (rule_tac x = "s1 @ s1a" in exI, rule_tac x = "s2a" in exI, simp) |
|
933 apply (rule_tac x = a in exI, rule_tac x = b in exI, simp) |
|
934 apply (rule_tac x = s1 in exI, rule_tac x = s1a in exI, simp) |
|
935 apply (rule_tac x = X in exI, rule_tac x = "SEQ ra r" in exI, simp) |
|
936 apply (rule conjI) |
|
937 apply (rule_tac x = "(X, ra)" in bexI, simp+) |
|
938 apply (rule_tac x = s1a in exI, rule_tac x = "s2a @ s2" in exI, simp) |
|
939 apply (simp add:lang_seq_def) |
|
940 by (rule_tac x = s2a in exI, rule_tac x = s2 in exI, simp) |
|
941 |
|
942 lemma del_x_paired_prop1: |
|
943 "\<lbrakk>distinct_rhs rhs; (X, r) \<in> rhs\<rbrakk> \<Longrightarrow> X ; L r \<union> L (del_x_paired rhs X) = L rhs" |
|
944 apply (simp add:L_def del_x_paired_def) |
|
945 apply (rule set_ext, rule iffI, simp) |
|
946 apply (erule disjE, rule_tac x = X in exI, rule_tac x = r in exI, simp) |
|
947 apply (clarify, rule_tac x = Xa in exI, rule_tac x = ra in exI, simp) |
|
948 apply (clarsimp, drule_tac x = Xa in spec, drule_tac x = ra in spec) |
|
949 apply (auto simp:distinct_rhs_def) |
|
950 done |
|
951 |
|
952 lemma arden_variate_prop: |
|
953 assumes "(X, rx) \<in> rhs" |
|
954 shows "(\<forall> Y. Y \<noteq> X \<longrightarrow> (\<exists> r. (Y, r) \<in> rhs) = (\<exists> r. (Y, r) \<in> (arden_variate X rx rhs)))" |
|
955 proof (rule allI, rule impI) |
|
956 fix Y |
|
957 assume "(1)": "Y \<noteq> X" |
|
958 show "(\<exists>r. (Y, r) \<in> rhs) = (\<exists>r. (Y, r) \<in> arden_variate X rx rhs)" |
|
959 proof |
|
960 assume "(1_1)": "\<exists>r. (Y, r) \<in> rhs" |
|
961 show "\<exists>r. (Y, r) \<in> arden_variate X rx rhs" (is "\<exists>r. ?P r") |
|
962 proof - |
|
963 from "(1_1)" obtain r where "(Y, r) \<in> rhs" .. |
|
964 hence "?P (SEQ r (STAR rx))" |
|
965 proof (simp add:arden_variate_def image_def) |
|
966 have "(Y, r) \<in> rhs \<Longrightarrow> (Y, r) \<in> del_x_paired rhs X" |
|
967 by (auto simp:del_x_paired_def "(1)") |
|
968 thus "(Y, r) \<in> rhs \<Longrightarrow> (Y, SEQ r (STAR rx)) \<in> seq_rhs_r (del_x_paired rhs X) (STAR rx)" |
|
969 by (auto simp:seq_rhs_r_def) |
|
970 qed |
|
971 thus ?thesis by blast |
|
972 qed |
|
973 next |
|
974 assume "(2_1)": "\<exists>r. (Y, r) \<in> arden_variate X rx rhs" |
|
975 thus "\<exists>r. (Y, r) \<in> rhs" (is "\<exists> r. ?P r") |
|
976 by (auto simp:arden_variate_def del_x_paired_def seq_rhs_r_def image_def) |
|
977 qed |
|
978 qed |
|
979 |
|
980 text {* |
|
981 arden_variate_valid: proves variation from "X = X;r + Y;ry + \<dots>" to "X = Y;(SEQ ry (STAR r)) + \<dots>" holds the law of "language of left equiv language of right" |
|
982 *} |
|
983 lemma arden_variate_valid: |
|
984 assumes X_not_empty: "X \<noteq> {[]}" |
|
985 and l_eq_r: "X = L rhs" |
|
986 and dist: "distinct_rhs rhs" |
|
987 and no_empty: "no_EMPTY_rhs rhs" |
|
988 and self_contained: "(X, r) \<in> rhs" |
|
989 shows "X = L (arden_variate X r rhs)" |
|
990 proof - |
|
991 have "[] \<notin> L r" using no_empty X_not_empty self_contained |
|
992 by (auto simp:no_EMPTY_rhs_def) |
|
993 hence ardens: "X = X;(L r) \<union> (L (del_x_paired rhs X)) \<longleftrightarrow> X = (L (del_x_paired rhs X)) ; (L r)\<star>" |
|
994 by (rule ardens_revised) |
|
995 have del_x: "X = X ; L r \<union> L (del_x_paired rhs X) \<longleftrightarrow> X = L rhs" using dist l_eq_r self_contained |
|
996 by (auto dest:del_x_paired_prop1) |
|
997 show ?thesis |
|
998 proof |
|
999 show "X \<subseteq> L (arden_variate X r rhs)" |
|
1000 proof |
|
1001 fix x |
|
1002 assume "(1_1)": "x \<in> X" with l_eq_r ardens del_x |
|
1003 show "x \<in> L (arden_variate X r rhs)" |
|
1004 by (simp add:arden_variate_def seq_rhs_r_prop1) |
|
1005 qed |
|
1006 next |
|
1007 show "L (arden_variate X r rhs) \<subseteq> X" |
|
1008 proof |
|
1009 fix x |
|
1010 assume "(2_1)": "x \<in> L (arden_variate X r rhs)" with ardens del_x l_eq_r |
|
1011 show "x \<in> X" |
|
1012 by (simp add:arden_variate_def seq_rhs_r_prop1) |
|
1013 qed |
|
1014 qed |
|
1015 qed |
|
1016 |
|
1017 text {* merge_rhs {(X1, r1), (x2, r2}, (x4, r4), \<dots>} {(x1, r1'), (x3, r3'), \<dots>} = {(x1, ALT r1 r1'}, (x2, r2), (x3, r3'), (x4, r4), \<dots>} *} |
|
1018 definition |
|
1019 merge_rhs :: "t_equa_rhs \<Rightarrow> t_equa_rhs \<Rightarrow> t_equa_rhs" |
|
1020 where |
|
1021 "merge_rhs rhs rhs' \<equiv> {(X, r). (\<exists> r1 r2. ((X,r1) \<in> rhs \<and> (X, r2) \<in> rhs') \<and> r = ALT r1 r2) \<or> |
|
1022 (\<exists> r1. (X, r1) \<in> rhs \<and> (\<not> (\<exists> r2. (X, r2) \<in> rhs')) \<and> r = r1) \<or> |
|
1023 (\<exists> r2. (X, r2) \<in> rhs' \<and> (\<not> (\<exists> r1. (X, r1) \<in> rhs)) \<and> r = r2) }" |
|
1024 |
|
1025 |
|
1026 text {* rhs_subst rhs X=xrhs r: substitude all occurence of X in rhs((X,r) \<in> rhs) with xrhs *} |
|
1027 definition |
|
1028 rhs_subst :: "t_equa_rhs \<Rightarrow> string set \<Rightarrow> t_equa_rhs \<Rightarrow> rexp \<Rightarrow> t_equa_rhs" |
|
1029 where |
|
1030 "rhs_subst rhs X xrhs r \<equiv> merge_rhs (del_x_paired rhs X) (seq_rhs_r xrhs r)" |
|
1031 |
|
1032 definition |
|
1033 equas_subst_f :: "string set \<Rightarrow> t_equa_rhs \<Rightarrow> t_equa \<Rightarrow> t_equa" |
|
1034 where |
|
1035 "equas_subst_f X xrhs equa \<equiv> let (Y, rhs) = equa in |
|
1036 if (\<exists> r. (X, r) \<in> rhs) |
|
1037 then (Y, rhs_subst rhs X xrhs (SOME r. (X, r) \<in> rhs)) |
|
1038 else equa" |
|
1039 |
|
1040 definition |
|
1041 equas_subst :: "t_equas \<Rightarrow> string set \<Rightarrow> t_equa_rhs \<Rightarrow> t_equas" |
|
1042 where |
|
1043 "equas_subst ES X xrhs \<equiv> del_x_paired (equas_subst_f X xrhs ` ES) X" |
|
1044 |
|
1045 lemma lang_seq_prop1: |
|
1046 "x \<in> X ; L r \<Longrightarrow> x \<in> X ; (L r \<union> L r')" |
|
1047 by (auto simp:lang_seq_def) |
|
1048 |
|
1049 lemma lang_seq_prop1': |
|
1050 "x \<in> X; L r \<Longrightarrow> x \<in> X ; (L r' \<union> L r)" |
|
1051 by (auto simp:lang_seq_def) |
|
1052 |
|
1053 lemma lang_seq_prop2: |
|
1054 "x \<in> X; (L r \<union> L r') \<Longrightarrow> x \<in> X;L r \<or> x \<in> X;L r'" |
|
1055 by (auto simp:lang_seq_def) |
|
1056 |
|
1057 lemma merge_rhs_prop1: |
|
1058 shows "L (merge_rhs rhs rhs') = L rhs \<union> L rhs' " |
|
1059 apply (auto simp add:merge_rhs_def L_def dest!:lang_seq_prop2 intro:lang_seq_prop1) |
|
1060 apply (rule_tac x = X in exI, rule_tac x = r1 in exI, simp) |
|
1061 apply (case_tac "\<exists> r2. (X, r2) \<in> rhs'") |
|
1062 apply (clarify, rule_tac x = X in exI, rule_tac x = "ALT r r2" in exI, simp add:lang_seq_prop1) |
|
1063 apply (rule_tac x = X in exI, rule_tac x = r in exI, simp) |
|
1064 apply (case_tac "\<exists> r1. (X, r1) \<in> rhs") |
|
1065 apply (clarify, rule_tac x = X in exI, rule_tac x = "ALT r1 r" in exI, simp add:lang_seq_prop1') |
|
1066 apply (rule_tac x = X in exI, rule_tac x = r in exI, simp) |
|
1067 done |
|
1068 |
|
1069 lemma no_EMPTY_rhss_imp_merge_no_EMPTY: |
|
1070 "\<lbrakk>no_EMPTY_rhs rhs; no_EMPTY_rhs rhs'\<rbrakk> \<Longrightarrow> no_EMPTY_rhs (merge_rhs rhs rhs')" |
|
1071 apply (simp add:no_EMPTY_rhs_def merge_rhs_def) |
|
1072 apply (clarify, (erule conjE | erule exE | erule disjE)+) |
|
1073 by auto |
|
1074 |
|
1075 lemma distinct_rhs_prop: |
|
1076 "\<lbrakk>distinct_rhs rhs; (X, r1) \<in> rhs; (X, r2) \<in> rhs\<rbrakk> \<Longrightarrow> r1 = r2" |
|
1077 by (auto simp:distinct_rhs_def) |
|
1078 |
|
1079 lemma merge_rhs_prop2: |
|
1080 assumes dist_rhs: "distinct_rhs rhs" |
|
1081 and dist_rhs':"distinct_rhs rhs'" |
|
1082 shows "distinct_rhs (merge_rhs rhs rhs')" |
|
1083 apply (auto simp:merge_rhs_def distinct_rhs_def) |
|
1084 using dist_rhs |
|
1085 apply (drule distinct_rhs_prop, simp+) |
|
1086 using dist_rhs' |
|
1087 apply (drule distinct_rhs_prop, simp+) |
|
1088 using dist_rhs |
|
1089 apply (drule distinct_rhs_prop, simp+) |
|
1090 using dist_rhs' |
|
1091 apply (drule distinct_rhs_prop, simp+) |
|
1092 done |
|
1093 |
|
1094 lemma seq_rhs_r_holds_distinct: |
|
1095 "distinct_rhs rhs \<Longrightarrow> distinct_rhs (seq_rhs_r rhs r)" |
|
1096 by (auto simp:distinct_rhs_def seq_rhs_r_def) |
|
1097 |
|
1098 lemma seq_rhs_r_prop0: |
|
1099 assumes l_eq_r: "X = L xrhs" |
|
1100 shows "L (seq_rhs_r xrhs r) = X ; L r " |
|
1101 using l_eq_r |
|
1102 by (auto simp:seq_rhs_r_prop1) |
|
1103 |
|
1104 lemma rhs_subst_prop1: |
|
1105 assumes l_eq_r: "X = L xrhs" |
|
1106 and dist: "distinct_rhs rhs" |
|
1107 shows "(X, r) \<in> rhs \<Longrightarrow> L rhs = L (rhs_subst rhs X xrhs r)" |
|
1108 apply (simp add:rhs_subst_def merge_rhs_prop1) |
|
1109 using l_eq_r |
|
1110 apply (drule_tac r = r in seq_rhs_r_prop0, simp) |
|
1111 using dist |
|
1112 apply (auto dest:del_x_paired_prop1) |
|
1113 done |
|
1114 |
|
1115 lemma del_x_paired_holds_distinct_rhs: |
|
1116 "distinct_rhs rhs \<Longrightarrow> distinct_rhs (del_x_paired rhs x)" |
|
1117 by (auto simp:distinct_rhs_def del_x_paired_def) |
|
1118 |
|
1119 lemma rhs_subst_holds_distinct_rhs: |
|
1120 "\<lbrakk>distinct_rhs rhs; distinct_rhs xrhs\<rbrakk> \<Longrightarrow> distinct_rhs (rhs_subst rhs X xrhs r)" |
|
1121 apply (drule_tac r = r and rhs = xrhs in seq_rhs_r_holds_distinct) |
|
1122 apply (drule_tac x = X in del_x_paired_holds_distinct_rhs) |
|
1123 by (auto dest:merge_rhs_prop2[where rhs = "del_x_paired rhs X"] simp:rhs_subst_def) |
|
1124 |
|
1125 section {* myhill-nerode theorem *} |
|
1126 |
|
1127 definition left_eq_cls :: "t_equas \<Rightarrow> (string set) set" |
|
1128 where |
|
1129 "left_eq_cls ES \<equiv> {X. \<exists> rhs. (X, rhs) \<in> ES} " |
|
1130 |
|
1131 definition right_eq_cls :: "t_equas \<Rightarrow> (string set) set" |
|
1132 where |
|
1133 "right_eq_cls ES \<equiv> {Y. \<exists> X rhs r. (X, rhs) \<in> ES \<and> (Y, r) \<in> rhs }" |
|
1134 |
|
1135 definition rhs_eq_cls :: "t_equa_rhs \<Rightarrow> (string set) set" |
|
1136 where |
|
1137 "rhs_eq_cls rhs \<equiv> {Y. \<exists> r. (Y, r) \<in> rhs}" |
|
1138 |
|
1139 definition ardenable :: "t_equa \<Rightarrow> bool" |
|
1140 where |
|
1141 "ardenable equa \<equiv> let (X, rhs) = equa in |
|
1142 distinct_rhs rhs \<and> no_EMPTY_rhs rhs \<and> X = L rhs" |
|
1143 |
|
1144 text {* |
|
1145 Inv: Invairance of the equation-system, during the decrease of the equation-system, Inv holds. |
|
1146 *} |
|
1147 definition Inv :: "string set \<Rightarrow> t_equas \<Rightarrow> bool" |
|
1148 where |
|
1149 "Inv X ES \<equiv> finite ES \<and> (\<exists> rhs. (X, rhs) \<in> ES) \<and> distinct_equas ES \<and> |
|
1150 (\<forall> X xrhs. (X, xrhs) \<in> ES \<longrightarrow> ardenable (X, xrhs) \<and> X \<noteq> {} \<and> rhs_eq_cls xrhs \<subseteq> insert {[]} (left_eq_cls ES))" |
|
1151 |
|
1152 text {* |
|
1153 TCon: Termination Condition of the equation-system decreasion. |
|
1154 *} |
|
1155 definition TCon:: "'a set \<Rightarrow> bool" |
|
1156 where |
|
1157 "TCon ES \<equiv> card ES = 1" |
|
1158 |
|
1159 |
|
1160 text {* |
|
1161 The following is a iteration principle, and is the main framework for the proof: |
|
1162 1: We can form the initial equation-system using "equations" defined above, and prove it has invariance Inv by lemma "init_ES_satisfy_Inv"; |
|
1163 2: We can decrease the number of the equation-system using ardens_lemma_revised and substitution ("equas_subst", defined above), |
|
1164 and prove it holds the property "step" in "wf_iter" by lemma "iteration_step" |
|
1165 and finally using property P and Q to prove the myhill-nerode theorem |
|
1166 |
|
1167 *} |
|
1168 lemma wf_iter [rule_format]: |
|
1169 fixes f |
|
1170 assumes step: "\<And> e. \<lbrakk>P e; \<not> Q e\<rbrakk> \<Longrightarrow> (\<exists> e'. P e' \<and> (f(e'), f(e)) \<in> less_than)" |
|
1171 shows pe: "P e \<longrightarrow> (\<exists> e'. P e' \<and> Q e')" |
|
1172 proof(induct e rule: wf_induct |
|
1173 [OF wf_inv_image[OF wf_less_than, where f = "f"]], clarify) |
|
1174 fix x |
|
1175 assume h [rule_format]: |
|
1176 "\<forall>y. (y, x) \<in> inv_image less_than f \<longrightarrow> P y \<longrightarrow> (\<exists>e'. P e' \<and> Q e')" |
|
1177 and px: "P x" |
|
1178 show "\<exists>e'. P e' \<and> Q e'" |
|
1179 proof(cases "Q x") |
|
1180 assume "Q x" with px show ?thesis by blast |
|
1181 next |
|
1182 assume nq: "\<not> Q x" |
|
1183 from step [OF px nq] |
|
1184 obtain e' where pe': "P e'" and ltf: "(f e', f x) \<in> less_than" by auto |
|
1185 show ?thesis |
|
1186 proof(rule h) |
|
1187 from ltf show "(e', x) \<in> inv_image less_than f" |
|
1188 by (simp add:inv_image_def) |
|
1189 next |
|
1190 from pe' show "P e'" . |
|
1191 qed |
|
1192 qed |
|
1193 qed |
|
1194 |
|
1195 |
|
1196 (* ********************************* BEGIN: proving the initial equation-system satisfies Inv **************************************** *) |
|
1197 |
|
1198 lemma distinct_rhs_equations: |
|
1199 "(X, xrhs) \<in> equations (UNIV Quo Lang) \<Longrightarrow> distinct_rhs xrhs" |
|
1200 by (auto simp: equations_def equation_rhs_def distinct_rhs_def empty_rhs_def dest:no_two_cls_inters) |
|
1201 |
|
1202 lemma every_nonempty_eqclass_has_strings: |
|
1203 "\<lbrakk>X \<in> (UNIV Quo Lang); X \<noteq> {[]}\<rbrakk> \<Longrightarrow> \<exists> clist. clist \<in> X \<and> clist \<noteq> []" |
|
1204 by (auto simp:quot_def equiv_class_def equiv_str_def) |
|
1205 |
|
1206 lemma every_eqclass_is_derived_from_empty: |
|
1207 assumes not_empty: "X \<noteq> {[]}" |
|
1208 shows "X \<in> (UNIV Quo Lang) \<Longrightarrow> \<exists> clist. {[]};{clist} \<subseteq> X \<and> clist \<noteq> []" |
|
1209 using not_empty |
|
1210 apply (drule_tac every_nonempty_eqclass_has_strings, simp) |
|
1211 by (auto intro:exI[where x = clist] simp:lang_seq_def) |
|
1212 |
|
1213 lemma equiv_str_in_CS: |
|
1214 "\<lbrakk>clist\<rbrakk>Lang \<in> (UNIV Quo Lang)" |
|
1215 by (auto simp:quot_def) |
|
1216 |
|
1217 lemma has_str_imp_defined_by_str: |
|
1218 "\<lbrakk>str \<in> X; X \<in> UNIV Quo Lang\<rbrakk> \<Longrightarrow> X = \<lbrakk>str\<rbrakk>Lang" |
|
1219 by (auto simp:quot_def equiv_class_def equiv_str_def) |
|
1220 |
|
1221 lemma every_eqclass_has_ascendent: |
|
1222 assumes has_str: "clist @ [c] \<in> X" |
|
1223 and in_CS: "X \<in> UNIV Quo Lang" |
|
1224 shows "\<exists> Y. Y \<in> UNIV Quo Lang \<and> Y-c\<rightarrow>X \<and> clist \<in> Y" (is "\<exists> Y. ?P Y") |
|
1225 proof - |
|
1226 have "?P (\<lbrakk>clist\<rbrakk>Lang)" |
|
1227 proof - |
|
1228 have "\<lbrakk>clist\<rbrakk>Lang \<in> UNIV Quo Lang" |
|
1229 by (simp add:quot_def, rule_tac x = clist in exI, simp) |
|
1230 moreover have "\<lbrakk>clist\<rbrakk>Lang-c\<rightarrow>X" |
|
1231 proof - |
|
1232 have "X = \<lbrakk>(clist @ [c])\<rbrakk>Lang" using has_str in_CS |
|
1233 by (auto intro!:has_str_imp_defined_by_str) |
|
1234 moreover have "\<forall> sl. sl \<in> \<lbrakk>clist\<rbrakk>Lang \<longrightarrow> sl @ [c] \<in> \<lbrakk>(clist @ [c])\<rbrakk>Lang" |
|
1235 by (auto simp:equiv_class_def equiv_str_def) |
|
1236 ultimately show ?thesis unfolding CT_def lang_seq_def |
|
1237 by auto |
|
1238 qed |
|
1239 moreover have "clist \<in> \<lbrakk>clist\<rbrakk>Lang" |
|
1240 by (auto simp:equiv_str_def equiv_class_def) |
|
1241 ultimately show "?P (\<lbrakk>clist\<rbrakk>Lang)" by simp |
|
1242 qed |
|
1243 thus ?thesis by blast |
|
1244 qed |
|
1245 |
|
1246 lemma finite_charset_rS: |
|
1247 "finite {CHAR c |c. Y-c\<rightarrow>X}" |
|
1248 by (rule_tac A = UNIV and f = CHAR in finite_surj, auto) |
|
1249 |
|
1250 lemma l_eq_r_in_equations: |
|
1251 assumes X_in_equas: "(X, xrhs) \<in> equations (UNIV Quo Lang)" |
|
1252 shows "X = L xrhs" |
|
1253 proof (cases "X = {[]}") |
|
1254 case True |
|
1255 thus ?thesis using X_in_equas |
|
1256 by (simp add:equations_def equation_rhs_def L_def lang_seq_def) |
|
1257 next |
|
1258 case False |
|
1259 show ?thesis |
|
1260 proof |
|
1261 show "X \<subseteq> L xrhs" |
|
1262 proof |
|
1263 fix x |
|
1264 assume "(1)": "x \<in> X" |
|
1265 show "x \<in> L xrhs" |
|
1266 proof (cases "x = []") |
|
1267 assume empty: "x = []" |
|
1268 hence "x \<in> L (empty_rhs X)" using "(1)" |
|
1269 by (auto simp:empty_rhs_def L_def lang_seq_def) |
|
1270 thus ?thesis using X_in_equas False empty "(1)" |
|
1271 unfolding equations_def equation_rhs_def by (auto simp:L_def) |
|
1272 next |
|
1273 assume not_empty: "x \<noteq> []" |
|
1274 hence "\<exists> clist c. x = clist @ [c]" by (case_tac x rule:rev_cases, auto) |
|
1275 then obtain clist c where decom: "x = clist @ [c]" by blast |
|
1276 moreover have "\<And> Y. \<lbrakk>Y \<in> UNIV Quo Lang; Y-c\<rightarrow>X; clist \<in> Y\<rbrakk>\<Longrightarrow> [c] \<in> L (folds ALT NULL {CHAR c |c. Y-c\<rightarrow>X})" |
|
1277 proof - |
|
1278 fix Y |
|
1279 assume Y_is_eq_cl: "Y \<in> UNIV Quo Lang" |
|
1280 and Y_CT_X: "Y-c\<rightarrow>X" |
|
1281 and clist_in_Y: "clist \<in> Y" |
|
1282 with finite_charset_rS |
|
1283 show "[c] \<in> L (folds ALT NULL {CHAR c |c. Y-c\<rightarrow>X})" |
|
1284 by (auto simp :fold_alt_null_eqs) |
|
1285 qed |
|
1286 hence "\<exists>Xa. Xa \<in> UNIV Quo Lang \<and> clist @ [c] \<in> Xa ; L (folds ALT NULL {CHAR c |c. Xa-c\<rightarrow>X})" |
|
1287 using X_in_equas False not_empty "(1)" decom |
|
1288 by (auto dest!:every_eqclass_has_ascendent simp:equations_def equation_rhs_def L_def lang_seq_def) |
|
1289 then obtain Xa where "Xa \<in> UNIV Quo Lang \<and> clist @ [c] \<in> Xa ; L (folds ALT NULL {CHAR c |c. Xa-c\<rightarrow>X})" by blast |
|
1290 hence "x \<in> L {(S, folds ALT NULL {CHAR c |c. S-c\<rightarrow>X}) |S. S \<in> UNIV Quo Lang}" using X_in_equas "(1)" decom |
|
1291 by (auto simp add:L_def equations_def equation_rhs_def intro!:exI[where x = Xa]) |
|
1292 thus "x \<in> L xrhs" using X_in_equas False not_empty unfolding equations_def equation_rhs_def |
|
1293 by (auto simp:L_def) |
|
1294 qed |
|
1295 qed |
|
1296 next |
|
1297 show "L xrhs \<subseteq> X" |
|
1298 proof |
|
1299 fix x |
|
1300 assume "(2)": "x \<in> L xrhs" |
|
1301 have "(2_1)": "\<And> s1 s2 r Xa. \<lbrakk>s1 \<in> Xa; s2 \<in> L (folds ALT NULL {CHAR c |c. Xa-c\<rightarrow>X})\<rbrakk> \<Longrightarrow> s1 @ s2 \<in> X" |
|
1302 using finite_charset_rS |
|
1303 by (auto simp:CT_def lang_seq_def fold_alt_null_eqs) |
|
1304 have "(2_2)": "\<And> s1 s2 Xa r.\<lbrakk>s1 \<in> Xa; s2 \<in> L r; (Xa, r) \<in> empty_rhs X\<rbrakk> \<Longrightarrow> s1 @ s2 \<in> X" |
|
1305 by (simp add:empty_rhs_def split:if_splits) |
|
1306 show "x \<in> X" using X_in_equas False "(2)" |
|
1307 by (auto intro:"(2_1)" "(2_2)" simp:equations_def equation_rhs_def L_def lang_seq_def) |
|
1308 qed |
|
1309 qed |
|
1310 qed |
|
1311 |
|
1312 lemma finite_CT_chars: |
|
1313 "finite {CHAR c |c. Xa-c\<rightarrow>X}" |
|
1314 by (auto) |
|
1315 |
|
1316 lemma no_EMPTY_equations: |
|
1317 "(X, xrhs) \<in> equations CS \<Longrightarrow> no_EMPTY_rhs xrhs" |
|
1318 apply (clarsimp simp add:equations_def equation_rhs_def) |
|
1319 apply (simp add:no_EMPTY_rhs_def empty_rhs_def, auto) |
|
1320 apply (subgoal_tac "finite {CHAR c |c. Xa-c\<rightarrow>X}", drule_tac x = "[]" in fold_alt_null_eqs, clarsimp, rule finite_CT_chars)+ |
|
1321 done |
|
1322 |
|
1323 lemma init_ES_satisfy_ardenable: |
|
1324 "(X, xrhs) \<in> equations (UNIV Quo Lang) \<Longrightarrow> ardenable (X, xrhs)" |
|
1325 unfolding ardenable_def |
|
1326 by (auto intro:distinct_rhs_equations no_EMPTY_equations simp:l_eq_r_in_equations) |
|
1327 |
|
1328 lemma init_ES_satisfy_Inv: |
|
1329 assumes finite_CS: "finite (UNIV Quo Lang)" |
|
1330 and X_in_eq_cls: "X \<in> UNIV Quo Lang" |
|
1331 shows "Inv X (equations (UNIV Quo Lang))" |
|
1332 proof - |
|
1333 have "finite (equations (UNIV Quo Lang))" using finite_CS |
|
1334 by (auto simp:equations_def) |
|
1335 moreover have "\<exists>rhs. (X, rhs) \<in> equations (UNIV Quo Lang)" using X_in_eq_cls |
|
1336 by (simp add:equations_def) |
|
1337 moreover have "distinct_equas (equations (UNIV Quo Lang))" |
|
1338 by (auto simp:distinct_equas_def equations_def) |
|
1339 moreover have "\<forall>X xrhs. (X, xrhs) \<in> equations (UNIV Quo Lang) \<longrightarrow> |
|
1340 rhs_eq_cls xrhs \<subseteq> insert {[]} (left_eq_cls (equations (UNIV Quo Lang)))" |
|
1341 apply (simp add:left_eq_cls_def equations_def rhs_eq_cls_def equation_rhs_def) |
|
1342 by (auto simp:empty_rhs_def split:if_splits) |
|
1343 moreover have "\<forall>X xrhs. (X, xrhs) \<in> equations (UNIV Quo Lang) \<longrightarrow> X \<noteq> {}" |
|
1344 by (clarsimp simp:equations_def empty_notin_CS intro:classical) |
|
1345 moreover have "\<forall>X xrhs. (X, xrhs) \<in> equations (UNIV Quo Lang) \<longrightarrow> ardenable (X, xrhs)" |
|
1346 by (auto intro!:init_ES_satisfy_ardenable) |
|
1347 ultimately show ?thesis by (simp add:Inv_def) |
|
1348 qed |
|
1349 |
|
1350 |
|
1351 (* ********************************* END: proving the initial equation-system satisfies Inv **************************************** *) |
|
1352 |
|
1353 |
|
1354 (* ***************************** BEGIN: proving every equation-system's iteration step satisfies Inv ******************************* *) |
|
1355 |
|
1356 lemma not_T_aux: "\<lbrakk>\<not> TCon (insert a A); x = a\<rbrakk> |
|
1357 \<Longrightarrow> \<exists>y. x \<noteq> y \<and> y \<in> insert a A " |
|
1358 apply (case_tac "insert a A = {a}") |
|
1359 by (auto simp:TCon_def) |
|
1360 |
|
1361 lemma not_T_atleast_2[rule_format]: |
|
1362 "finite S \<Longrightarrow> \<forall> x. x \<in> S \<and> (\<not> TCon S)\<longrightarrow> (\<exists> y. x \<noteq> y \<and> y \<in> S)" |
|
1363 apply (erule finite.induct, simp) |
|
1364 apply (clarify, case_tac "x = a") |
|
1365 by (erule not_T_aux, auto) |
|
1366 |
|
1367 lemma exist_another_equa: |
|
1368 "\<lbrakk>\<not> TCon ES; finite ES; distinct_equas ES; (X, rhl) \<in> ES\<rbrakk> \<Longrightarrow> \<exists> Y yrhl. (Y, yrhl) \<in> ES \<and> X \<noteq> Y" |
|
1369 apply (drule not_T_atleast_2, simp) |
|
1370 apply (clarsimp simp:distinct_equas_def) |
|
1371 apply (drule_tac x= X in spec, drule_tac x = rhl in spec, drule_tac x = b in spec) |
|
1372 by auto |
|
1373 |
|
1374 lemma Inv_mono_with_lambda: |
|
1375 assumes Inv_ES: "Inv X ES" |
|
1376 and X_noteq_Y: "X \<noteq> {[]}" |
|
1377 shows "Inv X (ES - {({[]}, yrhs)})" |
|
1378 proof - |
|
1379 have "finite (ES - {({[]}, yrhs)})" using Inv_ES |
|
1380 by (simp add:Inv_def) |
|
1381 moreover have "\<exists>rhs. (X, rhs) \<in> ES - {({[]}, yrhs)}" using Inv_ES X_noteq_Y |
|
1382 by (simp add:Inv_def) |
|
1383 moreover have "distinct_equas (ES - {({[]}, yrhs)})" using Inv_ES X_noteq_Y |
|
1384 apply (clarsimp simp:Inv_def distinct_equas_def) |
|
1385 by (drule_tac x = Xa in spec, simp) |
|
1386 moreover have "\<forall>X xrhs.(X, xrhs) \<in> ES - {({[]}, yrhs)} \<longrightarrow> |
|
1387 ardenable (X, xrhs) \<and> X \<noteq> {}" using Inv_ES |
|
1388 by (clarify, simp add:Inv_def) |
|
1389 moreover |
|
1390 have "insert {[]} (left_eq_cls (ES - {({[]}, yrhs)})) = insert {[]} (left_eq_cls ES)" |
|
1391 by (auto simp:left_eq_cls_def) |
|
1392 hence "\<forall>X xrhs.(X, xrhs) \<in> ES - {({[]}, yrhs)} \<longrightarrow> |
|
1393 rhs_eq_cls xrhs \<subseteq> insert {[]} (left_eq_cls (ES - {({[]}, yrhs)}))" |
|
1394 using Inv_ES by (auto simp:Inv_def) |
|
1395 ultimately show ?thesis by (simp add:Inv_def) |
|
1396 qed |
|
1397 |
|
1398 lemma non_empty_card_prop: |
|
1399 "finite ES \<Longrightarrow> \<forall>e. e \<in> ES \<longrightarrow> card ES - Suc 0 < card ES" |
|
1400 apply (erule finite.induct, simp) |
|
1401 apply (case_tac[!] "a \<in> A") |
|
1402 by (auto simp:insert_absorb) |
|
1403 |
|
1404 lemma ardenable_prop: |
|
1405 assumes not_lambda: "Y \<noteq> {[]}" |
|
1406 and ardable: "ardenable (Y, yrhs)" |
|
1407 shows "\<exists> yrhs'. Y = L yrhs' \<and> distinct_rhs yrhs' \<and> rhs_eq_cls yrhs' = rhs_eq_cls yrhs - {Y}" (is "\<exists> yrhs'. ?P yrhs'") |
|
1408 proof (cases "(\<exists> reg. (Y, reg) \<in> yrhs)") |
|
1409 case True |
|
1410 thus ?thesis |
|
1411 proof |
|
1412 fix reg |
|
1413 assume self_contained: "(Y, reg) \<in> yrhs" |
|
1414 show ?thesis |
|
1415 proof - |
|
1416 have "?P (arden_variate Y reg yrhs)" |
|
1417 proof - |
|
1418 have "Y = L (arden_variate Y reg yrhs)" |
|
1419 using self_contained not_lambda ardable |
|
1420 by (rule_tac arden_variate_valid, simp_all add:ardenable_def) |
|
1421 moreover have "distinct_rhs (arden_variate Y reg yrhs)" |
|
1422 using ardable |
|
1423 by (auto simp:distinct_rhs_def arden_variate_def seq_rhs_r_def del_x_paired_def ardenable_def) |
|
1424 moreover have "rhs_eq_cls (arden_variate Y reg yrhs) = rhs_eq_cls yrhs - {Y}" |
|
1425 proof - |
|
1426 have "\<And> rhs r. rhs_eq_cls (seq_rhs_r rhs r) = rhs_eq_cls rhs" |
|
1427 apply (auto simp:rhs_eq_cls_def seq_rhs_r_def image_def) |
|
1428 by (rule_tac x = "SEQ ra r" in exI, rule_tac x = "(x, ra)" in bexI, simp+) |
|
1429 moreover have "\<And> rhs X. rhs_eq_cls (del_x_paired rhs X) = rhs_eq_cls rhs - {X}" |
|
1430 by (auto simp:rhs_eq_cls_def del_x_paired_def) |
|
1431 ultimately show ?thesis by (simp add:arden_variate_def) |
|
1432 qed |
|
1433 ultimately show ?thesis by simp |
|
1434 qed |
|
1435 thus ?thesis by (rule_tac x= "arden_variate Y reg yrhs" in exI, simp) |
|
1436 qed |
|
1437 qed |
|
1438 next |
|
1439 case False |
|
1440 hence "(2)": "rhs_eq_cls yrhs - {Y} = rhs_eq_cls yrhs" |
|
1441 by (auto simp:rhs_eq_cls_def) |
|
1442 show ?thesis |
|
1443 proof - |
|
1444 have "?P yrhs" using False ardable "(2)" |
|
1445 by (simp add:ardenable_def) |
|
1446 thus ?thesis by blast |
|
1447 qed |
|
1448 qed |
|
1449 |
|
1450 lemma equas_subst_f_del_no_other: |
|
1451 assumes self_contained: "(Y, rhs) \<in> ES" |
|
1452 shows "\<exists> rhs'. (Y, rhs') \<in> (equas_subst_f X xrhs ` ES)" (is "\<exists> rhs'. ?P rhs'") |
|
1453 proof - |
|
1454 have "\<exists> rhs'. equas_subst_f X xrhs (Y, rhs) = (Y, rhs')" |
|
1455 by (auto simp:equas_subst_f_def) |
|
1456 then obtain rhs' where "equas_subst_f X xrhs (Y, rhs) = (Y, rhs')" by blast |
|
1457 hence "?P rhs'" unfolding image_def using self_contained |
|
1458 by (auto intro:bexI[where x = "(Y, rhs)"]) |
|
1459 thus ?thesis by blast |
|
1460 qed |
|
1461 |
|
1462 lemma del_x_paired_del_only_x: |
|
1463 "\<lbrakk>X \<noteq> Y; (X, rhs) \<in> ES\<rbrakk> \<Longrightarrow> (X, rhs) \<in> del_x_paired ES Y" |
|
1464 by (auto simp:del_x_paired_def) |
|
1465 |
|
1466 lemma del_x_paired_del_only_x': |
|
1467 "(X, rhs) \<in> del_x_paired ES Y \<Longrightarrow> X \<noteq> Y \<and> (X, rhs) \<in> ES" |
|
1468 by (auto simp:del_x_paired_def) |
|
1469 |
|
1470 lemma equas_subst_del_no_other: |
|
1471 "\<lbrakk>(X, rhs) \<in> ES; X \<noteq> Y\<rbrakk> \<Longrightarrow> (\<exists>rhs. (X, rhs) \<in> equas_subst ES Y rhs')" |
|
1472 unfolding equas_subst_def |
|
1473 apply (drule_tac X = Y and xrhs = rhs' in equas_subst_f_del_no_other) |
|
1474 by (erule exE, drule del_x_paired_del_only_x, auto) |
|
1475 |
|
1476 lemma equas_subst_holds_distinct: |
|
1477 "distinct_equas ES \<Longrightarrow> distinct_equas (equas_subst ES Y rhs')" |
|
1478 apply (clarsimp simp add:equas_subst_def distinct_equas_def del_x_paired_def equas_subst_f_def) |
|
1479 by (auto split:if_splits) |
|
1480 |
|
1481 lemma del_x_paired_dels: |
|
1482 "(X, rhs) \<in> ES \<Longrightarrow> {Y. Y \<in> ES \<and> fst Y = X} \<inter> ES \<noteq> {}" |
|
1483 by (auto) |
|
1484 |
|
1485 lemma del_x_paired_subset: |
|
1486 "(X, rhs) \<in> ES \<Longrightarrow> ES - {Y. Y \<in> ES \<and> fst Y = X} \<subset> ES" |
|
1487 apply (drule del_x_paired_dels) |
|
1488 by auto |
|
1489 |
|
1490 lemma del_x_paired_card_less: |
|
1491 "\<lbrakk>finite ES; (X, rhs) \<in> ES\<rbrakk> \<Longrightarrow> card (del_x_paired ES X) < card ES" |
|
1492 apply (simp add:del_x_paired_def) |
|
1493 apply (drule del_x_paired_subset) |
|
1494 by (auto intro:psubset_card_mono) |
|
1495 |
|
1496 lemma equas_subst_card_less: |
|
1497 "\<lbrakk>finite ES; (Y, yrhs) \<in> ES\<rbrakk> \<Longrightarrow> card (equas_subst ES Y rhs') < card ES" |
|
1498 apply (simp add:equas_subst_def) |
|
1499 apply (frule_tac h = "equas_subst_f Y rhs'" in finite_imageI) |
|
1500 apply (drule_tac f = "equas_subst_f Y rhs'" in Finite_Set.card_image_le) |
|
1501 apply (drule_tac X = Y and xrhs = rhs' in equas_subst_f_del_no_other,erule exE) |
|
1502 by (drule del_x_paired_card_less, auto) |
|
1503 |
|
1504 lemma equas_subst_holds_distinct_rhs: |
|
1505 assumes dist': "distinct_rhs yrhs'" |
|
1506 and history: "\<forall>X xrhs. (X, xrhs) \<in> ES \<longrightarrow> ardenable (X, xrhs)" |
|
1507 and X_in : "(X, xrhs) \<in> equas_subst ES Y yrhs'" |
|
1508 shows "distinct_rhs xrhs" |
|
1509 using X_in history |
|
1510 apply (clarsimp simp:equas_subst_def del_x_paired_def) |
|
1511 apply (drule_tac x = a in spec, drule_tac x = b in spec) |
|
1512 apply (simp add:ardenable_def equas_subst_f_def) |
|
1513 by (auto intro:rhs_subst_holds_distinct_rhs simp:dist' split:if_splits) |
|
1514 |
|
1515 lemma r_no_EMPTY_imp_seq_rhs_r_no_EMPTY: |
|
1516 "[] \<notin> L r \<Longrightarrow> no_EMPTY_rhs (seq_rhs_r rhs r)" |
|
1517 by (auto simp:no_EMPTY_rhs_def seq_rhs_r_def lang_seq_def) |
|
1518 |
|
1519 lemma del_x_paired_holds_no_EMPTY: |
|
1520 "no_EMPTY_rhs yrhs \<Longrightarrow> no_EMPTY_rhs (del_x_paired yrhs Y)" |
|
1521 by (auto simp:no_EMPTY_rhs_def del_x_paired_def) |
|
1522 |
|
1523 lemma rhs_subst_holds_no_EMPTY: |
|
1524 "\<lbrakk>no_EMPTY_rhs yrhs; (Y, r) \<in> yrhs; Y \<noteq> {[]}\<rbrakk> \<Longrightarrow> no_EMPTY_rhs (rhs_subst yrhs Y rhs' r)" |
|
1525 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) |
|
1526 by (auto simp:no_EMPTY_rhs_def) |
|
1527 |
|
1528 lemma equas_subst_holds_no_EMPTY: |
|
1529 assumes substor: "Y \<noteq> {[]}" |
|
1530 and history: "\<forall>X xrhs. (X, xrhs) \<in> ES \<longrightarrow> ardenable (X, xrhs)" |
|
1531 and X_in:"(X, xrhs) \<in> equas_subst ES Y yrhs'" |
|
1532 shows "no_EMPTY_rhs xrhs" |
|
1533 proof- |
|
1534 from X_in have "\<exists> (Z, zrhs) \<in> ES. (X, xrhs) = equas_subst_f Y yrhs' (Z, zrhs)" |
|
1535 by (auto simp add:equas_subst_def del_x_paired_def) |
|
1536 then obtain Z zrhs where Z_in: "(Z, zrhs) \<in> ES" |
|
1537 and X_Z: "(X, xrhs) = equas_subst_f Y yrhs' (Z, zrhs)" by blast |
|
1538 hence dist_zrhs: "distinct_rhs zrhs" using history |
|
1539 by (auto simp:ardenable_def) |
|
1540 show ?thesis |
|
1541 proof (cases "\<exists> r. (Y, r) \<in> zrhs") |
|
1542 case True |
|
1543 then obtain r where Y_in_zrhs: "(Y, r) \<in> zrhs" .. |
|
1544 hence some: "(SOME r. (Y, r) \<in> zrhs) = r" using Z_in dist_zrhs |
|
1545 by (auto simp:distinct_rhs_def) |
|
1546 hence "no_EMPTY_rhs (rhs_subst zrhs Y yrhs' r)" |
|
1547 using substor Y_in_zrhs history Z_in |
|
1548 by (rule_tac rhs_subst_holds_no_EMPTY, auto simp:ardenable_def) |
|
1549 thus ?thesis using X_Z True some |
|
1550 by (simp add:equas_subst_def equas_subst_f_def) |
|
1551 next |
|
1552 case False |
|
1553 hence "(X, xrhs) = (Z, zrhs)" using Z_in X_Z |
|
1554 by (simp add:equas_subst_f_def) |
|
1555 thus ?thesis using history Z_in |
|
1556 by (auto simp:ardenable_def) |
|
1557 qed |
|
1558 qed |
|
1559 |
|
1560 lemma equas_subst_f_holds_left_eq_right: |
|
1561 assumes substor: "Y = L rhs'" |
|
1562 and history: "\<forall>X xrhs. (X, xrhs) \<in> ES \<longrightarrow> distinct_rhs xrhs \<and> X = L xrhs" |
|
1563 and subst: "(X, xrhs) = equas_subst_f Y rhs' (Z, zrhs)" |
|
1564 and self_contained: "(Z, zrhs) \<in> ES" |
|
1565 shows "X = L xrhs" |
|
1566 proof (cases "\<exists> r. (Y, r) \<in> zrhs") |
|
1567 case True |
|
1568 from True obtain r where "(1)":"(Y, r) \<in> zrhs" .. |
|
1569 show ?thesis |
|
1570 proof - |
|
1571 from history self_contained |
|
1572 have dist: "distinct_rhs zrhs" by auto |
|
1573 hence "(SOME r. (Y, r) \<in> zrhs) = r" using self_contained "(1)" |
|
1574 using distinct_rhs_def by (auto intro:some_equality) |
|
1575 moreover have "L zrhs = L (rhs_subst zrhs Y rhs' r)" using substor dist "(1)" self_contained |
|
1576 by (rule_tac rhs_subst_prop1, auto simp:distinct_equas_rhs_def) |
|
1577 ultimately show ?thesis using subst history self_contained |
|
1578 by (auto simp:equas_subst_f_def split:if_splits) |
|
1579 qed |
|
1580 next |
|
1581 case False |
|
1582 thus ?thesis using history subst self_contained |
|
1583 by (auto simp:equas_subst_f_def) |
|
1584 qed |
|
1585 |
|
1586 lemma equas_subst_holds_left_eq_right: |
|
1587 assumes history: "\<forall>X xrhs. (X, xrhs) \<in> ES \<longrightarrow> ardenable (X, xrhs)" |
|
1588 and substor: "Y = L rhs'" |
|
1589 and X_in : "(X, xrhs) \<in> equas_subst ES Y yrhs'" |
|
1590 shows "\<forall>X xrhs. (X, xrhs) \<in> equas_subst ES Y rhs' \<longrightarrow> X = L xrhs" |
|
1591 apply (clarsimp simp add:equas_subst_def del_x_paired_def) |
|
1592 using substor |
|
1593 apply (drule_tac equas_subst_f_holds_left_eq_right) |
|
1594 using history |
|
1595 by (auto simp:ardenable_def) |
|
1596 |
|
1597 lemma equas_subst_holds_ardenable: |
|
1598 assumes substor: "Y = L yrhs'" |
|
1599 and history: "\<forall>X xrhs. (X, xrhs) \<in> ES \<longrightarrow> ardenable (X, xrhs)" |
|
1600 and X_in:"(X, xrhs) \<in> equas_subst ES Y yrhs'" |
|
1601 and dist': "distinct_rhs yrhs'" |
|
1602 and not_lambda: "Y \<noteq> {[]}" |
|
1603 shows "ardenable (X, xrhs)" |
|
1604 proof - |
|
1605 have "distinct_rhs xrhs" using history X_in dist' |
|
1606 by (auto dest:equas_subst_holds_distinct_rhs) |
|
1607 moreover have "no_EMPTY_rhs xrhs" using history X_in not_lambda |
|
1608 by (auto intro:equas_subst_holds_no_EMPTY) |
|
1609 moreover have "X = L xrhs" using history substor X_in |
|
1610 by (auto dest: equas_subst_holds_left_eq_right) |
|
1611 ultimately show ?thesis using ardenable_def by simp |
|
1612 qed |
|
1613 |
|
1614 lemma equas_subst_holds_cls_defined: |
|
1615 assumes X_in: "(X, xrhs) \<in> equas_subst ES Y yrhs'" |
|
1616 and Inv_ES: "Inv X' ES" |
|
1617 and subst: "(Y, yrhs) \<in> ES" |
|
1618 and cls_holds_but_Y: "rhs_eq_cls yrhs' = rhs_eq_cls yrhs - {Y}" |
|
1619 shows "rhs_eq_cls xrhs \<subseteq> insert {[]} (left_eq_cls (equas_subst ES Y yrhs'))" |
|
1620 proof- |
|
1621 have tac: "\<lbrakk> A \<subseteq> B; C \<subseteq> D; E \<subseteq> A \<union> B\<rbrakk> \<Longrightarrow> E \<subseteq> B \<union> D" by auto |
|
1622 from X_in have "\<exists> (Z, zrhs) \<in> ES. (X, xrhs) = equas_subst_f Y yrhs' (Z, zrhs)" |
|
1623 by (auto simp add:equas_subst_def del_x_paired_def) |
|
1624 then obtain Z zrhs where Z_in: "(Z, zrhs) \<in> ES" |
|
1625 and X_Z: "(X, xrhs) = equas_subst_f Y yrhs' (Z, zrhs)" by blast |
|
1626 hence "rhs_eq_cls zrhs \<subseteq> insert {[]} (left_eq_cls ES)" using Inv_ES |
|
1627 by (auto simp:Inv_def) |
|
1628 moreover have "rhs_eq_cls yrhs' \<subseteq> insert {[]} (left_eq_cls ES) - {Y}" |
|
1629 using Inv_ES subst cls_holds_but_Y |
|
1630 by (auto simp:Inv_def) |
|
1631 moreover have "rhs_eq_cls xrhs \<subseteq> rhs_eq_cls zrhs \<union> rhs_eq_cls yrhs' - {Y}" |
|
1632 using X_Z cls_holds_but_Y |
|
1633 apply (clarsimp simp add:equas_subst_f_def rhs_subst_def split:if_splits) |
|
1634 by (auto simp:rhs_eq_cls_def merge_rhs_def del_x_paired_def seq_rhs_r_def) |
|
1635 moreover have "left_eq_cls (equas_subst ES Y yrhs') = left_eq_cls ES - {Y}" using subst |
|
1636 by (auto simp: left_eq_cls_def equas_subst_def del_x_paired_def equas_subst_f_def |
|
1637 dest: equas_subst_f_del_no_other |
|
1638 split: if_splits) |
|
1639 ultimately show ?thesis by blast |
|
1640 qed |
|
1641 |
|
1642 lemma iteration_step: |
|
1643 assumes Inv_ES: "Inv X ES" |
|
1644 and not_T: "\<not> TCon ES" |
|
1645 shows "(\<exists> ES'. Inv X ES' \<and> (card ES', card ES) \<in> less_than)" |
|
1646 proof - |
|
1647 from Inv_ES not_T have another: "\<exists>Y yrhs. (Y, yrhs) \<in> ES \<and> X \<noteq> Y" unfolding Inv_def |
|
1648 by (clarify, rule_tac exist_another_equa[where X = X], auto) |
|
1649 then obtain Y yrhs where subst: "(Y, yrhs) \<in> ES" and not_X: " X \<noteq> Y" by blast |
|
1650 show ?thesis (is "\<exists> ES'. ?P ES'") |
|
1651 proof (cases "Y = {[]}") |
|
1652 case True |
|
1653 --"in this situation, we pick a \"\<lambda>\" equation, thus directly remove it from the equation-system" |
|
1654 have "?P (ES - {(Y, yrhs)})" |
|
1655 proof |
|
1656 show "Inv X (ES - {(Y, yrhs)})" using True not_X |
|
1657 by (simp add:Inv_ES Inv_mono_with_lambda) |
|
1658 next |
|
1659 show "(card (ES - {(Y, yrhs)}), card ES) \<in> less_than" using Inv_ES subst |
|
1660 by (auto elim:non_empty_card_prop[rule_format] simp:Inv_def) |
|
1661 qed |
|
1662 thus ?thesis by blast |
|
1663 next |
|
1664 case False |
|
1665 --"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" |
|
1666 hence "\<exists> yrhs'. Y = L yrhs' \<and> distinct_rhs yrhs' \<and> rhs_eq_cls yrhs' = rhs_eq_cls yrhs - {Y}" using subst Inv_ES |
|
1667 by (auto intro:ardenable_prop simp:Inv_def) |
|
1668 then obtain yrhs' where Y'_l_eq_r: "Y = L yrhs'" |
|
1669 and dist_Y': "distinct_rhs yrhs'" |
|
1670 and cls_holds_but_Y: "rhs_eq_cls yrhs' = rhs_eq_cls yrhs - {Y}" by blast |
|
1671 hence "?P (equas_subst ES Y yrhs')" |
|
1672 proof - |
|
1673 have finite_del: "\<And> S x. finite S \<Longrightarrow> finite (del_x_paired S x)" |
|
1674 apply (rule_tac A = "del_x_paired S x" in finite_subset) |
|
1675 by (auto simp:del_x_paired_def) |
|
1676 have "finite (equas_subst ES Y yrhs')" using Inv_ES |
|
1677 by (auto intro!:finite_del simp:equas_subst_def Inv_def) |
|
1678 moreover have "\<exists>rhs. (X, rhs) \<in> equas_subst ES Y yrhs'" using Inv_ES not_X |
|
1679 by (auto intro:equas_subst_del_no_other simp:Inv_def) |
|
1680 moreover have "distinct_equas (equas_subst ES Y yrhs')" using Inv_ES |
|
1681 by (auto intro:equas_subst_holds_distinct simp:Inv_def) |
|
1682 moreover have "\<forall>X xrhs. (X, xrhs) \<in> equas_subst ES Y yrhs' \<longrightarrow> ardenable (X, xrhs)" |
|
1683 using Inv_ES dist_Y' False Y'_l_eq_r |
|
1684 apply (clarsimp simp:Inv_def) |
|
1685 by (rule equas_subst_holds_ardenable, simp_all) |
|
1686 moreover have "\<forall>X xrhs. (X, xrhs) \<in> equas_subst ES Y yrhs' \<longrightarrow> X \<noteq> {}" using Inv_ES |
|
1687 by (clarsimp simp:equas_subst_def Inv_def del_x_paired_def equas_subst_f_def split:if_splits, auto) |
|
1688 moreover have "\<forall>X xrhs. (X, xrhs) \<in> equas_subst ES Y yrhs' \<longrightarrow> |
|
1689 rhs_eq_cls xrhs \<subseteq> insert {[]} (left_eq_cls (equas_subst ES Y yrhs'))" |
|
1690 using Inv_ES subst cls_holds_but_Y |
|
1691 apply (rule_tac impI | rule_tac allI)+ |
|
1692 by (erule equas_subst_holds_cls_defined, auto) |
|
1693 moreover have "(card (equas_subst ES Y yrhs'), card ES) \<in> less_than"using Inv_ES subst |
|
1694 by (simp add:equas_subst_card_less Inv_def) |
|
1695 ultimately show "?P (equas_subst ES Y yrhs')" by (auto simp:Inv_def) |
|
1696 qed |
|
1697 thus ?thesis by blast |
|
1698 qed |
|
1699 qed |
|
1700 |
|
1701 (* ****************************** END: proving every equation-system's iteration step satisfies Inv ******************************* *) |
|
1702 |
|
1703 lemma iteration_conc: |
|
1704 assumes history: "Inv X ES" |
|
1705 shows "\<exists> ES'. Inv X ES' \<and> TCon ES'" (is "\<exists> ES'. ?P ES'") |
|
1706 proof (cases "TCon ES") |
|
1707 case True |
|
1708 hence "?P ES" using history by simp |
|
1709 thus ?thesis by blast |
|
1710 next |
|
1711 case False |
|
1712 thus ?thesis using history iteration_step |
|
1713 by (rule_tac f = card in wf_iter, simp_all) |
|
1714 qed |
|
1715 |
|
1716 lemma eqset_imp_iff': "A = B \<Longrightarrow> \<forall> x. x \<in> A \<longleftrightarrow> x \<in> B" |
|
1717 apply (auto simp:mem_def) |
|
1718 done |
|
1719 |
|
1720 lemma set_cases2: |
|
1721 "\<lbrakk>(A = {} \<Longrightarrow> R A); \<And> x. (A = {x}) \<Longrightarrow> R A; \<And> x y. \<lbrakk>x \<noteq> y; x \<in> A; y \<in> A\<rbrakk> \<Longrightarrow> R A\<rbrakk> \<Longrightarrow> R A" |
|
1722 apply (case_tac "A = {}", simp) |
|
1723 by (case_tac "\<exists> x. A = {x}", clarsimp, blast) |
|
1724 |
|
1725 lemma rhs_aux:"\<lbrakk>distinct_rhs rhs; {Y. \<exists>r. (Y, r) \<in> rhs} = {X}\<rbrakk> \<Longrightarrow> (\<exists>r. rhs = {(X, r)})" |
|
1726 apply (rule_tac A = rhs in set_cases2, simp) |
|
1727 apply (drule_tac x = X in eqset_imp_iff, clarsimp) |
|
1728 apply (drule eqset_imp_iff',clarsimp) |
|
1729 apply (frule_tac x = a in spec, drule_tac x = aa in spec) |
|
1730 by (auto simp:distinct_rhs_def) |
|
1731 |
|
1732 lemma every_eqcl_has_reg: |
|
1733 assumes finite_CS: "finite (UNIV Quo Lang)" |
|
1734 and X_in_CS: "X \<in> (UNIV Quo Lang)" |
|
1735 shows "\<exists> (reg::rexp). L reg = X" (is "\<exists> r. ?E r") |
|
1736 proof- |
|
1737 have "\<exists>ES'. Inv X ES' \<and> TCon ES'" using finite_CS X_in_CS |
|
1738 by (auto intro:init_ES_satisfy_Inv iteration_conc) |
|
1739 then obtain ES' where Inv_ES': "Inv X ES'" |
|
1740 and TCon_ES': "TCon ES'" by blast |
|
1741 from Inv_ES' TCon_ES' |
|
1742 have "\<exists> rhs. ES' = {(X, rhs)}" |
|
1743 apply (clarsimp simp:Inv_def TCon_def) |
|
1744 apply (rule_tac x = rhs in exI) |
|
1745 by (auto dest!:card_Suc_Diff1 simp:card_eq_0_iff) |
|
1746 then obtain rhs where ES'_single_equa: "ES' = {(X, rhs)}" .. |
|
1747 hence X_ardenable: "ardenable (X, rhs)" using Inv_ES' |
|
1748 by (simp add:Inv_def) |
|
1749 |
|
1750 from X_ardenable have X_l_eq_r: "X = L rhs" |
|
1751 by (simp add:ardenable_def) |
|
1752 hence rhs_not_empty: "rhs \<noteq> {}" using Inv_ES' ES'_single_equa |
|
1753 by (auto simp:Inv_def ardenable_def L_def) |
|
1754 have rhs_eq_cls: "rhs_eq_cls rhs \<subseteq> {X, {[]}}" |
|
1755 using Inv_ES' ES'_single_equa |
|
1756 by (auto simp:Inv_def ardenable_def left_eq_cls_def) |
|
1757 have X_not_empty: "X \<noteq> {}" using Inv_ES' ES'_single_equa |
|
1758 by (auto simp:Inv_def) |
|
1759 show ?thesis |
|
1760 proof (cases "X = {[]}") |
|
1761 case True |
|
1762 hence "?E EMPTY" by (simp add:L_def) |
|
1763 thus ?thesis by blast |
|
1764 next |
|
1765 case False with X_ardenable |
|
1766 have "\<exists> rhs'. X = L rhs' \<and> rhs_eq_cls rhs' = rhs_eq_cls rhs - {X} \<and> distinct_rhs rhs'" |
|
1767 by (drule_tac ardenable_prop, auto) |
|
1768 then obtain rhs' where X_eq_rhs': "X = L rhs'" |
|
1769 and rhs'_eq_cls: "rhs_eq_cls rhs' = rhs_eq_cls rhs - {X}" |
|
1770 and rhs'_dist : "distinct_rhs rhs'" by blast |
|
1771 have "rhs_eq_cls rhs' \<subseteq> {{[]}}" using rhs_eq_cls False rhs'_eq_cls rhs_not_empty |
|
1772 by blast |
|
1773 hence "rhs_eq_cls rhs' = {{[]}}" using X_not_empty X_eq_rhs' |
|
1774 by (auto simp:L_def rhs_eq_cls_def) |
|
1775 hence "\<exists> r. rhs' = {({[]}, r)}" using rhs'_dist |
|
1776 by (auto intro:rhs_aux simp:rhs_eq_cls_def) |
|
1777 then obtain r where "rhs' = {({[]}, r)}" .. |
|
1778 hence "?E r" using X_eq_rhs' by (auto simp add:L_def lang_seq_def) |
|
1779 thus ?thesis by blast |
|
1780 qed |
|
1781 qed |
|
1782 |
|
1783 theorem myhill_nerode: |
|
1784 assumes finite_CS: "finite (UNIV Quo Lang)" |
|
1785 shows "\<exists> (reg::rexp). Lang = L reg" (is "\<exists> r. ?P r") |
|
1786 proof - |
|
1787 have has_r_each: "\<forall>C\<in>{X \<in> UNIV Quo Lang. \<forall>x\<in>X. x \<in> Lang}. \<exists>(r::rexp). C = L r" using finite_CS |
|
1788 by (auto dest:every_eqcl_has_reg) |
|
1789 have "\<exists> (rS::rexp set). finite rS \<and> |
|
1790 (\<forall> C \<in> {X \<in> UNIV Quo Lang. \<forall>x\<in>X. x \<in> Lang}. \<exists> r \<in> rS. C = L r) \<and> |
|
1791 (\<forall> r \<in> rS. \<exists> C \<in> {X \<in> UNIV Quo Lang. \<forall>x\<in>X. x \<in> Lang}. C = L r)" |
|
1792 (is "\<exists> rS. ?Q rS") |
|
1793 proof- |
|
1794 have "\<And> C. C \<in> {X \<in> UNIV Quo Lang. \<forall>x\<in>X. x \<in> Lang} \<Longrightarrow> C = L (SOME (ra::rexp). C = L ra)" |
|
1795 using has_r_each |
|
1796 apply (erule_tac x = C in ballE, erule_tac exE) |
|
1797 by (rule_tac a = r in someI2, simp+) |
|
1798 hence "?Q ((\<lambda> C. SOME r. C = L r) ` {X \<in> UNIV Quo Lang. \<forall>x\<in>X. x \<in> Lang})" using has_r_each |
|
1799 using finite_CS by auto |
|
1800 thus ?thesis by blast |
|
1801 qed |
|
1802 then obtain rS where finite_rS : "finite rS" |
|
1803 and has_r_each': "\<forall> C \<in> {X \<in> UNIV Quo Lang. \<forall>x\<in>X. x \<in> Lang}. \<exists> r \<in> (rS::rexp set). C = L r" |
|
1804 and has_cl_each: "\<forall> r \<in> (rS::rexp set). \<exists> C \<in> {X \<in> UNIV Quo Lang. \<forall>x\<in>X. x \<in> Lang}. C = L r" by blast |
|
1805 have "?P (folds ALT NULL rS)" |
|
1806 proof |
|
1807 show "Lang \<subseteq> L (folds ALT NULL rS)" using finite_rS lang_eqs_union_of_eqcls[of Lang] has_r_each' |
|
1808 apply (clarsimp simp:fold_alt_null_eqs) by blast |
|
1809 next |
|
1810 show "L (folds ALT NULL rS) \<subseteq> Lang" using finite_rS lang_eqs_union_of_eqcls[of Lang] has_cl_each |
|
1811 by (clarsimp simp:fold_alt_null_eqs) |
|
1812 qed |
|
1813 thus ?thesis by blast |
|
1814 qed |
|
1815 |
|
1816 end |
|
1817 |
|
1818 |
|
1819 |
|
1820 |
|
1821 |
|
1822 |
|
1823 |
|
1824 |
|
1825 |
|
1826 |