# HG changeset patch # User wenzelm # Date 1442497686 -7200 # Node ID 9583ddfc07b37f3f0cd5d76b5b74b65aa59da6cd # Parent b34551d94934adc719c980f57efe8736e0c4df68 isabelle update_cartouches; tuned proofs; tuned whitespace; diff -r b34551d94934 -r 9583ddfc07b3 src/HOL/Library/Omega_Words_Fun.thy --- a/src/HOL/Library/Omega_Words_Fun.thy Thu Sep 17 15:47:24 2015 +0200 +++ b/src/HOL/Library/Omega_Words_Fun.thy Thu Sep 17 15:48:06 2015 +0200 @@ -1,13 +1,20 @@ -(* Author: Stefan Merz - Additions by Salomon Sickert, Julian Brunner, Peter Lammich. +(* + Author: Stefan Merz + Author: Salomon Sickert + Author: Julian Brunner + Author: Peter Lammich *) -section {* $\omega$-words *} + +section \$\omega$-words\ + theory Omega_Words_Fun -imports "~~/src/HOL/Library/Infinite_Set" + +imports Infinite_Set begin -text {* Note: This theory is based on Stefan Merz's work. *} -text {* +text \Note: This theory is based on Stefan Merz's work.\ + +text \ Automata recognize languages, which are sets of words. For the theory of $\omega$-automata, we are mostly interested in $\omega$-words, but it is sometimes useful to reason about @@ -15,25 +22,26 @@ lets us benefit from the existing library. Other formalizations could be investigated, such as representing words as functions whose domains are initial intervals of the natural numbers. -*} +\ + -subsection {* Type declaration and elementary operations *} +subsection \Type declaration and elementary operations\ -text {* +text \ We represent $\omega$-words as functions from the natural numbers to the alphabet type. Other possible formalizations include a coinductive definition or a uniform encoding of finite and infinite words, as studied by M\"uller et al. -*} +\ type_synonym 'a word = "nat \ 'a" -text {* +text \ We can prefix a finite word to an $\omega$-word, and a way to obtain an $\omega$-word from a finite, non-empty word is by $\omega$-iteration. -*} +\ definition conc :: "['a list, 'a word] \ 'a word" (infixr "conc" 65) @@ -50,20 +58,16 @@ lemma conc_empty[simp]: "[] \ w = w" unfolding conc_def by auto -lemma conc_fst[simp]: - "n < length w \ (w \ x) n = w!n" -by (simp add: conc_def) +lemma conc_fst[simp]: "n < length w \ (w \ x) n = w!n" + by (simp add: conc_def) -lemma conc_snd[simp]: - "\(n < length w) \ (w \ x) n = x (n - length w)" -by (simp add: conc_def) +lemma conc_snd[simp]: "\(n < length w) \ (w \ x) n = x (n - length w)" + by (simp add: conc_def) -lemma iter_nth [simp]: - "0 < length w \ w\<^sup>\ n = w!(n mod (length w))" -by (simp add: iter_def) +lemma iter_nth [simp]: "0 < length w \ w\<^sup>\ n = w!(n mod (length w))" + by (simp add: iter_def) -lemma conc_conc[simp]: - "u \ v \ w = (u @ v) \ w" (is "?lhs = ?rhs") +lemma conc_conc[simp]: "u \ v \ w = (u @ v) \ w" (is "?lhs = ?rhs") proof fix n have u: "n < length u \ ?lhs n = ?rhs n" @@ -77,24 +81,27 @@ lemma range_conc[simp]: "range (w\<^sub>1 \ w\<^sub>2) = set w\<^sub>1 \ range w\<^sub>2" proof (intro equalityI subsetI) - case (goal1 a) - obtain i where 1: "a = (w\<^sub>1 \ w\<^sub>2) i" using goal1 by auto - show ?case unfolding 1 by (cases "i < length w\<^sub>1", simp+) + fix a + assume "a \ range (w\<^sub>1 \ w\<^sub>2)" + then obtain i where 1: "a = (w\<^sub>1 \ w\<^sub>2) i" by auto + then show "a \ set w\<^sub>1 \ range w\<^sub>2" + unfolding 1 by (cases "i < length w\<^sub>1") simp_all next - case (goal2 a) - show ?case - using goal2 + fix a + assume a: "a \ set w\<^sub>1 \ range w\<^sub>2" + then show "a \ range (w\<^sub>1 \ w\<^sub>2)" proof - case (goal1) - obtain i where 1: "i < length w\<^sub>1" "a = w\<^sub>1 ! i" using goal1 in_set_conv_nth by metis + assume "a \ set w\<^sub>1" + then obtain i where 1: "i < length w\<^sub>1" "a = w\<^sub>1 ! i" + using in_set_conv_nth by metis show ?thesis proof show "a = (w\<^sub>1 \ w\<^sub>2) i" using 1 by auto show "i \ UNIV" by rule qed next - case (goal2) - obtain i where 1: "a = w\<^sub>2 i" using goal2 by auto + assume "a \ range w\<^sub>2" + then obtain i where 1: "a = w\<^sub>2 i" by auto show ?thesis proof show "a = (w\<^sub>1 \ w\<^sub>2) (length w\<^sub>1 + i)" using 1 by simp @@ -104,114 +111,107 @@ qed -lemma iter_unroll: - "0 < length w \ w\<^sup>\ = w \ w\<^sup>\" -by (rule ext, simp add: conc_def mod_geq) +lemma iter_unroll: "0 < length w \ w\<^sup>\ = w \ w\<^sup>\" + by (rule ext) (simp add: conc_def mod_geq) + subsection \Subsequence, Prefix, and Suffix\ -definition - suffix :: "[nat, 'a word] \ 'a word" + +definition suffix :: "[nat, 'a word] \ 'a word" where "suffix k x \ \n. x (k+n)" -definition subsequence :: "'a word \ nat \ nat \ 'a list" - ("_ [_ \ _]" 900) -where - "subsequence w i j \ map w [i.. nat \ nat \ 'a list" ("_ [_ \ _]" 900) + where "subsequence w i j \ map w [i.. 'a word \ 'a list" -where - "prefix n w \ subsequence w 0 n" +abbreviation prefix :: "nat \ 'a word \ 'a list" + where "prefix n w \ subsequence w 0 n" -lemma suffix_nth [simp]: - "(suffix k x) n = x (k+n)" -by (simp add: suffix_def) +lemma suffix_nth [simp]: "(suffix k x) n = x (k+n)" + by (simp add: suffix_def) -lemma suffix_0 [simp]: - "suffix 0 x = x" -by (simp add: suffix_def) +lemma suffix_0 [simp]: "suffix 0 x = x" + by (simp add: suffix_def) -lemma suffix_suffix [simp]: - "suffix m (suffix k x) = suffix (k+m) x" -by (rule ext, simp add: suffix_def add.assoc) +lemma suffix_suffix [simp]: "suffix m (suffix k x) = suffix (k+m) x" + by (rule ext) (simp add: suffix_def add.assoc) -lemma subsequence_append: - "prefix (i + j) w = prefix i w @ (w [i \ i + j])" +lemma subsequence_append: "prefix (i + j) w = prefix i w @ (w [i \ i + j])" unfolding map_append[symmetric] upt_add_eq_append[OF le0] subsequence_def .. -lemma subsequence_drop[simp]: - "drop i (w [j \ k]) = w [j + i \ k]" +lemma subsequence_drop[simp]: "drop i (w [j \ k]) = w [j + i \ k]" by (simp add: subsequence_def drop_map) -lemma subsequence_empty[simp]: - "w [i \ j] = [] \ j \ i" - by (auto simp add: subsequence_def) +lemma subsequence_empty[simp]: "w [i \ j] = [] \ j \ i" + by (auto simp add: subsequence_def) -lemma subsequence_length[simp]: - "length (subsequence w i j) = j - i" +lemma subsequence_length[simp]: "length (subsequence w i j) = j - i" by (simp add: subsequence_def) -lemma subsequence_nth[simp]: - "k < j - i \ (w [i \ j]) ! k = w (i + k)" +lemma subsequence_nth[simp]: "k < j - i \ (w [i \ j]) ! k = w (i + k)" unfolding subsequence_def by auto -lemma subseq_to_zero[simp]: "w[i\0] = []" by simp -lemma subseq_to_smaller[simp]: "i\j \ w[i\j] = []" by simp -lemma subseq_to_Suc[simp]: "i\j \ w [i \ Suc j] = w [ i \ j ] @ [w j]" +lemma subseq_to_zero[simp]: "w[i\0] = []" + by simp + +lemma subseq_to_smaller[simp]: "i\j \ w[i\j] = []" + by simp + +lemma subseq_to_Suc[simp]: "i\j \ w [i \ Suc j] = w [ i \ j ] @ [w j]" by (auto simp: subsequence_def) lemma subsequence_singleton[simp]: "w [i \ Suc i] = [w i]" by (auto simp: subsequence_def) -lemma subsequence_prefix_suffix: - "prefix (j - i) (suffix i w) = w [i \ j]" +lemma subsequence_prefix_suffix: "prefix (j - i) (suffix i w) = w [i \ j]" proof (cases "i \ j") case True - have "w [i \ j] = map w (map (\n. n + i) [0.. = map (\n. w (n + i)) [0.. j] = map w (map (\n. n + i) [0.. = map (\n. w (n + i)) [0.. (suffix n x)" - by (rule ext, simp add: subsequence_def conc_def) +lemma prefix_suffix: "x = prefix n x \ (suffix n x)" + by (rule ext) (simp add: subsequence_def conc_def) declare prefix_suffix[symmetric, simp] -lemma word_split: - obtains v\<^sub>1 v\<^sub>2 - where "v = v\<^sub>1 \ v\<^sub>2" "length v\<^sub>1 = k" +lemma word_split: obtains v\<^sub>1 v\<^sub>2 where "v = v\<^sub>1 \ v\<^sub>2" "length v\<^sub>1 = k" proof - show "v = prefix k v \ suffix k v" using prefix_suffix by this - show "length (prefix k v) = k" by simp + show "v = prefix k v \ suffix k v" + by (rule prefix_suffix) + show "length (prefix k v) = k" + by simp qed lemma set_subsequence[simp]: "set (w[i\j]) = w`{i.. k]) = w [j \ min (j + i) k]" +lemma subsequence_take[simp]: "take i (w [j \ k]) = w [j \ min (j + i) k]" by (simp add: subsequence_def take_map min_def) -lemma subsequence_shift[simp]: - "(suffix i w) [j \ k] = w [i + j \ i + k]" +lemma subsequence_shift[simp]: "(suffix i w) [j \ k] = w [i + j \ i + k]" by (metis add_diff_cancel_left subsequence_prefix_suffix suffix_suffix) lemma suffix_subseq_join[simp]: "i \ j \ v [i \ j] \ suffix j v = suffix i v" - by (metis (no_types, lifting) Nat.add_0_right le_add_diff_inverse prefix_suffix + by (metis (no_types, lifting) Nat.add_0_right le_add_diff_inverse prefix_suffix subsequence_shift suffix_suffix) lemma prefix_conc_fst[simp]: - assumes "j \ length w" + assumes "j \ length w" shows "prefix j (w \ w') = take j w" proof - have "\i < j. (prefix j (w \ w')) ! i = (take j w) ! i" @@ -219,95 +219,98 @@ thus ?thesis by (simp add: assms list_eq_iff_nth_eq min.absorb2) qed - + lemma prefix_conc_snd[simp]: assumes "n \ length u" shows "prefix n (u \ v) = u @ prefix (n - length u) v" proof (intro nth_equalityI allI impI) - case (goal1) - show ?case using assms by simp -next - case (goal2 i) - show ?case using goal2 - by (cases "i < length u") - (auto simp: nth_append) - + show "length (prefix n (u \ v)) = length (u @ prefix (n - length u) v)" + using assms by simp + fix i + assume "i < length (prefix n (u \ v))" + then show "prefix n (u \ v) ! i = (u @ prefix (n - length u) v) ! i" + by (cases "i < length u") (auto simp: nth_append) qed -lemma prefix_conc_length[simp]: - "prefix (length w) (w \ w') = w" +lemma prefix_conc_length[simp]: "prefix (length w) (w \ w') = w" by simp lemma suffix_conc_fst[simp]: assumes "n \ length u" shows "suffix n (u \ v) = drop n u \ v" proof - case (goal1 i) - show ?case using assms by (cases "n + i < length u", auto simp: algebra_simps) + show "suffix n (u \ v) i = (drop n u \ v) i" for i + using assms by (cases "n + i < length u") (auto simp: algebra_simps) qed lemma suffix_conc_snd[simp]: assumes "n \ length u" shows "suffix n (u \ v) = suffix (n - length u) v" proof - case (goal1 i) - show ?case using assms by simp + show "suffix n (u \ v) i = suffix (n - length u) v i" for i + using assms by simp qed -lemma suffix_conc_length[simp]: - "suffix (length w) (w \ w') = w'" +lemma suffix_conc_length[simp]: "suffix (length w) (w \ w') = w'" unfolding conc_def by force lemma concat_eq[iff]: assumes "length v\<^sub>1 = length v\<^sub>2" shows "v\<^sub>1 \ u\<^sub>1 = v\<^sub>2 \ u\<^sub>2 \ v\<^sub>1 = v\<^sub>2 \ u\<^sub>1 = u\<^sub>2" + (is "?lhs \ ?rhs") proof - case (goal1) - have 1: "\ i. (v\<^sub>1 \ u\<^sub>1) i = (v\<^sub>2 \ u\<^sub>2) i" using goal1 by auto - show ?case + assume ?lhs + then have 1: "(v\<^sub>1 \ u\<^sub>1) i = (v\<^sub>2 \ u\<^sub>2) i" for i by auto + show ?rhs proof (intro conjI ext nth_equalityI allI impI) - show "length v\<^sub>1 = length v\<^sub>2" using assms(1) by this + show "length v\<^sub>1 = length v\<^sub>2" by (rule assms(1)) next fix i assume 2: "i < length v\<^sub>1" have 3: "i < length v\<^sub>2" using assms(1) 2 by simp show "v\<^sub>1 ! i = v\<^sub>2 ! i" using 1[of i] 2 3 by simp next - fix i - show "u\<^sub>1 i = u\<^sub>2 i" using 1[of "length v\<^sub>1 + i"] assms(1) by simp + show "u\<^sub>1 i = u\<^sub>2 i" for i + using 1[of "length v\<^sub>1 + i"] assms(1) by simp qed next - case (goal2) - show ?case using goal2 by simp + assume ?rhs + then show ?lhs by simp qed -lemma same_concat_eq[iff]: "u \ v = u \ w \ v = w" by simp + +lemma same_concat_eq[iff]: "u \ v = u \ w \ v = w" + by simp lemma comp_concat[simp]: "f \ u \ v = map f u \ (f \ v)" proof fix i - show "(f \ u \ v) i = (map f u \ (f \ v)) i" by (cases "i < length u", simp+) + show "(f \ u \ v) i = (map f u \ (f \ v)) i" + by (cases "i < length u") simp_all qed + subsection \Prepending\ -primrec build :: "'a \ 'a word \ 'a word" (infixr "##" 65) +primrec build :: "'a \ 'a word \ 'a word" (infixr "##" 65) where "(a ## w) 0 = a" | "(a ## w) (Suc i) = w i" lemma build_eq[iff]: "a\<^sub>1 ## w\<^sub>1 = a\<^sub>2 ## w\<^sub>2 \ a\<^sub>1 = a\<^sub>2 \ w\<^sub>1 = w\<^sub>2" proof assume 1: "a\<^sub>1 ## w\<^sub>1 = a\<^sub>2 ## w\<^sub>2" - have 2: "\ i. (a\<^sub>1 ## w\<^sub>1) i = (a\<^sub>2 ## w\<^sub>2) i" using 1 by auto + have 2: "(a\<^sub>1 ## w\<^sub>1) i = (a\<^sub>2 ## w\<^sub>2) i" for i + using 1 by auto show "a\<^sub>1 = a\<^sub>2 \ w\<^sub>1 = w\<^sub>2" proof (intro conjI ext) - show "a\<^sub>1 = a\<^sub>2" using 2[of "0"] by simp - next - fix i - show "w\<^sub>1 i = w\<^sub>2 i" using 2[of "Suc i"] by simp + show "a\<^sub>1 = a\<^sub>2" + using 2[of "0"] by simp + show "w\<^sub>1 i = w\<^sub>2 i" for i + using 2[of "Suc i"] by simp qed next assume 1: "a\<^sub>1 = a\<^sub>2 \ w\<^sub>1 = w\<^sub>2" show "a\<^sub>1 ## w\<^sub>1 = a\<^sub>2 ## w\<^sub>2" using 1 by simp qed + lemma build_cons[simp]: "(a # u) \ v = a ## u \ v" proof fix i @@ -320,89 +323,93 @@ show ?thesis unfolding Suc by (cases "j < length u", simp+) qed qed + lemma build_append[simp]: "(w @ a # u) \ v = w \ a ## u \ v" unfolding conc_conc[symmetric] by simp + lemma build_first[simp]: "w 0 ## suffix (Suc 0) w = w" proof - fix i - show "(w 0 ## suffix (Suc 0) w) i = w i" by (cases i, simp+) + show "(w 0 ## suffix (Suc 0) w) i = w i" for i + by (cases i) simp_all qed -lemma build_split[intro]: "w = w 0 ## suffix 1 w" by simp + +lemma build_split[intro]: "w = w 0 ## suffix 1 w" + by simp + lemma build_range[simp]: "range (a ## w) = insert a (range w)" proof safe - fix i - show "(a ## w) i \ range w \ (a ## w) i = a" by (cases i, auto) -next + show "(a ## w) i \ range w \ (a ## w) i = a" for i + by (cases i) auto show "a \ range (a ## w)" proof (rule range_eqI) show "a = (a ## w) 0" by simp qed -next - fix i - show "w i \ range (a ## w)" + show "w i \ range (a ## w)" for i proof (rule range_eqI) show "w i = (a ## w) (Suc i)" by simp qed qed lemma suffix_singleton_suffix[simp]: "w i ## suffix (Suc i) w = suffix i w" - using suffix_subseq_join[of i "Suc i" w] + using suffix_subseq_join[of i "Suc i" w] by simp text \Find the first occurrence of a letter from a given set\ lemma word_first_split_set: assumes "A \ range w \ {}" - obtains u a v - where "w = u \ [a] \ v" "A \ set u = {}" "a \ A" + obtains u a v where "w = u \ [a] \ v" "A \ set u = {}" "a \ A" proof - def i \ "LEAST i. w i \ A" show ?thesis proof - show "w = prefix i w \ [w i] \ suffix (Suc i) w" by simp + show "w = prefix i w \ [w i] \ suffix (Suc i) w" + by simp show "A \ set (prefix i w) = {}" - proof safe - case (goal1 a) - obtain k where 3: "k < i" "w k = a" using goal1(2) by auto - have 4: "w k \ A" using not_less_Least 3(1) unfolding i_def by this - show ?case using goal1(1) 3(2) 4 by auto - qed - show "w i \ A" using LeastI assms(1) unfolding i_def by fast + apply safe + subgoal premises prems for a + proof - + from prems obtain k where 3: "k < i" "w k = a" + by auto + have 4: "w k \ A" + using not_less_Least 3(1) unfolding i_def . + show ?thesis + using prems(1) 3(2) 4 by auto + qed + done + show "w i \ A" + using LeastI assms(1) unfolding i_def by fast qed qed +subsection \The limit set of an $\omega$-word\ -subsection {* The limit set of an $\omega$-word *} - -text {* +text \ The limit set (also called infinity set) of an $\omega$-word is the set of letters that appear infinitely often in the word. This set plays an important role in defining acceptance conditions of $\omega$-automata. -*} +\ -definition - limit :: "'a word \ 'a set" - where "limit x \ { a . \\<^sub>\n . x n = a }" +definition limit :: "'a word \ 'a set" + where "limit x \ {a . \\<^sub>\n . x n = a}" -lemma limit_iff_frequent: - "(a \ limit x) = (\\<^sub>\n . x n = a)" -by (simp add: limit_def) +lemma limit_iff_frequent: "a \ limit x \ (\\<^sub>\n . x n = a)" + by (simp add: limit_def) -text {* +text \ The following is a different way to define the limit, using the reverse image, making the laws about reverse - image applicable to the limit set. + image applicable to the limit set. (Might want to change the definition above?) -*} +\ -lemma limit_vimage: - "(a \ limit x) = infinite (x -` {a})" -by (simp add: limit_def Inf_many_def vimage_def) +lemma limit_vimage: "(a \ limit x) = infinite (x -` {a})" + by (simp add: limit_def Inf_many_def vimage_def) lemma two_in_limit_iff: - "({a,b} \ limit x) = - ((\n. x n =a ) \ (\n. x n = a \ (\m>n. x m = b)) \ (\m. x m = b \ (\n>m. x n = a)))" + "({a, b} \ limit x) = + ((\n. x n =a ) \ (\n. x n = a \ (\m>n. x m = b)) \ (\m. x m = b \ (\n>m. x n = a)))" (is "?lhs = (?r1 \ ?r2 \ ?r3)") proof assume lhs: "?lhs" @@ -444,18 +451,18 @@ with infa' show "?lhs" by (auto simp: limit_def) qed -text {* +text \ For $\omega$-words over a finite alphabet, the limit set is non-empty. Moreover, from some position onward, any such word contains only letters from its limit set. -*} +\ lemma limit_nonempty: assumes fin: "finite (range x)" shows "\a. a \ limit x" proof - from fin obtain a where "a \ range x \ infinite (x -` {a})" - by (rule inf_img_fin_domE, auto) + by (rule inf_img_fin_domE) auto hence "a \ limit x" by (auto simp add: limit_vimage) thus ?thesis .. @@ -473,12 +480,13 @@ by (auto elim: INFM_mono) qed -text {* +text \ The reverse implication is true only if $S$ is finite. -*} +\ lemma INF_limit_inter: - assumes hyp: "\\<^sub>\ n. w n \ S" and fin: "finite (S \ range w)" + assumes hyp: "\\<^sub>\ n. w n \ S" + and fin: "finite (S \ range w)" shows "\a. a \ limit w \ S" proof (rule ccontr) assume contra: "\(\a. a \ limit w \ S)" @@ -498,8 +506,7 @@ lemma fin_ex_inf_eq_limit: "finite A \ (\\<^sub>\i. w i \ A) \ limit w \ A \ {}" by (metis INF_limit_inter equals0D finite_Int limit_inter_INF) -lemma limit_in_range_suffix: - "limit x \ range (suffix k x)" +lemma limit_in_range_suffix: "limit x \ range (suffix k x)" proof fix a assume "a \ limit x" @@ -517,8 +524,7 @@ lemmas limit_in_range_suffixD = limit_in_range_suffix[THEN subsetD] -lemma limit_subset: - "limit f \ f ` {n..}" +lemma limit_subset: "limit f \ f ` {n..}" using limit_in_range_suffix[of f n] unfolding suffix_def by auto theorem limit_is_suffix: @@ -557,13 +563,12 @@ theorems limit_is_suffixE = limit_is_suffix[THEN exE] -text {* +text \ The limit set enjoys some simple algebraic laws with respect to concatenation, suffixes, iteration, and renaming. -*} +\ -theorem limit_conc [simp]: - "limit (w \ x) = limit x" +theorem limit_conc [simp]: "limit (w \ x) = limit x" proof (auto) fix a assume a: "a \ limit (w \ x)" have "\m. \n. m x n = a" @@ -597,8 +602,7 @@ by (simp add: limit_def Inf_many_def) qed -theorem limit_suffix [simp]: - "limit (suffix n x) = limit x" +theorem limit_suffix [simp]: "limit (suffix n x) = limit x" proof - have "x = (prefix n x) \ (suffix n x)" by (simp add: prefix_suffix) @@ -625,8 +629,7 @@ then obtain k where k: "k < length w \ w!k = a" by (auto simp add: set_conv_nth) -- "the following bound is terrible, but it simplifies the proof" - from nempty k - have "\m. w\<^sup>\ ((Suc m)*(length w) + k) = a" + from nempty k have "\m. w\<^sup>\ ((Suc m)*(length w) + k) = a" by (simp add: mod_add_left_eq) moreover -- "why is the following so hard to prove??" @@ -659,26 +662,27 @@ by (simp add: limit_iff_frequent) qed -text {* +text \ The converse relation is not true in general: $f(a)$ can be in the limit of $f \circ w$ even though $a$ is not in the limit of $w$. However, @{text limit} commutes with renaming if the function is injective. More generally, if $f(a)$ is the image of only finitely many elements, some of these must be in the limit of $w$. -*} +\ lemma limit_o_inv: - assumes fin: "finite (f -` {x})" and x: "x \ limit (f \ w)" + assumes fin: "finite (f -` {x})" + and x: "x \ limit (f \ w)" shows "\a \ (f -` {x}). a \ limit w" proof (rule ccontr) - assume contra: "\(\a \ (f -` {x}). a \ limit w)" + assume contra: "\ ?thesis" -- "hence, every element in the pre-image occurs only finitely often" then have "\a \ (f -` {x}). finite {n. w n = a}" by (simp add: limit_def Inf_many_def) -- "so there are only finitely many occurrences of any such element" with fin have "finite (\ a \ (f -` {x}). {n. w n = a})" by auto - -- {* these are precisely those positions where $x$ occurs in $f \circ w$ *} + -- \these are precisely those positions where $x$ occurs in $f \circ w$\ moreover have "(\ a \ (f -` {x}). {n. w n = a}) = {n. f(w n) = x}" by auto @@ -686,7 +690,7 @@ -- "so $x$ can occur only finitely often in the translated word" have "finite {n. f(w n) = x}" by simp - -- {* \ldots\ which yields a contradiction *} + -- \\ldots\ which yields a contradiction\ with x show "False" by (simp add: limit_def Inf_many_def) qed @@ -697,7 +701,6 @@ proof show "f ` limit w \ limit (f \ w)" by auto -next show "limit (f \ w) \ f ` limit w" proof fix x @@ -718,7 +721,7 @@ proof - from fin obtain k where k_def: "limit w = range (suffix k w)" using limit_is_suffix by blast - have "\k'. w (k + k') \ S" + have "w (k + k') \ S" for k' using hyp unfolding k_def suffix_def image_def by blast thus ?thesis unfolding MOST_nat_le using le_Suc_ex by blast @@ -730,16 +733,16 @@ assumes "limit r = range (suffix i r)" assumes "j\i" shows "limit r = range (suffix j r)" - (is "?lhs = ?rhs") + (is "?lhs = ?rhs") proof - have "?lhs = range (suffix i r)" using assms by simp moreover have "\ \ ?rhs" using \j\i\ - by (metis (mono_tags, lifting) assms(2) image_subsetI le_Suc_ex range_eqI suffix_def suffix_suffix) + by (metis (mono_tags, lifting) assms(2) + image_subsetI le_Suc_ex range_eqI suffix_def suffix_suffix) moreover - have "\ \ ?lhs" - using limit_in_range_suffix . + have "\ \ ?lhs" by (rule limit_in_range_suffix) ultimately show "?lhs = ?rhs" by (metis antisym_conv limit_in_range_suffix) @@ -748,15 +751,15 @@ text \For two finite sequences, we can find a common suffix index such that the limits can be represented as these suffixes' ranges.\ lemma common_range_limit: - assumes "finite (range x)" and "finite (range y)" - obtains i where "limit x = range (suffix i x)" + assumes "finite (range x)" + and "finite (range y)" + obtains i where "limit x = range (suffix i x)" and "limit y = range (suffix i y)" proof - - obtain i j where - 1: "limit x = range (suffix i x)" + obtain i j where 1: "limit x = range (suffix i x)" and 2: "limit y = range (suffix j y)" using assms limit_is_suffix by metis - have "limit x = range (suffix (max i j) x)" + have "limit x = range (suffix (max i j) x)" and "limit y = range (suffix (max i j) y)" using limit_range_suffix_incr[OF 1] limit_range_suffix_incr[OF 2] by auto @@ -765,9 +768,9 @@ qed -subsection {* Index sequences and piecewise definitions *} +subsection \Index sequences and piecewise definitions\ -text {* +text \ A word can be defined piecewise: given a sequence of words $w_0, w_1, \ldots$ and a strictly increasing sequence of integers $i_0, i_1, \ldots$ where $i_0=0$, a single word is obtained by concatenating subwords of the $w_n$ as given by @@ -775,12 +778,11 @@ \[ (w_0)_{i_0} \ldots (w_0)_{i_1-1} (w_1)_{i_1} \ldots (w_1)_{i_2-1} \ldots \] - We prepare the field by proving some trivial facts about such sequences of + We prepare the field by proving some trivial facts about such sequences of indexes. -*} +\ -definition - idx_sequence :: "nat word \ bool" +definition idx_sequence :: "nat word \ bool" where "idx_sequence idx \ (idx 0 = 0) \ (\n. idx n < idx (Suc n))" lemma idx_sequence_less: @@ -800,7 +802,7 @@ lemma idx_sequence_inj: assumes iseq: "idx_sequence idx" - and eq: "idx m = idx n" + and eq: "idx m = idx n" shows "m = n" proof (rule nat_less_cases) assume "n n" + and m: "m \ n" shows "idx m \ idx n" proof (cases "m=n") case True @@ -837,11 +839,11 @@ thus ?thesis by simp qed -text {* +text \ Given an index sequence, every natural number is contained in the interval defined by two adjacent indexes, and in fact this interval is determined uniquely. -*} +\ lemma idx_sequence_idx: assumes "idx_sequence idx" @@ -882,8 +884,8 @@ lemma idx_sequence_interval_unique: assumes iseq: "idx_sequence idx" - and k: "n \ {idx k ..< idx (Suc k) }" - and m: "n \ {idx m ..< idx (Suc m) }" + and k: "n \ {idx k ..< idx (Suc k)}" + and m: "n \ {idx m ..< idx (Suc m)}" shows "k = m" proof (rule nat_less_cases) assume "k < m" @@ -919,19 +921,17 @@ with iseq show "k = y" by (auto elim: idx_sequence_interval_unique) qed -text {* +text \ Now we can define the piecewise construction of a word using an index sequence. -*} +\ -definition - merge :: "['a word word, nat word] \ 'a word" - where "merge ws idx \ - \ n. let i = THE i. n \ {idx i ..< idx (Suc i) } in ws i n" +definition merge :: "'a word word \ nat word \ 'a word" + where "merge ws idx \ \n. let i = THE i. n \ {idx i ..< idx (Suc i) } in ws i n" lemma merge: assumes idx: "idx_sequence idx" - and n: "n \ {idx i ..< idx (Suc i) }" + and n: "n \ {idx i ..< idx (Suc i)}" shows "merge ws idx n = ws i n" proof - from n have "(THE k. n \ {idx k ..< idx (Suc k) }) = i" @@ -945,20 +945,19 @@ shows "merge ws idx 0 = ws 0 0" proof (rule merge[OF idx]) from idx have "idx 0 < idx (Suc 0)" - by (unfold idx_sequence_def, blast) + unfolding idx_sequence_def by blast with idx show "0 \ {idx 0 ..< idx (Suc 0)}" by (simp add: idx_sequence_def) qed lemma merge_Suc: assumes idx: "idx_sequence idx" - and n: "n \ {idx i ..< idx (Suc i) }" - shows "merge ws idx (Suc n) = - (if Suc n = idx (Suc i) then ws (Suc i) else ws i) (Suc n)" -proof (auto) + and n: "n \ {idx i ..< idx (Suc i)}" + shows "merge ws idx (Suc n) = (if Suc n = idx (Suc i) then ws (Suc i) else ws i) (Suc n)" +proof auto assume eq: "Suc n = idx (Suc i)" from idx have "idx (Suc i) < idx (Suc(Suc i))" - by (unfold idx_sequence_def, blast) + unfolding idx_sequence_def by blast with eq idx show "merge ws idx (idx (Suc i)) = ws (Suc i) (idx (Suc i))" by (simp add: merge) next