1 theory Myhill_2 |
1 theory Myhill_2 |
2 imports Myhill_1 |
2 imports Myhill_1 Prefix_subtract |
3 Prefix_subtract |
|
4 "~~/src/HOL/Library/List_Prefix" |
3 "~~/src/HOL/Library/List_Prefix" |
5 begin |
4 begin |
6 |
5 |
7 section {* Direction @{text "regular language \<Rightarrow>finite partition"} *} |
6 section {* Direction @{text "regular language \<Rightarrow>finite partition"} *} |
8 |
|
9 subsection {* The scheme*} |
|
10 |
|
11 text {* |
|
12 The following convenient notation @{text "x \<approx>A y"} means: |
|
13 string @{text "x"} and @{text "y"} are equivalent with respect to |
|
14 language @{text "A"}. |
|
15 *} |
|
16 |
7 |
17 definition |
8 definition |
18 str_eq :: "string \<Rightarrow> lang \<Rightarrow> string \<Rightarrow> bool" ("_ \<approx>_ _") |
9 str_eq :: "string \<Rightarrow> lang \<Rightarrow> string \<Rightarrow> bool" ("_ \<approx>_ _") |
19 where |
10 where |
20 "x \<approx>A y \<equiv> (x, y) \<in> (\<approx>A)" |
11 "x \<approx>A y \<equiv> (x, y) \<in> (\<approx>A)" |
21 |
|
22 text {* |
|
23 The main lemma (@{text "rexp_imp_finite"}) is proved by a structural |
|
24 induction over regular expressions. where base cases (cases for @{const |
|
25 "NULL"}, @{const "EMPTY"}, @{const "CHAR"}) are quite straightforward to |
|
26 proof. Real difficulty lies in inductive cases. By inductive hypothesis, |
|
27 languages defined by sub-expressions induce finite partitiions. Under such |
|
28 hypothsis, we need to prove that the language defined by the composite |
|
29 regular expression gives rise to finite partion. The basic idea is to |
|
30 attach a tag @{text "tag(x)"} to every string @{text "x"}. The tagging |
|
31 fuction @{text "tag"} is carefully devised, which returns tags made of |
|
32 equivalent classes of the partitions induced by subexpressoins, and |
|
33 therefore has a finite range. Let @{text "Lang"} be the composite language, |
|
34 it is proved that: |
|
35 \begin{quote} |
|
36 If strings with the same tag are equivalent with respect to @{text "Lang"}, expressed as: |
|
37 \[ |
|
38 @{text "tag(x) = tag(y) \<Longrightarrow> x \<approx>Lang y"} |
|
39 \] |
|
40 then the partition induced by @{text "Lang"} must be finite. |
|
41 \end{quote} |
|
42 There are two arguments for this. The first goes as the following: |
|
43 \begin{enumerate} |
|
44 \item First, the tagging function @{text "tag"} induces an equivalent relation @{text "(=tag=)"} |
|
45 (defiintion of @{text "f_eq_rel"} and lemma @{text "equiv_f_eq_rel"}). |
|
46 \item It is shown that: if the range of @{text "tag"} (denoted @{text "range(tag)"}) is finite, |
|
47 the partition given rise by @{text "(=tag=)"} is finite (lemma @{text "finite_eq_f_rel"}). |
|
48 Since tags are made from equivalent classes from component partitions, and the inductive |
|
49 hypothesis ensures the finiteness of these partitions, it is not difficult to prove |
|
50 the finiteness of @{text "range(tag)"}. |
|
51 \item It is proved that if equivalent relation @{text "R1"} is more refined than @{text "R2"} |
|
52 (expressed as @{text "R1 \<subseteq> R2"}), |
|
53 and the partition induced by @{text "R1"} is finite, then the partition induced by @{text "R2"} |
|
54 is finite as well (lemma @{text "refined_partition_finite"}). |
|
55 \item The injectivity assumption @{text "tag(x) = tag(y) \<Longrightarrow> x \<approx>Lang y"} implies that |
|
56 @{text "(=tag=)"} is more refined than @{text "(\<approx>Lang)"}. |
|
57 \item Combining the points above, we have: the partition induced by language @{text "Lang"} |
|
58 is finite (lemma @{text "tag_finite_imageD"}). |
|
59 \end{enumerate} |
|
60 *} |
|
61 |
12 |
62 definition |
13 definition |
63 tag_eq_rel :: "(string \<Rightarrow> 'b) \<Rightarrow> (string \<times> string) set" ("=_=") |
14 tag_eq_rel :: "(string \<Rightarrow> 'b) \<Rightarrow> (string \<times> string) set" ("=_=") |
64 where |
15 where |
65 "=tag= \<equiv> {(x, y) | x y. tag x = tag y}" |
16 "=tag= \<equiv> {(x, y) | x y. tag x = tag y}" |
159 unfolding equiv_def str_eq_rel_def sym_def refl_on_def trans_def |
107 unfolding equiv_def str_eq_rel_def sym_def refl_on_def trans_def |
160 by blast |
108 by blast |
161 qed |
109 qed |
162 |
110 |
163 |
111 |
164 subsection {* The proof*} |
112 subsection {* The proof *} |
165 |
|
166 text {* |
|
167 Each case is given in a separate section, as well as the final main lemma. Detailed explainations accompanied by |
|
168 illustrations are given for non-trivial cases. |
|
169 |
|
170 For ever inductive case, there are two tasks, the easier one is to show the range finiteness of |
|
171 of the tagging function based on the finiteness of component partitions, the |
|
172 difficult one is to show that strings with the same tag are equivalent with respect to the |
|
173 composite language. Suppose the composite language be @{text "Lang"}, tagging function be |
|
174 @{text "tag"}, it amounts to show: |
|
175 \[ |
|
176 @{text "tag(x) = tag(y) \<Longrightarrow> x \<approx>Lang y"} |
|
177 \] |
|
178 expanding the definition of @{text "\<approx>Lang"}, it amounts to show: |
|
179 \[ |
|
180 @{text "tag(x) = tag(y) \<Longrightarrow> (\<forall> z. x@z \<in> Lang \<longleftrightarrow> y@z \<in> Lang)"} |
|
181 \] |
|
182 Because the assumed tag equlity @{text "tag(x) = tag(y)"} is symmetric, |
|
183 it is suffcient to show just one direction: |
|
184 \[ |
|
185 @{text "\<And> x y z. \<lbrakk>tag(x) = tag(y); x@z \<in> Lang\<rbrakk> \<Longrightarrow> y@z \<in> Lang"} |
|
186 \] |
|
187 This is the pattern followed by every inductive case. |
|
188 *} |
|
189 |
113 |
190 subsubsection {* The base case for @{const "NULL"} *} |
114 subsubsection {* The base case for @{const "NULL"} *} |
191 |
115 |
192 lemma quot_null_eq: |
116 lemma quot_null_eq: |
193 shows "(UNIV // \<approx>{}) = ({UNIV}::lang set)" |
117 shows "UNIV // \<approx>{} = {UNIV}" |
194 unfolding quotient_def Image_def str_eq_rel_def by auto |
118 unfolding quotient_def Image_def str_eq_rel_def by auto |
195 |
119 |
196 lemma quot_null_finiteI [intro]: |
120 lemma quot_null_finiteI [intro]: |
197 shows "finite ((UNIV // \<approx>{})::lang set)" |
121 shows "finite (UNIV // \<approx>{})" |
198 unfolding quot_null_eq by simp |
122 unfolding quot_null_eq by simp |
199 |
123 |
200 |
124 |
201 subsubsection {* The base case for @{const "EMPTY"} *} |
125 subsubsection {* The base case for @{const "EMPTY"} *} |
202 |
126 |
203 |
|
204 lemma quot_empty_subset: |
127 lemma quot_empty_subset: |
205 "UNIV // (\<approx>{[]}) \<subseteq> {{[]}, UNIV - {[]}}" |
128 shows "UNIV // \<approx>{[]} \<subseteq> {{[]}, UNIV - {[]}}" |
206 proof |
129 proof |
207 fix x |
130 fix x |
208 assume "x \<in> UNIV // \<approx>{[]}" |
131 assume "x \<in> UNIV // \<approx>{[]}" |
209 then obtain y where h: "x = {z. (y, z) \<in> \<approx>{[]}}" |
132 then obtain y where h: "x = {z. (y, z) \<in> \<approx>{[]}}" |
210 unfolding quotient_def Image_def by blast |
133 unfolding quotient_def Image_def by blast |
235 then obtain y where h: "x = {z. (y, z) \<in> \<approx>{[c]}}" |
158 then obtain y where h: "x = {z. (y, z) \<in> \<approx>{[c]}}" |
236 unfolding quotient_def Image_def by blast |
159 unfolding quotient_def Image_def by blast |
237 show "x \<in> {{[]},{[c]}, UNIV - {[], [c]}}" |
160 show "x \<in> {{[]},{[c]}, UNIV - {[], [c]}}" |
238 proof - |
161 proof - |
239 { assume "y = []" hence "x = {[]}" using h |
162 { assume "y = []" hence "x = {[]}" using h |
240 by (auto simp:str_eq_rel_def) |
163 by (auto simp:str_eq_rel_def) } |
241 } moreover { |
164 moreover |
242 assume "y = [c]" hence "x = {[c]}" using h |
165 { assume "y = [c]" hence "x = {[c]}" using h |
243 by (auto dest!:spec[where x = "[]"] simp:str_eq_rel_def) |
166 by (auto dest!:spec[where x = "[]"] simp:str_eq_rel_def) } |
244 } moreover { |
167 moreover |
245 assume "y \<noteq> []" and "y \<noteq> [c]" |
168 { assume "y \<noteq> []" and "y \<noteq> [c]" |
246 hence "\<forall> z. (y @ z) \<noteq> [c]" by (case_tac y, auto) |
169 hence "\<forall> z. (y @ z) \<noteq> [c]" by (case_tac y, auto) |
247 moreover have "\<And> p. (p \<noteq> [] \<and> p \<noteq> [c]) = (\<forall> q. p @ q \<noteq> [c])" |
170 moreover have "\<And> p. (p \<noteq> [] \<and> p \<noteq> [c]) = (\<forall> q. p @ q \<noteq> [c])" |
248 by (case_tac p, auto) |
171 by (case_tac p, auto) |
249 ultimately have "x = UNIV - {[],[c]}" using h |
172 ultimately have "x = UNIV - {[],[c]}" using h |
250 by (auto simp add:str_eq_rel_def) |
173 by (auto simp add:str_eq_rel_def) |
251 } ultimately show ?thesis by blast |
174 } |
|
175 ultimately show ?thesis by blast |
252 qed |
176 qed |
253 qed |
177 qed |
254 |
178 |
255 lemma quot_char_finiteI [intro]: |
179 lemma quot_char_finiteI [intro]: |
256 shows "finite (UNIV // (\<approx>{[c]}))" |
180 shows "finite (UNIV // \<approx>{[c]})" |
257 by (rule finite_subset[OF quot_char_subset]) (simp) |
181 by (rule finite_subset[OF quot_char_subset]) (simp) |
258 |
182 |
259 |
183 |
260 subsubsection {* The inductive case for @{const ALT} *} |
184 subsubsection {* The inductive case for @{const ALT} *} |
261 |
185 |
281 unfolding str_eq_def |
204 unfolding str_eq_def |
282 unfolding str_eq_rel_def |
205 unfolding str_eq_rel_def |
283 by auto |
206 by auto |
284 qed |
207 qed |
285 |
208 |
|
209 |
286 subsubsection {* The inductive case for @{text "SEQ"}*} |
210 subsubsection {* The inductive case for @{text "SEQ"}*} |
287 |
|
288 text {* |
|
289 For case @{const "SEQ"}, the language @{text "L"} is @{text "L\<^isub>1 ;; L\<^isub>2"}. |
|
290 Given @{text "x @ z \<in> L\<^isub>1 ;; L\<^isub>2"}, according to the defintion of @{text " L\<^isub>1 ;; L\<^isub>2"}, |
|
291 string @{text "x @ z"} can be splitted with the prefix in @{text "L\<^isub>1"} and suffix in @{text "L\<^isub>2"}. |
|
292 The split point can either be in @{text "x"} (as shown in Fig. \ref{seq_first_split}), |
|
293 or in @{text "z"} (as shown in Fig. \ref{seq_snd_split}). Whichever way it goes, the structure |
|
294 on @{text "x @ z"} cn be transfered faithfully onto @{text "y @ z"} |
|
295 (as shown in Fig. \ref{seq_trans_first_split} and \ref{seq_trans_snd_split}) with the the help of the assumed |
|
296 tag equality. The following tag function @{text "tag_str_SEQ"} is such designed to facilitate |
|
297 such transfers and lemma @{text "tag_str_SEQ_injI"} formalizes the informal argument above. The details |
|
298 of structure transfer will be given their. |
|
299 \input{fig_seq} |
|
300 |
|
301 *} |
|
302 |
211 |
303 definition |
212 definition |
304 tag_str_SEQ :: "lang \<Rightarrow> lang \<Rightarrow> string \<Rightarrow> (lang \<times> lang set)" |
213 tag_str_SEQ :: "lang \<Rightarrow> lang \<Rightarrow> string \<Rightarrow> (lang \<times> lang set)" |
305 where |
214 where |
306 "tag_str_SEQ L1 L2 \<equiv> |
215 "tag_str_SEQ L1 L2 \<equiv> |
307 (\<lambda>x. (\<approx>L1 `` {x}, {(\<approx>L2 `` {x - x'}) | x'. x' \<le> x \<and> x' \<in> L1}))" |
216 (\<lambda>x. (\<approx>L1 `` {x}, {(\<approx>L2 `` {x - xa}) | xa. xa \<le> x \<and> xa \<in> L1}))" |
308 |
217 |
309 text {* The following is a techical lemma which helps to split the @{text "x @ z \<in> L\<^isub>1 ;; L\<^isub>2"} mentioned above.*} |
218 lemma Seq_in_cases: |
310 |
219 assumes "x @ z \<in> A ;; B" |
311 lemma append_seq_elim: |
220 shows "(\<exists> x' \<le> x. x' \<in> A \<and> (x - x') @ z \<in> B) \<or> |
312 assumes "x @ y \<in> L\<^isub>1 ;; L\<^isub>2" |
221 (\<exists> z' \<le> z. (x @ z') \<in> A \<and> (z - z') \<in> B)" |
313 shows "(\<exists> xa \<le> x. xa \<in> L\<^isub>1 \<and> (x - xa) @ y \<in> L\<^isub>2) \<or> |
222 using assms |
314 (\<exists> ya \<le> y. (x @ ya) \<in> L\<^isub>1 \<and> (y - ya) \<in> L\<^isub>2)" |
223 unfolding Seq_def prefix_def |
315 proof- |
224 by (auto simp add: append_eq_append_conv2) |
316 from assms obtain s\<^isub>1 s\<^isub>2 |
|
317 where eq_xys: "x @ y = s\<^isub>1 @ s\<^isub>2" |
|
318 and in_seq: "s\<^isub>1 \<in> L\<^isub>1 \<and> s\<^isub>2 \<in> L\<^isub>2" |
|
319 by (auto simp:Seq_def) |
|
320 from app_eq_dest [OF eq_xys] |
|
321 have |
|
322 "(x \<le> s\<^isub>1 \<and> (s\<^isub>1 - x) @ s\<^isub>2 = y) \<or> (s\<^isub>1 \<le> x \<and> (x - s\<^isub>1) @ y = s\<^isub>2)" |
|
323 (is "?Split1 \<or> ?Split2") . |
|
324 moreover have "?Split1 \<Longrightarrow> \<exists> ya \<le> y. (x @ ya) \<in> L\<^isub>1 \<and> (y - ya) \<in> L\<^isub>2" |
|
325 using in_seq by (rule_tac x = "s\<^isub>1 - x" in exI, auto elim:prefixE) |
|
326 moreover have "?Split2 \<Longrightarrow> \<exists> xa \<le> x. xa \<in> L\<^isub>1 \<and> (x - xa) @ y \<in> L\<^isub>2" |
|
327 using in_seq by (rule_tac x = s\<^isub>1 in exI, auto) |
|
328 ultimately show ?thesis by blast |
|
329 qed |
|
330 |
|
331 |
225 |
332 lemma tag_str_SEQ_injI: |
226 lemma tag_str_SEQ_injI: |
333 fixes v w |
227 assumes eq_tag: "tag_str_SEQ A B x = tag_str_SEQ A B y" |
334 assumes eq_tag: "tag_str_SEQ L\<^isub>1 L\<^isub>2 v = tag_str_SEQ L\<^isub>1 L\<^isub>2 w" |
228 shows "x \<approx>(A ;; B) y" |
335 shows "v \<approx>(L\<^isub>1 ;; L\<^isub>2) w" |
229 proof - |
336 proof- |
|
337 -- {* As explained before, a pattern for just one direction needs to be dealt with:*} |
|
338 { fix x y z |
230 { fix x y z |
339 assume xz_in_seq: "x @ z \<in> L\<^isub>1 ;; L\<^isub>2" |
231 assume xz_in_seq: "x @ z \<in> A ;; B" |
340 and tag_xy: "tag_str_SEQ L\<^isub>1 L\<^isub>2 x = tag_str_SEQ L\<^isub>1 L\<^isub>2 y" |
232 and tag_xy: "tag_str_SEQ A B x = tag_str_SEQ A B y" |
341 have"y @ z \<in> L\<^isub>1 ;; L\<^isub>2" |
233 have"y @ z \<in> A ;; B" |
342 proof- |
234 proof - |
343 -- {* There are two ways to split @{text "x@z"}: *} |
235 { (* first case with x' in A and (x - x') @ z in B *) |
344 from append_seq_elim [OF xz_in_seq] |
236 fix x' |
345 have "(\<exists> xa \<le> x. xa \<in> L\<^isub>1 \<and> (x - xa) @ z \<in> L\<^isub>2) \<or> |
237 assume h1: "x' \<le> x" and h2: "x' \<in> A" and h3: "(x - x') @ z \<in> B" |
346 (\<exists> za \<le> z. (x @ za) \<in> L\<^isub>1 \<and> (z - za) \<in> L\<^isub>2)" . |
238 obtain y' |
347 -- {* It can be shown that @{text "?thesis"} holds in either case: *} |
239 where "y' \<le> y" |
348 moreover { |
240 and "y' \<in> A" |
349 -- {* The case for the first split:*} |
241 and "(y - y') @ z \<in> B" |
350 fix xa |
|
351 assume h1: "xa \<le> x" and h2: "xa \<in> L\<^isub>1" and h3: "(x - xa) @ z \<in> L\<^isub>2" |
|
352 -- {* The following subgoal implements the structure transfer:*} |
|
353 obtain ya |
|
354 where "ya \<le> y" |
|
355 and "ya \<in> L\<^isub>1" |
|
356 and "(y - ya) @ z \<in> L\<^isub>2" |
|
357 proof - |
242 proof - |
358 -- {* |
243 have "{\<approx>B `` {x - x'} |x'. x' \<le> x \<and> x' \<in> A} = |
359 \begin{minipage}{0.8\textwidth} |
244 {\<approx>B `` {y - y'} |y'. y' \<le> y \<and> y' \<in> A}" (is "?Left = ?Right") |
360 By expanding the definition of |
|
361 @{thm [display] "tag_xy"} |
|
362 and extracting the second compoent, we get: |
|
363 \end{minipage} |
|
364 *} |
|
365 have "{\<approx>L\<^isub>2 `` {x - xa} |xa. xa \<le> x \<and> xa \<in> L\<^isub>1} = |
|
366 {\<approx>L\<^isub>2 `` {y - ya} |ya. ya \<le> y \<and> ya \<in> L\<^isub>1}" (is "?Left = ?Right") |
|
367 using tag_xy unfolding tag_str_SEQ_def by simp |
245 using tag_xy unfolding tag_str_SEQ_def by simp |
368 -- {* Since @{thm "h1"} and @{thm "h2"} hold, it is not difficult to show: *} |
246 moreover |
369 moreover have "\<approx>L\<^isub>2 `` {x - xa} \<in> ?Left" using h1 h2 by auto |
247 have "\<approx>B `` {x - x'} \<in> ?Left" using h1 h2 by auto |
370 -- {* |
248 ultimately |
371 \begin{minipage}{0.7\textwidth} |
249 have "\<approx>B `` {x - x'} \<in> ?Right" by simp |
372 Through tag equality, equivalent class @{term "\<approx>L\<^isub>2 `` {x - xa}"} also |
250 then obtain y' |
373 belongs to the @{text "?Right"}: |
251 where eq_xy': "\<approx>B `` {x - x'} = \<approx>B `` {y - y'}" |
374 \end{minipage} |
252 and pref_y': "y' \<le> y" and y'_in: "y' \<in> A" |
375 *} |
|
376 ultimately have "\<approx>L\<^isub>2 `` {x - xa} \<in> ?Right" by simp |
|
377 -- {* From this, the counterpart of @{text "xa"} in @{text "y"} is obtained:*} |
|
378 then obtain ya |
|
379 where eq_xya: "\<approx>L\<^isub>2 `` {x - xa} = \<approx>L\<^isub>2 `` {y - ya}" |
|
380 and pref_ya: "ya \<le> y" and ya_in: "ya \<in> L\<^isub>1" |
|
381 by simp blast |
253 by simp blast |
382 -- {* It can be proved that @{text "ya"} has the desired property:*} |
254 |
383 have "(y - ya)@z \<in> L\<^isub>2" |
255 have "(x - x') \<approx>B (y - y')" using eq_xy' |
384 proof - |
256 unfolding Image_def str_eq_rel_def str_eq_def by auto |
385 from eq_xya have "(x - xa) \<approx>L\<^isub>2 (y - ya)" |
257 with h3 have "(y - y') @ z \<in> B" |
386 unfolding Image_def str_eq_rel_def str_eq_def by auto |
258 unfolding str_eq_rel_def str_eq_def by simp |
387 with h3 show ?thesis unfolding str_eq_rel_def str_eq_def by simp |
259 with pref_y' y'_in |
388 qed |
|
389 -- {* Now, @{text "ya"} has all properties to be a qualified candidate:*} |
|
390 with pref_ya ya_in |
|
391 show ?thesis using that by blast |
260 show ?thesis using that by blast |
392 qed |
261 qed |
393 -- {* From the properties of @{text "ya"}, @{text "y @ z \<in> L\<^isub>1 ;; L\<^isub>2"} is derived easily.*} |
262 then have "y @ z \<in> A ;; B" by (erule_tac prefixE) (auto simp: Seq_def) |
394 hence "y @ z \<in> L\<^isub>1 ;; L\<^isub>2" by (erule_tac prefixE, auto simp:Seq_def) |
263 } |
395 } moreover { |
264 moreover |
396 -- {* The other case is even more simpler: *} |
265 { (* second case with x @ z' in A and z - z' in B *) |
397 fix za |
266 fix z' |
398 assume h1: "za \<le> z" and h2: "(x @ za) \<in> L\<^isub>1" and h3: "z - za \<in> L\<^isub>2" |
267 assume h1: "z' \<le> z" and h2: "(x @ z') \<in> A" and h3: "z - z' \<in> B" |
399 have "y @ za \<in> L\<^isub>1" |
268 have "\<approx>A `` {x} = \<approx>A `` {y}" |
400 proof- |
269 using tag_xy unfolding tag_str_SEQ_def by simp |
401 have "\<approx>L\<^isub>1 `` {x} = \<approx>L\<^isub>1 `` {y}" |
270 with h2 have "y @ z' \<in> A" |
402 using tag_xy unfolding tag_str_SEQ_def by simp |
|
403 with h2 show ?thesis |
|
404 unfolding Image_def str_eq_rel_def str_eq_def by auto |
271 unfolding Image_def str_eq_rel_def str_eq_def by auto |
405 qed |
272 with h1 h3 have "y @ z \<in> A ;; B" |
406 with h1 h3 have "y @ z \<in> L\<^isub>1 ;; L\<^isub>2" |
273 unfolding prefix_def Seq_def |
407 by (drule_tac A = L\<^isub>1 in seq_intro, auto elim:prefixE) |
274 by (auto) (metis append_assoc) |
408 } |
275 } |
409 ultimately show ?thesis by blast |
276 ultimately show "y @ z \<in> A ;; B" |
|
277 using Seq_in_cases [OF xz_in_seq] by blast |
410 qed |
278 qed |
411 } |
279 } |
412 -- {* |
|
413 \begin{minipage}{0.8\textwidth} |
|
414 @{text "?thesis"} is proved by exploiting the symmetry of |
|
415 @{thm [source] "eq_tag"}: |
|
416 \end{minipage} |
|
417 *} |
|
418 from this [OF _ eq_tag] and this [OF _ eq_tag [THEN sym]] |
280 from this [OF _ eq_tag] and this [OF _ eq_tag [THEN sym]] |
419 show ?thesis unfolding str_eq_def str_eq_rel_def by blast |
281 show "x \<approx>(A ;; B) y" unfolding str_eq_def str_eq_rel_def by blast |
420 qed |
282 qed |
421 |
283 |
422 lemma quot_seq_finiteI [intro]: |
284 lemma quot_seq_finiteI [intro]: |
423 fixes L1 L2::"lang" |
285 fixes L1 L2::"lang" |
424 assumes fin1: "finite (UNIV // \<approx>L1)" |
286 assumes fin1: "finite (UNIV // \<approx>L1)" |
435 apply(rule finite_subset[OF _ *]) |
297 apply(rule finite_subset[OF _ *]) |
436 unfolding quotient_def |
298 unfolding quotient_def |
437 by auto |
299 by auto |
438 qed |
300 qed |
439 |
301 |
|
302 |
440 subsubsection {* The inductive case for @{const "STAR"} *} |
303 subsubsection {* The inductive case for @{const "STAR"} *} |
441 |
|
442 text {* |
|
443 This turned out to be the trickiest case. The essential goal is |
|
444 to proved @{text "y @ z \<in> L\<^isub>1*"} under the assumptions that @{text "x @ z \<in> L\<^isub>1*"} |
|
445 and that @{text "x"} and @{text "y"} have the same tag. The reasoning goes as the following: |
|
446 \begin{enumerate} |
|
447 \item Since @{text "x @ z \<in> L\<^isub>1*"} holds, a prefix @{text "xa"} of @{text "x"} can be found |
|
448 such that @{text "xa \<in> L\<^isub>1*"} and @{text "(x - xa)@z \<in> L\<^isub>1*"}, as shown in Fig. \ref{first_split}. |
|
449 Such a prefix always exists, @{text "xa = []"}, for example, is one. |
|
450 \item There could be many but fintie many of such @{text "xa"}, from which we can find the longest |
|
451 and name it @{text "xa_max"}, as shown in Fig. \ref{max_split}. |
|
452 \item The next step is to split @{text "z"} into @{text "za"} and @{text "zb"} such that |
|
453 @{text "(x - xa_max) @ za \<in> L\<^isub>1"} and @{text "zb \<in> L\<^isub>1*"} as shown in Fig. \ref{last_split}. |
|
454 Such a split always exists because: |
|
455 \begin{enumerate} |
|
456 \item Because @{text "(x - x_max) @ z \<in> L\<^isub>1*"}, it can always be splitted into prefix @{text "a"} |
|
457 and suffix @{text "b"}, such that @{text "a \<in> L\<^isub>1"} and @{text "b \<in> L\<^isub>1*"}, |
|
458 as shown in Fig. \ref{ab_split}. |
|
459 \item But the prefix @{text "a"} CANNOT be shorter than @{text "x - xa_max"} |
|
460 (as shown in Fig. \ref{ab_split_wrong}), becasue otherwise, |
|
461 @{text "ma_max@a"} would be in the same kind as @{text "xa_max"} but with |
|
462 a larger size, conflicting with the fact that @{text "xa_max"} is the longest. |
|
463 \end{enumerate} |
|
464 \item \label{tansfer_step} |
|
465 By the assumption that @{text "x"} and @{text "y"} have the same tag, the structure on @{text "x @ z"} |
|
466 can be transferred to @{text "y @ z"} as shown in Fig. \ref{trans_split}. The detailed steps are: |
|
467 \begin{enumerate} |
|
468 \item A @{text "y"}-prefix @{text "ya"} corresponding to @{text "xa"} can be found, |
|
469 which satisfies conditions: @{text "ya \<in> L\<^isub>1*"} and @{text "(y - ya)@za \<in> L\<^isub>1"}. |
|
470 \item Since we already know @{text "zb \<in> L\<^isub>1*"}, we get @{text "(y - ya)@za@zb \<in> L\<^isub>1*"}, |
|
471 and this is just @{text "(y - ya)@z \<in> L\<^isub>1*"}. |
|
472 \item With fact @{text "ya \<in> L\<^isub>1*"}, we finally get @{text "y@z \<in> L\<^isub>1*"}. |
|
473 \end{enumerate} |
|
474 \end{enumerate} |
|
475 |
|
476 The formal proof of lemma @{text "tag_str_STAR_injI"} faithfully follows this informal argument |
|
477 while the tagging function @{text "tag_str_STAR"} is defined to make the transfer in step |
|
478 \ref{ansfer_step} feasible. |
|
479 |
|
480 \input{fig_star} |
|
481 *} |
|
482 |
304 |
483 definition |
305 definition |
484 tag_str_STAR :: "lang \<Rightarrow> string \<Rightarrow> lang set" |
306 tag_str_STAR :: "lang \<Rightarrow> string \<Rightarrow> lang set" |
485 where |
307 where |
486 "tag_str_STAR L1 \<equiv> (\<lambda>x. {\<approx>L1 `` {x - x'} | x'. x' < x \<and> x' \<in> L1\<star>})" |
308 "tag_str_STAR L1 \<equiv> (\<lambda>x. {\<approx>L1 `` {x - xa} | xa. xa < x \<and> xa \<in> L1\<star>})" |
487 |
309 |
488 text {* A technical lemma. *} |
310 text {* A technical lemma. *} |
489 lemma finite_set_has_max: "\<lbrakk>finite A; A \<noteq> {}\<rbrakk> \<Longrightarrow> |
311 lemma finite_set_has_max: "\<lbrakk>finite A; A \<noteq> {}\<rbrakk> \<Longrightarrow> |
490 (\<exists> max \<in> A. \<forall> a \<in> A. f a <= (f max :: nat))" |
312 (\<exists> max \<in> A. \<forall> a \<in> A. f a <= (f max :: nat))" |
491 proof (induct rule:finite.induct) |
313 proof (induct rule:finite.induct) |
511 qed |
333 qed |
512 qed |
334 qed |
513 qed |
335 qed |
514 |
336 |
515 |
337 |
516 text {* The following is a technical lemma.which helps to show the range finiteness of tag function. *} |
338 text {* The following is a technical lemma, which helps to show the range finiteness of tag function. *} |
|
339 |
517 lemma finite_strict_prefix_set: "finite {xa. xa < (x::string)}" |
340 lemma finite_strict_prefix_set: "finite {xa. xa < (x::string)}" |
518 apply (induct x rule:rev_induct, simp) |
341 apply (induct x rule:rev_induct, simp) |
519 apply (subgoal_tac "{xa. xa < xs @ [x]} = {xa. xa < xs} \<union> {xs}") |
342 apply (subgoal_tac "{xa. xa < xs @ [x]} = {xa. xa < xs} \<union> {xs}") |
520 by (auto simp:strict_prefix_def) |
343 by (auto simp:strict_prefix_def) |
521 |
344 |
522 |
345 |
523 lemma tag_str_STAR_injI: |
346 lemma tag_str_STAR_injI: |
524 fixes v w |
|
525 assumes eq_tag: "tag_str_STAR L\<^isub>1 v = tag_str_STAR L\<^isub>1 w" |
347 assumes eq_tag: "tag_str_STAR L\<^isub>1 v = tag_str_STAR L\<^isub>1 w" |
526 shows "(v::string) \<approx>(L\<^isub>1\<star>) w" |
348 shows "v \<approx>(L\<^isub>1\<star>) w" |
527 proof- |
349 proof- |
528 -- {* As explained before, a pattern for just one direction needs to be dealt with:*} |
|
529 { fix x y z |
350 { fix x y z |
530 assume xz_in_star: "x @ z \<in> L\<^isub>1\<star>" |
351 assume xz_in_star: "x @ z \<in> L\<^isub>1\<star>" |
531 and tag_xy: "tag_str_STAR L\<^isub>1 x = tag_str_STAR L\<^isub>1 y" |
352 and tag_xy: "tag_str_STAR L\<^isub>1 x = tag_str_STAR L\<^isub>1 y" |
532 have "y @ z \<in> L\<^isub>1\<star>" |
353 have "y @ z \<in> L\<^isub>1\<star>" |
533 proof(cases "x = []") |
354 proof(cases "x = []") |
534 -- {* |
|
535 The degenerated case when @{text "x"} is a null string is easy to prove: |
|
536 *} |
|
537 case True |
355 case True |
538 with tag_xy have "y = []" |
356 with tag_xy have "y = []" |
539 by (auto simp add: tag_str_STAR_def strict_prefix_def) |
357 by (auto simp add: tag_str_STAR_def strict_prefix_def) |
540 thus ?thesis using xz_in_star True by simp |
358 thus ?thesis using xz_in_star True by simp |
541 next |
359 next |
542 -- {* The nontrival case: |
|
543 *} |
|
544 case False |
360 case False |
545 -- {* |
|
546 \begin{minipage}{0.8\textwidth} |
|
547 Since @{text "x @ z \<in> L\<^isub>1\<star>"}, @{text "x"} can always be splitted |
|
548 by a prefix @{text "xa"} together with its suffix @{text "x - xa"}, such |
|
549 that both @{text "xa"} and @{text "(x - xa) @ z"} are in @{text "L\<^isub>1\<star>"}, |
|
550 and there could be many such splittings.Therefore, the following set @{text "?S"} |
|
551 is nonempty, and finite as well: |
|
552 \end{minipage} |
|
553 *} |
|
554 let ?S = "{xa. xa < x \<and> xa \<in> L\<^isub>1\<star> \<and> (x - xa) @ z \<in> L\<^isub>1\<star>}" |
361 let ?S = "{xa. xa < x \<and> xa \<in> L\<^isub>1\<star> \<and> (x - xa) @ z \<in> L\<^isub>1\<star>}" |
555 have "finite ?S" |
362 have "finite ?S" |
556 by (rule_tac B = "{xa. xa < x}" in finite_subset, |
363 by (rule_tac B = "{xa. xa < x}" in finite_subset, |
557 auto simp:finite_strict_prefix_set) |
364 auto simp:finite_strict_prefix_set) |
558 moreover have "?S \<noteq> {}" using False xz_in_star |
365 moreover have "?S \<noteq> {}" using False xz_in_star |
559 by (simp, rule_tac x = "[]" in exI, auto simp:strict_prefix_def) |
366 by (simp, rule_tac x = "[]" in exI, auto simp:strict_prefix_def) |
560 -- {* \begin{minipage}{0.7\textwidth} |
|
561 Since @{text "?S"} is finite, we can always single out the longest and name it @{text "xa_max"}: |
|
562 \end{minipage} |
|
563 *} |
|
564 ultimately have "\<exists> xa_max \<in> ?S. \<forall> xa \<in> ?S. length xa \<le> length xa_max" |
367 ultimately have "\<exists> xa_max \<in> ?S. \<forall> xa \<in> ?S. length xa \<le> length xa_max" |
565 using finite_set_has_max by blast |
368 using finite_set_has_max by blast |
566 then obtain xa_max |
369 then obtain xa_max |
567 where h1: "xa_max < x" |
370 where h1: "xa_max < x" |
568 and h2: "xa_max \<in> L\<^isub>1\<star>" |
371 and h2: "xa_max \<in> L\<^isub>1\<star>" |
569 and h3: "(x - xa_max) @ z \<in> L\<^isub>1\<star>" |
372 and h3: "(x - xa_max) @ z \<in> L\<^isub>1\<star>" |
570 and h4:"\<forall> xa < x. xa \<in> L\<^isub>1\<star> \<and> (x - xa) @ z \<in> L\<^isub>1\<star> |
373 and h4:"\<forall> xa < x. xa \<in> L\<^isub>1\<star> \<and> (x - xa) @ z \<in> L\<^isub>1\<star> |
571 \<longrightarrow> length xa \<le> length xa_max" |
374 \<longrightarrow> length xa \<le> length xa_max" |
572 by blast |
375 by blast |
573 -- {* |
|
574 \begin{minipage}{0.8\textwidth} |
|
575 By the equality of tags, the counterpart of @{text "xa_max"} among |
|
576 @{text "y"}-prefixes, named @{text "ya"}, can be found: |
|
577 \end{minipage} |
|
578 *} |
|
579 obtain ya |
376 obtain ya |
580 where h5: "ya < y" and h6: "ya \<in> L\<^isub>1\<star>" |
377 where h5: "ya < y" and h6: "ya \<in> L\<^isub>1\<star>" |
581 and eq_xya: "(x - xa_max) \<approx>L\<^isub>1 (y - ya)" |
378 and eq_xya: "(x - xa_max) \<approx>L\<^isub>1 (y - ya)" |
582 proof- |
379 proof- |
583 from tag_xy have "{\<approx>L\<^isub>1 `` {x - xa} |xa. xa < x \<and> xa \<in> L\<^isub>1\<star>} = |
380 from tag_xy have "{\<approx>L\<^isub>1 `` {x - xa} |xa. xa < x \<and> xa \<in> L\<^isub>1\<star>} = |
586 moreover have "\<approx>L\<^isub>1 `` {x - xa_max} \<in> ?left" using h1 h2 by auto |
383 moreover have "\<approx>L\<^isub>1 `` {x - xa_max} \<in> ?left" using h1 h2 by auto |
587 ultimately have "\<approx>L\<^isub>1 `` {x - xa_max} \<in> ?right" by simp |
384 ultimately have "\<approx>L\<^isub>1 `` {x - xa_max} \<in> ?right" by simp |
588 thus ?thesis using that |
385 thus ?thesis using that |
589 apply (simp add:Image_def str_eq_rel_def str_eq_def) by blast |
386 apply (simp add:Image_def str_eq_rel_def str_eq_def) by blast |
590 qed |
387 qed |
591 -- {* |
|
592 \begin{minipage}{0.8\textwidth} |
|
593 The @{text "?thesis"}, @{prop "y @ z \<in> L\<^isub>1\<star>"}, is a simple consequence |
|
594 of the following proposition: |
|
595 \end{minipage} |
|
596 *} |
|
597 have "(y - ya) @ z \<in> L\<^isub>1\<star>" |
388 have "(y - ya) @ z \<in> L\<^isub>1\<star>" |
598 proof- |
389 proof- |
599 -- {* The idea is to split the suffix @{text "z"} into @{text "za"} and @{text "zb"}, |
|
600 such that: *} |
|
601 obtain za zb where eq_zab: "z = za @ zb" |
390 obtain za zb where eq_zab: "z = za @ zb" |
602 and l_za: "(y - ya)@za \<in> L\<^isub>1" and ls_zb: "zb \<in> L\<^isub>1\<star>" |
391 and l_za: "(y - ya)@za \<in> L\<^isub>1" and ls_zb: "zb \<in> L\<^isub>1\<star>" |
603 proof - |
392 proof - |
604 -- {* |
|
605 \begin{minipage}{0.8\textwidth} |
|
606 Since @{thm "h1"}, @{text "x"} can be splitted into |
|
607 @{text "a"} and @{text "b"} such that: |
|
608 \end{minipage} |
|
609 *} |
|
610 from h1 have "(x - xa_max) @ z \<noteq> []" |
393 from h1 have "(x - xa_max) @ z \<noteq> []" |
611 by (auto simp:strict_prefix_def elim:prefixE) |
394 by (auto simp:strict_prefix_def elim:prefixE) |
612 from star_decom [OF h3 this] |
395 from star_decom [OF h3 this] |
613 obtain a b where a_in: "a \<in> L\<^isub>1" |
396 obtain a b where a_in: "a \<in> L\<^isub>1" |
614 and a_neq: "a \<noteq> []" and b_in: "b \<in> L\<^isub>1\<star>" |
397 and a_neq: "a \<noteq> []" and b_in: "b \<in> L\<^isub>1\<star>" |
615 and ab_max: "(x - xa_max) @ z = a @ b" by blast |
398 and ab_max: "(x - xa_max) @ z = a @ b" by blast |
616 -- {* Now the candiates for @{text "za"} and @{text "zb"} are found:*} |
|
617 let ?za = "a - (x - xa_max)" and ?zb = "b" |
399 let ?za = "a - (x - xa_max)" and ?zb = "b" |
618 have pfx: "(x - xa_max) \<le> a" (is "?P1") |
400 have pfx: "(x - xa_max) \<le> a" (is "?P1") |
619 and eq_z: "z = ?za @ ?zb" (is "?P2") |
401 and eq_z: "z = ?za @ ?zb" (is "?P2") |
620 proof - |
402 proof - |
621 -- {* |
|
622 \begin{minipage}{0.8\textwidth} |
|
623 Since @{text "(x - xa_max) @ z = a @ b"}, string @{text "(x - xa_max) @ z"} |
|
624 can be splitted in two ways: |
|
625 \end{minipage} |
|
626 *} |
|
627 have "((x - xa_max) \<le> a \<and> (a - (x - xa_max)) @ b = z) \<or> |
403 have "((x - xa_max) \<le> a \<and> (a - (x - xa_max)) @ b = z) \<or> |
628 (a < (x - xa_max) \<and> ((x - xa_max) - a) @ z = b)" |
404 (a < (x - xa_max) \<and> ((x - xa_max) - a) @ z = b)" |
629 using app_eq_dest[OF ab_max] by (auto simp:strict_prefix_def) |
405 using append_eq_dest[OF ab_max] by (auto simp:strict_prefix_def) |
630 moreover { |
406 moreover { |
631 -- {* However, the undsired way can be refuted by absurdity: *} |
|
632 assume np: "a < (x - xa_max)" |
407 assume np: "a < (x - xa_max)" |
633 and b_eqs: "((x - xa_max) - a) @ z = b" |
408 and b_eqs: "((x - xa_max) - a) @ z = b" |
634 have "False" |
409 have "False" |
635 proof - |
410 proof - |
636 let ?xa_max' = "xa_max @ a" |
411 let ?xa_max' = "xa_max @ a" |
637 have "?xa_max' < x" |
412 have "?xa_max' < x" |
638 using np h1 by (clarsimp simp:strict_prefix_def diff_prefix) |
413 using np h1 by (clarsimp simp:strict_prefix_def diff_prefix) |
639 moreover have "?xa_max' \<in> L\<^isub>1\<star>" |
414 moreover have "?xa_max' \<in> L\<^isub>1\<star>" |
640 using a_in h2 by (simp add:star_intro3) |
415 using a_in h2 by (simp add:star_intro3) |
641 moreover have "(x - ?xa_max') @ z \<in> L\<^isub>1\<star>" |
416 moreover have "(x - ?xa_max') @ z \<in> L\<^isub>1\<star>" |
642 using b_eqs b_in np h1 by (simp add:diff_diff_appd) |
417 using b_eqs b_in np h1 by (simp add:diff_diff_append) |
643 moreover have "\<not> (length ?xa_max' \<le> length xa_max)" |
418 moreover have "\<not> (length ?xa_max' \<le> length xa_max)" |
644 using a_neq by simp |
419 using a_neq by simp |
645 ultimately show ?thesis using h4 by blast |
420 ultimately show ?thesis using h4 by blast |
646 qed } |
421 qed } |
647 -- {* Now it can be shown that the splitting goes the way we desired. *} |
|
648 ultimately show ?P1 and ?P2 by auto |
422 ultimately show ?P1 and ?P2 by auto |
649 qed |
423 qed |
650 hence "(x - xa_max)@?za \<in> L\<^isub>1" using a_in by (auto elim:prefixE) |
424 hence "(x - xa_max)@?za \<in> L\<^isub>1" using a_in by (auto elim:prefixE) |
651 -- {* Now candidates @{text "?za"} and @{text "?zb"} have all the requred properteis. *} |
|
652 with eq_xya have "(y - ya) @ ?za \<in> L\<^isub>1" |
425 with eq_xya have "(y - ya) @ ?za \<in> L\<^isub>1" |
653 by (auto simp:str_eq_def str_eq_rel_def) |
426 by (auto simp:str_eq_def str_eq_rel_def) |
654 with eq_z and b_in |
427 with eq_z and b_in |
655 show ?thesis using that by blast |
428 show ?thesis using that by blast |
656 qed |
429 qed |
657 -- {* |
|
658 @{text "?thesis"} can easily be shown using properties of @{text "za"} and @{text "zb"}: |
|
659 *} |
|
660 have "((y - ya) @ za) @ zb \<in> L\<^isub>1\<star>" using l_za ls_zb by blast |
430 have "((y - ya) @ za) @ zb \<in> L\<^isub>1\<star>" using l_za ls_zb by blast |
661 with eq_zab show ?thesis by simp |
431 with eq_zab show ?thesis by simp |
662 qed |
432 qed |
663 with h5 h6 show ?thesis |
433 with h5 h6 show ?thesis |
664 by (drule_tac star_intro1) (auto simp:strict_prefix_def elim:prefixE) |
434 by (drule_tac star_intro1) (auto simp:strict_prefix_def elim:prefixE) |
665 qed |
435 qed |
666 } |
436 } |
667 -- {* By instantiating the reasoning pattern just derived for both directions:*} |
|
668 from this [OF _ eq_tag] and this [OF _ eq_tag [THEN sym]] |
437 from this [OF _ eq_tag] and this [OF _ eq_tag [THEN sym]] |
669 -- {* The thesis is proved as a trival consequence: *} |
|
670 show ?thesis unfolding str_eq_def str_eq_rel_def by blast |
438 show ?thesis unfolding str_eq_def str_eq_rel_def by blast |
671 qed |
439 qed |
672 |
440 |
673 lemma -- {* The oringal version with less explicit details. *} |
|
674 fixes v w |
|
675 assumes eq_tag: "tag_str_STAR L\<^isub>1 v = tag_str_STAR L\<^isub>1 w" |
|
676 shows "(v::string) \<approx>(L\<^isub>1\<star>) w" |
|
677 proof- |
|
678 -- {* |
|
679 \begin{minipage}{0.8\textwidth} |
|
680 According to the definition of @{text "\<approx>Lang"}, |
|
681 proving @{text "v \<approx>(L\<^isub>1\<star>) w"} amounts to |
|
682 showing: for any string @{text "u"}, |
|
683 if @{text "v @ u \<in> (L\<^isub>1\<star>)"} then @{text "w @ u \<in> (L\<^isub>1\<star>)"} and vice versa. |
|
684 The reasoning pattern for both directions are the same, as derived |
|
685 in the following: |
|
686 \end{minipage} |
|
687 *} |
|
688 { fix x y z |
|
689 assume xz_in_star: "x @ z \<in> L\<^isub>1\<star>" |
|
690 and tag_xy: "tag_str_STAR L\<^isub>1 x = tag_str_STAR L\<^isub>1 y" |
|
691 have "y @ z \<in> L\<^isub>1\<star>" |
|
692 proof(cases "x = []") |
|
693 -- {* |
|
694 The degenerated case when @{text "x"} is a null string is easy to prove: |
|
695 *} |
|
696 case True |
|
697 with tag_xy have "y = []" |
|
698 by (auto simp:tag_str_STAR_def strict_prefix_def) |
|
699 thus ?thesis using xz_in_star True by simp |
|
700 next |
|
701 -- {* |
|
702 \begin{minipage}{0.8\textwidth} |
|
703 The case when @{text "x"} is not null, and |
|
704 @{text "x @ z"} is in @{text "L\<^isub>1\<star>"}, |
|
705 \end{minipage} |
|
706 *} |
|
707 case False |
|
708 obtain x_max |
|
709 where h1: "x_max < x" |
|
710 and h2: "x_max \<in> L\<^isub>1\<star>" |
|
711 and h3: "(x - x_max) @ z \<in> L\<^isub>1\<star>" |
|
712 and h4:"\<forall> xa < x. xa \<in> L\<^isub>1\<star> \<and> (x - xa) @ z \<in> L\<^isub>1\<star> |
|
713 \<longrightarrow> length xa \<le> length x_max" |
|
714 proof- |
|
715 let ?S = "{xa. xa < x \<and> xa \<in> L\<^isub>1\<star> \<and> (x - xa) @ z \<in> L\<^isub>1\<star>}" |
|
716 have "finite ?S" |
|
717 by (rule_tac B = "{xa. xa < x}" in finite_subset, |
|
718 auto simp:finite_strict_prefix_set) |
|
719 moreover have "?S \<noteq> {}" using False xz_in_star |
|
720 by (simp, rule_tac x = "[]" in exI, auto simp:strict_prefix_def) |
|
721 ultimately have "\<exists> max \<in> ?S. \<forall> a \<in> ?S. length a \<le> length max" |
|
722 using finite_set_has_max by blast |
|
723 thus ?thesis using that by blast |
|
724 qed |
|
725 obtain ya |
|
726 where h5: "ya < y" and h6: "ya \<in> L\<^isub>1\<star>" and h7: "(x - x_max) \<approx>L\<^isub>1 (y - ya)" |
|
727 proof- |
|
728 from tag_xy have "{\<approx>L\<^isub>1 `` {x - xa} |xa. xa < x \<and> xa \<in> L\<^isub>1\<star>} = |
|
729 {\<approx>L\<^isub>1 `` {y - xa} |xa. xa < y \<and> xa \<in> L\<^isub>1\<star>}" (is "?left = ?right") |
|
730 by (auto simp:tag_str_STAR_def) |
|
731 moreover have "\<approx>L\<^isub>1 `` {x - x_max} \<in> ?left" using h1 h2 by auto |
|
732 ultimately have "\<approx>L\<^isub>1 `` {x - x_max} \<in> ?right" by simp |
|
733 with that show ?thesis apply |
|
734 (simp add:Image_def str_eq_rel_def str_eq_def) by blast |
|
735 qed |
|
736 have "(y - ya) @ z \<in> L\<^isub>1\<star>" |
|
737 proof- |
|
738 from h3 h1 obtain a b where a_in: "a \<in> L\<^isub>1" |
|
739 and a_neq: "a \<noteq> []" and b_in: "b \<in> L\<^isub>1\<star>" |
|
740 and ab_max: "(x - x_max) @ z = a @ b" |
|
741 by (drule_tac star_decom, auto simp:strict_prefix_def elim:prefixE) |
|
742 have "(x - x_max) \<le> a \<and> (a - (x - x_max)) @ b = z" |
|
743 proof - |
|
744 have "((x - x_max) \<le> a \<and> (a - (x - x_max)) @ b = z) \<or> |
|
745 (a < (x - x_max) \<and> ((x - x_max) - a) @ z = b)" |
|
746 using app_eq_dest[OF ab_max] by (auto simp:strict_prefix_def) |
|
747 moreover { |
|
748 assume np: "a < (x - x_max)" and b_eqs: " ((x - x_max) - a) @ z = b" |
|
749 have "False" |
|
750 proof - |
|
751 let ?x_max' = "x_max @ a" |
|
752 have "?x_max' < x" |
|
753 using np h1 by (clarsimp simp:strict_prefix_def diff_prefix) |
|
754 moreover have "?x_max' \<in> L\<^isub>1\<star>" |
|
755 using a_in h2 by (simp add:star_intro3) |
|
756 moreover have "(x - ?x_max') @ z \<in> L\<^isub>1\<star>" |
|
757 using b_eqs b_in np h1 by (simp add:diff_diff_appd) |
|
758 moreover have "\<not> (length ?x_max' \<le> length x_max)" |
|
759 using a_neq by simp |
|
760 ultimately show ?thesis using h4 by blast |
|
761 qed |
|
762 } ultimately show ?thesis by blast |
|
763 qed |
|
764 then obtain za where z_decom: "z = za @ b" |
|
765 and x_za: "(x - x_max) @ za \<in> L\<^isub>1" |
|
766 using a_in by (auto elim:prefixE) |
|
767 from x_za h7 have "(y - ya) @ za \<in> L\<^isub>1" |
|
768 by (auto simp:str_eq_def str_eq_rel_def) |
|
769 with b_in have "((y - ya) @ za) @ b \<in> L\<^isub>1\<star>" by blast |
|
770 with z_decom show ?thesis by auto |
|
771 qed |
|
772 with h5 h6 show ?thesis |
|
773 by (drule_tac star_intro1) (auto simp:strict_prefix_def elim:prefixE) |
|
774 qed |
|
775 } |
|
776 -- {* By instantiating the reasoning pattern just derived for both directions:*} |
|
777 from this [OF _ eq_tag] and this [OF _ eq_tag [THEN sym]] |
|
778 -- {* The thesis is proved as a trival consequence: *} |
|
779 show ?thesis unfolding str_eq_def str_eq_rel_def by blast |
|
780 qed |
|
781 |
|
782 lemma quot_star_finiteI [intro]: |
441 lemma quot_star_finiteI [intro]: |
783 fixes L1::"lang" |
|
784 assumes finite1: "finite (UNIV // \<approx>L1)" |
442 assumes finite1: "finite (UNIV // \<approx>L1)" |
785 shows "finite (UNIV // \<approx>(L1\<star>))" |
443 shows "finite (UNIV // \<approx>(L1\<star>))" |
786 proof (rule_tac tag = "tag_str_STAR L1" in tag_finite_imageD) |
444 proof (rule_tac tag = "tag_str_STAR L1" in tag_finite_imageD) |
787 show "\<And>x y. tag_str_STAR L1 x = tag_str_STAR L1 y \<Longrightarrow> x \<approx>(L1\<star>) y" |
445 show "\<And>x y. tag_str_STAR L1 x = tag_str_STAR L1 y \<Longrightarrow> x \<approx>(L1\<star>) y" |
788 by (rule tag_str_STAR_injI) |
446 by (rule tag_str_STAR_injI) |