|
1 |
|
2 theory Lexer |
|
3 imports Main |
|
4 begin |
|
5 |
|
6 |
|
7 section {* Sequential Composition of Languages *} |
|
8 |
|
9 definition |
|
10 Sequ :: "string set \<Rightarrow> string set \<Rightarrow> string set" ("_ ;; _" [100,100] 100) |
|
11 where |
|
12 "A ;; B = {s1 @ s2 | s1 s2. s1 \<in> A \<and> s2 \<in> B}" |
|
13 |
|
14 text {* Two Simple Properties about Sequential Composition *} |
|
15 |
|
16 lemma seq_empty [simp]: |
|
17 shows "A ;; {[]} = A" |
|
18 and "{[]} ;; A = A" |
|
19 by (simp_all add: Sequ_def) |
|
20 |
|
21 lemma seq_null [simp]: |
|
22 shows "A ;; {} = {}" |
|
23 and "{} ;; A = {}" |
|
24 by (simp_all add: Sequ_def) |
|
25 |
|
26 |
|
27 section {* Semantic Derivative (Left Quotient) of Languages *} |
|
28 |
|
29 definition |
|
30 Der :: "char \<Rightarrow> string set \<Rightarrow> string set" |
|
31 where |
|
32 "Der c A \<equiv> {s. c # s \<in> A}" |
|
33 |
|
34 lemma Der_null [simp]: |
|
35 shows "Der c {} = {}" |
|
36 unfolding Der_def |
|
37 by auto |
|
38 |
|
39 lemma Der_empty [simp]: |
|
40 shows "Der c {[]} = {}" |
|
41 unfolding Der_def |
|
42 by auto |
|
43 |
|
44 lemma Der_char [simp]: |
|
45 shows "Der c {[d]} = (if c = d then {[]} else {})" |
|
46 unfolding Der_def |
|
47 by auto |
|
48 |
|
49 lemma Der_union [simp]: |
|
50 shows "Der c (A \<union> B) = Der c A \<union> Der c B" |
|
51 unfolding Der_def |
|
52 by auto |
|
53 |
|
54 lemma Der_Sequ [simp]: |
|
55 shows "Der c (A ;; B) = (Der c A) ;; B \<union> (if [] \<in> A then Der c B else {})" |
|
56 unfolding Der_def Sequ_def |
|
57 by (auto simp add: Cons_eq_append_conv) |
|
58 |
|
59 |
|
60 section {* Kleene Star for Languages *} |
|
61 |
|
62 inductive_set |
|
63 Star :: "string set \<Rightarrow> string set" ("_\<star>" [101] 102) |
|
64 for A :: "string set" |
|
65 where |
|
66 start[intro]: "[] \<in> A\<star>" |
|
67 | step[intro]: "\<lbrakk>s1 \<in> A; s2 \<in> A\<star>\<rbrakk> \<Longrightarrow> s1 @ s2 \<in> A\<star>" |
|
68 |
|
69 lemma star_cases: |
|
70 shows "A\<star> = {[]} \<union> A ;; A\<star>" |
|
71 unfolding Sequ_def |
|
72 by (auto) (metis Star.simps) |
|
73 |
|
74 lemma star_decomp: |
|
75 assumes a: "c # x \<in> A\<star>" |
|
76 shows "\<exists>a b. x = a @ b \<and> c # a \<in> A \<and> b \<in> A\<star>" |
|
77 using a |
|
78 by (induct x\<equiv>"c # x" rule: Star.induct) |
|
79 (auto simp add: append_eq_Cons_conv) |
|
80 |
|
81 lemma Der_star [simp]: |
|
82 shows "Der c (A\<star>) = (Der c A) ;; A\<star>" |
|
83 proof - |
|
84 have "Der c (A\<star>) = Der c ({[]} \<union> A ;; A\<star>)" |
|
85 by (simp only: star_cases[symmetric]) |
|
86 also have "... = Der c (A ;; A\<star>)" |
|
87 by (simp only: Der_union Der_empty) (simp) |
|
88 also have "... = (Der c A) ;; A\<star> \<union> (if [] \<in> A then Der c (A\<star>) else {})" |
|
89 by simp |
|
90 also have "... = (Der c A) ;; A\<star>" |
|
91 unfolding Sequ_def Der_def |
|
92 by (auto dest: star_decomp) |
|
93 finally show "Der c (A\<star>) = (Der c A) ;; A\<star>" . |
|
94 qed |
|
95 |
|
96 |
|
97 section {* Regular Expressions *} |
|
98 |
|
99 datatype rexp = |
|
100 ZERO |
|
101 | ONE |
|
102 | CHAR char |
|
103 | SEQ rexp rexp |
|
104 | ALT rexp rexp |
|
105 | STAR rexp |
|
106 |
|
107 section {* Semantics of Regular Expressions *} |
|
108 |
|
109 fun |
|
110 L :: "rexp \<Rightarrow> string set" |
|
111 where |
|
112 "L (ZERO) = {}" |
|
113 | "L (ONE) = {[]}" |
|
114 | "L (CHAR c) = {[c]}" |
|
115 | "L (SEQ r1 r2) = (L r1) ;; (L r2)" |
|
116 | "L (ALT r1 r2) = (L r1) \<union> (L r2)" |
|
117 | "L (STAR r) = (L r)\<star>" |
|
118 |
|
119 |
|
120 section {* Nullable, Derivatives *} |
|
121 |
|
122 fun |
|
123 nullable :: "rexp \<Rightarrow> bool" |
|
124 where |
|
125 "nullable (ZERO) = False" |
|
126 | "nullable (ONE) = True" |
|
127 | "nullable (CHAR c) = False" |
|
128 | "nullable (ALT r1 r2) = (nullable r1 \<or> nullable r2)" |
|
129 | "nullable (SEQ r1 r2) = (nullable r1 \<and> nullable r2)" |
|
130 | "nullable (STAR r) = True" |
|
131 |
|
132 |
|
133 fun |
|
134 der :: "char \<Rightarrow> rexp \<Rightarrow> rexp" |
|
135 where |
|
136 "der c (ZERO) = ZERO" |
|
137 | "der c (ONE) = ZERO" |
|
138 | "der c (CHAR d) = (if c = d then ONE else ZERO)" |
|
139 | "der c (ALT r1 r2) = ALT (der c r1) (der c r2)" |
|
140 | "der c (SEQ r1 r2) = |
|
141 (if nullable r1 |
|
142 then ALT (SEQ (der c r1) r2) (der c r2) |
|
143 else SEQ (der c r1) r2)" |
|
144 | "der c (STAR r) = SEQ (der c r) (STAR r)" |
|
145 |
|
146 fun |
|
147 ders :: "string \<Rightarrow> rexp \<Rightarrow> rexp" |
|
148 where |
|
149 "ders [] r = r" |
|
150 | "ders (c # s) r = ders s (der c r)" |
|
151 |
|
152 |
|
153 lemma nullable_correctness: |
|
154 shows "nullable r \<longleftrightarrow> [] \<in> (L r)" |
|
155 by (induct r) (auto simp add: Sequ_def) |
|
156 |
|
157 |
|
158 lemma der_correctness: |
|
159 shows "L (der c r) = Der c (L r)" |
|
160 by (induct r) (simp_all add: nullable_correctness) |
|
161 |
|
162 |
|
163 section {* Values *} |
|
164 |
|
165 datatype val = |
|
166 Void |
|
167 | Char char |
|
168 | Seq val val |
|
169 | Right val |
|
170 | Left val |
|
171 | Stars "val list" |
|
172 |
|
173 |
|
174 section {* The string behind a value *} |
|
175 |
|
176 fun |
|
177 flat :: "val \<Rightarrow> string" |
|
178 where |
|
179 "flat (Void) = []" |
|
180 | "flat (Char c) = [c]" |
|
181 | "flat (Left v) = flat v" |
|
182 | "flat (Right v) = flat v" |
|
183 | "flat (Seq v1 v2) = (flat v1) @ (flat v2)" |
|
184 | "flat (Stars []) = []" |
|
185 | "flat (Stars (v#vs)) = (flat v) @ (flat (Stars vs))" |
|
186 |
|
187 lemma flat_Stars [simp]: |
|
188 "flat (Stars vs) = concat (map flat vs)" |
|
189 by (induct vs) (auto) |
|
190 |
|
191 |
|
192 section {* Relation between values and regular expressions *} |
|
193 |
|
194 inductive |
|
195 Prf :: "val \<Rightarrow> rexp \<Rightarrow> bool" ("\<turnstile> _ : _" [100, 100] 100) |
|
196 where |
|
197 "\<lbrakk>\<turnstile> v1 : r1; \<turnstile> v2 : r2\<rbrakk> \<Longrightarrow> \<turnstile> Seq v1 v2 : SEQ r1 r2" |
|
198 | "\<turnstile> v1 : r1 \<Longrightarrow> \<turnstile> Left v1 : ALT r1 r2" |
|
199 | "\<turnstile> v2 : r2 \<Longrightarrow> \<turnstile> Right v2 : ALT r1 r2" |
|
200 | "\<turnstile> Void : ONE" |
|
201 | "\<turnstile> Char c : CHAR c" |
|
202 | "\<turnstile> Stars [] : STAR r" |
|
203 | "\<lbrakk>\<turnstile> v : r; \<turnstile> Stars vs : STAR r\<rbrakk> \<Longrightarrow> \<turnstile> Stars (v # vs) : STAR r" |
|
204 |
|
205 inductive_cases Prf_elims: |
|
206 "\<turnstile> v : ZERO" |
|
207 "\<turnstile> v : SEQ r1 r2" |
|
208 "\<turnstile> v : ALT r1 r2" |
|
209 "\<turnstile> v : ONE" |
|
210 "\<turnstile> v : CHAR c" |
|
211 (* "\<turnstile> vs : STAR r"*) |
|
212 |
|
213 lemma Prf_flat_L: |
|
214 assumes "\<turnstile> v : r" shows "flat v \<in> L r" |
|
215 using assms |
|
216 by(induct v r rule: Prf.induct) |
|
217 (auto simp add: Sequ_def) |
|
218 |
|
219 lemma Prf_Stars: |
|
220 assumes "\<forall>v \<in> set vs. \<turnstile> v : r" |
|
221 shows "\<turnstile> Stars vs : STAR r" |
|
222 using assms |
|
223 by(induct vs) (auto intro: Prf.intros) |
|
224 |
|
225 lemma Star_string: |
|
226 assumes "s \<in> A\<star>" |
|
227 shows "\<exists>ss. concat ss = s \<and> (\<forall>s \<in> set ss. s \<in> A)" |
|
228 using assms |
|
229 apply(induct rule: Star.induct) |
|
230 apply(auto) |
|
231 apply(rule_tac x="[]" in exI) |
|
232 apply(simp) |
|
233 apply(rule_tac x="s1#ss" in exI) |
|
234 apply(simp) |
|
235 done |
|
236 |
|
237 |
|
238 lemma Star_val: |
|
239 assumes "\<forall>s\<in>set ss. \<exists>v. s = flat v \<and> \<turnstile> v : r" |
|
240 shows "\<exists>vs. concat (map flat vs) = concat ss \<and> (\<forall>v\<in>set vs. \<turnstile> v : r)" |
|
241 using assms |
|
242 apply(induct ss) |
|
243 apply(auto) |
|
244 apply (metis empty_iff list.set(1)) |
|
245 by (metis concat.simps(2) list.simps(9) set_ConsD) |
|
246 |
|
247 lemma L_flat_Prf1: |
|
248 assumes "\<turnstile> v : r" shows "flat v \<in> L r" |
|
249 using assms |
|
250 by (induct)(auto simp add: Sequ_def) |
|
251 |
|
252 lemma L_flat_Prf2: |
|
253 assumes "s \<in> L r" shows "\<exists>v. \<turnstile> v : r \<and> flat v = s" |
|
254 using assms |
|
255 apply(induct r arbitrary: s) |
|
256 apply(auto simp add: Sequ_def intro: Prf.intros) |
|
257 using Prf.intros(1) flat.simps(5) apply blast |
|
258 using Prf.intros(2) flat.simps(3) apply blast |
|
259 using Prf.intros(3) flat.simps(4) apply blast |
|
260 apply(subgoal_tac "\<exists>vs::val list. concat (map flat vs) = s \<and> (\<forall>v \<in> set vs. \<turnstile> v : r)") |
|
261 apply(auto)[1] |
|
262 apply(rule_tac x="Stars vs" in exI) |
|
263 apply(simp) |
|
264 apply (simp add: Prf_Stars) |
|
265 apply(drule Star_string) |
|
266 apply(auto) |
|
267 apply(rule Star_val) |
|
268 apply(auto) |
|
269 done |
|
270 |
|
271 lemma L_flat_Prf: |
|
272 "L(r) = {flat v | v. \<turnstile> v : r}" |
|
273 using L_flat_Prf1 L_flat_Prf2 by blast |
|
274 |
|
275 |
|
276 section {* Sulzmann and Lu functions *} |
|
277 |
|
278 fun |
|
279 mkeps :: "rexp \<Rightarrow> val" |
|
280 where |
|
281 "mkeps(ONE) = Void" |
|
282 | "mkeps(SEQ r1 r2) = Seq (mkeps r1) (mkeps r2)" |
|
283 | "mkeps(ALT r1 r2) = (if nullable(r1) then Left (mkeps r1) else Right (mkeps r2))" |
|
284 | "mkeps(STAR r) = Stars []" |
|
285 |
|
286 fun injval :: "rexp \<Rightarrow> char \<Rightarrow> val \<Rightarrow> val" |
|
287 where |
|
288 "injval (CHAR d) c Void = Char d" |
|
289 | "injval (ALT r1 r2) c (Left v1) = Left(injval r1 c v1)" |
|
290 | "injval (ALT r1 r2) c (Right v2) = Right(injval r2 c v2)" |
|
291 | "injval (SEQ r1 r2) c (Seq v1 v2) = Seq (injval r1 c v1) v2" |
|
292 | "injval (SEQ r1 r2) c (Left (Seq v1 v2)) = Seq (injval r1 c v1) v2" |
|
293 | "injval (SEQ r1 r2) c (Right v2) = Seq (mkeps r1) (injval r2 c v2)" |
|
294 | "injval (STAR r) c (Seq v (Stars vs)) = Stars ((injval r c v) # vs)" |
|
295 |
|
296 |
|
297 section {* Mkeps, injval *} |
|
298 |
|
299 lemma mkeps_nullable: |
|
300 assumes "nullable(r)" |
|
301 shows "\<turnstile> mkeps r : r" |
|
302 using assms |
|
303 by (induct rule: nullable.induct) |
|
304 (auto intro: Prf.intros) |
|
305 |
|
306 lemma mkeps_flat: |
|
307 assumes "nullable(r)" |
|
308 shows "flat (mkeps r) = []" |
|
309 using assms |
|
310 by (induct rule: nullable.induct) (auto) |
|
311 |
|
312 |
|
313 lemma Prf_injval: |
|
314 assumes "\<turnstile> v : der c r" |
|
315 shows "\<turnstile> (injval r c v) : r" |
|
316 using assms |
|
317 apply(induct r arbitrary: c v rule: rexp.induct) |
|
318 apply(auto intro!: Prf.intros mkeps_nullable elim!: Prf_elims split: if_splits) |
|
319 (* STAR *) |
|
320 apply(rotate_tac 2) |
|
321 apply(erule Prf.cases) |
|
322 apply(simp_all)[7] |
|
323 apply(auto) |
|
324 apply (metis Prf.intros(6) Prf.intros(7)) |
|
325 by (metis Prf.intros(7)) |
|
326 |
|
327 lemma Prf_injval_flat: |
|
328 assumes "\<turnstile> v : der c r" |
|
329 shows "flat (injval r c v) = c # (flat v)" |
|
330 using assms |
|
331 apply(induct arbitrary: v rule: der.induct) |
|
332 apply(auto elim!: Prf_elims split: if_splits) |
|
333 apply(metis mkeps_flat) |
|
334 apply(rotate_tac 2) |
|
335 apply(erule Prf.cases) |
|
336 apply(simp_all)[7] |
|
337 done |
|
338 |
|
339 |
|
340 |
|
341 section {* Our Alternative Posix definition *} |
|
342 |
|
343 inductive |
|
344 Posix :: "string \<Rightarrow> rexp \<Rightarrow> val \<Rightarrow> bool" ("_ \<in> _ \<rightarrow> _" [100, 100, 100] 100) |
|
345 where |
|
346 Posix_ONE: "[] \<in> ONE \<rightarrow> Void" |
|
347 | Posix_CHAR: "[c] \<in> (CHAR c) \<rightarrow> (Char c)" |
|
348 | Posix_ALT1: "s \<in> r1 \<rightarrow> v \<Longrightarrow> s \<in> (ALT r1 r2) \<rightarrow> (Left v)" |
|
349 | Posix_ALT2: "\<lbrakk>s \<in> r2 \<rightarrow> v; s \<notin> L(r1)\<rbrakk> \<Longrightarrow> s \<in> (ALT r1 r2) \<rightarrow> (Right v)" |
|
350 | Posix_SEQ: "\<lbrakk>s1 \<in> r1 \<rightarrow> v1; s2 \<in> r2 \<rightarrow> v2; |
|
351 \<not>(\<exists>s\<^sub>3 s\<^sub>4. s\<^sub>3 \<noteq> [] \<and> s\<^sub>3 @ s\<^sub>4 = s2 \<and> (s1 @ s\<^sub>3) \<in> L r1 \<and> s\<^sub>4 \<in> L r2)\<rbrakk> \<Longrightarrow> |
|
352 (s1 @ s2) \<in> (SEQ r1 r2) \<rightarrow> (Seq v1 v2)" |
|
353 | Posix_STAR1: "\<lbrakk>s1 \<in> r \<rightarrow> v; s2 \<in> STAR r \<rightarrow> Stars vs; flat v \<noteq> []; |
|
354 \<not>(\<exists>s\<^sub>3 s\<^sub>4. s\<^sub>3 \<noteq> [] \<and> s\<^sub>3 @ s\<^sub>4 = s2 \<and> (s1 @ s\<^sub>3) \<in> L r \<and> s\<^sub>4 \<in> L (STAR r))\<rbrakk> |
|
355 \<Longrightarrow> (s1 @ s2) \<in> STAR r \<rightarrow> Stars (v # vs)" |
|
356 | Posix_STAR2: "[] \<in> STAR r \<rightarrow> Stars []" |
|
357 |
|
358 inductive_cases Posix_elims: |
|
359 "s \<in> ZERO \<rightarrow> v" |
|
360 "s \<in> ONE \<rightarrow> v" |
|
361 "s \<in> CHAR c \<rightarrow> v" |
|
362 "s \<in> ALT r1 r2 \<rightarrow> v" |
|
363 "s \<in> SEQ r1 r2 \<rightarrow> v" |
|
364 "s \<in> STAR r \<rightarrow> v" |
|
365 |
|
366 lemma Posix1: |
|
367 assumes "s \<in> r \<rightarrow> v" |
|
368 shows "s \<in> L r" "flat v = s" |
|
369 using assms |
|
370 by (induct s r v rule: Posix.induct) |
|
371 (auto simp add: Sequ_def) |
|
372 |
|
373 |
|
374 lemma Posix1a: |
|
375 assumes "s \<in> r \<rightarrow> v" |
|
376 shows "\<turnstile> v : r" |
|
377 using assms |
|
378 by (induct s r v rule: Posix.induct)(auto intro: Prf.intros) |
|
379 |
|
380 |
|
381 lemma Posix_mkeps: |
|
382 assumes "nullable r" |
|
383 shows "[] \<in> r \<rightarrow> mkeps r" |
|
384 using assms |
|
385 apply(induct r rule: nullable.induct) |
|
386 apply(auto intro: Posix.intros simp add: nullable_correctness Sequ_def) |
|
387 apply(subst append.simps(1)[symmetric]) |
|
388 apply(rule Posix.intros) |
|
389 apply(auto) |
|
390 done |
|
391 |
|
392 |
|
393 lemma Posix_determ: |
|
394 assumes "s \<in> r \<rightarrow> v1" "s \<in> r \<rightarrow> v2" |
|
395 shows "v1 = v2" |
|
396 using assms |
|
397 proof (induct s r v1 arbitrary: v2 rule: Posix.induct) |
|
398 case (Posix_ONE v2) |
|
399 have "[] \<in> ONE \<rightarrow> v2" by fact |
|
400 then show "Void = v2" by cases auto |
|
401 next |
|
402 case (Posix_CHAR c v2) |
|
403 have "[c] \<in> CHAR c \<rightarrow> v2" by fact |
|
404 then show "Char c = v2" by cases auto |
|
405 next |
|
406 case (Posix_ALT1 s r1 v r2 v2) |
|
407 have "s \<in> ALT r1 r2 \<rightarrow> v2" by fact |
|
408 moreover |
|
409 have "s \<in> r1 \<rightarrow> v" by fact |
|
410 then have "s \<in> L r1" by (simp add: Posix1) |
|
411 ultimately obtain v' where eq: "v2 = Left v'" "s \<in> r1 \<rightarrow> v'" by cases auto |
|
412 moreover |
|
413 have IH: "\<And>v2. s \<in> r1 \<rightarrow> v2 \<Longrightarrow> v = v2" by fact |
|
414 ultimately have "v = v'" by simp |
|
415 then show "Left v = v2" using eq by simp |
|
416 next |
|
417 case (Posix_ALT2 s r2 v r1 v2) |
|
418 have "s \<in> ALT r1 r2 \<rightarrow> v2" by fact |
|
419 moreover |
|
420 have "s \<notin> L r1" by fact |
|
421 ultimately obtain v' where eq: "v2 = Right v'" "s \<in> r2 \<rightarrow> v'" |
|
422 by cases (auto simp add: Posix1) |
|
423 moreover |
|
424 have IH: "\<And>v2. s \<in> r2 \<rightarrow> v2 \<Longrightarrow> v = v2" by fact |
|
425 ultimately have "v = v'" by simp |
|
426 then show "Right v = v2" using eq by simp |
|
427 next |
|
428 case (Posix_SEQ s1 r1 v1 s2 r2 v2 v') |
|
429 have "(s1 @ s2) \<in> SEQ r1 r2 \<rightarrow> v'" |
|
430 "s1 \<in> r1 \<rightarrow> v1" "s2 \<in> r2 \<rightarrow> v2" |
|
431 "\<not> (\<exists>s\<^sub>3 s\<^sub>4. s\<^sub>3 \<noteq> [] \<and> s\<^sub>3 @ s\<^sub>4 = s2 \<and> s1 @ s\<^sub>3 \<in> L r1 \<and> s\<^sub>4 \<in> L r2)" by fact+ |
|
432 then obtain v1' v2' where "v' = Seq v1' v2'" "s1 \<in> r1 \<rightarrow> v1'" "s2 \<in> r2 \<rightarrow> v2'" |
|
433 apply(cases) apply (auto simp add: append_eq_append_conv2) |
|
434 using Posix1(1) by fastforce+ |
|
435 moreover |
|
436 have IHs: "\<And>v1'. s1 \<in> r1 \<rightarrow> v1' \<Longrightarrow> v1 = v1'" |
|
437 "\<And>v2'. s2 \<in> r2 \<rightarrow> v2' \<Longrightarrow> v2 = v2'" by fact+ |
|
438 ultimately show "Seq v1 v2 = v'" by simp |
|
439 next |
|
440 case (Posix_STAR1 s1 r v s2 vs v2) |
|
441 have "(s1 @ s2) \<in> STAR r \<rightarrow> v2" |
|
442 "s1 \<in> r \<rightarrow> v" "s2 \<in> STAR r \<rightarrow> Stars vs" "flat v \<noteq> []" |
|
443 "\<not> (\<exists>s\<^sub>3 s\<^sub>4. s\<^sub>3 \<noteq> [] \<and> s\<^sub>3 @ s\<^sub>4 = s2 \<and> s1 @ s\<^sub>3 \<in> L r \<and> s\<^sub>4 \<in> L (STAR r))" by fact+ |
|
444 then obtain v' vs' where "v2 = Stars (v' # vs')" "s1 \<in> r \<rightarrow> v'" "s2 \<in> (STAR r) \<rightarrow> (Stars vs')" |
|
445 apply(cases) apply (auto simp add: append_eq_append_conv2) |
|
446 using Posix1(1) apply fastforce |
|
447 apply (metis Posix1(1) Posix_STAR1.hyps(6) append_Nil append_Nil2) |
|
448 using Posix1(2) by blast |
|
449 moreover |
|
450 have IHs: "\<And>v2. s1 \<in> r \<rightarrow> v2 \<Longrightarrow> v = v2" |
|
451 "\<And>v2. s2 \<in> STAR r \<rightarrow> v2 \<Longrightarrow> Stars vs = v2" by fact+ |
|
452 ultimately show "Stars (v # vs) = v2" by auto |
|
453 next |
|
454 case (Posix_STAR2 r v2) |
|
455 have "[] \<in> STAR r \<rightarrow> v2" by fact |
|
456 then show "Stars [] = v2" by cases (auto simp add: Posix1) |
|
457 qed |
|
458 |
|
459 |
|
460 lemma Posix_injval: |
|
461 assumes "s \<in> (der c r) \<rightarrow> v" |
|
462 shows "(c # s) \<in> r \<rightarrow> (injval r c v)" |
|
463 using assms |
|
464 proof(induct r arbitrary: s v rule: rexp.induct) |
|
465 case ZERO |
|
466 have "s \<in> der c ZERO \<rightarrow> v" by fact |
|
467 then have "s \<in> ZERO \<rightarrow> v" by simp |
|
468 then have "False" by cases |
|
469 then show "(c # s) \<in> ZERO \<rightarrow> (injval ZERO c v)" by simp |
|
470 next |
|
471 case ONE |
|
472 have "s \<in> der c ONE \<rightarrow> v" by fact |
|
473 then have "s \<in> ZERO \<rightarrow> v" by simp |
|
474 then have "False" by cases |
|
475 then show "(c # s) \<in> ONE \<rightarrow> (injval ONE c v)" by simp |
|
476 next |
|
477 case (CHAR d) |
|
478 consider (eq) "c = d" | (ineq) "c \<noteq> d" by blast |
|
479 then show "(c # s) \<in> (CHAR d) \<rightarrow> (injval (CHAR d) c v)" |
|
480 proof (cases) |
|
481 case eq |
|
482 have "s \<in> der c (CHAR d) \<rightarrow> v" by fact |
|
483 then have "s \<in> ONE \<rightarrow> v" using eq by simp |
|
484 then have eqs: "s = [] \<and> v = Void" by cases simp |
|
485 show "(c # s) \<in> CHAR d \<rightarrow> injval (CHAR d) c v" using eq eqs |
|
486 by (auto intro: Posix.intros) |
|
487 next |
|
488 case ineq |
|
489 have "s \<in> der c (CHAR d) \<rightarrow> v" by fact |
|
490 then have "s \<in> ZERO \<rightarrow> v" using ineq by simp |
|
491 then have "False" by cases |
|
492 then show "(c # s) \<in> CHAR d \<rightarrow> injval (CHAR d) c v" by simp |
|
493 qed |
|
494 next |
|
495 case (ALT r1 r2) |
|
496 have IH1: "\<And>s v. s \<in> der c r1 \<rightarrow> v \<Longrightarrow> (c # s) \<in> r1 \<rightarrow> injval r1 c v" by fact |
|
497 have IH2: "\<And>s v. s \<in> der c r2 \<rightarrow> v \<Longrightarrow> (c # s) \<in> r2 \<rightarrow> injval r2 c v" by fact |
|
498 have "s \<in> der c (ALT r1 r2) \<rightarrow> v" by fact |
|
499 then have "s \<in> ALT (der c r1) (der c r2) \<rightarrow> v" by simp |
|
500 then consider (left) v' where "v = Left v'" "s \<in> der c r1 \<rightarrow> v'" |
|
501 | (right) v' where "v = Right v'" "s \<notin> L (der c r1)" "s \<in> der c r2 \<rightarrow> v'" |
|
502 by cases auto |
|
503 then show "(c # s) \<in> ALT r1 r2 \<rightarrow> injval (ALT r1 r2) c v" |
|
504 proof (cases) |
|
505 case left |
|
506 have "s \<in> der c r1 \<rightarrow> v'" by fact |
|
507 then have "(c # s) \<in> r1 \<rightarrow> injval r1 c v'" using IH1 by simp |
|
508 then have "(c # s) \<in> ALT r1 r2 \<rightarrow> injval (ALT r1 r2) c (Left v')" by (auto intro: Posix.intros) |
|
509 then show "(c # s) \<in> ALT r1 r2 \<rightarrow> injval (ALT r1 r2) c v" using left by simp |
|
510 next |
|
511 case right |
|
512 have "s \<notin> L (der c r1)" by fact |
|
513 then have "c # s \<notin> L r1" by (simp add: der_correctness Der_def) |
|
514 moreover |
|
515 have "s \<in> der c r2 \<rightarrow> v'" by fact |
|
516 then have "(c # s) \<in> r2 \<rightarrow> injval r2 c v'" using IH2 by simp |
|
517 ultimately have "(c # s) \<in> ALT r1 r2 \<rightarrow> injval (ALT r1 r2) c (Right v')" |
|
518 by (auto intro: Posix.intros) |
|
519 then show "(c # s) \<in> ALT r1 r2 \<rightarrow> injval (ALT r1 r2) c v" using right by simp |
|
520 qed |
|
521 next |
|
522 case (SEQ r1 r2) |
|
523 have IH1: "\<And>s v. s \<in> der c r1 \<rightarrow> v \<Longrightarrow> (c # s) \<in> r1 \<rightarrow> injval r1 c v" by fact |
|
524 have IH2: "\<And>s v. s \<in> der c r2 \<rightarrow> v \<Longrightarrow> (c # s) \<in> r2 \<rightarrow> injval r2 c v" by fact |
|
525 have "s \<in> der c (SEQ r1 r2) \<rightarrow> v" by fact |
|
526 then consider |
|
527 (left_nullable) v1 v2 s1 s2 where |
|
528 "v = Left (Seq v1 v2)" "s = s1 @ s2" |
|
529 "s1 \<in> der c r1 \<rightarrow> v1" "s2 \<in> r2 \<rightarrow> v2" "nullable r1" |
|
530 "\<not> (\<exists>s\<^sub>3 s\<^sub>4. s\<^sub>3 \<noteq> [] \<and> s\<^sub>3 @ s\<^sub>4 = s2 \<and> s1 @ s\<^sub>3 \<in> L (der c r1) \<and> s\<^sub>4 \<in> L r2)" |
|
531 | (right_nullable) v1 s1 s2 where |
|
532 "v = Right v1" "s = s1 @ s2" |
|
533 "s \<in> der c r2 \<rightarrow> v1" "nullable r1" "s1 @ s2 \<notin> L (SEQ (der c r1) r2)" |
|
534 | (not_nullable) v1 v2 s1 s2 where |
|
535 "v = Seq v1 v2" "s = s1 @ s2" |
|
536 "s1 \<in> der c r1 \<rightarrow> v1" "s2 \<in> r2 \<rightarrow> v2" "\<not>nullable r1" |
|
537 "\<not> (\<exists>s\<^sub>3 s\<^sub>4. s\<^sub>3 \<noteq> [] \<and> s\<^sub>3 @ s\<^sub>4 = s2 \<and> s1 @ s\<^sub>3 \<in> L (der c r1) \<and> s\<^sub>4 \<in> L r2)" |
|
538 by (force split: if_splits elim!: Posix_elims simp add: Sequ_def der_correctness Der_def) |
|
539 then show "(c # s) \<in> SEQ r1 r2 \<rightarrow> injval (SEQ r1 r2) c v" |
|
540 proof (cases) |
|
541 case left_nullable |
|
542 have "s1 \<in> der c r1 \<rightarrow> v1" by fact |
|
543 then have "(c # s1) \<in> r1 \<rightarrow> injval r1 c v1" using IH1 by simp |
|
544 moreover |
|
545 have "\<not> (\<exists>s\<^sub>3 s\<^sub>4. s\<^sub>3 \<noteq> [] \<and> s\<^sub>3 @ s\<^sub>4 = s2 \<and> s1 @ s\<^sub>3 \<in> L (der c r1) \<and> s\<^sub>4 \<in> L r2)" by fact |
|
546 then have "\<not> (\<exists>s\<^sub>3 s\<^sub>4. s\<^sub>3 \<noteq> [] \<and> s\<^sub>3 @ s\<^sub>4 = s2 \<and> (c # s1) @ s\<^sub>3 \<in> L r1 \<and> s\<^sub>4 \<in> L r2)" by (simp add: der_correctness Der_def) |
|
547 ultimately have "((c # s1) @ s2) \<in> SEQ r1 r2 \<rightarrow> Seq (injval r1 c v1) v2" using left_nullable by (rule_tac Posix.intros) |
|
548 then show "(c # s) \<in> SEQ r1 r2 \<rightarrow> injval (SEQ r1 r2) c v" using left_nullable by simp |
|
549 next |
|
550 case right_nullable |
|
551 have "nullable r1" by fact |
|
552 then have "[] \<in> r1 \<rightarrow> (mkeps r1)" by (rule Posix_mkeps) |
|
553 moreover |
|
554 have "s \<in> der c r2 \<rightarrow> v1" by fact |
|
555 then have "(c # s) \<in> r2 \<rightarrow> (injval r2 c v1)" using IH2 by simp |
|
556 moreover |
|
557 have "s1 @ s2 \<notin> L (SEQ (der c r1) r2)" by fact |
|
558 then have "\<not> (\<exists>s\<^sub>3 s\<^sub>4. s\<^sub>3 \<noteq> [] \<and> s\<^sub>3 @ s\<^sub>4 = c # s \<and> [] @ s\<^sub>3 \<in> L r1 \<and> s\<^sub>4 \<in> L r2)" using right_nullable |
|
559 by(auto simp add: der_correctness Der_def append_eq_Cons_conv Sequ_def) |
|
560 ultimately have "([] @ (c # s)) \<in> SEQ r1 r2 \<rightarrow> Seq (mkeps r1) (injval r2 c v1)" |
|
561 by(rule Posix.intros) |
|
562 then show "(c # s) \<in> SEQ r1 r2 \<rightarrow> injval (SEQ r1 r2) c v" using right_nullable by simp |
|
563 next |
|
564 case not_nullable |
|
565 have "s1 \<in> der c r1 \<rightarrow> v1" by fact |
|
566 then have "(c # s1) \<in> r1 \<rightarrow> injval r1 c v1" using IH1 by simp |
|
567 moreover |
|
568 have "\<not> (\<exists>s\<^sub>3 s\<^sub>4. s\<^sub>3 \<noteq> [] \<and> s\<^sub>3 @ s\<^sub>4 = s2 \<and> s1 @ s\<^sub>3 \<in> L (der c r1) \<and> s\<^sub>4 \<in> L r2)" by fact |
|
569 then have "\<not> (\<exists>s\<^sub>3 s\<^sub>4. s\<^sub>3 \<noteq> [] \<and> s\<^sub>3 @ s\<^sub>4 = s2 \<and> (c # s1) @ s\<^sub>3 \<in> L r1 \<and> s\<^sub>4 \<in> L r2)" by (simp add: der_correctness Der_def) |
|
570 ultimately have "((c # s1) @ s2) \<in> SEQ r1 r2 \<rightarrow> Seq (injval r1 c v1) v2" using not_nullable |
|
571 by (rule_tac Posix.intros) (simp_all) |
|
572 then show "(c # s) \<in> SEQ r1 r2 \<rightarrow> injval (SEQ r1 r2) c v" using not_nullable by simp |
|
573 qed |
|
574 next |
|
575 case (STAR r) |
|
576 have IH: "\<And>s v. s \<in> der c r \<rightarrow> v \<Longrightarrow> (c # s) \<in> r \<rightarrow> injval r c v" by fact |
|
577 have "s \<in> der c (STAR r) \<rightarrow> v" by fact |
|
578 then consider |
|
579 (cons) v1 vs s1 s2 where |
|
580 "v = Seq v1 (Stars vs)" "s = s1 @ s2" |
|
581 "s1 \<in> der c r \<rightarrow> v1" "s2 \<in> (STAR r) \<rightarrow> (Stars vs)" |
|
582 "\<not> (\<exists>s\<^sub>3 s\<^sub>4. s\<^sub>3 \<noteq> [] \<and> s\<^sub>3 @ s\<^sub>4 = s2 \<and> s1 @ s\<^sub>3 \<in> L (der c r) \<and> s\<^sub>4 \<in> L (STAR r))" |
|
583 apply(auto elim!: Posix_elims(1-5) simp add: der_correctness Der_def intro: Posix.intros) |
|
584 apply(rotate_tac 3) |
|
585 apply(erule_tac Posix_elims(6)) |
|
586 apply (simp add: Posix.intros(6)) |
|
587 using Posix.intros(7) by blast |
|
588 then show "(c # s) \<in> STAR r \<rightarrow> injval (STAR r) c v" |
|
589 proof (cases) |
|
590 case cons |
|
591 have "s1 \<in> der c r \<rightarrow> v1" by fact |
|
592 then have "(c # s1) \<in> r \<rightarrow> injval r c v1" using IH by simp |
|
593 moreover |
|
594 have "s2 \<in> STAR r \<rightarrow> Stars vs" by fact |
|
595 moreover |
|
596 have "(c # s1) \<in> r \<rightarrow> injval r c v1" by fact |
|
597 then have "flat (injval r c v1) = (c # s1)" by (rule Posix1) |
|
598 then have "flat (injval r c v1) \<noteq> []" by simp |
|
599 moreover |
|
600 have "\<not> (\<exists>s\<^sub>3 s\<^sub>4. s\<^sub>3 \<noteq> [] \<and> s\<^sub>3 @ s\<^sub>4 = s2 \<and> s1 @ s\<^sub>3 \<in> L (der c r) \<and> s\<^sub>4 \<in> L (STAR r))" by fact |
|
601 then have "\<not> (\<exists>s\<^sub>3 s\<^sub>4. s\<^sub>3 \<noteq> [] \<and> s\<^sub>3 @ s\<^sub>4 = s2 \<and> (c # s1) @ s\<^sub>3 \<in> L r \<and> s\<^sub>4 \<in> L (STAR r))" |
|
602 by (simp add: der_correctness Der_def) |
|
603 ultimately |
|
604 have "((c # s1) @ s2) \<in> STAR r \<rightarrow> Stars (injval r c v1 # vs)" by (rule Posix.intros) |
|
605 then show "(c # s) \<in> STAR r \<rightarrow> injval (STAR r) c v" using cons by(simp) |
|
606 qed |
|
607 qed |
|
608 |
|
609 |
|
610 section {* The Lexer by Sulzmann and Lu *} |
|
611 |
|
612 fun |
|
613 lexer :: "rexp \<Rightarrow> string \<Rightarrow> val option" |
|
614 where |
|
615 "lexer r [] = (if nullable r then Some(mkeps r) else None)" |
|
616 | "lexer r (c#s) = (case (lexer (der c r) s) of |
|
617 None \<Rightarrow> None |
|
618 | Some(v) \<Rightarrow> Some(injval r c v))" |
|
619 |
|
620 |
|
621 lemma lexer_correct_None: |
|
622 shows "s \<notin> L r \<longleftrightarrow> lexer r s = None" |
|
623 using assms |
|
624 apply(induct s arbitrary: r) |
|
625 apply(simp add: nullable_correctness) |
|
626 apply(drule_tac x="der a r" in meta_spec) |
|
627 apply(auto simp add: der_correctness Der_def) |
|
628 done |
|
629 |
|
630 lemma lexer_correct_Some: |
|
631 shows "s \<in> L r \<longleftrightarrow> (\<exists>v. lexer r s = Some(v) \<and> s \<in> r \<rightarrow> v)" |
|
632 using assms |
|
633 apply(induct s arbitrary: r) |
|
634 apply(auto simp add: Posix_mkeps nullable_correctness)[1] |
|
635 apply(drule_tac x="der a r" in meta_spec) |
|
636 apply(simp add: der_correctness Der_def) |
|
637 apply(rule iffI) |
|
638 apply(auto intro: Posix_injval simp add: Posix1(1)) |
|
639 done |
|
640 |
|
641 |
|
642 end |