src/HOL/Library/Omega_Words_Fun.thy
author wenzelm
Tue Oct 06 15:14:28 2015 +0200 (2015-10-06)
changeset 61337 4645502c3c64
parent 61189 9583ddfc07b3
child 61384 9f5145281888
permissions -rw-r--r--
fewer aliases for toplevel theorem statements;
wenzelm@61189
     1
(*
wenzelm@61189
     2
    Author:     Stefan Merz
wenzelm@61189
     3
    Author:     Salomon Sickert
wenzelm@61189
     4
    Author:     Julian Brunner
wenzelm@61189
     5
    Author:     Peter Lammich
lammich@61178
     6
*)
wenzelm@61189
     7
wenzelm@61189
     8
section \<open>$\omega$-words\<close>
wenzelm@61189
     9
lammich@61178
    10
theory Omega_Words_Fun
wenzelm@61189
    11
wenzelm@61189
    12
imports Infinite_Set
lammich@61178
    13
begin
lammich@61178
    14
wenzelm@61189
    15
text \<open>Note: This theory is based on Stefan Merz's work.\<close>
wenzelm@61189
    16
wenzelm@61189
    17
text \<open>
lammich@61178
    18
  Automata recognize languages, which are sets of words. For the
lammich@61178
    19
  theory of $\omega$-automata, we are mostly interested in
lammich@61178
    20
  $\omega$-words, but it is sometimes useful to reason about
lammich@61178
    21
  finite words, too. We are modeling finite words as lists; this
lammich@61178
    22
  lets us benefit from the existing library. Other formalizations
lammich@61178
    23
  could be investigated, such as representing words as functions
lammich@61178
    24
  whose domains are initial intervals of the natural numbers.
wenzelm@61189
    25
\<close>
wenzelm@61189
    26
lammich@61178
    27
wenzelm@61189
    28
subsection \<open>Type declaration and elementary operations\<close>
lammich@61178
    29
wenzelm@61189
    30
text \<open>
lammich@61178
    31
  We represent $\omega$-words as functions from the natural numbers
lammich@61178
    32
  to the alphabet type. Other possible formalizations include
lammich@61178
    33
  a coinductive definition or a uniform encoding of finite and
lammich@61178
    34
  infinite words, as studied by M\"uller et al.
wenzelm@61189
    35
\<close>
lammich@61178
    36
lammich@61178
    37
type_synonym
lammich@61178
    38
  'a word = "nat \<Rightarrow> 'a"
lammich@61178
    39
wenzelm@61189
    40
text \<open>
lammich@61178
    41
  We can prefix a finite word to an $\omega$-word, and a way
lammich@61178
    42
  to obtain an $\omega$-word from a finite, non-empty word is by
lammich@61178
    43
  $\omega$-iteration.
wenzelm@61189
    44
\<close>
lammich@61178
    45
lammich@61178
    46
definition
lammich@61178
    47
  conc :: "['a list, 'a word] \<Rightarrow> 'a word"    (infixr "conc" 65)
lammich@61178
    48
  where "w conc x == \<lambda>n. if n < length w then w!n else x (n - length w)"
lammich@61178
    49
lammich@61178
    50
definition
lammich@61178
    51
  iter :: "'a list \<Rightarrow> 'a word"
lammich@61178
    52
  where "iter w == if w = [] then undefined else (\<lambda>n. w!(n mod (length w)))"
lammich@61178
    53
lammich@61178
    54
notation (xsymbols)
lammich@61178
    55
  conc (infixr "\<frown>" 65) and
lammich@61178
    56
  iter ("(_\<^sup>\<omega>)" [1000])
lammich@61178
    57
lammich@61178
    58
lemma conc_empty[simp]: "[] \<frown> w = w"
lammich@61178
    59
  unfolding conc_def by auto
lammich@61178
    60
wenzelm@61189
    61
lemma conc_fst[simp]: "n < length w \<Longrightarrow> (w \<frown> x) n = w!n"
wenzelm@61189
    62
  by (simp add: conc_def)
lammich@61178
    63
wenzelm@61189
    64
lemma conc_snd[simp]: "\<not>(n < length w) \<Longrightarrow> (w \<frown> x) n = x (n - length w)"
wenzelm@61189
    65
  by (simp add: conc_def)
lammich@61178
    66
wenzelm@61189
    67
lemma iter_nth [simp]: "0 < length w \<Longrightarrow> w\<^sup>\<omega> n = w!(n mod (length w))"
wenzelm@61189
    68
  by (simp add: iter_def)
lammich@61178
    69
wenzelm@61189
    70
lemma conc_conc[simp]: "u \<frown> v \<frown> w = (u @ v) \<frown> w" (is "?lhs = ?rhs")
lammich@61178
    71
proof
lammich@61178
    72
  fix n
lammich@61178
    73
  have u: "n < length u \<Longrightarrow> ?lhs n = ?rhs n"
lammich@61178
    74
    by (simp add: conc_def nth_append)
lammich@61178
    75
  have v: "\<lbrakk> \<not>(n < length u); n < length u + length v \<rbrakk> \<Longrightarrow> ?lhs n = ?rhs n"
lammich@61178
    76
    by (simp add: conc_def nth_append, arith)
lammich@61178
    77
  have w: "\<not>(n < length u + length v) \<Longrightarrow> ?lhs n = ?rhs n"
lammich@61178
    78
    by (simp add: conc_def nth_append, arith)
lammich@61178
    79
  from u v w show "?lhs n = ?rhs n" by blast
lammich@61178
    80
qed
lammich@61178
    81
lammich@61178
    82
lemma range_conc[simp]: "range (w\<^sub>1 \<frown> w\<^sub>2) = set w\<^sub>1 \<union> range w\<^sub>2"
lammich@61178
    83
proof (intro equalityI subsetI)
wenzelm@61189
    84
  fix a
wenzelm@61189
    85
  assume "a \<in> range (w\<^sub>1 \<frown> w\<^sub>2)"
wenzelm@61189
    86
  then obtain i where 1: "a = (w\<^sub>1 \<frown> w\<^sub>2) i" by auto
wenzelm@61189
    87
  then show "a \<in> set w\<^sub>1 \<union> range w\<^sub>2"
wenzelm@61189
    88
    unfolding 1 by (cases "i < length w\<^sub>1") simp_all
lammich@61178
    89
next
wenzelm@61189
    90
  fix a
wenzelm@61189
    91
  assume a: "a \<in> set w\<^sub>1 \<union> range w\<^sub>2"
wenzelm@61189
    92
  then show "a \<in> range (w\<^sub>1 \<frown> w\<^sub>2)"
lammich@61178
    93
  proof
wenzelm@61189
    94
    assume "a \<in> set w\<^sub>1"
wenzelm@61189
    95
    then obtain i where 1: "i < length w\<^sub>1" "a = w\<^sub>1 ! i"
wenzelm@61189
    96
      using in_set_conv_nth by metis
lammich@61178
    97
    show ?thesis
lammich@61178
    98
    proof
lammich@61178
    99
      show "a = (w\<^sub>1 \<frown> w\<^sub>2) i" using 1 by auto
lammich@61178
   100
      show "i \<in> UNIV" by rule
lammich@61178
   101
    qed
lammich@61178
   102
  next
wenzelm@61189
   103
    assume "a \<in> range w\<^sub>2"
wenzelm@61189
   104
    then obtain i where 1: "a = w\<^sub>2 i" by auto
lammich@61178
   105
    show ?thesis
lammich@61178
   106
    proof
lammich@61178
   107
      show "a = (w\<^sub>1 \<frown> w\<^sub>2) (length w\<^sub>1 + i)" using 1 by simp
lammich@61178
   108
      show "length w\<^sub>1 + i \<in> UNIV" by rule
lammich@61178
   109
    qed
lammich@61178
   110
  qed
lammich@61178
   111
qed
lammich@61178
   112
lammich@61178
   113
wenzelm@61189
   114
lemma iter_unroll: "0 < length w \<Longrightarrow> w\<^sup>\<omega> = w \<frown> w\<^sup>\<omega>"
wenzelm@61189
   115
  by (rule ext) (simp add: conc_def mod_geq)
wenzelm@61189
   116
lammich@61178
   117
lammich@61178
   118
subsection \<open>Subsequence, Prefix, and Suffix\<close>
wenzelm@61189
   119
wenzelm@61189
   120
definition suffix :: "[nat, 'a word] \<Rightarrow> 'a word"
lammich@61178
   121
  where "suffix k x \<equiv> \<lambda>n. x (k+n)"
lammich@61178
   122
wenzelm@61189
   123
definition subsequence :: "'a word \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> 'a list"  ("_ [_ \<rightarrow> _]" 900)
wenzelm@61189
   124
  where "subsequence w i j \<equiv> map w [i..<j]"
lammich@61178
   125
wenzelm@61189
   126
abbreviation prefix :: "nat \<Rightarrow> 'a word \<Rightarrow> 'a list"
wenzelm@61189
   127
  where "prefix n w \<equiv> subsequence w 0 n"
lammich@61178
   128
wenzelm@61189
   129
lemma suffix_nth [simp]: "(suffix k x) n = x (k+n)"
wenzelm@61189
   130
  by (simp add: suffix_def)
lammich@61178
   131
wenzelm@61189
   132
lemma suffix_0 [simp]: "suffix 0 x = x"
wenzelm@61189
   133
  by (simp add: suffix_def)
lammich@61178
   134
wenzelm@61189
   135
lemma suffix_suffix [simp]: "suffix m (suffix k x) = suffix (k+m) x"
wenzelm@61189
   136
  by (rule ext) (simp add: suffix_def add.assoc)
lammich@61178
   137
wenzelm@61189
   138
lemma subsequence_append: "prefix (i + j) w = prefix i w @ (w [i \<rightarrow> i + j])"
lammich@61178
   139
  unfolding map_append[symmetric] upt_add_eq_append[OF le0] subsequence_def ..
lammich@61178
   140
wenzelm@61189
   141
lemma subsequence_drop[simp]: "drop i (w [j \<rightarrow> k]) = w [j + i \<rightarrow> k]"
lammich@61178
   142
  by (simp add: subsequence_def drop_map)
lammich@61178
   143
wenzelm@61189
   144
lemma subsequence_empty[simp]: "w [i \<rightarrow> j] = [] \<longleftrightarrow> j \<le> i"
wenzelm@61189
   145
  by (auto simp add: subsequence_def)
lammich@61178
   146
wenzelm@61189
   147
lemma subsequence_length[simp]: "length (subsequence w i j) = j - i"
lammich@61178
   148
  by (simp add: subsequence_def)
lammich@61178
   149
wenzelm@61189
   150
lemma subsequence_nth[simp]: "k < j - i \<Longrightarrow> (w [i \<rightarrow> j]) ! k = w (i + k)"
lammich@61178
   151
  unfolding subsequence_def
lammich@61178
   152
  by auto
lammich@61178
   153
wenzelm@61189
   154
lemma subseq_to_zero[simp]: "w[i\<rightarrow>0] = []"
wenzelm@61189
   155
  by simp
wenzelm@61189
   156
wenzelm@61189
   157
lemma subseq_to_smaller[simp]: "i\<ge>j \<Longrightarrow> w[i\<rightarrow>j] = []"
wenzelm@61189
   158
  by simp
wenzelm@61189
   159
wenzelm@61189
   160
lemma subseq_to_Suc[simp]: "i\<le>j \<Longrightarrow> w [i \<rightarrow> Suc j] = w [ i \<rightarrow> j ] @ [w j]"
lammich@61178
   161
  by (auto simp: subsequence_def)
lammich@61178
   162
lammich@61178
   163
lemma subsequence_singleton[simp]: "w [i \<rightarrow> Suc i] = [w i]"
lammich@61178
   164
  by (auto simp: subsequence_def)
lammich@61178
   165
lammich@61178
   166
wenzelm@61189
   167
lemma subsequence_prefix_suffix: "prefix (j - i) (suffix i w) = w [i \<rightarrow> j]"
lammich@61178
   168
proof (cases "i \<le> j")
lammich@61178
   169
  case True
wenzelm@61189
   170
  have "w [i \<rightarrow> j] = map w (map (\<lambda>n. n + i) [0..<j - i])"
wenzelm@61189
   171
    unfolding map_add_upt subsequence_def
wenzelm@61189
   172
    using le_add_diff_inverse2[OF True] by force
wenzelm@61189
   173
  also
wenzelm@61189
   174
  have "\<dots> = map (\<lambda>n. w (n + i)) [0..<j - i]"
wenzelm@61189
   175
    unfolding map_map comp_def by blast
wenzelm@61189
   176
  finally
wenzelm@61189
   177
  show ?thesis
wenzelm@61189
   178
    unfolding subsequence_def suffix_def add.commute[of i] by simp
wenzelm@61189
   179
next
wenzelm@61189
   180
  case False
wenzelm@61189
   181
  then show ?thesis
wenzelm@61189
   182
    by (simp add: subsequence_def)
wenzelm@61189
   183
qed
lammich@61178
   184
wenzelm@61189
   185
lemma prefix_suffix: "x = prefix n x \<frown> (suffix n x)"
wenzelm@61189
   186
  by (rule ext) (simp add: subsequence_def conc_def)
lammich@61178
   187
lammich@61178
   188
declare prefix_suffix[symmetric, simp]
lammich@61178
   189
lammich@61178
   190
wenzelm@61189
   191
lemma word_split: obtains v\<^sub>1 v\<^sub>2 where "v = v\<^sub>1 \<frown> v\<^sub>2" "length v\<^sub>1 = k"
lammich@61178
   192
proof
wenzelm@61189
   193
  show "v = prefix k v \<frown> suffix k v"
wenzelm@61189
   194
    by (rule prefix_suffix)
wenzelm@61189
   195
  show "length (prefix k v) = k"
wenzelm@61189
   196
    by simp
lammich@61178
   197
qed
lammich@61178
   198
lammich@61178
   199
lammich@61178
   200
lemma set_subsequence[simp]: "set (w[i\<rightarrow>j]) = w`{i..<j}"
lammich@61178
   201
  unfolding subsequence_def by auto
lammich@61178
   202
wenzelm@61189
   203
lemma subsequence_take[simp]: "take i (w [j \<rightarrow> k]) = w [j \<rightarrow> min (j + i) k]"
lammich@61178
   204
  by (simp add: subsequence_def take_map min_def)
lammich@61178
   205
wenzelm@61189
   206
lemma subsequence_shift[simp]: "(suffix i w) [j \<rightarrow> k] = w [i + j \<rightarrow> i + k]"
lammich@61178
   207
  by (metis add_diff_cancel_left subsequence_prefix_suffix suffix_suffix)
lammich@61178
   208
lammich@61178
   209
lemma suffix_subseq_join[simp]: "i \<le> j \<Longrightarrow> v [i \<rightarrow> j] \<frown> suffix j v = suffix i v"
wenzelm@61189
   210
  by (metis (no_types, lifting) Nat.add_0_right le_add_diff_inverse prefix_suffix
lammich@61178
   211
    subsequence_shift suffix_suffix)
lammich@61178
   212
lammich@61178
   213
lemma prefix_conc_fst[simp]:
wenzelm@61189
   214
  assumes "j \<le> length w"
lammich@61178
   215
  shows "prefix j (w \<frown> w') = take j w"
lammich@61178
   216
proof -
lammich@61178
   217
  have "\<forall>i < j. (prefix j (w \<frown> w')) ! i = (take j w) ! i"
lammich@61178
   218
    using assms by (simp add: conc_fst subsequence_def)
lammich@61178
   219
  thus ?thesis
lammich@61178
   220
    by (simp add: assms list_eq_iff_nth_eq min.absorb2)
lammich@61178
   221
qed
wenzelm@61189
   222
lammich@61178
   223
lemma prefix_conc_snd[simp]:
lammich@61178
   224
  assumes "n \<ge> length u"
lammich@61178
   225
  shows "prefix n (u \<frown> v) = u @ prefix (n - length u) v"
lammich@61178
   226
proof (intro nth_equalityI allI impI)
wenzelm@61189
   227
  show "length (prefix n (u \<frown> v)) = length (u @ prefix (n - length u) v)"
wenzelm@61189
   228
    using assms by simp
wenzelm@61189
   229
  fix i
wenzelm@61189
   230
  assume "i < length (prefix n (u \<frown> v))"
wenzelm@61189
   231
  then show "prefix n (u \<frown> v) ! i = (u @ prefix (n - length u) v) ! i"
wenzelm@61189
   232
    by (cases "i < length u") (auto simp: nth_append)
lammich@61178
   233
qed
lammich@61178
   234
wenzelm@61189
   235
lemma prefix_conc_length[simp]: "prefix (length w) (w \<frown> w') = w"
lammich@61178
   236
  by simp
lammich@61178
   237
lammich@61178
   238
lemma suffix_conc_fst[simp]:
lammich@61178
   239
  assumes "n \<le> length u"
lammich@61178
   240
  shows "suffix n (u \<frown> v) = drop n u \<frown> v"
lammich@61178
   241
proof
wenzelm@61189
   242
  show "suffix n (u \<frown> v) i = (drop n u \<frown> v) i" for i
wenzelm@61189
   243
    using assms by (cases "n + i < length u") (auto simp: algebra_simps)
lammich@61178
   244
qed
lammich@61178
   245
lammich@61178
   246
lemma suffix_conc_snd[simp]:
lammich@61178
   247
  assumes "n \<ge> length u"
lammich@61178
   248
  shows "suffix n (u \<frown> v) = suffix (n - length u) v"
lammich@61178
   249
proof
wenzelm@61189
   250
  show "suffix n (u \<frown> v) i = suffix (n - length u) v i" for i
wenzelm@61189
   251
    using assms by simp
lammich@61178
   252
qed
lammich@61178
   253
wenzelm@61189
   254
lemma suffix_conc_length[simp]: "suffix (length w) (w \<frown> w') = w'"
lammich@61178
   255
  unfolding conc_def by force
lammich@61178
   256
lammich@61178
   257
lemma concat_eq[iff]:
lammich@61178
   258
  assumes "length v\<^sub>1 = length v\<^sub>2"
lammich@61178
   259
  shows "v\<^sub>1 \<frown> u\<^sub>1 = v\<^sub>2 \<frown> u\<^sub>2 \<longleftrightarrow> v\<^sub>1 = v\<^sub>2 \<and> u\<^sub>1 = u\<^sub>2"
wenzelm@61189
   260
  (is "?lhs \<longleftrightarrow> ?rhs")
lammich@61178
   261
proof
wenzelm@61189
   262
  assume ?lhs
wenzelm@61189
   263
  then have 1: "(v\<^sub>1 \<frown> u\<^sub>1) i = (v\<^sub>2 \<frown> u\<^sub>2) i" for i by auto
wenzelm@61189
   264
  show ?rhs
lammich@61178
   265
  proof (intro conjI ext nth_equalityI allI impI)
wenzelm@61189
   266
    show "length v\<^sub>1 = length v\<^sub>2" by (rule assms(1))
lammich@61178
   267
  next
lammich@61178
   268
    fix i
lammich@61178
   269
    assume 2: "i < length v\<^sub>1"
lammich@61178
   270
    have 3: "i < length v\<^sub>2" using assms(1) 2 by simp
lammich@61178
   271
    show "v\<^sub>1 ! i = v\<^sub>2 ! i" using 1[of i] 2 3 by simp
lammich@61178
   272
  next
wenzelm@61189
   273
    show "u\<^sub>1 i = u\<^sub>2 i" for i
wenzelm@61189
   274
      using 1[of "length v\<^sub>1 + i"] assms(1) by simp
lammich@61178
   275
  qed
lammich@61178
   276
next
wenzelm@61189
   277
  assume ?rhs
wenzelm@61189
   278
  then show ?lhs by simp
lammich@61178
   279
qed
wenzelm@61189
   280
wenzelm@61189
   281
lemma same_concat_eq[iff]: "u \<frown> v = u \<frown> w \<longleftrightarrow> v = w"
wenzelm@61189
   282
  by simp
lammich@61178
   283
lammich@61178
   284
lemma comp_concat[simp]: "f \<circ> u \<frown> v = map f u \<frown> (f \<circ> v)"
lammich@61178
   285
proof
lammich@61178
   286
  fix i
wenzelm@61189
   287
  show "(f \<circ> u \<frown> v) i = (map f u \<frown> (f \<circ> v)) i"
wenzelm@61189
   288
    by (cases "i < length u") simp_all
lammich@61178
   289
qed
lammich@61178
   290
wenzelm@61189
   291
lammich@61178
   292
subsection \<open>Prepending\<close>
lammich@61178
   293
wenzelm@61189
   294
primrec build :: "'a \<Rightarrow> 'a word \<Rightarrow> 'a word"  (infixr "##" 65)
lammich@61178
   295
  where "(a ## w) 0 = a" | "(a ## w) (Suc i) = w i"
lammich@61178
   296
lammich@61178
   297
lemma build_eq[iff]: "a\<^sub>1 ## w\<^sub>1 = a\<^sub>2 ## w\<^sub>2 \<longleftrightarrow> a\<^sub>1 = a\<^sub>2 \<and> w\<^sub>1 = w\<^sub>2"
lammich@61178
   298
proof
lammich@61178
   299
  assume 1: "a\<^sub>1 ## w\<^sub>1 = a\<^sub>2 ## w\<^sub>2"
wenzelm@61189
   300
  have 2: "(a\<^sub>1 ## w\<^sub>1) i = (a\<^sub>2 ## w\<^sub>2) i" for i
wenzelm@61189
   301
    using 1 by auto
lammich@61178
   302
  show "a\<^sub>1 = a\<^sub>2 \<and> w\<^sub>1 = w\<^sub>2"
lammich@61178
   303
  proof (intro conjI ext)
wenzelm@61189
   304
    show "a\<^sub>1 = a\<^sub>2"
wenzelm@61189
   305
      using 2[of "0"] by simp
wenzelm@61189
   306
    show "w\<^sub>1 i = w\<^sub>2 i" for i
wenzelm@61189
   307
      using 2[of "Suc i"] by simp
lammich@61178
   308
  qed
lammich@61178
   309
next
lammich@61178
   310
  assume 1: "a\<^sub>1 = a\<^sub>2 \<and> w\<^sub>1 = w\<^sub>2"
lammich@61178
   311
  show "a\<^sub>1 ## w\<^sub>1 = a\<^sub>2 ## w\<^sub>2" using 1 by simp
lammich@61178
   312
qed
wenzelm@61189
   313
lammich@61178
   314
lemma build_cons[simp]: "(a # u) \<frown> v = a ## u \<frown> v"
lammich@61178
   315
proof
lammich@61178
   316
  fix i
lammich@61178
   317
  show "((a # u) \<frown> v) i = (a ## u \<frown> v) i"
lammich@61178
   318
  proof (cases i)
lammich@61178
   319
    case 0
lammich@61178
   320
    show ?thesis unfolding 0 by simp
lammich@61178
   321
  next
lammich@61178
   322
    case (Suc j)
lammich@61178
   323
    show ?thesis unfolding Suc by (cases "j < length u", simp+)
lammich@61178
   324
  qed
lammich@61178
   325
qed
wenzelm@61189
   326
lammich@61178
   327
lemma build_append[simp]: "(w @ a # u) \<frown> v = w \<frown> a ## u \<frown> v"
lammich@61178
   328
  unfolding conc_conc[symmetric] by simp
wenzelm@61189
   329
lammich@61178
   330
lemma build_first[simp]: "w 0 ## suffix (Suc 0) w = w"
lammich@61178
   331
proof
wenzelm@61189
   332
  show "(w 0 ## suffix (Suc 0) w) i = w i" for i
wenzelm@61189
   333
    by (cases i) simp_all
lammich@61178
   334
qed
wenzelm@61189
   335
wenzelm@61189
   336
lemma build_split[intro]: "w = w 0 ## suffix 1 w"
wenzelm@61189
   337
  by simp
wenzelm@61189
   338
lammich@61178
   339
lemma build_range[simp]: "range (a ## w) = insert a (range w)"
lammich@61178
   340
proof safe
wenzelm@61189
   341
  show "(a ## w) i \<notin> range w \<Longrightarrow> (a ## w) i = a" for i
wenzelm@61189
   342
    by (cases i) auto
lammich@61178
   343
  show "a \<in> range (a ## w)"
lammich@61178
   344
  proof (rule range_eqI)
lammich@61178
   345
    show "a = (a ## w) 0" by simp
lammich@61178
   346
  qed
wenzelm@61189
   347
  show "w i \<in> range (a ## w)" for i
lammich@61178
   348
  proof (rule range_eqI)
lammich@61178
   349
    show "w i = (a ## w) (Suc i)" by simp
lammich@61178
   350
  qed
lammich@61178
   351
qed
lammich@61178
   352
lammich@61178
   353
lemma suffix_singleton_suffix[simp]: "w i ## suffix (Suc i) w = suffix i w"
wenzelm@61189
   354
  using suffix_subseq_join[of i "Suc i" w]
lammich@61178
   355
  by simp
lammich@61178
   356
lammich@61178
   357
text \<open>Find the first occurrence of a letter from a given set\<close>
lammich@61178
   358
lemma word_first_split_set:
lammich@61178
   359
  assumes "A \<inter> range w \<noteq> {}"
wenzelm@61189
   360
  obtains u a v where "w = u \<frown> [a] \<frown> v" "A \<inter> set u = {}" "a \<in> A"
lammich@61178
   361
proof -
lammich@61178
   362
  def i \<equiv> "LEAST i. w i \<in> A"
lammich@61178
   363
  show ?thesis
lammich@61178
   364
  proof
wenzelm@61189
   365
    show "w = prefix i w \<frown> [w i] \<frown> suffix (Suc i) w"
wenzelm@61189
   366
      by simp
lammich@61178
   367
    show "A \<inter> set (prefix i w) = {}"
wenzelm@61189
   368
      apply safe
wenzelm@61189
   369
      subgoal premises prems for a
wenzelm@61189
   370
      proof -
wenzelm@61189
   371
        from prems obtain k where 3: "k < i" "w k = a"
wenzelm@61189
   372
          by auto
wenzelm@61189
   373
        have 4: "w k \<notin> A"
wenzelm@61189
   374
          using not_less_Least 3(1) unfolding i_def .
wenzelm@61189
   375
        show ?thesis
wenzelm@61189
   376
          using prems(1) 3(2) 4 by auto
wenzelm@61189
   377
      qed
wenzelm@61189
   378
      done
wenzelm@61189
   379
    show "w i \<in> A"
wenzelm@61189
   380
      using LeastI assms(1) unfolding i_def by fast
lammich@61178
   381
  qed
lammich@61178
   382
qed
lammich@61178
   383
lammich@61178
   384
wenzelm@61189
   385
subsection \<open>The limit set of an $\omega$-word\<close>
lammich@61178
   386
wenzelm@61189
   387
text \<open>
lammich@61178
   388
  The limit set (also called infinity set) of an $\omega$-word
lammich@61178
   389
  is the set of letters that appear infinitely often in the word.
lammich@61178
   390
  This set plays an important role in defining acceptance conditions
lammich@61178
   391
  of $\omega$-automata.
wenzelm@61189
   392
\<close>
lammich@61178
   393
wenzelm@61189
   394
definition limit :: "'a word \<Rightarrow> 'a set"
wenzelm@61189
   395
  where "limit x \<equiv> {a . \<exists>\<^sub>\<infinity>n . x n = a}"
lammich@61178
   396
wenzelm@61189
   397
lemma limit_iff_frequent: "a \<in> limit x \<longleftrightarrow> (\<exists>\<^sub>\<infinity>n . x n = a)"
wenzelm@61189
   398
  by (simp add: limit_def)
lammich@61178
   399
wenzelm@61189
   400
text \<open>
lammich@61178
   401
  The following is a different way to define the limit,
lammich@61178
   402
  using the reverse image, making the laws about reverse
wenzelm@61189
   403
  image applicable to the limit set.
lammich@61178
   404
  (Might want to change the definition above?)
wenzelm@61189
   405
\<close>
lammich@61178
   406
wenzelm@61189
   407
lemma limit_vimage: "(a \<in> limit x) = infinite (x -` {a})"
wenzelm@61189
   408
  by (simp add: limit_def Inf_many_def vimage_def)
lammich@61178
   409
lammich@61178
   410
lemma two_in_limit_iff:
wenzelm@61189
   411
  "({a, b} \<subseteq> limit x) =
wenzelm@61189
   412
    ((\<exists>n. x n =a ) \<and> (\<forall>n. x n = a \<longrightarrow> (\<exists>m>n. x m = b)) \<and> (\<forall>m. x m = b \<longrightarrow> (\<exists>n>m. x n = a)))"
lammich@61178
   413
  (is "?lhs = (?r1 \<and> ?r2 \<and> ?r3)")
lammich@61178
   414
proof
lammich@61178
   415
  assume lhs: "?lhs"
lammich@61178
   416
  hence 1: "?r1" by (auto simp: limit_def elim: INFM_EX)
lammich@61178
   417
  from lhs have "\<forall>n. \<exists>m>n. x m = b" by (auto simp: limit_def INFM_nat)
lammich@61178
   418
  hence 2: "?r2" by simp
lammich@61178
   419
  from lhs have "\<forall>m. \<exists>n>m. x n = a" by (auto simp: limit_def INFM_nat)
lammich@61178
   420
  hence 3: "?r3" by simp
lammich@61178
   421
  from 1 2 3 show "?r1 \<and> ?r2 \<and> ?r3" by simp
lammich@61178
   422
next
lammich@61178
   423
  assume "?r1 \<and> ?r2 \<and> ?r3"
lammich@61178
   424
  hence 1: "?r1" and 2: "?r2" and 3: "?r3" by simp+
lammich@61178
   425
  have infa: "\<forall>m. \<exists>n\<ge>m. x n = a"
lammich@61178
   426
  proof
lammich@61178
   427
    fix m
lammich@61178
   428
    show "\<exists>n\<ge>m. x n = a" (is "?A m")
lammich@61178
   429
    proof (induct m)
lammich@61178
   430
      from 1 show "?A 0" by simp
lammich@61178
   431
    next
lammich@61178
   432
      fix m
lammich@61178
   433
      assume ih: "?A m"
lammich@61178
   434
      then obtain n where n: "n \<ge> m" "x n = a" by auto
lammich@61178
   435
      with 2 obtain k where k: "k>n" "x k = b" by auto
lammich@61178
   436
      with 3 obtain l where l: "l>k" "x l = a" by auto
lammich@61178
   437
      from n k l have "l \<ge> Suc m" by auto
lammich@61178
   438
      with l show "?A (Suc m)" by auto
lammich@61178
   439
    qed
lammich@61178
   440
  qed
lammich@61178
   441
  hence infa': "\<exists>\<^sub>\<infinity>n. x n = a" by (simp add: INFM_nat_le)
lammich@61178
   442
  have "\<forall>n. \<exists>m>n. x m = b"
lammich@61178
   443
  proof
lammich@61178
   444
    fix n
lammich@61178
   445
    from infa obtain k where k1: "k\<ge>n" and k2: "x k = a" by auto
lammich@61178
   446
    from 2 k2 obtain l where l1: "l>k" and l2: "x l = b" by auto
lammich@61178
   447
    from k1 l1 have "l > n" by auto
lammich@61178
   448
    with l2 show "\<exists>m>n. x m = b" by auto
lammich@61178
   449
  qed
lammich@61178
   450
  hence "\<exists>\<^sub>\<infinity>m. x m = b" by (simp add: INFM_nat)
lammich@61178
   451
  with infa' show "?lhs" by (auto simp: limit_def)
lammich@61178
   452
qed
lammich@61178
   453
wenzelm@61189
   454
text \<open>
lammich@61178
   455
  For $\omega$-words over a finite alphabet, the limit set is
lammich@61178
   456
  non-empty. Moreover, from some position onward, any such word
lammich@61178
   457
  contains only letters from its limit set.
wenzelm@61189
   458
\<close>
lammich@61178
   459
lammich@61178
   460
lemma limit_nonempty:
lammich@61178
   461
  assumes fin: "finite (range x)"
lammich@61178
   462
  shows "\<exists>a. a \<in> limit x"
lammich@61178
   463
proof -
lammich@61178
   464
  from fin obtain a where "a \<in> range x \<and> infinite (x -` {a})"
wenzelm@61189
   465
    by (rule inf_img_fin_domE) auto
lammich@61178
   466
  hence "a \<in> limit x"
lammich@61178
   467
    by (auto simp add: limit_vimage)
lammich@61178
   468
  thus ?thesis ..
lammich@61178
   469
qed
lammich@61178
   470
lammich@61178
   471
lemmas limit_nonemptyE = limit_nonempty[THEN exE]
lammich@61178
   472
lammich@61178
   473
lemma limit_inter_INF:
lammich@61178
   474
  assumes hyp: "limit w \<inter> S \<noteq> {}"
lammich@61178
   475
  shows "\<exists>\<^sub>\<infinity> n. w n \<in> S"
lammich@61178
   476
proof -
lammich@61178
   477
  from hyp obtain x where "\<exists>\<^sub>\<infinity> n. w n = x" and "x \<in> S"
lammich@61178
   478
    by (auto simp add: limit_def)
lammich@61178
   479
  thus ?thesis
lammich@61178
   480
    by (auto elim: INFM_mono)
lammich@61178
   481
qed
lammich@61178
   482
wenzelm@61189
   483
text \<open>
lammich@61178
   484
  The reverse implication is true only if $S$ is finite.
wenzelm@61189
   485
\<close>
lammich@61178
   486
lammich@61178
   487
lemma INF_limit_inter:
wenzelm@61189
   488
  assumes hyp: "\<exists>\<^sub>\<infinity> n. w n \<in>  S"
wenzelm@61189
   489
    and fin: "finite (S \<inter> range w)"
lammich@61178
   490
  shows  "\<exists>a. a \<in> limit w \<inter> S"
lammich@61178
   491
proof (rule ccontr)
lammich@61178
   492
  assume contra: "\<not>(\<exists>a. a \<in> limit w \<inter> S)"
lammich@61178
   493
  hence "\<forall>a\<in>S. finite {n. w n = a}"
lammich@61178
   494
    by (auto simp add: limit_def Inf_many_def)
lammich@61178
   495
  with fin have "finite (UN a:S \<inter> range w. {n. w n = a})"
lammich@61178
   496
    by auto
lammich@61178
   497
  moreover
lammich@61178
   498
  have "(UN a:S \<inter> range w. {n. w n = a}) = {n. w n \<in> S}"
lammich@61178
   499
    by auto
lammich@61178
   500
  moreover
lammich@61178
   501
  note hyp
lammich@61178
   502
  ultimately show "False"
lammich@61178
   503
    by (simp add: Inf_many_def)
lammich@61178
   504
qed
lammich@61178
   505
lammich@61178
   506
lemma fin_ex_inf_eq_limit: "finite A \<Longrightarrow> (\<exists>\<^sub>\<infinity>i. w i \<in> A) \<longleftrightarrow> limit w \<inter> A \<noteq> {}"
lammich@61178
   507
  by (metis INF_limit_inter equals0D finite_Int limit_inter_INF)
lammich@61178
   508
wenzelm@61189
   509
lemma limit_in_range_suffix: "limit x \<subseteq> range (suffix k x)"
lammich@61178
   510
proof
lammich@61178
   511
  fix a
lammich@61178
   512
  assume "a \<in> limit x"
lammich@61178
   513
  then obtain l where
lammich@61178
   514
    kl: "k < l" and xl: "x l = a"
lammich@61178
   515
    by (auto simp add: limit_def INFM_nat)
lammich@61178
   516
  from kl obtain m where "l = k+m"
lammich@61178
   517
    by (auto simp add:  less_iff_Suc_add)
lammich@61178
   518
  with xl show "a \<in> range (suffix k x)"
lammich@61178
   519
    by auto
lammich@61178
   520
qed
lammich@61178
   521
lammich@61178
   522
lemma limit_in_range: "limit r \<subseteq> range r"
lammich@61178
   523
  using limit_in_range_suffix[of r 0] by simp
lammich@61178
   524
lammich@61178
   525
lemmas limit_in_range_suffixD = limit_in_range_suffix[THEN subsetD]
lammich@61178
   526
wenzelm@61189
   527
lemma limit_subset: "limit f \<subseteq> f ` {n..}"
lammich@61178
   528
  using limit_in_range_suffix[of f n] unfolding suffix_def by auto
lammich@61178
   529
lammich@61178
   530
theorem limit_is_suffix:
lammich@61178
   531
  assumes fin: "finite (range x)"
lammich@61178
   532
  shows "\<exists>k. limit x = range (suffix k x)"
lammich@61178
   533
proof -
lammich@61178
   534
  have "\<exists>k. range (suffix k x) \<subseteq> limit x"
lammich@61178
   535
  proof -
lammich@61178
   536
    -- "The set of letters that are not in the limit is certainly finite."
lammich@61178
   537
    from fin have "finite (range x - limit x)"
lammich@61178
   538
      by simp
lammich@61178
   539
    -- "Moreover, any such letter occurs only finitely often"
lammich@61178
   540
    moreover
lammich@61178
   541
    have "\<forall>a \<in> range x - limit x. finite (x -` {a})"
lammich@61178
   542
      by (auto simp add: limit_vimage)
lammich@61178
   543
    -- "Thus, there are only finitely many occurrences of such letters."
lammich@61178
   544
    ultimately have "finite (UN a : range x - limit x. x -` {a})"
lammich@61178
   545
      by (blast intro: finite_UN_I)
lammich@61178
   546
    -- "Therefore these occurrences are within some initial interval."
lammich@61178
   547
    then obtain k where "(UN a : range x - limit x. x -` {a}) \<subseteq> {..<k}"
lammich@61178
   548
      by (blast dest: finite_nat_bounded)
lammich@61178
   549
    -- "This is just the bound we are looking for."
lammich@61178
   550
    hence "\<forall>m. k \<le> m \<longrightarrow> x m \<in> limit x"
lammich@61178
   551
      by (auto simp add: limit_vimage)
lammich@61178
   552
    hence "range (suffix k x) \<subseteq> limit x"
lammich@61178
   553
      by auto
lammich@61178
   554
    thus ?thesis ..
lammich@61178
   555
  qed
lammich@61178
   556
  then obtain k where "range (suffix k x) \<subseteq> limit x" ..
lammich@61178
   557
  with limit_in_range_suffix
lammich@61178
   558
  have "limit x = range (suffix k x)"
lammich@61178
   559
    by (rule subset_antisym)
lammich@61178
   560
  thus ?thesis ..
lammich@61178
   561
qed
lammich@61178
   562
wenzelm@61337
   563
lemmas limit_is_suffixE = limit_is_suffix[THEN exE]
lammich@61178
   564
lammich@61178
   565
wenzelm@61189
   566
text \<open>
lammich@61178
   567
  The limit set enjoys some simple algebraic laws with respect
lammich@61178
   568
  to concatenation, suffixes, iteration, and renaming.
wenzelm@61189
   569
\<close>
lammich@61178
   570
wenzelm@61189
   571
theorem limit_conc [simp]: "limit (w \<frown> x) = limit x"
lammich@61178
   572
proof (auto)
lammich@61178
   573
  fix a assume a: "a \<in> limit (w \<frown> x)"
lammich@61178
   574
  have "\<forall>m. \<exists>n. m<n \<and> x n = a"
lammich@61178
   575
  proof
lammich@61178
   576
    fix m
lammich@61178
   577
    from a obtain n where "m + length w < n \<and> (w \<frown> x) n = a"
lammich@61178
   578
      by (auto simp add: limit_def Inf_many_def infinite_nat_iff_unbounded)
lammich@61178
   579
    hence "m < n - length w \<and> x (n - length w) = a"
lammich@61178
   580
      by (auto simp add: conc_def)
lammich@61178
   581
    thus "\<exists>n. m<n \<and> x n = a" ..
lammich@61178
   582
  qed
lammich@61178
   583
  hence "infinite {n . x n = a}"
lammich@61178
   584
    by (simp add: infinite_nat_iff_unbounded)
lammich@61178
   585
  thus "a \<in> limit x"
lammich@61178
   586
    by (simp add: limit_def Inf_many_def)
lammich@61178
   587
next
lammich@61178
   588
  fix a assume a: "a \<in> limit x"
lammich@61178
   589
  have "\<forall>m. length w < m \<longrightarrow> (\<exists>n. m<n \<and> (w \<frown> x) n = a)"
lammich@61178
   590
  proof (clarify)
lammich@61178
   591
    fix m
lammich@61178
   592
    assume m: "length w < m"
lammich@61178
   593
    with a obtain n where "m - length w < n \<and> x n = a"
lammich@61178
   594
      by (auto simp add: limit_def Inf_many_def infinite_nat_iff_unbounded)
lammich@61178
   595
    with m have "m < n + length w \<and> (w \<frown> x) (n + length w) = a"
lammich@61178
   596
      by (simp add: conc_def, arith)
lammich@61178
   597
    thus "\<exists>n. m<n \<and> (w \<frown> x) n = a" ..
lammich@61178
   598
  qed
lammich@61178
   599
  hence "infinite {n . (w \<frown> x) n = a}"
lammich@61178
   600
    by (simp add: unbounded_k_infinite)
lammich@61178
   601
  thus "a \<in> limit (w \<frown> x)"
lammich@61178
   602
    by (simp add: limit_def Inf_many_def)
lammich@61178
   603
qed
lammich@61178
   604
wenzelm@61189
   605
theorem limit_suffix [simp]: "limit (suffix n x) = limit x"
lammich@61178
   606
proof -
lammich@61178
   607
  have "x = (prefix n x) \<frown> (suffix n x)"
lammich@61178
   608
    by (simp add: prefix_suffix)
lammich@61178
   609
  hence "limit x = limit (prefix n x \<frown> suffix n x)"
lammich@61178
   610
    by simp
lammich@61178
   611
  also have "\<dots> = limit (suffix n x)"
lammich@61178
   612
    by (rule limit_conc)
lammich@61178
   613
  finally show ?thesis
lammich@61178
   614
    by (rule sym)
lammich@61178
   615
qed
lammich@61178
   616
lammich@61178
   617
theorem limit_iter [simp]:
lammich@61178
   618
  assumes nempty: "0 < length w"
lammich@61178
   619
  shows "limit w\<^sup>\<omega> = set w"
lammich@61178
   620
proof
lammich@61178
   621
  have "limit w\<^sup>\<omega> \<subseteq> range w\<^sup>\<omega>"
lammich@61178
   622
    by (auto simp add: limit_def dest: INFM_EX)
lammich@61178
   623
  also from nempty have "\<dots> \<subseteq> set w"
lammich@61178
   624
    by auto
lammich@61178
   625
  finally show "limit w\<^sup>\<omega> \<subseteq> set w" .
lammich@61178
   626
next
lammich@61178
   627
  {
lammich@61178
   628
    fix a assume a: "a \<in> set w"
lammich@61178
   629
    then obtain k where k: "k < length w \<and> w!k = a"
lammich@61178
   630
      by (auto simp add: set_conv_nth)
lammich@61178
   631
    -- "the following bound is terrible, but it simplifies the proof"
wenzelm@61189
   632
    from nempty k have "\<forall>m. w\<^sup>\<omega> ((Suc m)*(length w) + k) = a"
lammich@61178
   633
      by (simp add: mod_add_left_eq)
lammich@61178
   634
    moreover
lammich@61178
   635
    -- "why is the following so hard to prove??"
lammich@61178
   636
    have "\<forall>m. m < (Suc m)*(length w) + k"
lammich@61178
   637
    proof
lammich@61178
   638
      fix m
lammich@61178
   639
      from nempty have "1 \<le> length w" by arith
lammich@61178
   640
      hence "m*1 \<le> m*length w" by simp
lammich@61178
   641
      hence "m \<le> m*length w" by simp
lammich@61178
   642
      with nempty have "m < length w + (m*length w) + k" by arith
lammich@61178
   643
      thus "m < (Suc m)*(length w) + k" by simp
lammich@61178
   644
    qed
lammich@61178
   645
    moreover note nempty
lammich@61178
   646
    ultimately have "a \<in> limit w\<^sup>\<omega>"
lammich@61178
   647
      by (auto simp add: limit_iff_frequent INFM_nat)
lammich@61178
   648
  }
lammich@61178
   649
  then show "set w \<subseteq> limit w\<^sup>\<omega>" by auto
lammich@61178
   650
qed
lammich@61178
   651
lammich@61178
   652
lemma limit_o [simp]:
lammich@61178
   653
  assumes a: "a \<in> limit w"
lammich@61178
   654
  shows "f a \<in> limit (f \<circ> w)"
lammich@61178
   655
proof -
lammich@61178
   656
  from a
lammich@61178
   657
  have "\<exists>\<^sub>\<infinity>n. w n = a"
lammich@61178
   658
    by (simp add: limit_iff_frequent)
lammich@61178
   659
  hence "\<exists>\<^sub>\<infinity>n. f (w n) = f a"
lammich@61178
   660
    by (rule INFM_mono, simp)
lammich@61178
   661
  thus "f a \<in> limit (f \<circ> w)"
lammich@61178
   662
    by (simp add: limit_iff_frequent)
lammich@61178
   663
qed
lammich@61178
   664
wenzelm@61189
   665
text \<open>
lammich@61178
   666
  The converse relation is not true in general: $f(a)$ can be in the
lammich@61178
   667
  limit of $f \circ w$ even though $a$ is not in the limit of $w$.
lammich@61178
   668
  However, @{text limit} commutes with renaming if the function is
lammich@61178
   669
  injective. More generally, if $f(a)$ is the image of only finitely
lammich@61178
   670
  many elements, some of these must be in the limit of $w$.
wenzelm@61189
   671
\<close>
lammich@61178
   672
lammich@61178
   673
lemma limit_o_inv:
wenzelm@61189
   674
  assumes fin: "finite (f -` {x})"
wenzelm@61189
   675
    and x: "x \<in> limit (f \<circ> w)"
lammich@61178
   676
  shows "\<exists>a \<in> (f -` {x}). a \<in> limit w"
lammich@61178
   677
proof (rule ccontr)
wenzelm@61189
   678
  assume contra: "\<not> ?thesis"
lammich@61178
   679
  -- "hence, every element in the pre-image occurs only finitely often"
lammich@61178
   680
  then have "\<forall>a \<in> (f -` {x}). finite {n. w n = a}"
lammich@61178
   681
    by (simp add: limit_def Inf_many_def)
lammich@61178
   682
  -- "so there are only finitely many occurrences of any such element"
lammich@61178
   683
  with fin have "finite (\<Union> a \<in> (f -` {x}). {n. w n = a})"
lammich@61178
   684
    by auto
wenzelm@61189
   685
  -- \<open>these are precisely those positions where $x$ occurs in $f \circ w$\<close>
lammich@61178
   686
  moreover
lammich@61178
   687
  have "(\<Union> a \<in> (f -` {x}). {n. w n = a}) = {n. f(w n) = x}"
lammich@61178
   688
    by auto
lammich@61178
   689
  ultimately
lammich@61178
   690
  -- "so $x$ can occur only finitely often in the translated word"
lammich@61178
   691
  have "finite {n. f(w n) = x}"
lammich@61178
   692
    by simp
wenzelm@61189
   693
  -- \<open>\ldots\ which yields a contradiction\<close>
lammich@61178
   694
  with x show "False"
lammich@61178
   695
    by (simp add: limit_def Inf_many_def)
lammich@61178
   696
qed
lammich@61178
   697
lammich@61178
   698
theorem limit_inj [simp]:
lammich@61178
   699
  assumes inj: "inj f"
lammich@61178
   700
  shows "limit (f \<circ> w) = f ` (limit w)"
lammich@61178
   701
proof
lammich@61178
   702
  show "f ` limit w \<subseteq> limit (f \<circ> w)"
lammich@61178
   703
    by auto
lammich@61178
   704
  show "limit (f \<circ> w) \<subseteq> f ` limit w"
lammich@61178
   705
  proof
lammich@61178
   706
    fix x
lammich@61178
   707
    assume x: "x \<in> limit (f \<circ> w)"
lammich@61178
   708
    from inj have "finite (f -` {x})"
lammich@61178
   709
      by (blast intro: finite_vimageI)
lammich@61178
   710
    with x obtain a where a: "a \<in> (f -` {x}) \<and> a \<in> limit w"
lammich@61178
   711
      by (blast dest: limit_o_inv)
lammich@61178
   712
    thus "x \<in> f ` (limit w)"
lammich@61178
   713
      by auto
lammich@61178
   714
  qed
lammich@61178
   715
qed
lammich@61178
   716
lammich@61178
   717
lemma limit_inter_empty:
lammich@61178
   718
  assumes fin: "finite (range w)"
lammich@61178
   719
  assumes hyp: "limit w \<inter> S = {}"
lammich@61178
   720
  shows "\<forall>\<^sub>\<infinity>n. w n \<notin> S"
lammich@61178
   721
proof -
lammich@61178
   722
  from fin obtain k where k_def: "limit w = range (suffix k w)"
lammich@61178
   723
    using limit_is_suffix by blast
wenzelm@61189
   724
  have "w (k + k') \<notin> S" for k'
lammich@61178
   725
    using hyp unfolding k_def suffix_def image_def by blast
lammich@61178
   726
  thus ?thesis
lammich@61178
   727
    unfolding MOST_nat_le using le_Suc_ex by blast
lammich@61178
   728
qed
lammich@61178
   729
lammich@61178
   730
text \<open>If the limit is the suffix of the sequence's range,
lammich@61178
   731
  we may increase the suffix index arbitrarily\<close>
lammich@61178
   732
lemma limit_range_suffix_incr:
lammich@61178
   733
  assumes "limit r = range (suffix i r)"
lammich@61178
   734
  assumes "j\<ge>i"
lammich@61178
   735
  shows "limit r = range (suffix j r)"
wenzelm@61189
   736
    (is "?lhs = ?rhs")
lammich@61178
   737
proof -
lammich@61178
   738
  have "?lhs = range (suffix i r)"
lammich@61178
   739
    using assms by simp
lammich@61178
   740
  moreover
lammich@61178
   741
  have "\<dots> \<supseteq> ?rhs" using \<open>j\<ge>i\<close>
wenzelm@61189
   742
    by (metis (mono_tags, lifting) assms(2)
wenzelm@61189
   743
        image_subsetI le_Suc_ex range_eqI suffix_def suffix_suffix)
lammich@61178
   744
  moreover
wenzelm@61189
   745
  have "\<dots> \<supseteq> ?lhs" by (rule limit_in_range_suffix)
lammich@61178
   746
  ultimately
lammich@61178
   747
  show "?lhs = ?rhs"
lammich@61178
   748
    by (metis antisym_conv limit_in_range_suffix)
lammich@61178
   749
qed
lammich@61178
   750
lammich@61178
   751
text \<open>For two finite sequences, we can find a common suffix index such
lammich@61178
   752
  that the limits can be represented as these suffixes' ranges.\<close>
lammich@61178
   753
lemma common_range_limit:
wenzelm@61189
   754
  assumes "finite (range x)"
wenzelm@61189
   755
    and "finite (range y)"
wenzelm@61189
   756
  obtains i where "limit x = range (suffix i x)"
lammich@61178
   757
    and "limit y = range (suffix i y)"
lammich@61178
   758
proof -
wenzelm@61189
   759
  obtain i j where 1: "limit x = range (suffix i x)"
lammich@61178
   760
    and 2: "limit y = range (suffix j y)"
lammich@61178
   761
    using assms limit_is_suffix by metis
wenzelm@61189
   762
  have "limit x = range (suffix (max i j) x)"
lammich@61178
   763
    and "limit y = range (suffix (max i j) y)"
lammich@61178
   764
    using limit_range_suffix_incr[OF 1] limit_range_suffix_incr[OF 2]
lammich@61178
   765
    by auto
lammich@61178
   766
  thus ?thesis
lammich@61178
   767
    using that by metis
lammich@61178
   768
qed
lammich@61178
   769
lammich@61178
   770
wenzelm@61189
   771
subsection \<open>Index sequences and piecewise definitions\<close>
lammich@61178
   772
wenzelm@61189
   773
text \<open>
lammich@61178
   774
  A word can be defined piecewise: given a sequence of words $w_0, w_1, \ldots$
lammich@61178
   775
  and a strictly increasing sequence of integers $i_0, i_1, \ldots$ where $i_0=0$,
lammich@61178
   776
  a single word is obtained by concatenating subwords of the $w_n$ as given by
lammich@61178
   777
  the integers: the resulting word is
lammich@61178
   778
  \[
lammich@61178
   779
    (w_0)_{i_0} \ldots (w_0)_{i_1-1} (w_1)_{i_1} \ldots (w_1)_{i_2-1} \ldots
lammich@61178
   780
  \]
wenzelm@61189
   781
  We prepare the field by proving some trivial facts about such sequences of
lammich@61178
   782
  indexes.
wenzelm@61189
   783
\<close>
lammich@61178
   784
wenzelm@61189
   785
definition idx_sequence :: "nat word \<Rightarrow> bool"
lammich@61178
   786
  where "idx_sequence idx \<equiv> (idx 0 = 0) \<and> (\<forall>n. idx n < idx (Suc n))"
lammich@61178
   787
lammich@61178
   788
lemma idx_sequence_less:
lammich@61178
   789
  assumes iseq: "idx_sequence idx"
lammich@61178
   790
  shows "idx n < idx (Suc(n+k))"
lammich@61178
   791
proof (induct k)
lammich@61178
   792
  from iseq show "idx n < idx (Suc (n + 0))"
lammich@61178
   793
    by (simp add: idx_sequence_def)
lammich@61178
   794
next
lammich@61178
   795
  fix k
lammich@61178
   796
  assume ih: "idx n < idx (Suc(n+k))"
lammich@61178
   797
  from iseq have "idx (Suc(n+k)) < idx (Suc(n + Suc k))"
lammich@61178
   798
    by (simp add: idx_sequence_def)
lammich@61178
   799
  with ih show "idx n < idx (Suc(n + Suc k))"
lammich@61178
   800
    by (rule less_trans)
lammich@61178
   801
qed
lammich@61178
   802
lammich@61178
   803
lemma idx_sequence_inj:
lammich@61178
   804
  assumes iseq: "idx_sequence idx"
wenzelm@61189
   805
    and eq: "idx m = idx n"
lammich@61178
   806
  shows "m = n"
lammich@61178
   807
proof (rule nat_less_cases)
lammich@61178
   808
  assume "n<m"
lammich@61178
   809
  then obtain k where "m = Suc(n+k)"
lammich@61178
   810
    by (auto simp add: less_iff_Suc_add)
lammich@61178
   811
  with iseq have "idx n < idx m"
lammich@61178
   812
    by (simp add: idx_sequence_less)
lammich@61178
   813
  with eq show ?thesis
lammich@61178
   814
    by simp
lammich@61178
   815
next
lammich@61178
   816
  assume "m<n"
lammich@61178
   817
  then obtain k where "n = Suc(m+k)"
lammich@61178
   818
    by (auto simp add: less_iff_Suc_add)
lammich@61178
   819
  with iseq have "idx m < idx n"
lammich@61178
   820
    by (simp add: idx_sequence_less)
lammich@61178
   821
  with eq show ?thesis
lammich@61178
   822
    by simp
lammich@61178
   823
qed (simp)
lammich@61178
   824
lammich@61178
   825
lemma idx_sequence_mono:
lammich@61178
   826
  assumes iseq: "idx_sequence idx"
wenzelm@61189
   827
    and m: "m \<le> n"
lammich@61178
   828
  shows "idx m \<le> idx n"
lammich@61178
   829
proof (cases "m=n")
lammich@61178
   830
  case True
lammich@61178
   831
  thus ?thesis by simp
lammich@61178
   832
next
lammich@61178
   833
  case False
lammich@61178
   834
  with m have "m < n" by simp
lammich@61178
   835
  then obtain k where "n = Suc(m+k)"
lammich@61178
   836
    by (auto simp add: less_iff_Suc_add)
lammich@61178
   837
  with iseq have "idx m < idx n"
lammich@61178
   838
    by (simp add: idx_sequence_less)
lammich@61178
   839
  thus ?thesis by simp
lammich@61178
   840
qed
lammich@61178
   841
wenzelm@61189
   842
text \<open>
lammich@61178
   843
  Given an index sequence, every natural number is contained in the
lammich@61178
   844
  interval defined by two adjacent indexes, and in fact this interval
lammich@61178
   845
  is determined uniquely.
wenzelm@61189
   846
\<close>
lammich@61178
   847
lammich@61178
   848
lemma idx_sequence_idx:
lammich@61178
   849
  assumes "idx_sequence idx"
lammich@61178
   850
  shows "idx k \<in> {idx k ..< idx (Suc k)}"
lammich@61178
   851
using assms by (auto simp add: idx_sequence_def)
lammich@61178
   852
lammich@61178
   853
lemma idx_sequence_interval:
lammich@61178
   854
  assumes iseq: "idx_sequence idx"
lammich@61178
   855
  shows "\<exists>k. n \<in> {idx k ..< idx (Suc k) }"
lammich@61178
   856
    (is "?P n" is "\<exists>k. ?in n k")
lammich@61178
   857
proof (induct n)
lammich@61178
   858
  from iseq have "0 = idx 0"
lammich@61178
   859
    by (simp add: idx_sequence_def)
lammich@61178
   860
  moreover
lammich@61178
   861
  from iseq have "idx 0 \<in> {idx 0 ..< idx (Suc 0) }"
lammich@61178
   862
    by (rule idx_sequence_idx)
lammich@61178
   863
  ultimately
lammich@61178
   864
  show "?P 0" by auto
lammich@61178
   865
next
lammich@61178
   866
  fix n
lammich@61178
   867
  assume "?P n"
lammich@61178
   868
  then obtain k where k: "?in n k" ..
lammich@61178
   869
  show "?P (Suc n)"
lammich@61178
   870
  proof (cases "Suc n < idx (Suc k)")
lammich@61178
   871
    case True
lammich@61178
   872
    with k have "?in (Suc n) k"
lammich@61178
   873
      by simp
lammich@61178
   874
    thus ?thesis ..
lammich@61178
   875
  next
lammich@61178
   876
    case False
lammich@61178
   877
    with k have "Suc n = idx (Suc k)"
lammich@61178
   878
      by auto
lammich@61178
   879
    with iseq have "?in (Suc n) (Suc k)"
lammich@61178
   880
      by (simp add: idx_sequence_def)
lammich@61178
   881
    thus ?thesis ..
lammich@61178
   882
  qed
lammich@61178
   883
qed
lammich@61178
   884
lammich@61178
   885
lemma idx_sequence_interval_unique:
lammich@61178
   886
  assumes iseq: "idx_sequence idx"
wenzelm@61189
   887
    and k: "n \<in> {idx k ..< idx (Suc k)}"
wenzelm@61189
   888
    and m: "n \<in> {idx m ..< idx (Suc m)}"
lammich@61178
   889
  shows "k = m"
lammich@61178
   890
proof (rule nat_less_cases)
lammich@61178
   891
  assume "k < m"
lammich@61178
   892
  hence "Suc k \<le> m" by simp
lammich@61178
   893
  with iseq have "idx (Suc k) \<le> idx m"
lammich@61178
   894
    by (rule idx_sequence_mono)
lammich@61178
   895
  with m have "idx (Suc k) \<le> n"
lammich@61178
   896
    by auto
lammich@61178
   897
  with k have "False"
lammich@61178
   898
    by simp
lammich@61178
   899
  thus ?thesis ..
lammich@61178
   900
next
lammich@61178
   901
  assume "m < k"
lammich@61178
   902
  hence "Suc m \<le> k" by simp
lammich@61178
   903
  with iseq have "idx (Suc m) \<le> idx k"
lammich@61178
   904
    by (rule idx_sequence_mono)
lammich@61178
   905
  with k have "idx (Suc m) \<le> n"
lammich@61178
   906
    by auto
lammich@61178
   907
  with m have "False"
lammich@61178
   908
    by simp
lammich@61178
   909
  thus ?thesis ..
lammich@61178
   910
qed (simp)
lammich@61178
   911
lammich@61178
   912
lemma idx_sequence_unique_interval:
lammich@61178
   913
  assumes iseq: "idx_sequence idx"
lammich@61178
   914
  shows "\<exists>! k. n \<in> {idx k ..< idx (Suc k) }"
lammich@61178
   915
proof (rule ex_ex1I)
lammich@61178
   916
  from iseq show "\<exists>k. n \<in> {idx k ..< idx (Suc k)}"
lammich@61178
   917
    by (rule idx_sequence_interval)
lammich@61178
   918
next
lammich@61178
   919
  fix k y
lammich@61178
   920
  assume "n \<in> {idx k..<idx (Suc k)}" and "n \<in> {idx y..<idx (Suc y)}"
lammich@61178
   921
  with iseq show "k = y" by (auto elim: idx_sequence_interval_unique)
lammich@61178
   922
qed
lammich@61178
   923
wenzelm@61189
   924
text \<open>
lammich@61178
   925
  Now we can define the piecewise construction of a word using
lammich@61178
   926
  an index sequence.
wenzelm@61189
   927
\<close>
lammich@61178
   928
wenzelm@61189
   929
definition merge :: "'a word word \<Rightarrow> nat word \<Rightarrow> 'a word"
wenzelm@61189
   930
  where "merge ws idx \<equiv> \<lambda>n. let i = THE i. n \<in> {idx i ..< idx (Suc i) } in ws i n"
lammich@61178
   931
lammich@61178
   932
lemma merge:
lammich@61178
   933
  assumes idx: "idx_sequence idx"
wenzelm@61189
   934
    and n: "n \<in> {idx i ..< idx (Suc i)}"
lammich@61178
   935
  shows "merge ws idx n = ws i n"
lammich@61178
   936
proof -
lammich@61178
   937
  from n have "(THE k. n \<in> {idx k ..< idx (Suc k) }) = i"
lammich@61178
   938
    by (rule the_equality[OF _ sym[OF idx_sequence_interval_unique[OF idx n]]]) simp
lammich@61178
   939
  thus ?thesis
lammich@61178
   940
    by (simp add: merge_def Let_def)
lammich@61178
   941
qed
lammich@61178
   942
lammich@61178
   943
lemma merge0:
lammich@61178
   944
  assumes idx: "idx_sequence idx"
lammich@61178
   945
  shows "merge ws idx 0 = ws 0 0"
lammich@61178
   946
proof (rule merge[OF idx])
lammich@61178
   947
  from idx have "idx 0 < idx (Suc 0)"
wenzelm@61189
   948
    unfolding idx_sequence_def by blast
lammich@61178
   949
  with idx show "0 \<in> {idx 0 ..< idx (Suc 0)}"
lammich@61178
   950
    by (simp add: idx_sequence_def)
lammich@61178
   951
qed
lammich@61178
   952
lammich@61178
   953
lemma merge_Suc:
lammich@61178
   954
  assumes idx: "idx_sequence idx"
wenzelm@61189
   955
    and n: "n \<in> {idx i ..< idx (Suc i)}"
wenzelm@61189
   956
  shows "merge ws idx (Suc n) = (if Suc n = idx (Suc i) then ws (Suc i) else ws i) (Suc n)"
wenzelm@61189
   957
proof auto
lammich@61178
   958
  assume eq: "Suc n = idx (Suc i)"
lammich@61178
   959
  from idx have "idx (Suc i) < idx (Suc(Suc i))"
wenzelm@61189
   960
    unfolding idx_sequence_def by blast
lammich@61178
   961
  with eq idx show "merge ws idx (idx (Suc i)) = ws (Suc i) (idx (Suc i))"
lammich@61178
   962
    by (simp add: merge)
lammich@61178
   963
next
lammich@61178
   964
  assume neq: "Suc n \<noteq> idx (Suc i)"
lammich@61178
   965
  with n have "Suc n \<in> {idx i ..< idx (Suc i) }"
lammich@61178
   966
    by auto
lammich@61178
   967
  with idx show "merge ws idx (Suc n) = ws i (Suc n)"
lammich@61178
   968
    by (rule merge)
lammich@61178
   969
qed
lammich@61178
   970
lammich@61178
   971
end