utm/UTM.thy
changeset 370 1ce04eb1c8ad
child 371 48b231495281
equal deleted inserted replaced
369:cbb4ac6c8081 370:1ce04eb1c8ad
       
     1 theory UTM
       
     2 imports Main uncomputable recursive abacus UF GCD 
       
     3 begin
       
     4 
       
     5 section {* Wang coding of input arguments *}
       
     6 
       
     7 text {*
       
     8   The direct compilation of the universal function @{text "rec_F"} can not give us UTM, because @{text "rec_F"} is of arity 2,
       
     9   where the first argument represents the Godel coding of the TM being simulated and the second argument represents the right number (in Wang's coding) of the TM tape. 
       
    10   (Notice, left number is always @{text "0"} at the very beginning). However, UTM needs to simulate the execution of any TM which may
       
    11   very well take many input arguments. Therefore, a initialization TM needs to run before the TM compiled from @{text "rec_F"}, and the sequential 
       
    12   composition of these two TMs will give rise to the UTM we are seeking. The purpose of this initialization TM is to transform the multiple 
       
    13   input arguments of the TM being simulated into Wang's coding, so that it can be consumed by the TM compiled from @{text "rec_F"} as the second
       
    14   argument. 
       
    15 
       
    16   However, this initialization TM (named @{text "t_wcode"}) can not be constructed by compiling from any resurve function, because every recursive 
       
    17   function takes a fixed number of input arguments, while @{text "t_wcode"} needs to take varying number of arguments and tranform them into 
       
    18   Wang's coding. Therefore, this section give a direct construction of @{text "t_wcode"} with just some parts being obtained from recursive functions.
       
    19 *}
       
    20 
       
    21 definition rec_twice :: "recf"
       
    22   where
       
    23   "rec_twice = Cn 1 rec_mult [id 1 0, constn 2]"
       
    24 
       
    25 definition rec_fourtimes  :: "recf"
       
    26   where
       
    27   "rec_fourtimes = Cn 1 rec_mult [id 1 0, constn 4]"
       
    28 
       
    29 definition abc_twice :: "abc_prog"
       
    30   where
       
    31   "abc_twice = (let (aprog, ary, fp) = rec_ci rec_twice in 
       
    32                        aprog [+] dummy_abc ((Suc 0)))"
       
    33 
       
    34 definition abc_fourtimes :: "abc_prog"
       
    35   where
       
    36   "abc_fourtimes = (let (aprog, ary, fp) = rec_ci rec_fourtimes in 
       
    37                        aprog [+] dummy_abc ((Suc 0)))"
       
    38 
       
    39 definition twice_ly :: "nat list"
       
    40   where
       
    41   "twice_ly = layout_of abc_twice"
       
    42 
       
    43 definition fourtimes_ly :: "nat list"
       
    44   where
       
    45   "fourtimes_ly = layout_of abc_fourtimes"
       
    46 
       
    47 definition t_twice :: "tprog"
       
    48   where
       
    49   "t_twice = change_termi_state (tm_of (abc_twice) @ (tMp 1 (start_of twice_ly (length abc_twice) - Suc 0)))"
       
    50 
       
    51 definition t_fourtimes :: "tprog"
       
    52   where
       
    53   "t_fourtimes = change_termi_state (tm_of (abc_fourtimes) @ 
       
    54              (tMp 1 (start_of fourtimes_ly (length abc_fourtimes) - Suc 0)))"
       
    55 
       
    56 
       
    57 definition t_twice_len :: "nat"
       
    58   where
       
    59   "t_twice_len = length t_twice div 2"
       
    60 
       
    61 definition t_wcode_main_first_part:: "tprog"
       
    62   where
       
    63   "t_wcode_main_first_part \<equiv> 
       
    64                    [(L, 1), (L, 2), (L, 7), (R, 3),
       
    65                     (R, 4), (W0, 3), (R, 4), (R, 5),
       
    66                     (W1, 6), (R, 5), (R, 13), (L, 6),
       
    67                     (R, 0), (R, 8), (R, 9), (Nop, 8),
       
    68                     (R, 10), (W0, 9), (R, 10), (R, 11), 
       
    69                     (W1, 12), (R, 11), (R, t_twice_len + 14), (L, 12)]"
       
    70 
       
    71 definition t_wcode_main :: "tprog"
       
    72   where
       
    73   "t_wcode_main = (t_wcode_main_first_part @ tshift t_twice 12 @ [(L, 1), (L, 1)]
       
    74                     @ tshift t_fourtimes (t_twice_len + 13) @ [(L, 1), (L, 1)])"
       
    75 
       
    76 fun bl_bin :: "block list \<Rightarrow> nat"
       
    77   where
       
    78   "bl_bin [] = 0" 
       
    79 | "bl_bin (Bk # xs) = 2 * bl_bin xs"
       
    80 | "bl_bin (Oc # xs) = Suc (2 * bl_bin xs)"
       
    81 
       
    82 declare bl_bin.simps[simp del]
       
    83 
       
    84 type_synonym bin_inv_t = "block list \<Rightarrow> nat \<Rightarrow> tape \<Rightarrow> bool"
       
    85 
       
    86 fun wcode_before_double :: "bin_inv_t"
       
    87   where
       
    88   "wcode_before_double ires rs (l, r) =
       
    89      (\<exists> ln rn. l = Bk # Bk # Bk\<^bsup>ln\<^esup> @ Oc # ires \<and> 
       
    90                r = Oc\<^bsup>(Suc (Suc rs))\<^esup> @ Bk\<^bsup>rn \<^esup>)"
       
    91 
       
    92 declare wcode_before_double.simps[simp del]
       
    93 
       
    94 fun wcode_after_double :: "bin_inv_t"
       
    95   where
       
    96   "wcode_after_double ires rs (l, r) = 
       
    97      (\<exists> ln rn. l = Bk # Bk # Bk\<^bsup>ln\<^esup> @ Oc # ires \<and>
       
    98          r = Oc\<^bsup>Suc (Suc (Suc 2*rs))\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
    99 
       
   100 declare wcode_after_double.simps[simp del]
       
   101 
       
   102 fun wcode_on_left_moving_1_B :: "bin_inv_t"
       
   103   where
       
   104   "wcode_on_left_moving_1_B ires rs (l, r) = 
       
   105      (\<exists> ml mr rn. l = Bk\<^bsup>ml\<^esup> @ Oc # Oc # ires \<and> 
       
   106                r = Bk\<^bsup>mr\<^esup> @ Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>rn\<^esup> \<and>
       
   107                ml + mr > Suc 0 \<and> mr > 0)"
       
   108 
       
   109 declare wcode_on_left_moving_1_B.simps[simp del]
       
   110 
       
   111 fun wcode_on_left_moving_1_O :: "bin_inv_t"
       
   112   where
       
   113   "wcode_on_left_moving_1_O ires rs (l, r) = 
       
   114      (\<exists> ln rn.
       
   115                l = Oc # ires \<and> 
       
   116                r = Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
   117 
       
   118 declare wcode_on_left_moving_1_O.simps[simp del]
       
   119 
       
   120 fun wcode_on_left_moving_1 :: "bin_inv_t"
       
   121   where
       
   122   "wcode_on_left_moving_1 ires rs (l, r) = 
       
   123           (wcode_on_left_moving_1_B ires rs (l, r) \<or> wcode_on_left_moving_1_O ires rs (l, r))"
       
   124 
       
   125 declare wcode_on_left_moving_1.simps[simp del]
       
   126 
       
   127 fun wcode_on_checking_1 :: "bin_inv_t"
       
   128   where
       
   129    "wcode_on_checking_1 ires rs (l, r) = 
       
   130     (\<exists> ln rn. l = ires \<and>
       
   131               r = Oc # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
   132 
       
   133 fun wcode_erase1 :: "bin_inv_t"
       
   134   where
       
   135 "wcode_erase1 ires rs (l, r) = 
       
   136        (\<exists> ln rn. l = Oc # ires \<and> 
       
   137                  tl r = Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
   138 
       
   139 declare wcode_erase1.simps [simp del]
       
   140 
       
   141 fun wcode_on_right_moving_1 :: "bin_inv_t"
       
   142   where
       
   143   "wcode_on_right_moving_1 ires rs (l, r) = 
       
   144        (\<exists> ml mr rn.        
       
   145              l = Bk\<^bsup>ml\<^esup> @ Oc # ires \<and> 
       
   146              r = Bk\<^bsup>mr\<^esup> @ Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>rn\<^esup> \<and>
       
   147              ml + mr > Suc 0)"
       
   148 
       
   149 declare wcode_on_right_moving_1.simps [simp del] 
       
   150 
       
   151 declare wcode_on_right_moving_1.simps[simp del]
       
   152 
       
   153 fun wcode_goon_right_moving_1 :: "bin_inv_t"
       
   154   where
       
   155   "wcode_goon_right_moving_1 ires rs (l, r) = 
       
   156       (\<exists> ml mr ln rn. 
       
   157             l = Oc\<^bsup>ml\<^esup> @ Bk # Bk # Bk\<^bsup>ln\<^esup> @ Oc # ires \<and> 
       
   158             r = Oc\<^bsup>mr\<^esup> @ Bk\<^bsup>rn\<^esup> \<and>
       
   159             ml + mr = Suc rs)"
       
   160 
       
   161 declare wcode_goon_right_moving_1.simps[simp del]
       
   162 
       
   163 fun wcode_backto_standard_pos_B :: "bin_inv_t"
       
   164   where
       
   165   "wcode_backto_standard_pos_B ires rs (l, r) = 
       
   166           (\<exists> ln rn. l =  Bk # Bk\<^bsup>ln\<^esup> @ Oc # ires \<and> 
       
   167                r =  Bk # Oc\<^bsup>(Suc (Suc rs))\<^esup> @ Bk\<^bsup>rn \<^esup>)"
       
   168 
       
   169 declare wcode_backto_standard_pos_B.simps[simp del]
       
   170 
       
   171 fun wcode_backto_standard_pos_O :: "bin_inv_t"
       
   172   where
       
   173    "wcode_backto_standard_pos_O ires rs (l, r) = 
       
   174         (\<exists> ml mr ln rn. 
       
   175             l = Oc\<^bsup>ml\<^esup> @ Bk # Bk # Bk\<^bsup>ln\<^esup> @ Oc # ires \<and>
       
   176             r = Oc\<^bsup>mr\<^esup> @ Bk\<^bsup>rn\<^esup> \<and>
       
   177             ml + mr = Suc (Suc rs) \<and> mr > 0)"
       
   178 
       
   179 declare wcode_backto_standard_pos_O.simps[simp del]
       
   180 
       
   181 fun wcode_backto_standard_pos :: "bin_inv_t"
       
   182   where
       
   183   "wcode_backto_standard_pos ires rs (l, r) = (wcode_backto_standard_pos_B ires rs (l, r) \<or>
       
   184                                             wcode_backto_standard_pos_O ires rs (l, r))"
       
   185 
       
   186 declare wcode_backto_standard_pos.simps[simp del]
       
   187 
       
   188 lemma [simp]: "<0::nat> = [Oc]"
       
   189 apply(simp add: tape_of_nat_abv exponent_def tape_of_nat_list.simps)
       
   190 done
       
   191 
       
   192 lemma tape_of_Suc_nat: "<Suc (a ::nat)> = replicate a Oc @ [Oc, Oc]"
       
   193 apply(simp add: tape_of_nat_abv exp_ind tape_of_nat_list.simps)
       
   194 apply(simp only: exp_ind_def[THEN sym])
       
   195 apply(simp only: exp_ind, simp, simp add: exponent_def)
       
   196 done
       
   197 
       
   198 lemma [simp]: "length (<a::nat>) = Suc a"
       
   199 apply(simp add: tape_of_nat_abv tape_of_nat_list.simps)
       
   200 done
       
   201 
       
   202 lemma [simp]: "<[a::nat]> = <a>"
       
   203 apply(simp add: tape_of_nat_abv tape_of_nl_abv exponent_def
       
   204                 tape_of_nat_list.simps)
       
   205 done
       
   206 
       
   207 lemma bin_wc_eq: "bl_bin xs = bl2wc xs"
       
   208 proof(induct xs)
       
   209   show " bl_bin [] = bl2wc []" 
       
   210     apply(simp add: bl_bin.simps)
       
   211     done
       
   212 next
       
   213   fix a xs
       
   214   assume "bl_bin xs = bl2wc xs"
       
   215   thus " bl_bin (a # xs) = bl2wc (a # xs)"
       
   216     apply(case_tac a, simp_all add: bl_bin.simps bl2wc.simps)
       
   217     apply(simp_all add: bl2nat.simps bl2nat_double)
       
   218     done
       
   219 qed
       
   220 
       
   221 declare exp_def[simp del]
       
   222 
       
   223 lemma bl_bin_nat_Suc:  
       
   224   "bl_bin (<Suc a>) = bl_bin (<a>) + 2^(Suc a)"
       
   225 apply(simp add: tape_of_nat_abv bin_wc_eq)
       
   226 apply(simp add: bl2wc.simps)
       
   227 done
       
   228 lemma [simp]: " rev (a\<^bsup>aa\<^esup>) = a\<^bsup>aa\<^esup>"
       
   229 apply(simp add: exponent_def)
       
   230 done
       
   231  
       
   232 declare tape_of_nl_abv_cons[simp del]
       
   233 
       
   234 lemma tape_of_nl_rev: "rev (<lm::nat list>) = (<rev lm>)"
       
   235 apply(induct lm rule: list_tl_induct, simp)
       
   236 apply(case_tac "list = []", simp add: tape_of_nl_abv tape_of_nat_list.simps)
       
   237 apply(simp add: tape_of_nat_list_butlast_last tape_of_nl_abv_cons)
       
   238 done
       
   239 lemma [simp]: "a\<^bsup>Suc 0\<^esup> = [a]" 
       
   240 by(simp add: exp_def)
       
   241 lemma tape_of_nl_cons_app1: "(<a # xs @ [b]>) = (Oc\<^bsup>Suc a\<^esup> @ Bk # (<xs@ [b]>))"
       
   242 apply(case_tac xs, simp add: tape_of_nl_abv tape_of_nat_list.simps)
       
   243 apply(simp add: tape_of_nl_abv  tape_of_nat_list.simps)
       
   244 done
       
   245 
       
   246 lemma bl_bin_bk_oc[simp]:
       
   247   "bl_bin (xs @ [Bk, Oc]) = 
       
   248   bl_bin xs + 2*2^(length xs)"
       
   249 apply(simp add: bin_wc_eq)
       
   250 using bl2nat_cons_oc[of "xs @ [Bk]"]
       
   251 apply(simp add: bl2nat_cons_bk bl2wc.simps)
       
   252 done
       
   253 
       
   254 lemma tape_of_nat[simp]: "(<a::nat>) = Oc\<^bsup>Suc a\<^esup>"
       
   255 apply(simp add: tape_of_nat_abv)
       
   256 done
       
   257 lemma tape_of_nl_cons_app2: "(<c # xs @ [b]>) = (<c # xs> @ Bk # Oc\<^bsup>Suc b\<^esup>)"
       
   258 proof(induct "length xs" arbitrary: xs c,
       
   259   simp add: tape_of_nl_abv  tape_of_nat_list.simps)
       
   260   fix x xs c
       
   261   assume ind: "\<And>xs c. x = length xs \<Longrightarrow> <c # xs @ [b]> = 
       
   262     <c # xs> @ Bk # Oc\<^bsup>Suc b\<^esup>"
       
   263     and h: "Suc x = length (xs::nat list)" 
       
   264   show "<c # xs @ [b]> = <c # xs> @ Bk # Oc\<^bsup>Suc b\<^esup>"
       
   265   proof(case_tac xs, simp add: tape_of_nl_abv  tape_of_nat_list.simps)
       
   266     fix a list
       
   267     assume g: "xs = a # list"
       
   268     hence k: "<a # list @ [b]> =  <a # list> @ Bk # Oc\<^bsup>Suc b\<^esup>"
       
   269       apply(rule_tac ind)
       
   270       using h
       
   271       apply(simp)
       
   272       done
       
   273     from g and k show "<c # xs @ [b]> = <c # xs> @ Bk # Oc\<^bsup>Suc b\<^esup>"
       
   274       apply(simp add: tape_of_nl_abv tape_of_nat_list.simps)
       
   275       done
       
   276   qed
       
   277 qed
       
   278 
       
   279 lemma [simp]: "length (<aa # a # list>) = Suc (Suc aa) + length (<a # list>)"
       
   280 apply(simp add: tape_of_nl_abv tape_of_nat_list.simps)
       
   281 done
       
   282 
       
   283 lemma [simp]: "bl_bin (Oc\<^bsup>Suc aa\<^esup> @ Bk # tape_of_nat_list (a # lista) @ [Bk, Oc]) =
       
   284               bl_bin (Oc\<^bsup>Suc aa\<^esup> @ Bk # tape_of_nat_list (a # lista)) + 
       
   285               2* 2^(length (Oc\<^bsup>Suc aa\<^esup> @ Bk # tape_of_nat_list (a # lista)))"
       
   286 using bl_bin_bk_oc[of "Oc\<^bsup>Suc aa\<^esup> @ Bk # tape_of_nat_list (a # lista)"]
       
   287 apply(simp)
       
   288 done
       
   289 
       
   290 lemma [simp]: 
       
   291   "bl_bin (<aa # list>) + (4 * rs + 4) * 2 ^ (length (<aa # list>) - Suc 0)
       
   292   = bl_bin (Oc\<^bsup>Suc aa\<^esup> @ Bk # <list @ [0]>) + rs * (2 * 2 ^ (aa + length (<list @ [0]>)))"
       
   293 apply(case_tac "list", simp add: add_mult_distrib, simp)
       
   294 apply(simp add: tape_of_nl_cons_app2 add_mult_distrib)
       
   295 apply(simp add: tape_of_nl_abv tape_of_nat_list.simps)
       
   296 done
       
   297   
       
   298 lemma tape_of_nl_app_Suc: "((<list @ [Suc ab]>)) = (<list @ [ab]>) @ [Oc]"
       
   299 apply(induct list)
       
   300 apply(simp add: tape_of_nl_abv tape_of_nat_list.simps exp_ind)
       
   301 apply(case_tac list)
       
   302 apply(simp_all add:tape_of_nl_abv tape_of_nat_list.simps exp_ind)
       
   303 done
       
   304 
       
   305 lemma [simp]: "bl_bin (Oc # Oc\<^bsup>aa\<^esup> @ Bk # <list @ [ab]> @ [Oc])
       
   306               = bl_bin (Oc # Oc\<^bsup>aa\<^esup> @ Bk # <list @ [ab]>) +
       
   307               2^(length (Oc # Oc\<^bsup>aa\<^esup> @ Bk # <list @ [ab]>))"
       
   308 apply(simp add: bin_wc_eq)
       
   309 apply(simp add: bl2nat_cons_oc bl2wc.simps)
       
   310 using bl2nat_cons_oc[of "Oc # Oc\<^bsup>aa\<^esup> @ Bk # <list @ [ab]>"]
       
   311 apply(simp)
       
   312 done
       
   313 lemma [simp]: "bl_bin (Oc # Oc\<^bsup>aa\<^esup> @ Bk # <list @ [ab]>) + (4 * 2 ^ (aa + length (<list @ [ab]>)) +
       
   314          4 * (rs * 2 ^ (aa + length (<list @ [ab]>)))) =
       
   315        bl_bin (Oc # Oc\<^bsup>aa\<^esup> @ Bk # <list @ [Suc ab]>) +
       
   316          rs * (2 * 2 ^ (aa + length (<list @ [Suc ab]>)))"
       
   317 apply(simp add: tape_of_nl_app_Suc)
       
   318 done
       
   319 
       
   320 declare tape_of_nat[simp del]
       
   321 
       
   322 text{* double case*}
       
   323 fun wcode_double_case_inv :: "nat \<Rightarrow> bin_inv_t"
       
   324   where
       
   325   "wcode_double_case_inv st ires rs (l, r) = 
       
   326           (if st = Suc 0 then wcode_on_left_moving_1 ires rs (l, r)
       
   327           else if st = Suc (Suc 0) then wcode_on_checking_1 ires rs (l, r)
       
   328           else if st = 3 then wcode_erase1 ires rs (l, r)
       
   329           else if st = 4 then wcode_on_right_moving_1 ires rs (l, r)
       
   330           else if st = 5 then wcode_goon_right_moving_1 ires rs (l, r)
       
   331           else if st = 6 then wcode_backto_standard_pos ires rs (l, r)
       
   332           else if st = 13 then wcode_before_double ires rs (l, r)
       
   333           else False)"
       
   334 
       
   335 declare wcode_double_case_inv.simps[simp del]
       
   336 
       
   337 fun wcode_double_case_state :: "t_conf \<Rightarrow> nat"
       
   338   where
       
   339   "wcode_double_case_state (st, l, r) = 
       
   340    13 - st"
       
   341 
       
   342 fun wcode_double_case_step :: "t_conf \<Rightarrow> nat"
       
   343   where
       
   344   "wcode_double_case_step (st, l, r) = 
       
   345       (if st = Suc 0 then (length l)
       
   346       else if st = Suc (Suc 0) then (length r)
       
   347       else if st = 3 then 
       
   348                  if hd r = Oc then 1 else 0
       
   349       else if st = 4 then (length r)
       
   350       else if st = 5 then (length r)
       
   351       else if st = 6 then (length l)
       
   352       else 0)"
       
   353 
       
   354 fun wcode_double_case_measure :: "t_conf \<Rightarrow> nat \<times> nat"
       
   355   where
       
   356   "wcode_double_case_measure (st, l, r) = 
       
   357      (wcode_double_case_state (st, l, r), 
       
   358       wcode_double_case_step (st, l, r))"
       
   359 
       
   360 definition wcode_double_case_le :: "(t_conf \<times> t_conf) set"
       
   361   where "wcode_double_case_le \<equiv> (inv_image lex_pair wcode_double_case_measure)"
       
   362 
       
   363 lemma [intro]: "wf lex_pair"
       
   364 by(auto intro:wf_lex_prod simp:lex_pair_def)
       
   365 
       
   366 lemma wf_wcode_double_case_le[intro]: "wf wcode_double_case_le"
       
   367 by(auto intro:wf_inv_image simp: wcode_double_case_le_def )
       
   368 term fetch
       
   369 
       
   370 lemma [simp]: "fetch t_wcode_main (Suc 0) Bk = (L, Suc 0)"
       
   371 apply(simp add: t_wcode_main_def t_wcode_main_first_part_def
       
   372                 fetch.simps nth_of.simps)
       
   373 done
       
   374 
       
   375 lemma [simp]: "fetch t_wcode_main (Suc 0) Oc = (L, Suc (Suc 0))"
       
   376 apply(simp add: t_wcode_main_def t_wcode_main_first_part_def
       
   377                 fetch.simps nth_of.simps)
       
   378 done
       
   379 
       
   380 lemma [simp]: "fetch t_wcode_main (Suc (Suc 0)) Oc = (R, 3)"
       
   381 apply(simp add: t_wcode_main_def t_wcode_main_first_part_def
       
   382                 fetch.simps nth_of.simps)
       
   383 done
       
   384 
       
   385 lemma [simp]: "fetch t_wcode_main (Suc (Suc (Suc 0))) Bk = (R, 4)"
       
   386 apply(simp add: t_wcode_main_def t_wcode_main_first_part_def
       
   387                 fetch.simps nth_of.simps)
       
   388 done 
       
   389 
       
   390 lemma [simp]: "fetch t_wcode_main (Suc (Suc (Suc 0))) Oc = (W0, 3)"
       
   391 apply(simp add: t_wcode_main_def t_wcode_main_first_part_def
       
   392                 fetch.simps nth_of.simps)
       
   393 done
       
   394 
       
   395 lemma [simp]: "fetch t_wcode_main 4 Bk = (R, 4)"
       
   396 apply(simp add: t_wcode_main_def t_wcode_main_first_part_def
       
   397                 fetch.simps nth_of.simps)
       
   398 done
       
   399 
       
   400 lemma [simp]: "fetch t_wcode_main 4 Oc = (R, 5)"
       
   401 apply(simp add: t_wcode_main_def t_wcode_main_first_part_def
       
   402                 fetch.simps nth_of.simps)
       
   403 done
       
   404 
       
   405 lemma [simp]: "fetch t_wcode_main 5 Oc = (R, 5)"
       
   406 apply(simp add: t_wcode_main_def t_wcode_main_first_part_def
       
   407                 fetch.simps nth_of.simps)
       
   408 done
       
   409 
       
   410 lemma [simp]: "fetch t_wcode_main 5 Bk = (W1, 6)"
       
   411 apply(simp add: t_wcode_main_def t_wcode_main_first_part_def
       
   412                 fetch.simps nth_of.simps)
       
   413 done
       
   414 
       
   415 lemma [simp]: "fetch t_wcode_main 6 Bk = (R, 13)"
       
   416 apply(simp add: t_wcode_main_def t_wcode_main_first_part_def
       
   417                 fetch.simps nth_of.simps)
       
   418 done
       
   419 
       
   420 lemma [simp]: "fetch t_wcode_main 6 Oc = (L, 6)"
       
   421 apply(simp add: t_wcode_main_def t_wcode_main_first_part_def
       
   422                 fetch.simps nth_of.simps)
       
   423 done
       
   424 lemma [elim]: "Bk\<^bsup>mr\<^esup> = [] \<Longrightarrow> mr = 0"
       
   425 apply(case_tac mr, auto simp: exponent_def)
       
   426 done
       
   427 
       
   428 lemma [simp]: "wcode_on_left_moving_1 ires rs (b, []) = False"
       
   429 apply(simp add: wcode_on_left_moving_1.simps wcode_on_left_moving_1_B.simps
       
   430                 wcode_on_left_moving_1_O.simps, auto)
       
   431 done
       
   432 
       
   433 
       
   434 declare wcode_on_checking_1.simps[simp del]
       
   435 
       
   436 lemmas wcode_double_case_inv_simps = 
       
   437   wcode_on_left_moving_1.simps wcode_on_left_moving_1_O.simps
       
   438   wcode_on_left_moving_1_B.simps wcode_on_checking_1.simps
       
   439   wcode_erase1.simps wcode_on_right_moving_1.simps
       
   440   wcode_goon_right_moving_1.simps wcode_backto_standard_pos.simps
       
   441 
       
   442 
       
   443 lemma [simp]: "wcode_on_left_moving_1 ires rs (b, r) \<Longrightarrow> b \<noteq> []"
       
   444 apply(simp add: wcode_double_case_inv_simps, auto)
       
   445 done
       
   446 
       
   447 
       
   448 lemma [elim]: "\<lbrakk>wcode_on_left_moving_1 ires rs (b, Bk # list);
       
   449                 tl b = aa \<and> hd b # Bk # list = ba\<rbrakk> \<Longrightarrow> 
       
   450                wcode_on_left_moving_1 ires rs (aa, ba)"
       
   451 apply(simp only: wcode_on_left_moving_1.simps wcode_on_left_moving_1_O.simps
       
   452                 wcode_on_left_moving_1_B.simps)
       
   453 apply(erule_tac disjE)
       
   454 apply(erule_tac exE)+
       
   455 apply(case_tac ml, simp)
       
   456 apply(rule_tac x = "mr - Suc (Suc 0)" in exI, rule_tac x = rn in exI)
       
   457 apply(case_tac mr, simp, case_tac nat, simp, simp add: exp_ind)
       
   458 apply(rule_tac disjI1)
       
   459 apply(rule_tac x = nat in exI, rule_tac x = "Suc mr" in exI, rule_tac x = rn in exI, 
       
   460       simp add: exp_ind_def)
       
   461 apply(erule_tac exE)+
       
   462 apply(simp)
       
   463 done
       
   464 
       
   465 
       
   466 lemma [elim]: 
       
   467   "\<lbrakk>wcode_on_left_moving_1 ires rs (b, Oc # list); tl b = aa \<and> hd b # Oc # list = ba\<rbrakk> 
       
   468     \<Longrightarrow> wcode_on_checking_1 ires rs (aa, ba)"
       
   469 apply(simp only: wcode_double_case_inv_simps)
       
   470 apply(erule_tac disjE)
       
   471 apply(erule_tac [!] exE)+
       
   472 apply(case_tac mr, simp, simp add: exp_ind_def)
       
   473 apply(rule_tac x = ln in exI, rule_tac x = rn in exI, simp)
       
   474 done
       
   475 
       
   476 
       
   477 lemma [simp]: "wcode_on_checking_1 ires rs (b, []) = False" 
       
   478 apply(auto simp: wcode_double_case_inv_simps)
       
   479 done         
       
   480  
       
   481 lemma [simp]: "wcode_on_checking_1 ires rs (b, Bk # list) = False"
       
   482 apply(auto simp: wcode_double_case_inv_simps)
       
   483 done         
       
   484   
       
   485 lemma [elim]: "\<lbrakk>wcode_on_checking_1 ires rs (b, Oc # ba);Oc # b = aa \<and> list = ba\<rbrakk>
       
   486   \<Longrightarrow> wcode_erase1 ires rs (aa, ba)"
       
   487 apply(simp only: wcode_double_case_inv_simps)
       
   488 apply(erule_tac exE)+
       
   489 apply(rule_tac x = ln in exI, rule_tac x = rn in exI, simp)
       
   490 done
       
   491 
       
   492 
       
   493 lemma [simp]: "wcode_on_checking_1 ires rs (b, []) = False"
       
   494 apply(simp add: wcode_double_case_inv_simps)
       
   495 done
       
   496 
       
   497 lemma [simp]: "wcode_on_checking_1 ires rs ([], Bk # list) = False"
       
   498 apply(simp add: wcode_double_case_inv_simps)
       
   499 done
       
   500 
       
   501 lemma [simp]: "wcode_erase1 ires rs (b, []) = False"
       
   502 apply(simp add: wcode_double_case_inv_simps)
       
   503 done
       
   504 
       
   505 lemma [simp]: "wcode_on_right_moving_1 ires rs (b, []) = False"
       
   506 apply(simp add: wcode_double_case_inv_simps exp_ind_def)
       
   507 done
       
   508 
       
   509 lemma [simp]: "wcode_on_right_moving_1 ires rs (b, []) = False"
       
   510 apply(simp add: wcode_double_case_inv_simps exp_ind_def)
       
   511 done
       
   512 
       
   513 lemma [elim]: "\<lbrakk>wcode_on_right_moving_1 ires rs (b, Bk # ba);  Bk # b = aa \<and> list = b\<rbrakk> \<Longrightarrow> 
       
   514   wcode_on_right_moving_1 ires rs (aa, ba)"
       
   515 apply(simp only: wcode_double_case_inv_simps)
       
   516 apply(erule_tac exE)+
       
   517 apply(rule_tac x = "Suc ml" in exI, rule_tac x = "mr - Suc 0" in exI,
       
   518       rule_tac x = rn in exI)
       
   519 apply(simp add: exp_ind_def)
       
   520 apply(case_tac mr, simp, simp add: exp_ind_def)
       
   521 done
       
   522 
       
   523 lemma [elim]: 
       
   524   "\<lbrakk>wcode_on_right_moving_1 ires rs (b, Oc # ba); Oc # b = aa \<and> list = ba\<rbrakk> 
       
   525   \<Longrightarrow> wcode_goon_right_moving_1 ires rs (aa, ba)"
       
   526 apply(simp only: wcode_double_case_inv_simps)
       
   527 apply(erule_tac exE)+
       
   528 apply(rule_tac x = "Suc 0" in exI, rule_tac x = "rs" in exI,
       
   529       rule_tac x = "ml - Suc (Suc 0)" in exI, rule_tac x = rn in exI)
       
   530 apply(case_tac mr, simp_all add: exp_ind_def)
       
   531 apply(case_tac ml, simp, case_tac nat, simp, simp)
       
   532 apply(simp add: exp_ind_def)
       
   533 done
       
   534 
       
   535 lemma [simp]: 
       
   536   "wcode_on_right_moving_1 ires rs (b, []) \<Longrightarrow> False"
       
   537 apply(simp add: wcode_double_case_inv_simps exponent_def)
       
   538 done
       
   539 
       
   540 lemma [elim]: "\<lbrakk>wcode_erase1 ires rs (b, Bk # ba); Bk # b = aa \<and> list = ba; c = Bk # ba\<rbrakk> 
       
   541   \<Longrightarrow> wcode_on_right_moving_1 ires rs (aa, ba)"
       
   542 apply(simp only: wcode_double_case_inv_simps)
       
   543 apply(erule_tac exE)+
       
   544 apply(rule_tac x = "Suc 0" in exI, rule_tac x = "Suc (Suc ln)" in exI, 
       
   545       rule_tac x = rn in exI, simp add: exp_ind)
       
   546 done
       
   547 
       
   548 lemma [elim]: "\<lbrakk>wcode_erase1 ires rs (aa, Oc # list);  b = aa \<and> Bk # list = ba\<rbrakk> \<Longrightarrow> 
       
   549   wcode_erase1 ires rs (aa, ba)"
       
   550 apply(simp only: wcode_double_case_inv_simps)
       
   551 apply(erule_tac exE)+
       
   552 apply(rule_tac x = ln in exI, rule_tac x = rn in exI, auto)
       
   553 done
       
   554 
       
   555 lemma [elim]: "\<lbrakk>wcode_goon_right_moving_1 ires rs (aa, []); b = aa \<and> [Oc] = ba\<rbrakk> 
       
   556               \<Longrightarrow> wcode_backto_standard_pos ires rs (aa, ba)"
       
   557 apply(simp only: wcode_double_case_inv_simps)
       
   558 apply(erule_tac exE)+
       
   559 apply(rule_tac disjI2)
       
   560 apply(simp only:wcode_backto_standard_pos_O.simps)
       
   561 apply(rule_tac x = ml in exI, rule_tac x = "Suc 0" in exI, rule_tac x = ln in exI,
       
   562       rule_tac x = rn in exI, simp)
       
   563 apply(case_tac mr, simp_all add: exponent_def)
       
   564 done
       
   565 
       
   566 lemma [elim]: 
       
   567   "\<lbrakk>wcode_goon_right_moving_1 ires rs (aa, Bk # list);  b = aa \<and> Oc # list = ba\<rbrakk>
       
   568   \<Longrightarrow> wcode_backto_standard_pos ires rs (aa, ba)"
       
   569 apply(simp only: wcode_double_case_inv_simps)
       
   570 apply(erule_tac exE)+
       
   571 apply(rule_tac disjI2)
       
   572 apply(simp only:wcode_backto_standard_pos_O.simps)
       
   573 apply(rule_tac x = ml in exI, rule_tac x = "Suc 0" in exI, rule_tac x = ln in exI,
       
   574       rule_tac x = "rn - Suc 0" in exI, simp)
       
   575 apply(case_tac mr, simp, case_tac rn, simp, simp_all add: exp_ind_def)
       
   576 done
       
   577 
       
   578 lemma [elim]: "\<lbrakk>wcode_goon_right_moving_1 ires rs (b, Oc # ba);  Oc # b = aa \<and> list = ba\<rbrakk> 
       
   579   \<Longrightarrow> wcode_goon_right_moving_1 ires rs (aa, ba)"
       
   580 apply(simp only: wcode_double_case_inv_simps)
       
   581 apply(erule_tac exE)+
       
   582 apply(rule_tac x = "Suc ml" in exI, rule_tac x = "mr - Suc 0" in exI, 
       
   583       rule_tac x = ln in exI, rule_tac x = rn in exI)
       
   584 apply(simp add: exp_ind_def)
       
   585 apply(case_tac mr, simp, case_tac rn, simp_all add: exp_ind_def)
       
   586 done
       
   587 
       
   588 lemma [elim]: "\<lbrakk>wcode_backto_standard_pos ires rs (b, []);  Bk # b = aa\<rbrakk> \<Longrightarrow> False"
       
   589 apply(auto simp: wcode_double_case_inv_simps wcode_backto_standard_pos_O.simps
       
   590                  wcode_backto_standard_pos_B.simps)
       
   591 apply(case_tac mr, simp_all add: exp_ind_def)
       
   592 done
       
   593 
       
   594 lemma [elim]: "\<lbrakk>wcode_backto_standard_pos ires rs (b, Bk # ba); Bk # b = aa \<and> list = ba\<rbrakk> 
       
   595   \<Longrightarrow> wcode_before_double ires rs (aa, ba)"
       
   596 apply(simp only: wcode_double_case_inv_simps wcode_backto_standard_pos_B.simps
       
   597                  wcode_backto_standard_pos_O.simps wcode_before_double.simps)
       
   598 apply(erule_tac disjE)
       
   599 apply(erule_tac exE)+
       
   600 apply(rule_tac x = ln in exI, rule_tac x = rn in exI, simp)
       
   601 apply(auto)
       
   602 apply(case_tac [!] mr, simp_all add: exp_ind_def)
       
   603 done
       
   604 
       
   605 lemma [simp]: "wcode_backto_standard_pos ires rs ([], Oc # list) = False"
       
   606 apply(auto simp: wcode_backto_standard_pos.simps wcode_backto_standard_pos_B.simps
       
   607                  wcode_backto_standard_pos_O.simps)
       
   608 done
       
   609 
       
   610 lemma [simp]: "wcode_backto_standard_pos ires rs (b, []) = False"
       
   611 apply(auto simp: wcode_backto_standard_pos.simps wcode_backto_standard_pos_B.simps
       
   612                  wcode_backto_standard_pos_O.simps)
       
   613 apply(case_tac mr, simp, simp add: exp_ind_def)
       
   614 done
       
   615 
       
   616 lemma [elim]: "\<lbrakk>wcode_backto_standard_pos ires rs (b, Oc # list); tl b = aa; hd b # Oc # list =  ba\<rbrakk>
       
   617        \<Longrightarrow> wcode_backto_standard_pos ires rs (aa, ba)"
       
   618 apply(simp only:  wcode_backto_standard_pos.simps wcode_backto_standard_pos_B.simps
       
   619                  wcode_backto_standard_pos_O.simps)
       
   620 apply(erule_tac disjE)
       
   621 apply(simp)
       
   622 apply(erule_tac exE)+
       
   623 apply(case_tac ml, simp)
       
   624 apply(rule_tac disjI1, rule_tac conjI)
       
   625 apply(rule_tac x = ln  in exI, simp, rule_tac x = rn in exI, simp)
       
   626 apply(rule_tac disjI2)
       
   627 apply(rule_tac x = nat in exI, rule_tac x = "Suc mr" in exI, rule_tac x = ln in exI, 
       
   628       rule_tac x = rn in exI, simp)
       
   629 apply(simp add: exp_ind_def)
       
   630 done
       
   631 
       
   632 declare new_tape.simps[simp del] nth_of.simps[simp del] fetch.simps[simp del]
       
   633 lemma wcode_double_case_first_correctness:
       
   634   "let P = (\<lambda> (st, l, r). st = 13) in 
       
   635        let Q = (\<lambda> (st, l, r). wcode_double_case_inv st ires rs (l, r)) in 
       
   636        let f = (\<lambda> stp. steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc # Oc # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stp) in
       
   637        \<exists> n .P (f n) \<and> Q (f (n::nat))"
       
   638 proof -
       
   639   let ?P = "(\<lambda> (st, l, r). st = 13)"
       
   640   let ?Q = "(\<lambda> (st, l, r). wcode_double_case_inv st ires rs (l, r))"
       
   641   let ?f = "(\<lambda> stp. steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc # Oc # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stp)"
       
   642   have "\<exists> n. ?P (?f n) \<and> ?Q (?f (n::nat))"
       
   643   proof(rule_tac halt_lemma2)
       
   644     show "wf wcode_double_case_le"
       
   645       by auto
       
   646   next
       
   647     show "\<forall> na. \<not> ?P (?f na) \<and> ?Q (?f na) \<longrightarrow>
       
   648                    ?Q (?f (Suc na)) \<and> (?f (Suc na), ?f na) \<in> wcode_double_case_le"
       
   649     proof(rule_tac allI, case_tac "?f na", simp add: tstep_red)
       
   650       fix na a b c
       
   651       show "a \<noteq> 13 \<and> wcode_double_case_inv a ires rs (b, c) \<longrightarrow>
       
   652                (case tstep (a, b, c) t_wcode_main of (st, x) \<Rightarrow> 
       
   653                    wcode_double_case_inv st ires rs x) \<and> 
       
   654                 (tstep (a, b, c) t_wcode_main, a, b, c) \<in> wcode_double_case_le"
       
   655         apply(rule_tac impI, simp add: wcode_double_case_inv.simps)
       
   656         apply(auto split: if_splits simp: tstep.simps, 
       
   657               case_tac [!] c, simp_all, case_tac [!] "(c::block list)!0")
       
   658         apply(simp_all add: new_tape.simps wcode_double_case_inv.simps wcode_double_case_le_def
       
   659                                         lex_pair_def)
       
   660         apply(auto split: if_splits)
       
   661         done
       
   662     qed
       
   663   next
       
   664     show "?Q (?f 0)"
       
   665       apply(simp add: steps.simps wcode_double_case_inv.simps 
       
   666                                   wcode_on_left_moving_1.simps
       
   667                                   wcode_on_left_moving_1_B.simps)
       
   668       apply(rule_tac disjI1)
       
   669       apply(rule_tac x = "Suc m" in exI, simp add: exp_ind_def)
       
   670       apply(rule_tac x = "Suc 0" in exI, simp add: exp_ind_def)
       
   671       apply(auto)
       
   672       done
       
   673   next
       
   674     show "\<not> ?P (?f 0)"
       
   675       apply(simp add: steps.simps)
       
   676       done
       
   677   qed
       
   678   thus "let P = \<lambda>(st, l, r). st = 13;
       
   679     Q = \<lambda>(st, l, r). wcode_double_case_inv st ires rs (l, r);
       
   680     f = steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc # Oc # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main
       
   681     in \<exists>n. P (f n) \<and> Q (f n)"
       
   682     apply(simp add: Let_def)
       
   683     done
       
   684 qed
       
   685     
       
   686 lemma [elim]: "t_ncorrect tp
       
   687     \<Longrightarrow> t_ncorrect (abacus.tshift tp a)"
       
   688 apply(simp add: t_ncorrect.simps shift_length)
       
   689 done
       
   690 
       
   691 lemma tshift_fetch: "\<lbrakk> fetch tp a b = (aa, st'); 0 < st'\<rbrakk>
       
   692        \<Longrightarrow> fetch (abacus.tshift tp (length tp1 div 2)) a b 
       
   693           = (aa, st' + length tp1 div 2)"
       
   694 apply(subgoal_tac "a > 0")
       
   695 apply(auto simp: fetch.simps nth_of.simps shift_length nth_map
       
   696                  tshift.simps split: block.splits if_splits)
       
   697 done
       
   698 
       
   699 lemma t_steps_steps_eq: "\<lbrakk>steps (st, l, r) tp stp = (st', l', r');
       
   700          0 < st';  
       
   701          0 < st \<and> st \<le> length tp div 2; 
       
   702          t_ncorrect tp1;
       
   703           t_ncorrect tp\<rbrakk>
       
   704     \<Longrightarrow> t_steps (st + length tp1 div 2, l, r) (tshift tp (length tp1 div 2), 
       
   705                                                       length tp1 div 2) stp
       
   706        = (st' + length tp1 div 2, l', r')"
       
   707 apply(induct stp arbitrary: st' l' r', simp add: steps.simps t_steps.simps,
       
   708       simp add: tstep_red stepn)
       
   709 apply(case_tac "(steps (st, l, r) tp stp)", simp)
       
   710 proof -
       
   711   fix stp st' l' r' a b c
       
   712   assume ind: "\<And>st' l' r'.
       
   713     \<lbrakk>a = st' \<and> b = l' \<and> c = r'; 0 < st'\<rbrakk>
       
   714     \<Longrightarrow> t_steps (st + length tp1 div 2, l, r) 
       
   715     (abacus.tshift tp (length tp1 div 2), length tp1 div 2) stp = 
       
   716      (st' + length tp1 div 2, l', r')"
       
   717   and h: "tstep (a, b, c) tp = (st', l', r')" "0 < st'" "t_ncorrect tp1"  "t_ncorrect tp"
       
   718   have k: "t_steps (st + length tp1 div 2, l, r) (abacus.tshift tp (length tp1 div 2),
       
   719          length tp1 div 2) stp = (a + length tp1 div 2, b, c)"
       
   720     apply(rule_tac ind, simp)
       
   721     using h
       
   722     apply(case_tac a, simp_all add: tstep.simps fetch.simps)
       
   723     done
       
   724   from h and this show "t_step (t_steps (st + length tp1 div 2, l, r) (abacus.tshift tp (length tp1 div 2), length tp1 div 2) stp)
       
   725            (abacus.tshift tp (length tp1 div 2), length tp1 div 2) =
       
   726           (st' + length tp1 div 2, l', r')"
       
   727     apply(simp add: k)
       
   728     apply(simp add: tstep.simps t_step.simps)
       
   729     apply(case_tac "fetch tp a (case c of [] \<Rightarrow> Bk | x # xs \<Rightarrow> x)", simp)
       
   730     apply(subgoal_tac "fetch (abacus.tshift tp (length tp1 div 2)) a
       
   731                        (case c of [] \<Rightarrow> Bk | x # xs \<Rightarrow> x) = (aa, st' + length tp1 div 2)", simp)
       
   732     apply(simp add: tshift_fetch)
       
   733     done
       
   734 qed 
       
   735 
       
   736 lemma t_tshift_lemma: "\<lbrakk> steps (st, l, r) tp stp = (st', l', r'); 
       
   737                          st' \<noteq> 0; 
       
   738                          stp > 0;
       
   739                          0 < st \<and> st \<le> length tp div 2;
       
   740                          t_ncorrect tp1;
       
   741                          t_ncorrect tp;
       
   742                          t_ncorrect tp2
       
   743                          \<rbrakk>
       
   744          \<Longrightarrow> \<exists> stp>0. steps (st + length tp1 div 2, l, r) (tp1 @ tshift tp (length tp1 div 2) @ tp2) stp 
       
   745                   = (st' + length tp1 div 2, l', r')"
       
   746 proof -
       
   747   assume h: "steps (st, l, r) tp stp = (st', l', r')"
       
   748     "st' \<noteq> 0" "stp > 0"
       
   749     "0 < st \<and> st \<le> length tp div 2"
       
   750     "t_ncorrect tp1"
       
   751     "t_ncorrect tp"
       
   752     "t_ncorrect tp2"
       
   753   from h have 
       
   754     "\<exists>stp>0. t_steps (st + length tp1 div 2, l, r) (tp1 @ abacus.tshift tp (length tp1 div 2) @ tp2, 0) stp = 
       
   755                             (st' + length tp1 div 2, l', r')"
       
   756     apply(rule_tac stp = stp in turing_shift, simp_all add: shift_length)
       
   757     apply(simp add: t_steps_steps_eq)
       
   758     apply(simp add: t_ncorrect.simps shift_length)
       
   759     done
       
   760   thus "\<exists> stp>0. steps (st + length tp1 div 2, l, r) (tp1 @ tshift tp (length tp1 div 2) @ tp2) stp 
       
   761                   = (st' + length tp1 div 2, l', r')"
       
   762     apply(erule_tac exE)
       
   763     apply(rule_tac x = stp in exI, simp)
       
   764     apply(subgoal_tac "length (tp1 @ abacus.tshift tp (length tp1 div 2) @ tp2) mod 2 = 0")
       
   765     apply(simp only: steps_eq)
       
   766     using h
       
   767     apply(auto simp: t_ncorrect.simps shift_length)
       
   768     apply arith
       
   769     done
       
   770 qed  
       
   771   
       
   772 
       
   773 lemma t_twice_len_ge: "Suc 0 \<le> length t_twice div 2"
       
   774 apply(simp add: t_twice_def tMp.simps shift_length)
       
   775 done
       
   776 
       
   777 lemma [intro]: "rec_calc_rel (recf.id (Suc 0) 0) [rs] rs"
       
   778   apply(rule_tac calc_id, simp_all)
       
   779   done
       
   780   
       
   781 lemma [intro]: "rec_calc_rel (constn 2) [rs] 2"
       
   782 using prime_rel_exec_eq[of "constn 2" "[rs]" 2]
       
   783 apply(subgoal_tac "primerec (constn 2) 1", auto)
       
   784 done
       
   785 
       
   786 lemma  [intro]: "rec_calc_rel rec_mult [rs, 2] (2 * rs)"
       
   787 using prime_rel_exec_eq[of "rec_mult" "[rs, 2]"  "2*rs"]
       
   788 apply(subgoal_tac "primerec rec_mult (Suc (Suc 0))", auto)
       
   789 done
       
   790 lemma t_twice_correct: "\<exists>stp ln rn. steps (Suc 0, Bk # Bk # ires, Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) 
       
   791             (tm_of abc_twice @ tMp (Suc 0) (start_of twice_ly (length abc_twice) - Suc 0)) stp =
       
   792        (0, Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires, Oc\<^bsup>Suc (2 * rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
   793 proof(case_tac "rec_ci rec_twice")
       
   794   fix a b c
       
   795   assume h: "rec_ci rec_twice = (a, b, c)"
       
   796   have "\<exists>stp m l. steps (Suc 0, Bk # Bk # ires, <[rs]> @ Bk\<^bsup>n\<^esup>) (tm_of abc_twice @ tMp (Suc 0) 
       
   797     (start_of twice_ly (length abc_twice) - 1)) stp = (0, Bk\<^bsup>m\<^esup> @ Bk # Bk # ires, Oc\<^bsup>Suc (2*rs)\<^esup> @ Bk\<^bsup>l\<^esup>)"
       
   798   proof(rule_tac t_compiled_by_rec)
       
   799     show "rec_ci rec_twice = (a, b, c)" by (simp add: h)
       
   800   next
       
   801     show "rec_calc_rel rec_twice [rs] (2 * rs)"
       
   802       apply(simp add: rec_twice_def)
       
   803       apply(rule_tac rs =  "[rs, 2]" in calc_cn, simp_all)
       
   804       apply(rule_tac allI, case_tac k, auto)
       
   805       done
       
   806   next
       
   807     show "length [rs] = Suc 0" by simp
       
   808   next
       
   809     show "layout_of (a [+] dummy_abc (Suc 0)) = layout_of (a [+] dummy_abc (Suc 0))"
       
   810       by simp
       
   811   next
       
   812     show "start_of twice_ly (length abc_twice) = 
       
   813       start_of (layout_of (a [+] dummy_abc (Suc 0))) (length (a [+] dummy_abc (Suc 0)))"
       
   814       using h
       
   815       apply(simp add: twice_ly_def abc_twice_def)
       
   816       done
       
   817   next
       
   818     show "tm_of abc_twice = tm_of (a [+] dummy_abc (Suc 0))"
       
   819       using h
       
   820       apply(simp add: abc_twice_def)
       
   821       done
       
   822   qed
       
   823   thus "\<exists>stp ln rn. steps (Suc 0, Bk # Bk # ires, Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) 
       
   824             (tm_of abc_twice @ tMp (Suc 0) (start_of twice_ly (length abc_twice) - Suc 0)) stp =
       
   825        (0, Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires, Oc\<^bsup>Suc (2 * rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
   826     apply(simp add: tape_of_nl_abv tape_of_nat_list.simps)
       
   827     done
       
   828 qed
       
   829 
       
   830 lemma change_termi_state_fetch: "\<lbrakk>fetch ap a b = (aa, st); st > 0\<rbrakk>
       
   831        \<Longrightarrow> fetch (change_termi_state ap) a b = (aa, st)"
       
   832 apply(case_tac b, auto simp: fetch.simps nth_of.simps change_termi_state.simps nth_map
       
   833                        split: if_splits block.splits)
       
   834 done
       
   835 
       
   836 lemma change_termi_state_exec_in_range:
       
   837      "\<lbrakk>steps (st, l, r) ap stp = (st', l', r'); st' \<noteq> 0\<rbrakk>
       
   838     \<Longrightarrow> steps (st, l, r) (change_termi_state ap) stp = (st', l', r')"
       
   839 proof(induct stp arbitrary: st l r st' l' r', simp add: steps.simps)
       
   840   fix stp st l r st' l' r'
       
   841   assume ind: "\<And>st l r st' l' r'. 
       
   842     \<lbrakk>steps (st, l, r) ap stp = (st', l', r'); st' \<noteq> 0\<rbrakk> \<Longrightarrow>
       
   843     steps (st, l, r) (change_termi_state ap) stp = (st', l', r')"
       
   844   and h: "steps (st, l, r) ap (Suc stp) = (st', l', r')" "st' \<noteq> 0"
       
   845   from h show "steps (st, l, r) (change_termi_state ap) (Suc stp) = (st', l', r')"
       
   846   proof(simp add: tstep_red, case_tac "steps (st, l, r) ap stp", simp)
       
   847     fix a b c
       
   848     assume g: "steps (st, l, r) ap stp = (a, b, c)"
       
   849               "tstep (a, b, c) ap = (st', l', r')" "0 < st'"
       
   850     hence "steps (st, l, r) (change_termi_state ap) stp = (a, b, c)"
       
   851       apply(rule_tac ind, simp)
       
   852       apply(case_tac a, simp_all add: tstep_0)
       
   853       done
       
   854     from g and this show "tstep (steps (st, l, r) (change_termi_state ap) stp)
       
   855       (change_termi_state ap) = (st', l', r')"
       
   856       apply(simp add: tstep.simps)
       
   857       apply(case_tac "fetch ap a (case c of [] \<Rightarrow> Bk | x # xs \<Rightarrow> x)", simp)
       
   858       apply(subgoal_tac "fetch (change_termi_state ap) a (case c of [] \<Rightarrow> Bk | x # xs \<Rightarrow> x)
       
   859                    = (aa, st')", simp)
       
   860       apply(simp add: change_termi_state_fetch)
       
   861       done
       
   862   qed
       
   863 qed
       
   864 
       
   865 lemma change_termi_state_fetch0: 
       
   866   "\<lbrakk>0 < a; a \<le> length ap div 2; t_correct ap; fetch ap a b = (aa, 0)\<rbrakk>
       
   867   \<Longrightarrow> fetch (change_termi_state ap) a b = (aa, Suc (length ap div 2))"
       
   868 apply(case_tac b, auto simp: fetch.simps nth_of.simps change_termi_state.simps nth_map
       
   869                        split: if_splits block.splits)
       
   870 done
       
   871 
       
   872 lemma turing_change_termi_state: 
       
   873   "\<lbrakk>steps (Suc 0, l, r) ap stp = (0, l', r'); t_correct ap\<rbrakk>
       
   874      \<Longrightarrow> \<exists> stp. steps (Suc 0, l, r) (change_termi_state ap) stp = 
       
   875         (Suc (length ap div 2), l', r')"
       
   876 apply(drule first_halt_point)
       
   877 apply(erule_tac exE)
       
   878 apply(rule_tac x = "Suc stp" in exI, simp add: tstep_red)
       
   879 apply(case_tac "steps (Suc 0, l, r) ap stp")
       
   880 apply(simp add: isS0_def change_termi_state_exec_in_range)
       
   881 apply(subgoal_tac "steps (Suc 0, l, r) (change_termi_state ap) stp = (a, b, c)", simp)
       
   882 apply(simp add: tstep.simps)
       
   883 apply(case_tac "fetch ap a (case c of [] \<Rightarrow> Bk | x # xs \<Rightarrow> x)", simp)
       
   884 apply(subgoal_tac "fetch (change_termi_state ap) a 
       
   885   (case c of [] \<Rightarrow> Bk | x # xs \<Rightarrow> x) = (aa, Suc (length ap div 2))", simp)
       
   886 apply(rule_tac ap = ap in change_termi_state_fetch0, simp_all)
       
   887 apply(rule_tac tp = "(l, r)" and l = b and r = c  and stp = stp and A = ap in s_keep, simp_all)
       
   888 apply(simp add: change_termi_state_exec_in_range)
       
   889 done
       
   890 
       
   891 lemma t_twice_change_term_state:
       
   892   "\<exists> stp ln rn. steps (Suc 0, Bk # Bk # ires, Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_twice stp
       
   893      = (Suc t_twice_len, Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires, Oc\<^bsup>Suc (2 * rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
   894 using t_twice_correct[of ires rs n]
       
   895 apply(erule_tac exE)
       
   896 apply(erule_tac exE)
       
   897 apply(erule_tac exE)
       
   898 proof(drule_tac turing_change_termi_state)
       
   899   fix stp ln rn
       
   900   show "t_correct (tm_of abc_twice @ tMp (Suc 0) (start_of twice_ly (length abc_twice) - Suc 0))"
       
   901     apply(rule_tac t_compiled_correct, simp_all)
       
   902     apply(simp add: twice_ly_def)
       
   903     done
       
   904 next
       
   905   fix stp ln rn
       
   906   show "\<exists>stp. steps (Suc 0, Bk # Bk # ires, Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>)
       
   907     (change_termi_state (tm_of abc_twice @ tMp (Suc 0) 
       
   908     (start_of twice_ly (length abc_twice) - Suc 0))) stp =
       
   909     (Suc (length (tm_of abc_twice @ tMp (Suc 0) (start_of twice_ly (length abc_twice) - Suc 0)) div 2),
       
   910     Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires, Oc\<^bsup>Suc (2 * rs)\<^esup> @ Bk\<^bsup>rn\<^esup>) \<Longrightarrow>
       
   911     \<exists>stp ln rn. steps (Suc 0, Bk # Bk # ires, Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_twice stp = 
       
   912     (Suc t_twice_len, Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires, Oc\<^bsup>Suc (2 * rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
   913     apply(erule_tac exE)
       
   914     apply(simp add: t_twice_len_def t_twice_def)
       
   915     apply(rule_tac x = stp in exI, rule_tac x = ln in exI, rule_tac x = rn in exI, simp)
       
   916     done
       
   917 qed
       
   918 
       
   919 lemma t_twice_append_pre:
       
   920   "steps (Suc 0, Bk # Bk # ires, Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_twice stp
       
   921   = (Suc t_twice_len, Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires, Oc\<^bsup>Suc (2 * rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)
       
   922    \<Longrightarrow> \<exists> stp>0. steps (Suc 0 + length t_wcode_main_first_part div 2, Bk # Bk # ires, Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>)
       
   923      (t_wcode_main_first_part @ tshift t_twice (length t_wcode_main_first_part div 2) @
       
   924       ([(L, 1), (L, 1)] @ tshift t_fourtimes (t_twice_len + 13) @ [(L, 1), (L, 1)])) stp 
       
   925     = (Suc (t_twice_len) + length t_wcode_main_first_part div 2, Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires, Oc\<^bsup>Suc (2 * rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
   926 proof(rule_tac t_tshift_lemma, simp_all add: t_twice_len_ge)
       
   927   assume "steps (Suc 0, Bk # Bk # ires, Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_twice stp = 
       
   928     (Suc t_twice_len, Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires, Oc\<^bsup>Suc (2 * rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
   929   thus "0 < stp"
       
   930     apply(case_tac stp, simp add: steps.simps t_twice_len_ge t_twice_len_def)
       
   931     using t_twice_len_ge
       
   932     apply(simp, simp)
       
   933     done
       
   934 next
       
   935   show "t_ncorrect t_wcode_main_first_part"
       
   936     apply(simp add: t_ncorrect.simps t_wcode_main_first_part_def)
       
   937     done
       
   938 next
       
   939   show "t_ncorrect t_twice"
       
   940     using length_tm_even[of abc_twice]
       
   941     apply(auto simp: t_ncorrect.simps t_twice_def)
       
   942     apply(arith)
       
   943     done
       
   944 next
       
   945   show "t_ncorrect ((L, Suc 0) # (L, Suc 0) #
       
   946        abacus.tshift t_fourtimes (t_twice_len + 13) @ [(L, Suc 0), (L, Suc 0)])"
       
   947     using length_tm_even[of abc_fourtimes]
       
   948     apply(simp add: t_ncorrect.simps shift_length t_fourtimes_def)
       
   949     apply arith
       
   950     done
       
   951 qed
       
   952   
       
   953 lemma t_twice_append:
       
   954   "\<exists> stp ln rn. steps (Suc 0 + length t_wcode_main_first_part div 2, Bk # Bk # ires, Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>)
       
   955      (t_wcode_main_first_part @ tshift t_twice (length t_wcode_main_first_part div 2) @
       
   956       ([(L, 1), (L, 1)] @ tshift t_fourtimes (t_twice_len + 13) @ [(L, 1), (L, 1)])) stp 
       
   957     = (Suc (t_twice_len) + length t_wcode_main_first_part div 2, Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires, Oc\<^bsup>Suc (2 * rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
   958   using t_twice_change_term_state[of ires rs n]
       
   959   apply(erule_tac exE)
       
   960   apply(erule_tac exE)
       
   961   apply(erule_tac exE)
       
   962   apply(drule_tac t_twice_append_pre)
       
   963   apply(erule_tac exE)
       
   964   apply(rule_tac x = stpa in exI, rule_tac x = ln in exI, rule_tac x = rn in exI)
       
   965   apply(simp)
       
   966   done
       
   967   
       
   968 lemma [simp]: "fetch t_wcode_main (Suc (t_twice_len + length t_wcode_main_first_part div 2)) Oc
       
   969      = (L, Suc 0)"
       
   970 apply(subgoal_tac "length (t_twice) mod 2 = 0")
       
   971 apply(simp add: t_wcode_main_def nth_append fetch.simps t_wcode_main_first_part_def 
       
   972   nth_of.simps shift_length t_twice_len_def, auto)
       
   973 apply(simp add: t_twice_def)
       
   974 apply(subgoal_tac "length (tm_of abc_twice) mod 2 = 0")
       
   975 apply arith
       
   976 apply(rule_tac tm_even)
       
   977 done
       
   978 
       
   979 lemma wcode_jump1: 
       
   980   "\<exists> stp ln rn. steps (Suc (t_twice_len) + length t_wcode_main_first_part div 2,
       
   981                        Bk\<^bsup>m\<^esup> @ Bk # Bk # ires, Oc\<^bsup>Suc (2 * rs)\<^esup> @ Bk\<^bsup>n\<^esup>)
       
   982      t_wcode_main stp 
       
   983     = (Suc 0, Bk\<^bsup>ln\<^esup> @ Bk # ires, Bk # Oc\<^bsup>Suc (2 * rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
   984 apply(rule_tac x = "Suc 0" in exI, rule_tac x = "m" in exI, rule_tac x = n in exI)
       
   985 apply(simp add: steps.simps tstep.simps exp_ind_def new_tape.simps)
       
   986 apply(case_tac m, simp, simp add: exp_ind_def)
       
   987 apply(simp add: exp_ind_def[THEN sym] exp_ind[THEN sym])
       
   988 done
       
   989 
       
   990 lemma wcode_main_first_part_len:
       
   991   "length t_wcode_main_first_part = 24"
       
   992   apply(simp add: t_wcode_main_first_part_def)
       
   993   done
       
   994 
       
   995 lemma wcode_double_case: 
       
   996   shows "\<exists>stp ln rn. steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc # Oc # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stp =
       
   997           (Suc 0, Bk # Bk\<^bsup>ln\<^esup> @ Oc # ires, Bk # Oc\<^bsup>Suc (2 * rs + 2)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
   998 proof -
       
   999   have "\<exists>stp ln rn. steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc # Oc # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stp =
       
  1000           (13,  Bk # Bk # Bk\<^bsup>ln\<^esup> @ Oc # ires, Oc\<^bsup>Suc (Suc rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1001     using wcode_double_case_first_correctness[of ires rs m n]
       
  1002     apply(simp)
       
  1003     apply(erule_tac exE)
       
  1004     apply(case_tac "steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc # Oc # ires, 
       
  1005            Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main na",
       
  1006           auto simp: wcode_double_case_inv.simps
       
  1007                      wcode_before_double.simps)
       
  1008     apply(rule_tac x = na in exI, rule_tac x = ln in exI, rule_tac x = rn in exI)
       
  1009     apply(simp)
       
  1010     done    
       
  1011   from this obtain stpa lna rna where stp1: 
       
  1012     "steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc # Oc # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stpa = 
       
  1013     (13, Bk # Bk # Bk\<^bsup>lna\<^esup> @ Oc # ires, Oc\<^bsup>Suc (Suc rs)\<^esup> @ Bk\<^bsup>rna\<^esup>)" by blast
       
  1014   have "\<exists> stp ln rn. steps (13, Bk # Bk # Bk\<^bsup>lna\<^esup> @ Oc # ires, Oc\<^bsup>Suc (Suc rs)\<^esup> @ Bk\<^bsup>rna\<^esup>) t_wcode_main stp =
       
  1015     (13 + t_twice_len, Bk # Bk # Bk\<^bsup>ln\<^esup> @ Oc # ires, Oc\<^bsup>Suc (Suc (Suc (2 *rs)))\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1016     using t_twice_append[of "Bk\<^bsup>lna\<^esup> @ Oc # ires" "Suc rs" rna]
       
  1017     apply(erule_tac exE)
       
  1018     apply(erule_tac exE)
       
  1019     apply(erule_tac exE)
       
  1020     apply(simp add: wcode_main_first_part_len)
       
  1021     apply(rule_tac x = stp in exI, rule_tac x = "ln + lna" in exI, 
       
  1022           rule_tac x = rn in exI)
       
  1023     apply(simp add: t_wcode_main_def)
       
  1024     apply(simp add: exp_ind_def[THEN sym] exp_add[THEN sym])
       
  1025     done
       
  1026   from this obtain stpb lnb rnb where stp2: 
       
  1027     "steps (13, Bk # Bk # Bk\<^bsup>lna\<^esup> @ Oc # ires, Oc\<^bsup>Suc (Suc rs)\<^esup> @ Bk\<^bsup>rna\<^esup>) t_wcode_main stpb =
       
  1028     (13 + t_twice_len, Bk # Bk # Bk\<^bsup>lnb\<^esup> @ Oc # ires, Oc\<^bsup>Suc (Suc (Suc (2 *rs)))\<^esup> @ Bk\<^bsup>rnb\<^esup>)" by blast
       
  1029   have "\<exists>stp ln rn. steps (13 + t_twice_len, Bk # Bk # Bk\<^bsup>lnb\<^esup> @ Oc # ires,
       
  1030     Oc\<^bsup>Suc (Suc (Suc (2 *rs)))\<^esup> @ Bk\<^bsup>rnb\<^esup>) t_wcode_main stp = 
       
  1031        (Suc 0,  Bk # Bk\<^bsup>ln\<^esup> @ Oc # ires, Bk # Oc\<^bsup>Suc (Suc (Suc (2 *rs)))\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1032     using wcode_jump1[of lnb "Oc # ires" "Suc rs" rnb]
       
  1033     apply(erule_tac exE)
       
  1034     apply(erule_tac exE)
       
  1035     apply(erule_tac exE)
       
  1036     apply(rule_tac x = stp in exI, 
       
  1037           rule_tac x = ln in exI, 
       
  1038           rule_tac x = rn in exI, simp add:wcode_main_first_part_len t_wcode_main_def)
       
  1039     apply(subgoal_tac "Bk\<^bsup>lnb\<^esup> @ Bk # Bk # Oc # ires = Bk # Bk # Bk\<^bsup>lnb\<^esup> @ Oc # ires", simp)
       
  1040     apply(simp add: exp_ind_def[THEN sym] exp_ind[THEN sym])
       
  1041     apply(simp)
       
  1042     apply(case_tac lnb, simp, simp add: exp_ind_def[THEN sym] exp_ind)
       
  1043     done               
       
  1044   from this obtain stpc lnc rnc where stp3: 
       
  1045     "steps (13 + t_twice_len, Bk # Bk # Bk\<^bsup>lnb\<^esup> @ Oc # ires,
       
  1046     Oc\<^bsup>Suc (Suc (Suc (2 *rs)))\<^esup> @ Bk\<^bsup>rnb\<^esup>) t_wcode_main stpc = 
       
  1047        (Suc 0,  Bk # Bk\<^bsup>lnc\<^esup> @ Oc # ires, Bk # Oc\<^bsup>Suc (Suc (Suc (2 *rs)))\<^esup> @ Bk\<^bsup>rnc\<^esup>)"
       
  1048     by blast
       
  1049   from stp1 stp2 stp3 show "?thesis"
       
  1050     apply(rule_tac x = "stpa + stpb + stpc" in exI, rule_tac x = lnc in exI,
       
  1051          rule_tac x = rnc in exI)
       
  1052     apply(simp add: steps_add)
       
  1053     done
       
  1054 qed
       
  1055     
       
  1056 
       
  1057 (* Begin: fourtime_case*)
       
  1058 fun wcode_on_left_moving_2_B :: "bin_inv_t"
       
  1059   where
       
  1060   "wcode_on_left_moving_2_B ires rs (l, r) =
       
  1061      (\<exists> ml mr rn. l = Bk\<^bsup>ml\<^esup> @ Oc # Bk # Oc # ires \<and>
       
  1062                  r = Bk\<^bsup>mr\<^esup> @ Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>rn\<^esup> \<and> 
       
  1063                  ml + mr > Suc 0 \<and> mr > 0)"
       
  1064 
       
  1065 fun wcode_on_left_moving_2_O :: "bin_inv_t"
       
  1066   where
       
  1067   "wcode_on_left_moving_2_O ires rs (l, r) =
       
  1068      (\<exists> ln rn. l = Bk # Oc # ires \<and>
       
  1069                r = Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1070 
       
  1071 fun wcode_on_left_moving_2 :: "bin_inv_t"
       
  1072   where
       
  1073   "wcode_on_left_moving_2 ires rs (l, r) = 
       
  1074       (wcode_on_left_moving_2_B ires rs (l, r) \<or> 
       
  1075       wcode_on_left_moving_2_O ires rs (l, r))"
       
  1076 
       
  1077 fun wcode_on_checking_2 :: "bin_inv_t"
       
  1078   where
       
  1079   "wcode_on_checking_2 ires rs (l, r) =
       
  1080        (\<exists> ln rn. l = Oc#ires \<and> 
       
  1081                  r = Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1082 
       
  1083 fun wcode_goon_checking :: "bin_inv_t"
       
  1084   where
       
  1085   "wcode_goon_checking ires rs (l, r) =
       
  1086        (\<exists> ln rn. l = ires \<and>
       
  1087                  r = Oc # Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1088 
       
  1089 fun wcode_right_move :: "bin_inv_t"
       
  1090   where
       
  1091   "wcode_right_move ires rs (l, r) = 
       
  1092      (\<exists> ln rn. l = Oc # ires \<and>
       
  1093                  r = Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1094 
       
  1095 fun wcode_erase2 :: "bin_inv_t"
       
  1096   where
       
  1097   "wcode_erase2 ires rs (l, r) = 
       
  1098         (\<exists> ln rn. l = Bk # Oc # ires \<and>
       
  1099                  tl r = Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1100 
       
  1101 fun wcode_on_right_moving_2 :: "bin_inv_t"
       
  1102   where
       
  1103   "wcode_on_right_moving_2 ires rs (l, r) = 
       
  1104         (\<exists> ml mr rn. l = Bk\<^bsup>ml\<^esup> @ Oc # ires \<and> 
       
  1105                      r = Bk\<^bsup>mr\<^esup> @ Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>rn\<^esup> \<and> ml + mr > Suc 0)"
       
  1106 
       
  1107 fun wcode_goon_right_moving_2 :: "bin_inv_t"
       
  1108   where
       
  1109   "wcode_goon_right_moving_2 ires rs (l, r) = 
       
  1110         (\<exists> ml mr ln rn. l = Oc\<^bsup>ml\<^esup> @ Bk # Bk # Bk\<^bsup>ln\<^esup> @ Oc # ires \<and>
       
  1111                         r = Oc\<^bsup>mr\<^esup> @ Bk\<^bsup>rn\<^esup> \<and> ml + mr = Suc rs)"
       
  1112 
       
  1113 fun wcode_backto_standard_pos_2_B :: "bin_inv_t"
       
  1114   where
       
  1115   "wcode_backto_standard_pos_2_B ires rs (l, r) = 
       
  1116            (\<exists> ln rn. l = Bk # Bk\<^bsup>ln\<^esup> @ Oc # ires \<and> 
       
  1117                      r = Bk # Oc\<^bsup>Suc (Suc rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1118 
       
  1119 fun wcode_backto_standard_pos_2_O :: "bin_inv_t"
       
  1120   where
       
  1121   "wcode_backto_standard_pos_2_O ires rs (l, r) = 
       
  1122           (\<exists> ml mr ln rn. l = Oc\<^bsup>ml \<^esup>@ Bk # Bk # Bk\<^bsup>ln\<^esup> @ Oc # ires \<and> 
       
  1123                           r = Oc\<^bsup>mr\<^esup> @ Bk\<^bsup>rn\<^esup> \<and> 
       
  1124                           ml + mr = (Suc (Suc rs)) \<and> mr > 0)"
       
  1125 
       
  1126 fun wcode_backto_standard_pos_2 :: "bin_inv_t"
       
  1127   where
       
  1128   "wcode_backto_standard_pos_2 ires rs (l, r) = 
       
  1129            (wcode_backto_standard_pos_2_O ires rs (l, r) \<or> 
       
  1130            wcode_backto_standard_pos_2_B ires rs (l, r))"
       
  1131 
       
  1132 fun wcode_before_fourtimes :: "bin_inv_t"
       
  1133   where
       
  1134   "wcode_before_fourtimes ires rs (l, r) = 
       
  1135           (\<exists> ln rn. l = Bk # Bk # Bk\<^bsup>ln\<^esup> @ Oc # ires \<and> 
       
  1136                     r = Oc\<^bsup>Suc (Suc rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1137 
       
  1138 declare wcode_on_left_moving_2_B.simps[simp del] wcode_on_left_moving_2.simps[simp del]
       
  1139         wcode_on_left_moving_2_O.simps[simp del] wcode_on_checking_2.simps[simp del]
       
  1140         wcode_goon_checking.simps[simp del] wcode_right_move.simps[simp del]
       
  1141         wcode_erase2.simps[simp del]
       
  1142         wcode_on_right_moving_2.simps[simp del] wcode_goon_right_moving_2.simps[simp del]
       
  1143         wcode_backto_standard_pos_2_B.simps[simp del] wcode_backto_standard_pos_2_O.simps[simp del]
       
  1144         wcode_backto_standard_pos_2.simps[simp del]
       
  1145 
       
  1146 lemmas wcode_fourtimes_invs = 
       
  1147        wcode_on_left_moving_2_B.simps wcode_on_left_moving_2.simps
       
  1148         wcode_on_left_moving_2_O.simps wcode_on_checking_2.simps
       
  1149         wcode_goon_checking.simps wcode_right_move.simps
       
  1150         wcode_erase2.simps
       
  1151         wcode_on_right_moving_2.simps wcode_goon_right_moving_2.simps
       
  1152         wcode_backto_standard_pos_2_B.simps wcode_backto_standard_pos_2_O.simps
       
  1153         wcode_backto_standard_pos_2.simps
       
  1154 
       
  1155 fun wcode_fourtimes_case_inv :: "nat \<Rightarrow> bin_inv_t"
       
  1156   where
       
  1157   "wcode_fourtimes_case_inv st ires rs (l, r) = 
       
  1158            (if st = Suc 0 then wcode_on_left_moving_2 ires rs (l, r)
       
  1159             else if st = Suc (Suc 0) then wcode_on_checking_2 ires rs (l, r)
       
  1160             else if st = 7 then wcode_goon_checking ires rs (l, r)
       
  1161             else if st = 8 then wcode_right_move ires rs (l, r)
       
  1162             else if st = 9 then wcode_erase2 ires rs (l, r)
       
  1163             else if st = 10 then wcode_on_right_moving_2 ires rs (l, r)
       
  1164             else if st = 11 then wcode_goon_right_moving_2 ires rs (l, r)
       
  1165             else if st = 12 then wcode_backto_standard_pos_2 ires rs (l, r)
       
  1166             else if st = t_twice_len + 14 then wcode_before_fourtimes ires rs (l, r)
       
  1167             else False)"
       
  1168 
       
  1169 declare wcode_fourtimes_case_inv.simps[simp del]
       
  1170 
       
  1171 fun wcode_fourtimes_case_state :: "t_conf \<Rightarrow> nat"
       
  1172   where
       
  1173   "wcode_fourtimes_case_state (st, l, r) = 13 - st"
       
  1174 
       
  1175 fun wcode_fourtimes_case_step :: "t_conf \<Rightarrow> nat"
       
  1176   where
       
  1177   "wcode_fourtimes_case_step (st, l, r) = 
       
  1178          (if st = Suc 0 then length l
       
  1179           else if st = 9 then 
       
  1180            (if hd r = Oc then 1
       
  1181             else 0)
       
  1182           else if st = 10 then length r
       
  1183           else if st = 11 then length r
       
  1184           else if st = 12 then length l
       
  1185           else 0)"
       
  1186 
       
  1187 fun wcode_fourtimes_case_measure :: "t_conf \<Rightarrow> nat \<times> nat"
       
  1188   where
       
  1189   "wcode_fourtimes_case_measure (st, l, r) = 
       
  1190      (wcode_fourtimes_case_state (st, l, r), 
       
  1191       wcode_fourtimes_case_step (st, l, r))"
       
  1192 
       
  1193 definition wcode_fourtimes_case_le :: "(t_conf \<times> t_conf) set"
       
  1194   where "wcode_fourtimes_case_le \<equiv> (inv_image lex_pair wcode_fourtimes_case_measure)"
       
  1195 
       
  1196 lemma wf_wcode_fourtimes_case_le[intro]: "wf wcode_fourtimes_case_le"
       
  1197 by(auto intro:wf_inv_image simp: wcode_fourtimes_case_le_def)
       
  1198 
       
  1199 lemma [simp]: "fetch t_wcode_main (Suc (Suc 0)) Bk = (L, 7)"
       
  1200 apply(simp add: t_wcode_main_def fetch.simps 
       
  1201   t_wcode_main_first_part_def nth_of.simps)
       
  1202 done
       
  1203 
       
  1204 lemma [simp]: "fetch t_wcode_main 7 Oc = (R, 8)"
       
  1205 apply(simp add: t_wcode_main_def fetch.simps 
       
  1206   t_wcode_main_first_part_def nth_of.simps)
       
  1207 done
       
  1208  
       
  1209 lemma [simp]: "fetch t_wcode_main 8 Bk = (R, 9)"
       
  1210 apply(simp add: t_wcode_main_def fetch.simps 
       
  1211   t_wcode_main_first_part_def nth_of.simps)
       
  1212 done
       
  1213 
       
  1214 lemma [simp]: "fetch t_wcode_main 9 Bk = (R, 10)"
       
  1215 apply(simp add: t_wcode_main_def fetch.simps 
       
  1216   t_wcode_main_first_part_def nth_of.simps)
       
  1217 done
       
  1218 
       
  1219 lemma [simp]: "fetch t_wcode_main 9 Oc = (W0, 9)"
       
  1220 apply(simp add: t_wcode_main_def fetch.simps 
       
  1221   t_wcode_main_first_part_def nth_of.simps)
       
  1222 done
       
  1223 
       
  1224 lemma [simp]: "fetch t_wcode_main 10 Bk = (R, 10)"
       
  1225 apply(simp add: t_wcode_main_def fetch.simps 
       
  1226   t_wcode_main_first_part_def nth_of.simps)
       
  1227 done
       
  1228 
       
  1229 lemma [simp]: "fetch t_wcode_main 10 Oc = (R, 11)"
       
  1230 apply(simp add: t_wcode_main_def fetch.simps 
       
  1231   t_wcode_main_first_part_def nth_of.simps)
       
  1232 done 
       
  1233 
       
  1234 lemma [simp]: "fetch t_wcode_main 11 Bk = (W1, 12)"
       
  1235 apply(simp add: t_wcode_main_def fetch.simps 
       
  1236   t_wcode_main_first_part_def nth_of.simps)
       
  1237 done
       
  1238 
       
  1239 lemma [simp]: "fetch t_wcode_main 11 Oc = (R, 11)"
       
  1240 apply(simp add: t_wcode_main_def fetch.simps 
       
  1241   t_wcode_main_first_part_def nth_of.simps)
       
  1242 done 
       
  1243 
       
  1244 lemma [simp]: "fetch t_wcode_main 12 Oc = (L, 12)"
       
  1245 apply(simp add: t_wcode_main_def fetch.simps 
       
  1246   t_wcode_main_first_part_def nth_of.simps)
       
  1247 done 
       
  1248 
       
  1249 lemma [simp]: "fetch t_wcode_main 12 Bk = (R, t_twice_len + 14)"
       
  1250 apply(simp add: t_wcode_main_def fetch.simps 
       
  1251   t_wcode_main_first_part_def nth_of.simps)
       
  1252 done
       
  1253 
       
  1254 
       
  1255 lemma [simp]: "wcode_on_left_moving_2 ires rs (b, []) = False"
       
  1256 apply(auto simp: wcode_fourtimes_invs)
       
  1257 done
       
  1258 
       
  1259 lemma [simp]: "wcode_on_checking_2 ires rs (b, []) = False"
       
  1260 apply(auto simp: wcode_fourtimes_invs)
       
  1261 done          
       
  1262 
       
  1263 lemma [simp]: "wcode_goon_checking ires rs (b, []) = False"
       
  1264 apply(auto simp: wcode_fourtimes_invs)
       
  1265 done
       
  1266 
       
  1267 lemma [simp]: "wcode_right_move ires rs (b, []) = False"
       
  1268 apply(auto simp: wcode_fourtimes_invs)
       
  1269 done
       
  1270 
       
  1271 lemma [simp]: "wcode_erase2 ires rs (b, []) = False"
       
  1272 apply(auto simp: wcode_fourtimes_invs)
       
  1273 done
       
  1274 
       
  1275 lemma [simp]: "wcode_on_right_moving_2 ires rs (b, []) = False"
       
  1276 apply(auto simp: wcode_fourtimes_invs exponent_def)
       
  1277 done
       
  1278 
       
  1279 lemma [simp]: "wcode_backto_standard_pos_2 ires rs (b, []) = False"
       
  1280 apply(auto simp: wcode_fourtimes_invs exponent_def)
       
  1281 done
       
  1282     
       
  1283 lemma [simp]: "wcode_on_left_moving_2 ires rs (b, Bk # list) \<Longrightarrow> b \<noteq> []"
       
  1284 apply(simp add: wcode_fourtimes_invs, auto)
       
  1285 done
       
  1286         
       
  1287 lemma [simp]: "wcode_on_left_moving_2 ires rs (b, Bk # list) \<Longrightarrow>  wcode_on_left_moving_2 ires rs (tl b, hd b # Bk # list)"
       
  1288 apply(simp only: wcode_fourtimes_invs)
       
  1289 apply(erule_tac disjE)
       
  1290 apply(erule_tac exE)+
       
  1291 apply(case_tac ml, simp)
       
  1292 apply(rule_tac x = "mr - (Suc (Suc 0))" in exI, rule_tac x = rn in exI, simp)
       
  1293 apply(case_tac mr, simp, case_tac nat, simp, simp add: exp_ind)
       
  1294 apply(rule_tac disjI1)
       
  1295 apply(rule_tac x = nat in exI, rule_tac x = "Suc mr" in exI, rule_tac x = rn in exI,
       
  1296       simp add: exp_ind_def)
       
  1297 apply(simp)
       
  1298 done
       
  1299 
       
  1300 lemma [simp]: "wcode_on_checking_2 ires rs (b, Bk # list) \<Longrightarrow> b \<noteq> []"
       
  1301 apply(auto simp: wcode_fourtimes_invs)
       
  1302 done
       
  1303 
       
  1304 lemma  [simp]: "wcode_on_checking_2 ires rs (b, Bk # list)
       
  1305        \<Longrightarrow>   wcode_goon_checking ires rs (tl b, hd b # Bk # list)"
       
  1306 apply(simp only: wcode_fourtimes_invs)
       
  1307 apply(auto)
       
  1308 done
       
  1309 
       
  1310 lemma [simp]: "wcode_goon_checking ires rs (b, Bk # list) = False"
       
  1311 apply(simp add: wcode_fourtimes_invs)
       
  1312 done
       
  1313 
       
  1314 lemma [simp]: " wcode_right_move ires rs (b, Bk # list) \<Longrightarrow> b\<noteq> []" 
       
  1315 apply(simp add: wcode_fourtimes_invs)
       
  1316 done
       
  1317 
       
  1318 lemma [simp]: "wcode_right_move ires rs (b, Bk # list) \<Longrightarrow>  wcode_erase2 ires rs (Bk # b, list)"
       
  1319 apply(auto simp:wcode_fourtimes_invs )
       
  1320 apply(rule_tac x = ln in exI, rule_tac x = rn in exI, simp)
       
  1321 done
       
  1322 
       
  1323 lemma [simp]: "wcode_erase2 ires rs (b, Bk # list) \<Longrightarrow> b \<noteq> []"
       
  1324 apply(auto simp: wcode_fourtimes_invs)
       
  1325 done
       
  1326 
       
  1327 lemma [simp]: "wcode_erase2 ires rs (b, Bk # list) \<Longrightarrow> wcode_on_right_moving_2 ires rs (Bk # b, list)"
       
  1328 apply(auto simp:wcode_fourtimes_invs )
       
  1329 apply(rule_tac x = "Suc (Suc 0)" in exI, simp add: exp_ind)
       
  1330 apply(rule_tac x =  "Suc (Suc ln)" in exI, simp add: exp_ind, auto)
       
  1331 done
       
  1332 
       
  1333 lemma [simp]: "wcode_on_right_moving_2 ires rs (b, Bk # list) \<Longrightarrow> b \<noteq> []"
       
  1334 apply(auto simp:wcode_fourtimes_invs )
       
  1335 done
       
  1336 
       
  1337 lemma [simp]: "wcode_on_right_moving_2 ires rs (b, Bk # list)
       
  1338        \<Longrightarrow> wcode_on_right_moving_2 ires rs (Bk # b, list)"
       
  1339 apply(auto simp: wcode_fourtimes_invs)
       
  1340 apply(rule_tac x = "Suc ml" in exI, simp add: exp_ind_def)
       
  1341 apply(rule_tac x = "mr - 1" in exI, case_tac mr, auto simp: exp_ind_def)
       
  1342 done
       
  1343 
       
  1344 lemma [simp]: "wcode_goon_right_moving_2 ires rs (b, Bk # list) \<Longrightarrow> b \<noteq> []"
       
  1345 apply(auto simp: wcode_fourtimes_invs)
       
  1346 done
       
  1347 
       
  1348 lemma [simp]: "wcode_goon_right_moving_2 ires rs (b, Bk # list) \<Longrightarrow> 
       
  1349                  wcode_backto_standard_pos_2 ires rs (b, Oc # list)"
       
  1350 apply(simp add: wcode_fourtimes_invs, auto)
       
  1351 apply(rule_tac x = ml in exI, auto)
       
  1352 apply(rule_tac x = "Suc 0" in exI, simp)
       
  1353 apply(case_tac mr, simp_all add: exp_ind_def)
       
  1354 apply(rule_tac x = "rn - 1" in exI, simp)
       
  1355 apply(case_tac rn, simp, simp add: exp_ind_def)
       
  1356 done
       
  1357    
       
  1358 lemma  [simp]: "wcode_backto_standard_pos_2 ires rs (b, Bk # list) \<Longrightarrow>  b \<noteq> []"
       
  1359 apply(simp add: wcode_fourtimes_invs, auto)
       
  1360 done
       
  1361 
       
  1362 lemma [simp]: "wcode_on_left_moving_2 ires rs (b, Oc # list) \<Longrightarrow> b \<noteq> []"
       
  1363 apply(simp add: wcode_fourtimes_invs, auto)
       
  1364 done
       
  1365 
       
  1366 lemma [simp]: "wcode_on_left_moving_2 ires rs (b, Oc # list) \<Longrightarrow> 
       
  1367                      wcode_on_checking_2 ires rs (tl b, hd b # Oc # list)"
       
  1368 apply(auto simp: wcode_fourtimes_invs)
       
  1369 apply(case_tac [!] mr, simp_all add: exp_ind_def)
       
  1370 done
       
  1371 
       
  1372 lemma [simp]: "wcode_goon_right_moving_2 ires rs (b, []) \<Longrightarrow> b \<noteq> []"
       
  1373 apply(auto simp: wcode_fourtimes_invs)
       
  1374 done
       
  1375 
       
  1376 lemma [simp]: "wcode_goon_right_moving_2 ires rs (b, []) \<Longrightarrow>
       
  1377               wcode_backto_standard_pos_2 ires rs (b, [Oc])"
       
  1378 apply(simp only: wcode_fourtimes_invs)
       
  1379 apply(erule_tac exE)+
       
  1380 apply(rule_tac disjI1)
       
  1381 apply(rule_tac x = ml in exI, rule_tac x = "Suc 0" in exI, 
       
  1382       rule_tac x = ln in exI, rule_tac x = rn in exI, simp)
       
  1383 apply(case_tac mr, simp, simp add: exp_ind_def)
       
  1384 done
       
  1385 
       
  1386 lemma "wcode_backto_standard_pos_2 ires rs (b, Bk # list)
       
  1387        \<Longrightarrow> (\<exists>ln. b = Bk # Bk\<^bsup>ln\<^esup> @ Oc # ires) \<and> (\<exists>rn. list = Oc\<^bsup>Suc (Suc rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1388 apply(auto simp: wcode_fourtimes_invs)
       
  1389 apply(case_tac [!] mr, auto simp: exp_ind_def)
       
  1390 done
       
  1391 
       
  1392 
       
  1393 lemma [simp]: "wcode_on_checking_2 ires rs (b, Oc # list) \<Longrightarrow> False"
       
  1394 apply(simp add: wcode_fourtimes_invs)
       
  1395 done
       
  1396 
       
  1397 lemma [simp]: "wcode_goon_checking ires rs (b, Oc # list) \<Longrightarrow>
       
  1398   (b = [] \<longrightarrow> wcode_right_move ires rs ([Oc], list)) \<and>
       
  1399   (b \<noteq> [] \<longrightarrow> wcode_right_move ires rs (Oc # b, list))"
       
  1400 apply(simp only: wcode_fourtimes_invs)
       
  1401 apply(erule_tac exE)+
       
  1402 apply(auto)
       
  1403 done
       
  1404 
       
  1405 lemma [simp]: "wcode_right_move ires rs (b, Oc # list) = False"
       
  1406 apply(auto simp: wcode_fourtimes_invs)
       
  1407 done
       
  1408 
       
  1409 lemma [simp]: " wcode_erase2 ires rs (b, Oc # list) \<Longrightarrow> b \<noteq> []"
       
  1410 apply(simp add: wcode_fourtimes_invs)
       
  1411 done
       
  1412 
       
  1413 lemma [simp]: "wcode_erase2 ires rs (b, Oc # list)
       
  1414        \<Longrightarrow> wcode_erase2 ires rs (b, Bk # list)"
       
  1415 apply(auto simp: wcode_fourtimes_invs)
       
  1416 done
       
  1417 
       
  1418 lemma [simp]: "wcode_on_right_moving_2 ires rs (b, Oc # list) \<Longrightarrow> b \<noteq> []"
       
  1419 apply(simp only: wcode_fourtimes_invs)
       
  1420 apply(auto)
       
  1421 done
       
  1422 
       
  1423 lemma [simp]: "wcode_on_right_moving_2 ires rs (b, Oc # list)
       
  1424        \<Longrightarrow> wcode_goon_right_moving_2 ires rs (Oc # b, list)"
       
  1425 apply(auto simp: wcode_fourtimes_invs)
       
  1426 apply(case_tac mr, simp_all add: exp_ind_def)
       
  1427 apply(rule_tac x = "Suc 0" in exI, auto)
       
  1428 apply(rule_tac x = "ml - 2" in exI)
       
  1429 apply(case_tac ml, simp, case_tac nat, simp_all add: exp_ind_def)
       
  1430 done
       
  1431 
       
  1432 lemma [simp]: "wcode_goon_right_moving_2 ires rs (b, Oc # list) \<Longrightarrow> b \<noteq> []"
       
  1433 apply(simp only:wcode_fourtimes_invs, auto)
       
  1434 done
       
  1435 
       
  1436 lemma [simp]: "wcode_backto_standard_pos_2 ires rs (b, Bk # list)
       
  1437        \<Longrightarrow> (\<exists>ln. b = Bk # Bk\<^bsup>ln\<^esup> @ Oc # ires) \<and> (\<exists>rn. list = Oc\<^bsup>Suc (Suc rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1438 apply(simp add: wcode_fourtimes_invs, auto)
       
  1439 apply(case_tac [!] mr, simp_all add: exp_ind_def)
       
  1440 done
       
  1441 
       
  1442 lemma [simp]: "wcode_on_checking_2 ires rs (b, Oc # list) = False"
       
  1443 apply(simp add: wcode_fourtimes_invs)
       
  1444 done
       
  1445 
       
  1446 lemma [simp]: "wcode_goon_right_moving_2 ires rs (b, Oc # list) \<Longrightarrow>
       
  1447        wcode_goon_right_moving_2 ires rs (Oc # b, list)"
       
  1448 apply(simp only:wcode_fourtimes_invs, auto)
       
  1449 apply(rule_tac x = "Suc ml" in exI, auto simp: exp_ind_def)
       
  1450 apply(rule_tac x = "mr - 1" in exI)
       
  1451 apply(case_tac mr, case_tac rn, auto simp: exp_ind_def)
       
  1452 done
       
  1453 
       
  1454 lemma [simp]: "wcode_backto_standard_pos_2 ires rs (b, Oc # list) \<Longrightarrow> b \<noteq> []"
       
  1455 apply(simp only: wcode_fourtimes_invs, auto)
       
  1456 done
       
  1457  
       
  1458 lemma [simp]: "wcode_backto_standard_pos_2 ires rs (b, Oc # list)    
       
  1459             \<Longrightarrow> wcode_backto_standard_pos_2 ires rs (tl b, hd b # Oc # list)"
       
  1460 apply(simp only: wcode_fourtimes_invs)
       
  1461 apply(erule_tac disjE)
       
  1462 apply(erule_tac exE)+
       
  1463 apply(case_tac ml, simp)
       
  1464 apply(rule_tac disjI2)
       
  1465 apply(rule_tac conjI, rule_tac x = ln in exI, simp)
       
  1466 apply(rule_tac x = rn in exI, simp)
       
  1467 apply(rule_tac disjI1)
       
  1468 apply(rule_tac x = nat in exI, rule_tac x = "Suc mr" in exI, 
       
  1469       rule_tac x = ln in exI, rule_tac x = rn in exI, simp add: exp_ind_def)
       
  1470 apply(simp)
       
  1471 done
       
  1472 
       
  1473 lemma wcode_fourtimes_case_first_correctness:
       
  1474  shows "let P = (\<lambda> (st, l, r). st = t_twice_len + 14) in 
       
  1475   let Q = (\<lambda> (st, l, r). wcode_fourtimes_case_inv st ires rs (l, r)) in 
       
  1476   let f = (\<lambda> stp. steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc # Bk # Oc # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stp) in
       
  1477   \<exists> n .P (f n) \<and> Q (f (n::nat))"
       
  1478 proof -
       
  1479   let ?P = "(\<lambda> (st, l, r). st = t_twice_len + 14)"
       
  1480   let ?Q = "(\<lambda> (st, l, r). wcode_fourtimes_case_inv st ires rs (l, r))"
       
  1481   let ?f = "(\<lambda> stp. steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc # Bk # Oc # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stp)"
       
  1482   have "\<exists> n . ?P (?f n) \<and> ?Q (?f (n::nat))"
       
  1483   proof(rule_tac halt_lemma2)
       
  1484     show "wf wcode_fourtimes_case_le"
       
  1485       by auto
       
  1486   next
       
  1487     show "\<forall> na. \<not> ?P (?f na) \<and> ?Q (?f na) \<longrightarrow>
       
  1488                   ?Q (?f (Suc na)) \<and> (?f (Suc na), ?f na) \<in> wcode_fourtimes_case_le"
       
  1489     apply(rule_tac allI,
       
  1490      case_tac "steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc # Bk # Oc # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main na", simp,
       
  1491      rule_tac impI)
       
  1492     apply(simp add: tstep_red tstep.simps, case_tac c, simp, case_tac [2] aa, simp_all)
       
  1493     
       
  1494     apply(simp_all add: wcode_fourtimes_case_inv.simps new_tape.simps 
       
  1495                         wcode_fourtimes_case_le_def lex_pair_def split: if_splits)
       
  1496     done
       
  1497   next
       
  1498     show "?Q (?f 0)"
       
  1499       apply(simp add: steps.simps wcode_fourtimes_case_inv.simps)
       
  1500       apply(simp add: wcode_on_left_moving_2.simps wcode_on_left_moving_2_B.simps 
       
  1501                       wcode_on_left_moving_2_O.simps)
       
  1502       apply(rule_tac x = "Suc m" in exI, simp add: exp_ind_def)
       
  1503       apply(rule_tac x ="Suc 0" in exI, auto)
       
  1504       done
       
  1505   next
       
  1506     show "\<not> ?P (?f 0)"
       
  1507       apply(simp add: steps.simps)
       
  1508       done
       
  1509   qed
       
  1510   thus "?thesis"
       
  1511     apply(erule_tac exE, simp)
       
  1512     done
       
  1513 qed
       
  1514 
       
  1515 definition t_fourtimes_len :: "nat"
       
  1516   where
       
  1517   "t_fourtimes_len = (length t_fourtimes div 2)"
       
  1518 
       
  1519 lemma t_fourtimes_len_gr:  "t_fourtimes_len > 0"
       
  1520 apply(simp add: t_fourtimes_len_def t_fourtimes_def)
       
  1521 done
       
  1522 
       
  1523 lemma t_fourtimes_correct: 
       
  1524   "\<exists>stp ln rn. steps (Suc 0, Bk # Bk # ires, Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) 
       
  1525     (tm_of abc_fourtimes @ tMp (Suc 0) (start_of fourtimes_ly (length abc_fourtimes) - Suc 0)) stp =
       
  1526        (0, Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires, Oc\<^bsup>Suc (4 * rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1527 proof(case_tac "rec_ci rec_fourtimes")
       
  1528   fix a b c
       
  1529   assume h: "rec_ci rec_fourtimes = (a, b, c)"
       
  1530   have "\<exists>stp m l. steps (Suc 0, Bk # Bk # ires, <[rs]> @ Bk\<^bsup>n\<^esup>) (tm_of abc_fourtimes @ tMp (Suc 0) 
       
  1531     (start_of fourtimes_ly (length abc_fourtimes) - 1)) stp = (0, Bk\<^bsup>m\<^esup> @ Bk # Bk # ires, Oc\<^bsup>Suc (4*rs)\<^esup> @ Bk\<^bsup>l\<^esup>)"
       
  1532   proof(rule_tac t_compiled_by_rec)
       
  1533     show "rec_ci rec_fourtimes = (a, b, c)" by (simp add: h)
       
  1534   next
       
  1535     show "rec_calc_rel rec_fourtimes [rs] (4 * rs)"
       
  1536       using prime_rel_exec_eq [of rec_fourtimes "[rs]" "4 * rs"]
       
  1537       apply(subgoal_tac "primerec rec_fourtimes (length [rs])")
       
  1538       apply(simp_all add: rec_fourtimes_def rec_exec.simps)
       
  1539       apply(auto)
       
  1540       apply(simp only: Nat.One_nat_def[THEN sym], auto)
       
  1541       done
       
  1542   next
       
  1543     show "length [rs] = Suc 0" by simp
       
  1544   next
       
  1545     show "layout_of (a [+] dummy_abc (Suc 0)) = layout_of (a [+] dummy_abc (Suc 0))"
       
  1546       by simp
       
  1547   next
       
  1548     show "start_of fourtimes_ly (length abc_fourtimes) = 
       
  1549       start_of (layout_of (a [+] dummy_abc (Suc 0))) (length (a [+] dummy_abc (Suc 0)))"
       
  1550       using h
       
  1551       apply(simp add: fourtimes_ly_def abc_fourtimes_def)
       
  1552       done
       
  1553   next
       
  1554     show "tm_of abc_fourtimes = tm_of (a [+] dummy_abc (Suc 0))"
       
  1555       using h
       
  1556       apply(simp add: abc_fourtimes_def)
       
  1557       done
       
  1558   qed
       
  1559   thus "\<exists>stp ln rn. steps (Suc 0, Bk # Bk # ires, Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) 
       
  1560             (tm_of abc_fourtimes @ tMp (Suc 0) (start_of fourtimes_ly (length abc_fourtimes) - Suc 0)) stp =
       
  1561        (0, Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires, Oc\<^bsup>Suc (4 * rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1562     apply(simp add: tape_of_nl_abv tape_of_nat_list.simps)
       
  1563     done
       
  1564 qed
       
  1565 
       
  1566 lemma t_fourtimes_change_term_state:
       
  1567   "\<exists> stp ln rn. steps (Suc 0, Bk # Bk # ires, Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_fourtimes stp
       
  1568      = (Suc t_fourtimes_len, Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires, Oc\<^bsup>Suc (4 * rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1569 using t_fourtimes_correct[of ires rs n]
       
  1570 apply(erule_tac exE)
       
  1571 apply(erule_tac exE)
       
  1572 apply(erule_tac exE)
       
  1573 proof(drule_tac turing_change_termi_state)
       
  1574   fix stp ln rn
       
  1575   show "t_correct (tm_of abc_fourtimes @ tMp (Suc 0) 
       
  1576     (start_of fourtimes_ly (length abc_fourtimes) - Suc 0))"
       
  1577     apply(rule_tac t_compiled_correct, auto simp: fourtimes_ly_def)
       
  1578     done
       
  1579 next
       
  1580   fix stp ln rn
       
  1581   show "\<exists>stp. steps (Suc 0, Bk # Bk # ires, Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>)
       
  1582     (change_termi_state (tm_of abc_fourtimes @ tMp (Suc 0) 
       
  1583         (start_of fourtimes_ly (length abc_fourtimes) - Suc 0))) stp =
       
  1584     (Suc (length (tm_of abc_fourtimes @ tMp (Suc 0) (start_of fourtimes_ly 
       
  1585     (length abc_fourtimes) - Suc 0)) div 2), Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires, Oc\<^bsup>Suc (4 * rs)\<^esup> @ Bk\<^bsup>rn\<^esup>) \<Longrightarrow>
       
  1586     \<exists>stp ln rn. steps (Suc 0, Bk # Bk # ires, Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_fourtimes stp =
       
  1587     (Suc t_fourtimes_len, Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires, Oc\<^bsup>Suc (4 * rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1588     apply(erule_tac exE)
       
  1589     apply(simp add: t_fourtimes_len_def t_fourtimes_def)
       
  1590     apply(rule_tac x = stp in exI, rule_tac x = ln in exI, rule_tac x = rn in exI, simp)
       
  1591     done
       
  1592 qed
       
  1593 
       
  1594 lemma t_fourtimes_append_pre:
       
  1595   "steps (Suc 0, Bk # Bk # ires, Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_fourtimes stp
       
  1596   = (Suc t_fourtimes_len, Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires, Oc\<^bsup>Suc (4 * rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)
       
  1597    \<Longrightarrow> \<exists> stp>0. steps (Suc 0 + length (t_wcode_main_first_part @ 
       
  1598               tshift t_twice (length t_wcode_main_first_part div 2) @ [(L, 1), (L, 1)]) div 2,
       
  1599        Bk # Bk # ires, Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>)
       
  1600      ((t_wcode_main_first_part @ 
       
  1601   tshift t_twice (length t_wcode_main_first_part div 2) @ [(L, 1), (L, 1)]) @ 
       
  1602   tshift t_fourtimes (length (t_wcode_main_first_part @ 
       
  1603   tshift t_twice (length t_wcode_main_first_part div 2) @ [(L, 1), (L, 1)]) div 2) @ ([(L, 1), (L, 1)])) stp 
       
  1604   = (Suc t_fourtimes_len + length (t_wcode_main_first_part @ 
       
  1605   tshift t_twice (length t_wcode_main_first_part div 2) @ [(L, 1), (L, 1)]) div 2,
       
  1606   Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires, Oc\<^bsup>Suc (4 * rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1607 proof(rule_tac t_tshift_lemma, auto)
       
  1608   assume "steps (Suc 0, Bk # Bk # ires, Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_fourtimes stp =
       
  1609     (Suc t_fourtimes_len, Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires, Oc\<^bsup>Suc (4 * rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1610   thus "0 < stp"
       
  1611     using t_fourtimes_len_gr
       
  1612     apply(case_tac stp, simp_all add: steps.simps)
       
  1613     done
       
  1614 next
       
  1615   show "Suc 0 \<le> length t_fourtimes div 2"
       
  1616     apply(simp add: t_fourtimes_def shift_length tMp.simps)
       
  1617     done
       
  1618 next
       
  1619   show "t_ncorrect (t_wcode_main_first_part @ 
       
  1620     abacus.tshift t_twice (length t_wcode_main_first_part div 2) @ 
       
  1621     [(L, Suc 0), (L, Suc 0)])"
       
  1622     apply(simp add: t_ncorrect.simps t_wcode_main_first_part_def shift_length
       
  1623                     t_twice_def)
       
  1624     using tm_even[of abc_twice]
       
  1625     by arith
       
  1626 next
       
  1627   show "t_ncorrect t_fourtimes"
       
  1628     apply(simp add: t_fourtimes_def steps.simps t_ncorrect.simps)
       
  1629     using tm_even[of abc_fourtimes]
       
  1630     by arith
       
  1631 next
       
  1632   show "t_ncorrect [(L, Suc 0), (L, Suc 0)]"
       
  1633     apply(simp add: t_ncorrect.simps)
       
  1634     done
       
  1635 qed
       
  1636 
       
  1637 lemma [simp]: "length t_wcode_main_first_part = 24"
       
  1638 apply(simp add: t_wcode_main_first_part_def)
       
  1639 done
       
  1640 
       
  1641 lemma [simp]: "(26 + length t_twice) div 2 = (length t_twice) div 2 + 13"
       
  1642 using tm_even[of abc_twice]
       
  1643 apply(simp add: t_twice_def)
       
  1644 done
       
  1645 
       
  1646 lemma [simp]: "((26 + length (abacus.tshift t_twice 12)) div 2)
       
  1647              = (length (abacus.tshift t_twice 12) div 2 + 13)"
       
  1648 using tm_even[of abc_twice]
       
  1649 apply(simp add: t_twice_def)
       
  1650 done 
       
  1651 
       
  1652 lemma [simp]: "t_twice_len + 14 =  14 + length (abacus.tshift t_twice 12) div 2"
       
  1653 using tm_even[of abc_twice]
       
  1654 apply(simp add: t_twice_def t_twice_len_def shift_length)
       
  1655 done
       
  1656 
       
  1657 lemma t_fourtimes_append:
       
  1658   "\<exists> stp ln rn. 
       
  1659   steps (Suc 0 + length (t_wcode_main_first_part @ tshift t_twice
       
  1660   (length t_wcode_main_first_part div 2) @ [(L, 1), (L, 1)]) div 2, 
       
  1661   Bk # Bk # ires, Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>)
       
  1662   ((t_wcode_main_first_part @ tshift t_twice (length t_wcode_main_first_part div 2) @
       
  1663   [(L, 1), (L, 1)]) @ tshift t_fourtimes (t_twice_len + 13) @ [(L, 1), (L, 1)]) stp 
       
  1664   = (Suc t_fourtimes_len + length (t_wcode_main_first_part @ tshift t_twice
       
  1665   (length t_wcode_main_first_part div 2) @ [(L, 1), (L, 1)]) div 2, Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires,
       
  1666                                                                  Oc\<^bsup>Suc (4 * rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1667   using t_fourtimes_change_term_state[of ires rs n]
       
  1668   apply(erule_tac exE)
       
  1669   apply(erule_tac exE)
       
  1670   apply(erule_tac exE)
       
  1671   apply(drule_tac t_fourtimes_append_pre)
       
  1672   apply(erule_tac exE)
       
  1673   apply(rule_tac x = stpa in exI, rule_tac x = ln in exI, rule_tac x = rn in exI)
       
  1674   apply(simp add: t_twice_len_def shift_length)
       
  1675   done
       
  1676 
       
  1677 lemma t_wcode_main_len: "length t_wcode_main = length t_twice + length t_fourtimes + 28"
       
  1678 apply(simp add: t_wcode_main_def shift_length)
       
  1679 done
       
  1680  
       
  1681 lemma [simp]: "fetch t_wcode_main (14 + length t_twice div 2 + t_fourtimes_len) b
       
  1682              = (L, Suc 0)"
       
  1683 using tm_even[of "abc_twice"] tm_even[of "abc_fourtimes"]
       
  1684 apply(case_tac b)
       
  1685 apply(simp_all only: fetch.simps)
       
  1686 apply(auto simp: nth_of.simps t_wcode_main_len t_twice_len_def
       
  1687                  t_fourtimes_def t_twice_def t_fourtimes_def t_fourtimes_len_def)
       
  1688 apply(auto simp: t_wcode_main_def t_wcode_main_first_part_def shift_length t_twice_def nth_append 
       
  1689                     t_fourtimes_def)
       
  1690 done
       
  1691 
       
  1692 lemma wcode_jump2: 
       
  1693   "\<exists> stp ln rn. steps (t_twice_len + 14 + t_fourtimes_len
       
  1694   , Bk # Bk # Bk\<^bsup>lnb\<^esup> @ Oc # ires, Oc\<^bsup>Suc (4 * rs + 4)\<^esup> @ Bk\<^bsup>rnb\<^esup>) t_wcode_main stp =
       
  1695   (Suc 0, Bk # Bk\<^bsup>ln\<^esup> @ Oc # ires, Bk # Oc\<^bsup>Suc (4 * rs + 4)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1696 apply(rule_tac x = "Suc 0" in exI)
       
  1697 apply(simp add: steps.simps shift_length)
       
  1698 apply(rule_tac x = lnb in exI, rule_tac x = rnb in exI)
       
  1699 apply(simp add: tstep.simps new_tape.simps)
       
  1700 done
       
  1701 
       
  1702 lemma wcode_fourtimes_case:
       
  1703   shows "\<exists>stp ln rn.
       
  1704   steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc # Bk # Oc # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stp =
       
  1705   (Suc 0, Bk # Bk\<^bsup>ln\<^esup> @ Oc # ires, Bk # Oc\<^bsup>Suc (4*rs + 4)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1706 proof -
       
  1707   have "\<exists>stp ln rn.
       
  1708   steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc # Bk # Oc # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stp =
       
  1709   (t_twice_len + 14, Bk # Bk # Bk\<^bsup>ln\<^esup> @ Oc # ires, Oc\<^bsup>Suc (rs + 1)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1710     using wcode_fourtimes_case_first_correctness[of ires rs m n]
       
  1711     apply(simp add: wcode_fourtimes_case_inv.simps, auto)
       
  1712     apply(rule_tac x = na in exI, rule_tac x = ln in exI,
       
  1713           rule_tac x = rn in exI)
       
  1714     apply(simp)
       
  1715     done
       
  1716   from this obtain stpa lna rna where stp1:
       
  1717     "steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc # Bk # Oc # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stpa =
       
  1718   (t_twice_len + 14, Bk # Bk # Bk\<^bsup>lna\<^esup> @ Oc # ires, Oc\<^bsup>Suc (rs + 1)\<^esup> @ Bk\<^bsup>rna\<^esup>)" by blast
       
  1719   have "\<exists>stp ln rn. steps (t_twice_len + 14, Bk # Bk # Bk\<^bsup>lna\<^esup> @ Oc # ires, Oc\<^bsup>Suc (rs + 1)\<^esup> @ Bk\<^bsup>rna\<^esup>)
       
  1720                      t_wcode_main stp =
       
  1721           (t_twice_len + 14 + t_fourtimes_len, Bk # Bk # Bk\<^bsup>ln\<^esup> @ Oc # ires,  Oc\<^bsup>Suc (4*rs + 4)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1722     using t_fourtimes_append[of " Bk\<^bsup>lna\<^esup> @ Oc # ires" "rs + 1" rna]
       
  1723     apply(erule_tac exE)
       
  1724     apply(erule_tac exE)
       
  1725     apply(erule_tac exE)
       
  1726     apply(simp add: t_wcode_main_def)
       
  1727     apply(rule_tac x = stp in exI, 
       
  1728           rule_tac x = "ln + lna" in exI,
       
  1729           rule_tac x = rn in exI, simp)
       
  1730     apply(simp add: exp_ind_def[THEN sym] exp_add[THEN sym])
       
  1731     done
       
  1732   from this obtain stpb lnb rnb where stp2:
       
  1733     "steps (t_twice_len + 14, Bk # Bk # Bk\<^bsup>lna\<^esup> @ Oc # ires, Oc\<^bsup>Suc (rs + 1)\<^esup> @ Bk\<^bsup>rna\<^esup>)
       
  1734                      t_wcode_main stpb =
       
  1735        (t_twice_len + 14 + t_fourtimes_len, Bk # Bk # Bk\<^bsup>lnb\<^esup> @ Oc # ires,  Oc\<^bsup>Suc (4*rs + 4)\<^esup> @ Bk\<^bsup>rnb\<^esup>)"
       
  1736     by blast
       
  1737   have "\<exists>stp ln rn. steps (t_twice_len + 14 + t_fourtimes_len,
       
  1738     Bk # Bk # Bk\<^bsup>lnb\<^esup> @ Oc # ires,  Oc\<^bsup>Suc (4*rs + 4)\<^esup> @ Bk\<^bsup>rnb\<^esup>)
       
  1739     t_wcode_main stp =
       
  1740     (Suc 0, Bk # Bk\<^bsup>ln\<^esup> @ Oc # ires, Bk # Oc\<^bsup>Suc (4*rs + 4)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1741     apply(rule wcode_jump2)
       
  1742     done
       
  1743   from this obtain stpc lnc rnc where stp3: 
       
  1744     "steps (t_twice_len + 14 + t_fourtimes_len,
       
  1745     Bk # Bk # Bk\<^bsup>lnb\<^esup> @ Oc # ires,  Oc\<^bsup>Suc (4*rs + 4)\<^esup> @ Bk\<^bsup>rnb\<^esup>)
       
  1746     t_wcode_main stpc =
       
  1747     (Suc 0, Bk # Bk\<^bsup>lnc\<^esup> @ Oc # ires, Bk # Oc\<^bsup>Suc (4*rs + 4)\<^esup> @ Bk\<^bsup>rnc\<^esup>)"
       
  1748     by blast
       
  1749   from stp1 stp2 stp3 show "?thesis"
       
  1750     apply(rule_tac x = "stpa + stpb + stpc" in exI,
       
  1751           rule_tac x = lnc in exI, rule_tac x = rnc in exI)
       
  1752     apply(simp add: steps_add)
       
  1753     done
       
  1754 qed
       
  1755 
       
  1756 (**********************************************************)
       
  1757 
       
  1758 fun wcode_on_left_moving_3_B :: "bin_inv_t"
       
  1759   where
       
  1760   "wcode_on_left_moving_3_B ires rs (l, r) = 
       
  1761        (\<exists> ml mr rn. l = Bk\<^bsup>ml\<^esup> @ Oc # Bk # Bk # ires \<and>
       
  1762                     r = Bk\<^bsup>mr\<^esup> @ Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>rn\<^esup> \<and> 
       
  1763                     ml + mr > Suc 0 \<and> mr > 0 )"
       
  1764 
       
  1765 fun wcode_on_left_moving_3_O :: "bin_inv_t"
       
  1766   where
       
  1767   "wcode_on_left_moving_3_O ires rs (l, r) = 
       
  1768          (\<exists> ln rn. l = Bk # Bk # ires \<and>
       
  1769                    r = Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1770 
       
  1771 fun wcode_on_left_moving_3 :: "bin_inv_t"
       
  1772   where
       
  1773   "wcode_on_left_moving_3 ires rs (l, r) = 
       
  1774        (wcode_on_left_moving_3_B ires rs (l, r) \<or>  
       
  1775         wcode_on_left_moving_3_O ires rs (l, r))"
       
  1776 
       
  1777 fun wcode_on_checking_3 :: "bin_inv_t"
       
  1778   where
       
  1779   "wcode_on_checking_3 ires rs (l, r) = 
       
  1780          (\<exists> ln rn. l = Bk # ires \<and>
       
  1781              r = Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1782 
       
  1783 fun wcode_goon_checking_3 :: "bin_inv_t"
       
  1784   where
       
  1785   "wcode_goon_checking_3 ires rs (l, r) = 
       
  1786          (\<exists> ln rn. l = ires \<and>
       
  1787              r = Bk # Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1788 
       
  1789 fun wcode_stop :: "bin_inv_t"
       
  1790   where
       
  1791   "wcode_stop ires rs (l, r) = 
       
  1792           (\<exists> ln rn. l = Bk # ires \<and>
       
  1793              r = Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1794 
       
  1795 fun wcode_halt_case_inv :: "nat \<Rightarrow> bin_inv_t"
       
  1796   where
       
  1797   "wcode_halt_case_inv st ires rs (l, r) = 
       
  1798           (if st = 0 then wcode_stop ires rs (l, r)
       
  1799            else if st = Suc 0 then wcode_on_left_moving_3 ires rs (l, r)
       
  1800            else if st = Suc (Suc 0) then wcode_on_checking_3 ires rs (l, r)
       
  1801            else if st = 7 then wcode_goon_checking_3 ires rs (l, r)
       
  1802            else False)"
       
  1803 
       
  1804 fun wcode_halt_case_state :: "t_conf \<Rightarrow> nat"
       
  1805   where
       
  1806   "wcode_halt_case_state (st, l, r) = 
       
  1807            (if st = 1 then 5
       
  1808             else if st = Suc (Suc 0) then 4
       
  1809             else if st = 7 then 3
       
  1810             else 0)"
       
  1811 
       
  1812 fun wcode_halt_case_step :: "t_conf \<Rightarrow> nat"
       
  1813   where
       
  1814   "wcode_halt_case_step (st, l, r) = 
       
  1815          (if st = 1 then length l
       
  1816          else 0)"
       
  1817 
       
  1818 fun wcode_halt_case_measure :: "t_conf \<Rightarrow> nat \<times> nat"
       
  1819   where
       
  1820   "wcode_halt_case_measure (st, l, r) = 
       
  1821      (wcode_halt_case_state (st, l, r), 
       
  1822       wcode_halt_case_step (st, l, r))"
       
  1823 
       
  1824 definition wcode_halt_case_le :: "(t_conf \<times> t_conf) set"
       
  1825   where "wcode_halt_case_le \<equiv> (inv_image lex_pair wcode_halt_case_measure)"
       
  1826 
       
  1827 lemma wf_wcode_halt_case_le[intro]: "wf wcode_halt_case_le"
       
  1828 by(auto intro:wf_inv_image simp: wcode_halt_case_le_def)
       
  1829 
       
  1830 declare wcode_on_left_moving_3_B.simps[simp del] wcode_on_left_moving_3_O.simps[simp del]  
       
  1831         wcode_on_checking_3.simps[simp del] wcode_goon_checking_3.simps[simp del] 
       
  1832         wcode_on_left_moving_3.simps[simp del] wcode_stop.simps[simp del]
       
  1833 
       
  1834 lemmas wcode_halt_invs = 
       
  1835   wcode_on_left_moving_3_B.simps wcode_on_left_moving_3_O.simps
       
  1836   wcode_on_checking_3.simps wcode_goon_checking_3.simps 
       
  1837   wcode_on_left_moving_3.simps wcode_stop.simps
       
  1838 
       
  1839 lemma [simp]: "fetch t_wcode_main 7 Bk = (R, 0)"
       
  1840 apply(simp add: fetch.simps t_wcode_main_def nth_append nth_of.simps
       
  1841                 t_wcode_main_first_part_def)
       
  1842 done
       
  1843 
       
  1844 lemma [simp]: "wcode_on_left_moving_3 ires rs (b, [])  = False"
       
  1845 apply(simp only: wcode_halt_invs)
       
  1846 apply(simp add: exp_ind_def)
       
  1847 done    
       
  1848 
       
  1849 lemma [simp]: "wcode_on_checking_3 ires rs (b, []) = False"
       
  1850 apply(simp add: wcode_halt_invs)
       
  1851 done
       
  1852               
       
  1853 lemma [simp]: "wcode_goon_checking_3 ires rs (b, []) = False"
       
  1854 apply(simp add: wcode_halt_invs)
       
  1855 done 
       
  1856 
       
  1857 lemma [simp]: "wcode_on_left_moving_3 ires rs (b, Bk # list)
       
  1858  \<Longrightarrow> wcode_on_left_moving_3 ires rs (tl b, hd b # Bk # list)"
       
  1859 apply(simp only: wcode_halt_invs)
       
  1860 apply(erule_tac disjE)
       
  1861 apply(erule_tac exE)+
       
  1862 apply(case_tac ml, simp)
       
  1863 apply(rule_tac x = "mr - 2" in exI, rule_tac x = rn in exI)
       
  1864 apply(case_tac mr, simp, simp add: exp_ind, simp add: exp_ind[THEN sym])
       
  1865 apply(rule_tac disjI1)
       
  1866 apply(rule_tac x = nat in exI, rule_tac x = "Suc mr" in exI, 
       
  1867       rule_tac x = rn in exI, simp add: exp_ind_def)
       
  1868 apply(simp)
       
  1869 done
       
  1870 
       
  1871 lemma [simp]: "wcode_goon_checking_3 ires rs (b, Bk # list) \<Longrightarrow> 
       
  1872   (b = [] \<longrightarrow> wcode_stop ires rs ([Bk], list)) \<and>
       
  1873   (b \<noteq> [] \<longrightarrow> wcode_stop ires rs (Bk # b, list))"
       
  1874 apply(auto simp: wcode_halt_invs)
       
  1875 done
       
  1876 
       
  1877 lemma [simp]: "wcode_on_left_moving_3 ires rs (b, Oc # list) \<Longrightarrow> b \<noteq> []"
       
  1878 apply(auto simp: wcode_halt_invs)
       
  1879 done
       
  1880 
       
  1881 lemma [simp]: "wcode_on_left_moving_3 ires rs (b, Oc # list) \<Longrightarrow> 
       
  1882                wcode_on_checking_3 ires rs (tl b, hd b # Oc # list)"
       
  1883 apply(simp add:wcode_halt_invs, auto)
       
  1884 apply(case_tac [!] mr, simp_all add: exp_ind_def)
       
  1885 done     
       
  1886 
       
  1887 lemma [simp]: "wcode_on_checking_3 ires rs (b, Oc # list) = False"
       
  1888 apply(auto simp: wcode_halt_invs)
       
  1889 done
       
  1890 
       
  1891 lemma [simp]: "wcode_on_left_moving_3 ires rs (b, Bk # list) \<Longrightarrow> b \<noteq> []"
       
  1892 apply(simp add: wcode_halt_invs, auto)
       
  1893 done
       
  1894 
       
  1895 
       
  1896 lemma [simp]: "wcode_on_checking_3 ires rs (b, Bk # list) \<Longrightarrow> b \<noteq> []"
       
  1897 apply(auto simp: wcode_halt_invs)
       
  1898 done
       
  1899 
       
  1900 lemma [simp]: "wcode_on_checking_3 ires rs (b, Bk # list) \<Longrightarrow> 
       
  1901   wcode_goon_checking_3 ires rs (tl b, hd b # Bk # list)"
       
  1902 apply(auto simp: wcode_halt_invs)
       
  1903 done
       
  1904 
       
  1905 lemma [simp]: "wcode_goon_checking_3 ires rs (b, Oc # list) = False"
       
  1906 apply(simp add: wcode_goon_checking_3.simps)
       
  1907 done
       
  1908 
       
  1909 lemma t_halt_case_correctness: 
       
  1910 shows "let P = (\<lambda> (st, l, r). st = 0) in 
       
  1911        let Q = (\<lambda> (st, l, r). wcode_halt_case_inv st ires rs (l, r)) in 
       
  1912        let f = (\<lambda> stp. steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc # Bk # Bk # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stp) in
       
  1913        \<exists> n .P (f n) \<and> Q (f (n::nat))"
       
  1914 proof -
       
  1915   let ?P = "(\<lambda> (st, l, r). st = 0)"
       
  1916   let ?Q = "(\<lambda> (st, l, r). wcode_halt_case_inv st ires rs (l, r))"
       
  1917   let ?f = "(\<lambda> stp. steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc # Bk # Bk # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stp)"
       
  1918   have "\<exists> n. ?P (?f n) \<and> ?Q (?f (n::nat))"
       
  1919   proof(rule_tac halt_lemma2)
       
  1920     show "wf wcode_halt_case_le" by auto
       
  1921   next
       
  1922     show "\<forall> na. \<not> ?P (?f na) \<and> ?Q (?f na) \<longrightarrow> 
       
  1923                     ?Q (?f (Suc na)) \<and> (?f (Suc na), ?f na) \<in> wcode_halt_case_le"
       
  1924       apply(rule_tac allI, rule_tac impI, case_tac "?f na")
       
  1925       apply(simp add: tstep_red tstep.simps)
       
  1926       apply(case_tac c, simp, case_tac [2] aa)
       
  1927       apply(simp_all split: if_splits add: new_tape.simps wcode_halt_case_le_def lex_pair_def)
       
  1928       done      
       
  1929   next 
       
  1930     show "?Q (?f 0)"
       
  1931       apply(simp add: steps.simps wcode_halt_invs)
       
  1932       apply(rule_tac x = "Suc m" in exI, simp add: exp_ind_def)
       
  1933       apply(rule_tac x = "Suc 0" in exI, auto)
       
  1934       done
       
  1935   next
       
  1936     show "\<not> ?P (?f 0)"
       
  1937       apply(simp add: steps.simps)
       
  1938       done
       
  1939   qed
       
  1940   thus "?thesis"
       
  1941     apply(auto)
       
  1942     done
       
  1943 qed
       
  1944 
       
  1945 declare wcode_halt_case_inv.simps[simp del]
       
  1946 lemma [intro]: "\<exists> xs. (<rev list @ [aa::nat]> :: block list) = Oc # xs"
       
  1947 apply(case_tac "rev list", simp)
       
  1948 apply(simp add: tape_of_nat_abv tape_of_nat_list.simps exp_ind_def)
       
  1949 apply(case_tac list, simp, simp)
       
  1950 done
       
  1951 
       
  1952 lemma wcode_halt_case:
       
  1953   "\<exists>stp ln rn. steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc # Bk # Bk # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>)
       
  1954   t_wcode_main stp  = (0, Bk # ires, Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1955   using t_halt_case_correctness[of ires rs m n]
       
  1956 apply(simp)
       
  1957 apply(erule_tac exE)
       
  1958 apply(case_tac "steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc # Bk # Bk # ires,
       
  1959                 Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main na")
       
  1960 apply(auto simp: wcode_halt_case_inv.simps wcode_stop.simps)
       
  1961 apply(rule_tac x = na in exI, rule_tac x = ln in exI, 
       
  1962       rule_tac x = rn in exI, simp)
       
  1963 done
       
  1964 
       
  1965 lemma bl_bin_one: "bl_bin [Oc] =  Suc 0"
       
  1966 apply(simp add: bl_bin.simps)
       
  1967 done
       
  1968 
       
  1969 lemma t_wcode_main_lemma_pre:
       
  1970   "\<lbrakk>args \<noteq> []; lm = <args::nat list>\<rbrakk> \<Longrightarrow> 
       
  1971        \<exists> stp ln rn. steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ rev lm @ Bk # Bk # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main
       
  1972                     stp
       
  1973       = (0, Bk # ires, Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>bl_bin lm + rs * 2^(length lm - 1) \<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1974 proof(induct "length args" arbitrary: args lm rs m n, simp)
       
  1975   fix x args lm rs m n
       
  1976   assume ind:
       
  1977     "\<And>args lm rs m n.
       
  1978     \<lbrakk>x = length args; (args::nat list) \<noteq> []; lm = <args>\<rbrakk>
       
  1979     \<Longrightarrow> \<exists>stp ln rn.
       
  1980     steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ rev lm @ Bk # Bk # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stp =
       
  1981     (0, Bk # ires, Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>bl_bin lm + rs * 2 ^ (length lm - 1)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1982   
       
  1983     and h: "Suc x = length args" "(args::nat list) \<noteq> []" "lm = <args>"
       
  1984   from h have "\<exists> (a::nat) xs. args = xs @ [a]"
       
  1985     apply(rule_tac x = "last args" in exI)
       
  1986     apply(rule_tac x = "butlast args" in exI, auto)
       
  1987     done    
       
  1988   from this obtain a xs where "args = xs @ [a]" by blast
       
  1989   from h and this show
       
  1990     "\<exists>stp ln rn.
       
  1991     steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ rev lm @ Bk # Bk # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stp =
       
  1992     (0, Bk # ires, Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>bl_bin lm + rs * 2 ^ (length lm - 1)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1993   proof(case_tac "xs::nat list", simp)
       
  1994     show "\<exists>stp ln rn.
       
  1995       steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ rev (<a>) @ Bk # Bk # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stp =
       
  1996       (0, Bk # ires, Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>bl_bin (<a>) + rs * 2 ^ a\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  1997     proof(induct "a" arbitrary: m n rs ires, simp)
       
  1998       fix m n rs ires
       
  1999       show "\<exists>stp ln rn. steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc # Bk # Bk # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>)
       
  2000         t_wcode_main stp  = (0, Bk # ires, Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>bl_bin [Oc] + rs\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  2001         apply(simp add: bl_bin_one)
       
  2002         apply(rule_tac wcode_halt_case)
       
  2003         done
       
  2004     next
       
  2005       fix a m n rs ires
       
  2006       assume ind2: 
       
  2007         "\<And>m n rs ires.
       
  2008         \<exists>stp ln rn.
       
  2009         steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ rev (<a>) @ Bk # Bk # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stp =
       
  2010         (0, Bk # ires, Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>bl_bin (<a>) + rs * 2 ^ a\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  2011       show "\<exists>stp ln rn.
       
  2012         steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ rev (<Suc a>) @ Bk # Bk # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stp =
       
  2013         (0, Bk # ires, Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>bl_bin (<Suc a>) + rs * 2 ^ Suc a\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  2014       proof -
       
  2015         have "\<exists>stp ln rn.
       
  2016           steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ rev (<Suc a>) @ Bk # Bk # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stp =
       
  2017           (Suc 0, Bk # Bk\<^bsup>ln\<^esup> @ rev (<a>) @ Bk # Bk # ires, Bk # Oc\<^bsup>Suc (2 * rs + 2)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  2018           apply(simp add: tape_of_nat)
       
  2019           using wcode_double_case[of m "Oc\<^bsup>a\<^esup> @ Bk # Bk # ires" rs n]
       
  2020           apply(simp add: exp_ind_def)
       
  2021           done
       
  2022         from this obtain stpa lna rna where stp1:  
       
  2023           "steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ rev (<Suc a>) @ Bk # Bk # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stpa =
       
  2024           (Suc 0, Bk # Bk\<^bsup>lna\<^esup> @ rev (<a>) @ Bk # Bk # ires, Bk # Oc\<^bsup>Suc (2 * rs + 2)\<^esup> @ Bk\<^bsup>rna\<^esup>)" by blast
       
  2025         moreover have 
       
  2026           "\<exists>stp ln rn.
       
  2027           steps (Suc 0,  Bk # Bk\<^bsup>lna\<^esup> @ rev (<a>) @ Bk # Bk # ires, Bk # Oc\<^bsup>Suc (2 * rs + 2)\<^esup> @ Bk\<^bsup>rna\<^esup>) t_wcode_main stp =
       
  2028           (0, Bk # ires, Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>bl_bin (<a>) + (2*rs + 2)  * 2 ^ a\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  2029           using ind2[of lna ires "2*rs + 2" rna] by simp   
       
  2030         from this obtain stpb lnb rnb where stp2:  
       
  2031           "steps (Suc 0,  Bk # Bk\<^bsup>lna\<^esup> @ rev (<a>) @ Bk # Bk # ires, Bk # Oc\<^bsup>Suc (2 * rs + 2)\<^esup> @ Bk\<^bsup>rna\<^esup>) t_wcode_main stpb =
       
  2032           (0, Bk # ires, Bk # Oc # Bk\<^bsup>lnb\<^esup> @ Bk # Bk # Oc\<^bsup>bl_bin (<a>) + (2*rs + 2)  * 2 ^ a\<^esup> @ Bk\<^bsup>rnb\<^esup>)"
       
  2033           by blast
       
  2034         from stp1 and stp2 show "?thesis"
       
  2035           apply(rule_tac x = "stpa + stpb" in exI,
       
  2036             rule_tac x = lnb in exI, rule_tac x = rnb in exI, simp)
       
  2037           apply(simp add: steps_add bl_bin_nat_Suc exponent_def)
       
  2038           done
       
  2039       qed
       
  2040     qed
       
  2041   next
       
  2042     fix aa list
       
  2043     assume g: "Suc x = length args" "args \<noteq> []" "lm = <args>" "args = xs @ [a::nat]" "xs = (aa::nat) # list"
       
  2044     thus "\<exists>stp ln rn. steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ rev lm @ Bk # Bk # ires, Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stp =
       
  2045       (0, Bk # ires, Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>bl_bin lm + rs * 2 ^ (length lm - 1)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  2046     proof(induct a arbitrary: m n rs args lm, simp_all add: tape_of_nl_rev, 
       
  2047         simp only: tape_of_nl_cons_app1, simp)
       
  2048       fix m n rs args lm
       
  2049       have "\<exists>stp ln rn.
       
  2050         steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc # Bk # rev (<(aa::nat) # list>) @ Bk # Bk # ires,
       
  2051         Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stp =
       
  2052         (Suc 0, Bk # Bk\<^bsup>ln\<^esup> @ rev (<aa # list>) @ Bk # Bk # ires, 
       
  2053         Bk # Oc\<^bsup>Suc (4*rs + 4)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  2054         proof(simp add: tape_of_nl_rev)
       
  2055           have "\<exists> xs. (<rev list @ [aa]>) = Oc # xs" by auto           
       
  2056           from this obtain xs where "(<rev list @ [aa]>) = Oc # xs" ..
       
  2057           thus "\<exists>stp ln rn.
       
  2058             steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc # Bk # <rev list @ [aa]> @ Bk # Bk # ires,
       
  2059             Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stp =
       
  2060             (Suc 0, Bk # Bk\<^bsup>ln\<^esup> @ <rev list @ [aa]> @ Bk # Bk # ires, Bk # Oc\<^bsup>5 + 4 * rs\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  2061             apply(simp)
       
  2062             using wcode_fourtimes_case[of m "xs @ Bk # Bk # ires" rs n]
       
  2063             apply(simp)
       
  2064             done
       
  2065         qed
       
  2066       from this obtain stpa lna rna where stp1:
       
  2067         "steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc # Bk # rev (<aa # list>) @ Bk # Bk # ires,
       
  2068         Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stpa =
       
  2069         (Suc 0, Bk # Bk\<^bsup>lna\<^esup> @ rev (<aa # list>) @ Bk # Bk # ires, 
       
  2070         Bk # Oc\<^bsup>Suc (4*rs + 4)\<^esup> @ Bk\<^bsup>rna\<^esup>)" by blast
       
  2071       from g have 
       
  2072         "\<exists> stp ln rn. steps (Suc 0, Bk # Bk\<^bsup>lna\<^esup> @ rev (<(aa::nat) # list>) @ Bk # Bk # ires, 
       
  2073         Bk # Oc\<^bsup>Suc (4*rs + 4)\<^esup> @ Bk\<^bsup>rna\<^esup>) t_wcode_main stp = (0, Bk # ires, 
       
  2074         Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>bl_bin (<aa#list>)+ (4*rs + 4) * 2^(length (<aa#list>) - 1) \<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  2075          apply(rule_tac args = "(aa::nat)#list" in ind, simp_all)
       
  2076          done
       
  2077        from this obtain stpb lnb rnb where stp2:
       
  2078          "steps (Suc 0, Bk # Bk\<^bsup>lna\<^esup> @ rev (<(aa::nat) # list>) @ Bk # Bk # ires, 
       
  2079          Bk # Oc\<^bsup>Suc (4*rs + 4)\<^esup> @ Bk\<^bsup>rna\<^esup>) t_wcode_main stpb = (0, Bk # ires, 
       
  2080          Bk # Oc # Bk\<^bsup>lnb\<^esup> @ Bk # Bk # Oc\<^bsup>bl_bin (<aa#list>)+ (4*rs + 4) * 2^(length (<aa#list>) - 1) \<^esup> @ Bk\<^bsup>rnb\<^esup>)"
       
  2081          by blast
       
  2082        from stp1 and stp2 and h
       
  2083        show "\<exists>stp ln rn.
       
  2084          steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc # Bk # <rev list @ [aa]> @ Bk # Bk # ires,
       
  2085          Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stp =
       
  2086          (0, Bk # ires, Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk #
       
  2087          Bk # Oc\<^bsup>bl_bin (Oc\<^bsup>Suc aa\<^esup> @ Bk # <list @ [0]>) + rs * (2 * 2 ^ (aa + length (<list @ [0]>)))\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  2088          apply(rule_tac x = "stpa + stpb" in exI, rule_tac x = lnb in exI,
       
  2089            rule_tac x = rnb in exI, simp add: steps_add tape_of_nl_rev)
       
  2090          done
       
  2091      next
       
  2092        fix ab m n rs args lm
       
  2093        assume ind2:
       
  2094          "\<And> m n rs args lm.
       
  2095          \<lbrakk>lm = <aa # list @ [ab]>; args = aa # list @ [ab]\<rbrakk>
       
  2096          \<Longrightarrow> \<exists>stp ln rn.
       
  2097          steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ <ab # rev list @ [aa]> @ Bk # Bk # ires,
       
  2098          Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stp =
       
  2099          (0, Bk # ires, Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk #
       
  2100          Bk # Oc\<^bsup>bl_bin (<aa # list @ [ab]>) + rs * 2 ^ (length (<aa # list @ [ab]>) - Suc 0)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  2101          and k: "args = aa # list @ [Suc ab]" "lm = <aa # list @ [Suc ab]>"
       
  2102        show "\<exists>stp ln rn.
       
  2103          steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ <Suc ab # rev list @ [aa]> @ Bk # Bk # ires,
       
  2104          Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stp =
       
  2105          (0, Bk # ires,Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # 
       
  2106          Bk # Oc\<^bsup>bl_bin (<aa # list @ [Suc ab]>) + rs * 2 ^ (length (<aa # list @ [Suc ab]>) - Suc 0)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  2107        proof(simp add: tape_of_nl_cons_app1)
       
  2108          have "\<exists>stp ln rn.
       
  2109            steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc\<^bsup>Suc (Suc ab)\<^esup> @ Bk # <rev list @ [aa]> @ Bk # Bk # ires, 
       
  2110            Bk # Oc # Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stp
       
  2111            = (Suc 0, Bk # Bk\<^bsup>ln\<^esup> @ Oc\<^bsup>Suc ab\<^esup> @ Bk # <rev list @ [aa]> @ Bk # Bk # ires,
       
  2112            Bk # Oc\<^bsup>Suc (2*rs + 2)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  2113            using wcode_double_case[of m "Oc\<^bsup>ab\<^esup> @ Bk # <rev list @ [aa]> @ Bk # Bk # ires"
       
  2114                                       rs n]
       
  2115            apply(simp add: exp_ind_def)
       
  2116            done
       
  2117          from this obtain stpa lna rna where stp1:
       
  2118            "steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc\<^bsup>Suc (Suc ab)\<^esup> @ Bk # <rev list @ [aa]> @ Bk # Bk # ires, 
       
  2119            Bk # Oc # Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stpa
       
  2120            = (Suc 0, Bk # Bk\<^bsup>lna\<^esup> @ Oc\<^bsup>Suc ab\<^esup> @ Bk # <rev list @ [aa]> @ Bk # Bk # ires,
       
  2121            Bk # Oc\<^bsup>Suc (2*rs + 2)\<^esup> @ Bk\<^bsup>rna\<^esup>)" by blast
       
  2122          from k have 
       
  2123            "\<exists> stp ln rn. steps (Suc 0, Bk # Bk\<^bsup>lna\<^esup> @ <ab # rev list @ [aa]> @ Bk # Bk # ires,
       
  2124            Bk # Oc\<^bsup>Suc (2*rs + 2)\<^esup> @ Bk\<^bsup>rna\<^esup>) t_wcode_main stp
       
  2125            = (0, Bk # ires, Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk #
       
  2126            Bk # Oc\<^bsup>bl_bin (<aa # list @ [ab]> ) +  (2*rs + 2)* 2^(length (<aa # list @ [ab]>) - Suc 0)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  2127            apply(rule_tac ind2, simp_all)
       
  2128            done
       
  2129          from this obtain stpb lnb rnb where stp2: 
       
  2130            "steps (Suc 0, Bk # Bk\<^bsup>lna\<^esup> @  <ab # rev list @ [aa]> @ Bk # Bk # ires,
       
  2131            Bk # Oc\<^bsup>Suc (2*rs + 2)\<^esup> @ Bk\<^bsup>rna\<^esup>) t_wcode_main stpb
       
  2132            = (0, Bk # ires, Bk # Oc # Bk\<^bsup>lnb\<^esup> @ Bk #
       
  2133            Bk # Oc\<^bsup>bl_bin (<aa # list @ [ab]> ) +  (2*rs + 2)* 2^(length (<aa # list @ [ab]>) - Suc 0)\<^esup> @ Bk\<^bsup>rnb\<^esup>)" 
       
  2134            by blast
       
  2135          from stp1 and stp2 show 
       
  2136            "\<exists>stp ln rn.
       
  2137            steps (Suc 0, Bk # Bk\<^bsup>m\<^esup> @ Oc\<^bsup>Suc (Suc ab)\<^esup> @ Bk # <rev list @ [aa]> @ Bk # Bk # ires,
       
  2138            Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>) t_wcode_main stp =
       
  2139            (0, Bk # ires, Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # 
       
  2140            Oc\<^bsup>bl_bin (Oc\<^bsup>Suc aa\<^esup> @ Bk # <list @ [Suc ab]>) + rs * (2 * 2 ^ (aa + length (<list @ [Suc ab]>)))\<^esup> 
       
  2141            @ Bk\<^bsup>rn\<^esup>)"
       
  2142            apply(rule_tac x = "stpa + stpb" in exI, rule_tac x = lnb in exI,
       
  2143              rule_tac x = rnb in exI, simp add: steps_add tape_of_nl_cons_app1 exp_ind_def)
       
  2144            done
       
  2145        qed
       
  2146      qed
       
  2147    qed
       
  2148  qed
       
  2149 
       
  2150 
       
  2151          
       
  2152 (* turing_shift can be used*)
       
  2153 term t_wcode_main
       
  2154 definition t_wcode_prepare :: "tprog"
       
  2155   where
       
  2156   "t_wcode_prepare \<equiv> 
       
  2157          [(W1, 2), (L, 1), (L, 3), (R, 2), (R, 4), (W0, 3),
       
  2158           (R, 4), (R, 5), (R, 6), (R, 5), (R, 7), (R, 5),
       
  2159           (W1, 7), (L, 0)]"
       
  2160 
       
  2161 fun wprepare_add_one :: "nat \<Rightarrow> nat list \<Rightarrow> tape \<Rightarrow> bool"
       
  2162   where
       
  2163   "wprepare_add_one m lm (l, r) = 
       
  2164       (\<exists> rn. l = [] \<and>
       
  2165                (r = <m # lm> @ Bk\<^bsup>rn\<^esup> \<or> 
       
  2166                 r = Bk # <m # lm> @ Bk\<^bsup>rn\<^esup>))"
       
  2167 
       
  2168 fun wprepare_goto_first_end :: "nat \<Rightarrow> nat list \<Rightarrow> tape \<Rightarrow> bool"
       
  2169   where
       
  2170   "wprepare_goto_first_end m lm (l, r) = 
       
  2171       (\<exists> ml mr rn. l = Oc\<^bsup>ml\<^esup> \<and>
       
  2172                       r = Oc\<^bsup>mr\<^esup> @ Bk # <lm> @ Bk\<^bsup>rn\<^esup> \<and>
       
  2173                       ml + mr = Suc (Suc m))"
       
  2174 
       
  2175 fun wprepare_erase :: "nat \<Rightarrow> nat list \<Rightarrow> tape \<Rightarrow>  bool"
       
  2176   where
       
  2177   "wprepare_erase m lm (l, r) = 
       
  2178      (\<exists> rn. l = Oc\<^bsup>Suc m\<^esup> \<and> 
       
  2179                tl r = Bk # <lm> @ Bk\<^bsup>rn\<^esup>)"
       
  2180 
       
  2181 fun wprepare_goto_start_pos_B :: "nat \<Rightarrow> nat list \<Rightarrow> tape \<Rightarrow> bool"
       
  2182   where
       
  2183   "wprepare_goto_start_pos_B m lm (l, r) = 
       
  2184      (\<exists> rn. l = Bk # Oc\<^bsup>Suc m\<^esup> \<and>
       
  2185                r = Bk # <lm> @ Bk\<^bsup>rn\<^esup>)"
       
  2186 
       
  2187 fun wprepare_goto_start_pos_O :: "nat \<Rightarrow> nat list \<Rightarrow> tape \<Rightarrow> bool"
       
  2188   where
       
  2189   "wprepare_goto_start_pos_O m lm (l, r) = 
       
  2190      (\<exists> rn. l = Bk # Bk # Oc\<^bsup>Suc m\<^esup> \<and>
       
  2191                r = <lm> @ Bk\<^bsup>rn\<^esup>)"
       
  2192 
       
  2193 fun wprepare_goto_start_pos :: "nat \<Rightarrow> nat list \<Rightarrow> tape \<Rightarrow> bool"
       
  2194   where
       
  2195   "wprepare_goto_start_pos m lm (l, r) = 
       
  2196        (wprepare_goto_start_pos_B m lm (l, r) \<or>
       
  2197         wprepare_goto_start_pos_O m lm (l, r))"
       
  2198 
       
  2199 fun wprepare_loop_start_on_rightmost :: "nat \<Rightarrow> nat list \<Rightarrow> tape \<Rightarrow> bool"
       
  2200   where
       
  2201   "wprepare_loop_start_on_rightmost m lm (l, r) = 
       
  2202      (\<exists> rn mr. rev l @ r = Oc\<^bsup>Suc m\<^esup> @ Bk # Bk # <lm> @ Bk\<^bsup>rn\<^esup> \<and> l \<noteq> [] \<and>
       
  2203                        r = Oc\<^bsup>mr\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  2204 
       
  2205 fun wprepare_loop_start_in_middle :: "nat \<Rightarrow> nat list \<Rightarrow> tape \<Rightarrow> bool"
       
  2206   where
       
  2207   "wprepare_loop_start_in_middle m lm (l, r) =
       
  2208      (\<exists> rn (mr:: nat) (lm1::nat list). 
       
  2209   rev l @ r = Oc\<^bsup>Suc m\<^esup> @ Bk # Bk # <lm> @ Bk\<^bsup>rn\<^esup> \<and> l \<noteq> [] \<and>
       
  2210   r = Oc\<^bsup>mr\<^esup> @ Bk # <lm1> @ Bk\<^bsup>rn\<^esup> \<and> lm1 \<noteq> [])"
       
  2211 
       
  2212 fun wprepare_loop_start :: "nat \<Rightarrow> nat list \<Rightarrow> tape \<Rightarrow> bool"
       
  2213   where
       
  2214   "wprepare_loop_start m lm (l, r) = (wprepare_loop_start_on_rightmost m lm (l, r) \<or> 
       
  2215                                       wprepare_loop_start_in_middle m lm (l, r))"
       
  2216 
       
  2217 fun wprepare_loop_goon_on_rightmost :: "nat \<Rightarrow> nat list \<Rightarrow> tape \<Rightarrow> bool"
       
  2218   where
       
  2219   "wprepare_loop_goon_on_rightmost m lm (l, r) = 
       
  2220      (\<exists> rn. l = Bk # <rev lm> @ Bk # Bk # Oc\<^bsup>Suc m\<^esup> \<and>
       
  2221                r = Bk\<^bsup>rn\<^esup>)"
       
  2222 
       
  2223 fun wprepare_loop_goon_in_middle :: "nat \<Rightarrow> nat list \<Rightarrow> tape \<Rightarrow> bool"
       
  2224   where
       
  2225   "wprepare_loop_goon_in_middle m lm (l, r) = 
       
  2226      (\<exists> rn (mr:: nat) (lm1::nat list). 
       
  2227   rev l @ r = Oc\<^bsup>Suc m\<^esup> @ Bk # Bk # <lm> @ Bk\<^bsup>rn\<^esup> \<and> l \<noteq> [] \<and>
       
  2228                      (if lm1 = [] then r = Oc\<^bsup>mr\<^esup> @ Bk\<^bsup>rn\<^esup> 
       
  2229                      else r = Oc\<^bsup>mr\<^esup> @ Bk # <lm1> @ Bk\<^bsup>rn\<^esup>) \<and> mr > 0)"
       
  2230 
       
  2231 fun wprepare_loop_goon :: "nat \<Rightarrow> nat list \<Rightarrow> tape \<Rightarrow> bool"
       
  2232   where
       
  2233   "wprepare_loop_goon m lm (l, r) = 
       
  2234               (wprepare_loop_goon_in_middle m lm (l, r) \<or> 
       
  2235                wprepare_loop_goon_on_rightmost m lm (l, r))"
       
  2236 
       
  2237 fun wprepare_add_one2 :: "nat \<Rightarrow> nat list \<Rightarrow> tape \<Rightarrow> bool"
       
  2238   where
       
  2239   "wprepare_add_one2 m lm (l, r) =
       
  2240           (\<exists> rn. l = Bk # Bk # <rev lm> @ Bk # Bk # Oc\<^bsup>Suc m\<^esup> \<and>
       
  2241                (r = [] \<or> tl r = Bk\<^bsup>rn\<^esup>))"
       
  2242 
       
  2243 fun wprepare_stop :: "nat \<Rightarrow> nat list \<Rightarrow> tape \<Rightarrow> bool"
       
  2244   where
       
  2245   "wprepare_stop m lm (l, r) = 
       
  2246          (\<exists> rn. l = Bk # <rev lm> @ Bk # Bk # Oc\<^bsup>Suc m\<^esup> \<and>
       
  2247                r = Bk # Oc # Bk\<^bsup>rn\<^esup>)"
       
  2248 
       
  2249 fun wprepare_inv :: "nat \<Rightarrow> nat \<Rightarrow> nat list \<Rightarrow> tape \<Rightarrow> bool"
       
  2250   where
       
  2251   "wprepare_inv st m lm (l, r) = 
       
  2252         (if st = 0 then wprepare_stop m lm (l, r) 
       
  2253          else if st = Suc 0 then wprepare_add_one m lm (l, r)
       
  2254          else if st = Suc (Suc 0) then wprepare_goto_first_end m lm (l, r)
       
  2255          else if st = Suc (Suc (Suc 0)) then wprepare_erase m lm (l, r)
       
  2256          else if st = 4 then wprepare_goto_start_pos m lm (l, r)
       
  2257          else if st = 5 then wprepare_loop_start m lm (l, r)
       
  2258          else if st = 6 then wprepare_loop_goon m lm (l, r)
       
  2259          else if st = 7 then wprepare_add_one2 m lm (l, r)
       
  2260          else False)"
       
  2261 
       
  2262 fun wprepare_stage :: "t_conf \<Rightarrow> nat"
       
  2263   where
       
  2264   "wprepare_stage (st, l, r) = 
       
  2265       (if st \<ge> 1 \<and> st \<le> 4 then 3
       
  2266        else if st = 5 \<or> st = 6 then 2
       
  2267        else 1)"
       
  2268 
       
  2269 fun wprepare_state :: "t_conf \<Rightarrow> nat"
       
  2270   where
       
  2271   "wprepare_state (st, l, r) = 
       
  2272        (if st = 1 then 4
       
  2273         else if st = Suc (Suc 0) then 3
       
  2274         else if st = Suc (Suc (Suc 0)) then 2
       
  2275         else if st = 4 then 1
       
  2276         else if st = 7 then 2
       
  2277         else 0)"
       
  2278 
       
  2279 fun wprepare_step :: "t_conf \<Rightarrow> nat"
       
  2280   where
       
  2281   "wprepare_step (st, l, r) = 
       
  2282       (if st = 1 then (if hd r = Oc then Suc (length l)
       
  2283                        else 0)
       
  2284        else if st = Suc (Suc 0) then length r
       
  2285        else if st = Suc (Suc (Suc 0)) then (if hd r = Oc then 1
       
  2286                             else 0)
       
  2287        else if st = 4 then length r
       
  2288        else if st = 5 then Suc (length r)
       
  2289        else if st = 6 then (if r = [] then 0 else Suc (length r))
       
  2290        else if st = 7 then (if (r \<noteq> [] \<and> hd r = Oc) then 0
       
  2291                             else 1)
       
  2292        else 0)"
       
  2293 
       
  2294 fun wcode_prepare_measure :: "t_conf \<Rightarrow> nat \<times> nat \<times> nat"
       
  2295   where
       
  2296   "wcode_prepare_measure (st, l, r) = 
       
  2297      (wprepare_stage (st, l, r), 
       
  2298       wprepare_state (st, l, r), 
       
  2299       wprepare_step (st, l, r))"
       
  2300 
       
  2301 definition wcode_prepare_le :: "(t_conf \<times> t_conf) set"
       
  2302   where "wcode_prepare_le \<equiv> (inv_image lex_triple wcode_prepare_measure)"
       
  2303 
       
  2304 lemma [intro]: "wf lex_pair"
       
  2305 by(auto intro:wf_lex_prod simp:lex_pair_def)
       
  2306 
       
  2307 lemma wf_wcode_prepare_le[intro]: "wf wcode_prepare_le"
       
  2308 by(auto intro:wf_inv_image simp: wcode_prepare_le_def 
       
  2309            recursive.lex_triple_def)
       
  2310 
       
  2311 declare wprepare_add_one.simps[simp del] wprepare_goto_first_end.simps[simp del]
       
  2312         wprepare_erase.simps[simp del] wprepare_goto_start_pos.simps[simp del]
       
  2313         wprepare_loop_start.simps[simp del] wprepare_loop_goon.simps[simp del]
       
  2314         wprepare_add_one2.simps[simp del]
       
  2315 
       
  2316 lemmas wprepare_invs = wprepare_add_one.simps wprepare_goto_first_end.simps
       
  2317         wprepare_erase.simps wprepare_goto_start_pos.simps
       
  2318         wprepare_loop_start.simps wprepare_loop_goon.simps
       
  2319         wprepare_add_one2.simps
       
  2320 
       
  2321 declare wprepare_inv.simps[simp del]
       
  2322 lemma [simp]: "fetch t_wcode_prepare (Suc 0) Bk = (W1, 2)"
       
  2323 apply(simp add: fetch.simps t_wcode_prepare_def nth_of.simps)
       
  2324 done
       
  2325 
       
  2326 lemma [simp]: "fetch t_wcode_prepare (Suc 0) Oc = (L, 1)"
       
  2327 apply(simp add: fetch.simps t_wcode_prepare_def nth_of.simps)
       
  2328 done
       
  2329 
       
  2330 lemma [simp]: "fetch t_wcode_prepare (Suc (Suc 0)) Bk = (L, 3)"
       
  2331 apply(simp add: fetch.simps t_wcode_prepare_def nth_of.simps)
       
  2332 done
       
  2333 
       
  2334 lemma [simp]: "fetch t_wcode_prepare (Suc (Suc 0)) Oc = (R, 2)"
       
  2335 apply(simp add: fetch.simps t_wcode_prepare_def nth_of.simps)
       
  2336 done
       
  2337 
       
  2338 lemma [simp]: "fetch t_wcode_prepare (Suc (Suc (Suc 0))) Bk = (R, 4)"
       
  2339 apply(simp add: fetch.simps t_wcode_prepare_def nth_of.simps)
       
  2340 done
       
  2341 
       
  2342 lemma [simp]: "fetch t_wcode_prepare (Suc (Suc (Suc 0))) Oc = (W0, 3)"
       
  2343 apply(simp add: fetch.simps t_wcode_prepare_def nth_of.simps)
       
  2344 done
       
  2345 
       
  2346 lemma [simp]: "fetch t_wcode_prepare 4 Bk = (R, 4)"
       
  2347 apply(simp add: fetch.simps t_wcode_prepare_def nth_of.simps)
       
  2348 done
       
  2349 
       
  2350 lemma [simp]: "fetch t_wcode_prepare 4 Oc = (R, 5)"
       
  2351 apply(simp add: fetch.simps t_wcode_prepare_def nth_of.simps)
       
  2352 done
       
  2353 
       
  2354 lemma [simp]: "fetch t_wcode_prepare 5 Oc = (R, 5)"
       
  2355 apply(simp add: fetch.simps t_wcode_prepare_def nth_of.simps)
       
  2356 done
       
  2357 
       
  2358 lemma [simp]: "fetch t_wcode_prepare 5 Bk = (R, 6)"
       
  2359 apply(simp add: fetch.simps t_wcode_prepare_def nth_of.simps)
       
  2360 done
       
  2361 
       
  2362 lemma [simp]: "fetch t_wcode_prepare 6 Oc = (R, 5)"
       
  2363 apply(simp add: fetch.simps t_wcode_prepare_def nth_of.simps)
       
  2364 done
       
  2365 
       
  2366 lemma [simp]: "fetch t_wcode_prepare 6 Bk = (R, 7)"
       
  2367 apply(simp add: fetch.simps t_wcode_prepare_def nth_of.simps)
       
  2368 done
       
  2369 
       
  2370 lemma [simp]: "fetch t_wcode_prepare 7 Oc = (L, 0)"
       
  2371 apply(simp add: fetch.simps t_wcode_prepare_def nth_of.simps)
       
  2372 done
       
  2373 
       
  2374 lemma [simp]: "fetch t_wcode_prepare 7 Bk = (W1, 7)"
       
  2375 apply(simp add: fetch.simps t_wcode_prepare_def nth_of.simps)
       
  2376 done
       
  2377 
       
  2378 lemma tape_of_nl_not_null: "lm \<noteq> [] \<Longrightarrow> <lm::nat list> \<noteq> []"
       
  2379 apply(case_tac lm, auto)
       
  2380 apply(case_tac list, auto simp: tape_of_nl_abv tape_of_nat_list.simps exp_ind_def)
       
  2381 done
       
  2382 
       
  2383 lemma [simp]: "lm \<noteq> [] \<Longrightarrow> wprepare_add_one m lm (b, []) = False"
       
  2384 apply(simp add: wprepare_invs)
       
  2385 apply(simp add: tape_of_nl_not_null)
       
  2386 done
       
  2387 
       
  2388 lemma [simp]: "lm \<noteq> [] \<Longrightarrow> wprepare_goto_first_end m lm (b, []) = False"
       
  2389 apply(simp add: wprepare_invs)
       
  2390 done
       
  2391 
       
  2392 lemma [simp]: "lm \<noteq> [] \<Longrightarrow> wprepare_erase m lm (b, []) = False"
       
  2393 apply(simp add: wprepare_invs)
       
  2394 done
       
  2395 
       
  2396 
       
  2397 
       
  2398 lemma [simp]: "lm \<noteq> [] \<Longrightarrow> wprepare_goto_start_pos m lm (b, []) = False"
       
  2399 apply(simp add: wprepare_invs tape_of_nl_not_null)
       
  2400 done
       
  2401 
       
  2402 lemma [simp]: "\<lbrakk>lm \<noteq> []; wprepare_loop_start m lm (b, [])\<rbrakk> \<Longrightarrow> b \<noteq> []"
       
  2403 apply(simp add: wprepare_invs tape_of_nl_not_null, auto)
       
  2404 done
       
  2405 
       
  2406 lemma [simp]: "\<lbrakk>lm \<noteq> []; wprepare_loop_start m lm (b, [])\<rbrakk> \<Longrightarrow> 
       
  2407                                   wprepare_loop_goon m lm (Bk # b, [])"
       
  2408 apply(simp only: wprepare_invs tape_of_nl_not_null)
       
  2409 apply(erule_tac disjE)
       
  2410 apply(rule_tac disjI2)
       
  2411 apply(simp add: wprepare_loop_start_on_rightmost.simps
       
  2412                 wprepare_loop_goon_on_rightmost.simps, auto)
       
  2413 apply(rule_tac rev_eq, simp add: tape_of_nl_rev)
       
  2414 done
       
  2415 
       
  2416 lemma [simp]: "\<lbrakk>lm \<noteq> []; wprepare_loop_goon m lm (b, [])\<rbrakk> \<Longrightarrow> b \<noteq> []"
       
  2417 apply(simp only: wprepare_invs tape_of_nl_not_null, auto)
       
  2418 done
       
  2419 
       
  2420 lemma [simp]:"\<lbrakk>lm \<noteq> []; wprepare_loop_goon m lm (b, [])\<rbrakk> \<Longrightarrow> 
       
  2421   wprepare_add_one2 m lm (Bk # b, [])"
       
  2422 apply(simp only: wprepare_invs tape_of_nl_not_null, auto split: if_splits)
       
  2423 apply(case_tac mr, simp, simp add: exp_ind_def)
       
  2424 done
       
  2425 
       
  2426 lemma [simp]: "wprepare_add_one2 m lm (b, []) \<Longrightarrow> b \<noteq> []"
       
  2427 apply(simp only: wprepare_invs tape_of_nl_not_null, auto)
       
  2428 done
       
  2429 
       
  2430 lemma [simp]: "wprepare_add_one2 m lm (b, []) \<Longrightarrow> wprepare_add_one2 m lm (b, [Oc])"
       
  2431 apply(simp only: wprepare_invs tape_of_nl_not_null, auto)
       
  2432 done
       
  2433 
       
  2434 lemma [simp]: "Bk # list = <(m::nat) # lm> @ ys = False"
       
  2435 apply(case_tac lm, auto simp: tape_of_nl_abv tape_of_nat_list.simps exp_ind_def)
       
  2436 done
       
  2437 
       
  2438 lemma [simp]: "\<lbrakk>lm \<noteq> []; wprepare_add_one m lm (b, Bk # list)\<rbrakk>
       
  2439        \<Longrightarrow> (b = [] \<longrightarrow> wprepare_goto_first_end m lm ([], Oc # list)) \<and> 
       
  2440            (b \<noteq> [] \<longrightarrow> wprepare_goto_first_end m lm (b, Oc # list))"
       
  2441 apply(simp only: wprepare_invs, auto)
       
  2442 apply(rule_tac x = 0 in exI, simp add: exp_ind_def)
       
  2443 apply(case_tac lm, simp, simp add: tape_of_nl_abv tape_of_nat_list.simps exp_ind_def)
       
  2444 apply(rule_tac x = rn in exI, simp)
       
  2445 done
       
  2446 
       
  2447 lemma [simp]: "wprepare_goto_first_end m lm (b, Bk # list) \<Longrightarrow> b \<noteq> []"
       
  2448 apply(simp only: wprepare_invs tape_of_nl_not_null, auto)
       
  2449 apply(case_tac mr, simp_all add: exp_ind_def)
       
  2450 done
       
  2451 
       
  2452 lemma [simp]: "wprepare_goto_first_end m lm (b, Bk # list) \<Longrightarrow>
       
  2453                           wprepare_erase m lm (tl b, hd b # Bk # list)"
       
  2454 apply(simp only: wprepare_invs tape_of_nl_not_null, auto)
       
  2455 apply(case_tac mr, simp_all add: exp_ind_def)
       
  2456 apply(case_tac mr, auto simp: exp_ind_def)
       
  2457 done
       
  2458 
       
  2459 lemma [simp]: "wprepare_erase m lm (b, Bk # list) \<Longrightarrow> b \<noteq> []"
       
  2460 apply(simp only: wprepare_invs exp_ind_def, auto)
       
  2461 done
       
  2462 
       
  2463 lemma [simp]: "wprepare_erase m lm (b, Bk # list) \<Longrightarrow> 
       
  2464                            wprepare_goto_start_pos m lm (Bk # b, list)"
       
  2465 apply(simp only: wprepare_invs, auto)
       
  2466 done
       
  2467 
       
  2468 lemma [simp]: "\<lbrakk>wprepare_add_one m lm (b, Bk # list)\<rbrakk> \<Longrightarrow> list \<noteq> []"
       
  2469 apply(simp only: wprepare_invs)
       
  2470 apply(case_tac lm, simp_all add: tape_of_nl_abv 
       
  2471                          tape_of_nat_list.simps exp_ind_def, auto)
       
  2472 done
       
  2473     
       
  2474 lemma [simp]: "\<lbrakk>lm \<noteq> [];  wprepare_goto_first_end m lm (b, Bk # list)\<rbrakk> \<Longrightarrow> list \<noteq> []"
       
  2475 apply(simp only: wprepare_invs, auto)
       
  2476 apply(case_tac mr, simp_all add: exp_ind_def)
       
  2477 apply(simp add: tape_of_nl_not_null)
       
  2478 done
       
  2479      
       
  2480 lemma [simp]: "\<lbrakk>lm \<noteq> [];  wprepare_goto_first_end m lm (b, Bk # list)\<rbrakk> \<Longrightarrow> b \<noteq> []"
       
  2481 apply(simp only: wprepare_invs, auto)
       
  2482 apply(case_tac mr, simp_all add: exp_ind_def tape_of_nl_not_null)
       
  2483 done
       
  2484 
       
  2485 lemma [simp]: "\<lbrakk>lm \<noteq> []; wprepare_erase m lm (b, Bk # list)\<rbrakk> \<Longrightarrow> list \<noteq> []"
       
  2486 apply(simp only: wprepare_invs, auto)
       
  2487 done
       
  2488 
       
  2489 lemma [simp]: "\<lbrakk>lm \<noteq> []; wprepare_erase m lm (b, Bk # list)\<rbrakk> \<Longrightarrow> b \<noteq> []"
       
  2490 apply(simp only: wprepare_invs, auto simp: exp_ind_def)
       
  2491 done
       
  2492 
       
  2493 lemma [simp]: "\<lbrakk>lm \<noteq> [];  wprepare_goto_start_pos m lm (b, Bk # list)\<rbrakk> \<Longrightarrow> list \<noteq> []"
       
  2494 apply(simp only: wprepare_invs, auto)
       
  2495 apply(simp add: tape_of_nl_not_null)
       
  2496 apply(case_tac lm, simp, case_tac list)
       
  2497 apply(simp_all add: tape_of_nl_abv tape_of_nat_list.simps exp_ind_def)
       
  2498 done
       
  2499 
       
  2500 lemma [simp]: "\<lbrakk>lm \<noteq> [];  wprepare_goto_start_pos m lm (b, Bk # list)\<rbrakk> \<Longrightarrow> b \<noteq> []"
       
  2501 apply(simp only: wprepare_invs)
       
  2502 apply(auto)
       
  2503 done
       
  2504 
       
  2505 lemma [simp]: "\<lbrakk>lm \<noteq> []; wprepare_loop_goon m lm (b, Bk # list)\<rbrakk> \<Longrightarrow> b \<noteq> []"
       
  2506 apply(simp only: wprepare_invs, auto)
       
  2507 done
       
  2508 
       
  2509 lemma [simp]: "\<lbrakk>lm \<noteq> []; wprepare_loop_goon m lm (b, Bk # list)\<rbrakk> \<Longrightarrow> 
       
  2510   (list = [] \<longrightarrow> wprepare_add_one2 m lm (Bk # b, [])) \<and> 
       
  2511   (list \<noteq> [] \<longrightarrow> wprepare_add_one2 m lm (Bk # b, list))"
       
  2512 apply(simp only: wprepare_invs, simp)
       
  2513 apply(case_tac list, simp_all split: if_splits, auto)
       
  2514 apply(case_tac [1-3] mr, simp_all add: exp_ind_def)
       
  2515 apply(case_tac mr, simp_all add: exp_ind_def tape_of_nl_not_null)
       
  2516 apply(case_tac [1-2] mr, simp_all add: exp_ind_def)
       
  2517 apply(case_tac rn, simp, case_tac nat, auto simp: exp_ind_def)
       
  2518 done
       
  2519 
       
  2520 lemma [simp]: "wprepare_add_one2 m lm (b, Bk # list) \<Longrightarrow> b \<noteq> []"
       
  2521 apply(simp only: wprepare_invs, simp)
       
  2522 done
       
  2523 
       
  2524 lemma [simp]: "wprepare_add_one2 m lm (b, Bk # list) \<Longrightarrow> 
       
  2525       (list = [] \<longrightarrow> wprepare_add_one2 m lm (b, [Oc])) \<and> 
       
  2526       (list \<noteq> [] \<longrightarrow> wprepare_add_one2 m lm (b, Oc # list))"
       
  2527 apply(simp only:  wprepare_invs, auto)
       
  2528 done
       
  2529 
       
  2530 lemma [simp]: "wprepare_goto_first_end m lm (b, Oc # list)
       
  2531        \<Longrightarrow> (b = [] \<longrightarrow> wprepare_goto_first_end m lm ([Oc], list)) \<and> 
       
  2532            (b \<noteq> [] \<longrightarrow> wprepare_goto_first_end m lm (Oc # b, list))"
       
  2533 apply(simp only:  wprepare_invs, auto)
       
  2534 apply(rule_tac x = 1 in exI, auto)
       
  2535 apply(case_tac mr, simp_all add: exp_ind_def)
       
  2536 apply(case_tac ml, simp_all add: exp_ind_def)
       
  2537 apply(rule_tac x = rn in exI, simp)
       
  2538 apply(rule_tac x = "Suc ml" in exI, simp_all add: exp_ind_def)
       
  2539 apply(rule_tac x = "mr - 1" in exI, simp)
       
  2540 apply(case_tac mr, simp_all add: exp_ind_def, auto)
       
  2541 done
       
  2542 
       
  2543 lemma [simp]: "wprepare_erase m lm (b, Oc # list) \<Longrightarrow> b \<noteq> []"
       
  2544 apply(simp only: wprepare_invs, auto simp: exp_ind_def)
       
  2545 done
       
  2546 
       
  2547 lemma [simp]: "wprepare_erase m lm (b, Oc # list)
       
  2548   \<Longrightarrow> wprepare_erase m lm (b, Bk # list)"
       
  2549 apply(simp  only:wprepare_invs, auto simp: exp_ind_def)
       
  2550 done
       
  2551 
       
  2552 lemma [simp]: "\<lbrakk>lm \<noteq> []; wprepare_goto_start_pos m lm (b, Bk # list)\<rbrakk>
       
  2553        \<Longrightarrow> wprepare_goto_start_pos m lm (Bk # b, list)"
       
  2554 apply(simp only:wprepare_invs, auto)
       
  2555 apply(case_tac [!] lm, simp, simp_all)
       
  2556 done
       
  2557 
       
  2558 lemma [simp]: "wprepare_loop_start m lm (b, aa) \<Longrightarrow> b \<noteq> []"
       
  2559 apply(simp only:wprepare_invs, auto)
       
  2560 done
       
  2561 lemma [elim]: "Bk # list = Oc\<^bsup>mr\<^esup> @ Bk\<^bsup>rn\<^esup>  \<Longrightarrow> \<exists>rn. list = Bk\<^bsup>rn\<^esup>"
       
  2562 apply(case_tac mr, simp_all)
       
  2563 apply(case_tac rn, simp_all add: exp_ind_def, auto)
       
  2564 done
       
  2565 
       
  2566 lemma rev_equal_iff: "x = y \<Longrightarrow> rev x = rev y"
       
  2567 by simp
       
  2568 
       
  2569 lemma tape_of_nl_false1:
       
  2570   "lm \<noteq> [] \<Longrightarrow> rev b @ [Bk] \<noteq> Bk\<^bsup>ln\<^esup> @ Oc # Oc\<^bsup>m\<^esup> @ Bk # Bk # <lm::nat list>"
       
  2571 apply(auto)
       
  2572 apply(drule_tac rev_equal_iff, simp add: tape_of_nl_rev)
       
  2573 apply(case_tac "rev lm")
       
  2574 apply(case_tac [2] list, auto simp: tape_of_nl_abv tape_of_nat_list.simps exp_ind_def)
       
  2575 done
       
  2576 
       
  2577 lemma [simp]: "wprepare_loop_start_in_middle m lm (b, [Bk]) = False"
       
  2578 apply(simp add: wprepare_loop_start_in_middle.simps, auto)
       
  2579 apply(case_tac mr, simp_all add: exp_ind_def)
       
  2580 apply(case_tac lm1, simp, simp add: tape_of_nl_not_null)
       
  2581 done
       
  2582 
       
  2583 declare wprepare_loop_start_in_middle.simps[simp del]
       
  2584 
       
  2585 declare wprepare_loop_start_on_rightmost.simps[simp del] 
       
  2586         wprepare_loop_goon_in_middle.simps[simp del]
       
  2587         wprepare_loop_goon_on_rightmost.simps[simp del]
       
  2588 
       
  2589 lemma [simp]: "wprepare_loop_goon_in_middle m lm (Bk # b, []) = False"
       
  2590 apply(simp add: wprepare_loop_goon_in_middle.simps, auto)
       
  2591 done
       
  2592 
       
  2593 lemma [simp]: "\<lbrakk>lm \<noteq> []; wprepare_loop_start m lm (b, [Bk])\<rbrakk> \<Longrightarrow>
       
  2594   wprepare_loop_goon m lm (Bk # b, [])"
       
  2595 apply(simp only: wprepare_invs, simp)
       
  2596 apply(simp add: wprepare_loop_goon_on_rightmost.simps 
       
  2597   wprepare_loop_start_on_rightmost.simps, auto)
       
  2598 apply(case_tac mr, simp_all add: exp_ind_def)
       
  2599 apply(rule_tac rev_eq)
       
  2600 apply(simp add: tape_of_nl_rev)
       
  2601 apply(simp add: exp_ind_def[THEN sym] exp_ind)
       
  2602 done
       
  2603 
       
  2604 lemma [simp]: "wprepare_loop_start_on_rightmost m lm (b, Bk # a # lista)
       
  2605  \<Longrightarrow> wprepare_loop_goon_in_middle m lm (Bk # b, a # lista) = False"
       
  2606 apply(auto simp: wprepare_loop_start_on_rightmost.simps
       
  2607                  wprepare_loop_goon_in_middle.simps)
       
  2608 apply(case_tac [!] mr, simp_all add: exp_ind_def)
       
  2609 done
       
  2610 
       
  2611 lemma [simp]: "\<lbrakk>lm \<noteq> []; wprepare_loop_start_on_rightmost m lm (b, Bk # a # lista)\<rbrakk>
       
  2612     \<Longrightarrow> wprepare_loop_goon_on_rightmost m lm (Bk # b, a # lista)"
       
  2613 apply(simp only: wprepare_loop_start_on_rightmost.simps
       
  2614                  wprepare_loop_goon_on_rightmost.simps, auto)
       
  2615 apply(case_tac mr, simp_all add: exp_ind_def)
       
  2616 apply(simp add: tape_of_nl_rev)
       
  2617 apply(simp add: exp_ind_def[THEN sym] exp_ind)
       
  2618 done
       
  2619 
       
  2620 lemma [simp]: "\<lbrakk>lm \<noteq> []; wprepare_loop_start_in_middle m lm (b, Bk # a # lista)\<rbrakk>
       
  2621   \<Longrightarrow> wprepare_loop_goon_on_rightmost m lm (Bk # b, a # lista) = False"
       
  2622 apply(simp add: wprepare_loop_start_in_middle.simps
       
  2623                 wprepare_loop_goon_on_rightmost.simps, auto)
       
  2624 apply(case_tac mr, simp_all add: exp_ind_def)
       
  2625 apply(case_tac  "lm1::nat list", simp_all, case_tac  list, simp)
       
  2626 apply(simp add: tape_of_nl_abv tape_of_nat_list.simps tape_of_nat_abv exp_ind_def)
       
  2627 apply(case_tac [!] rna, simp_all add: exp_ind_def)
       
  2628 apply(case_tac mr, simp_all add: exp_ind_def)
       
  2629 apply(case_tac lm1, simp, case_tac list, simp)
       
  2630 apply(simp_all add: tape_of_nl_abv tape_of_nat_list.simps exp_ind_def tape_of_nat_abv)
       
  2631 done
       
  2632 
       
  2633 lemma [simp]: 
       
  2634   "\<lbrakk>lm \<noteq> []; wprepare_loop_start_in_middle m lm (b, Bk # a # lista)\<rbrakk> 
       
  2635   \<Longrightarrow> wprepare_loop_goon_in_middle m lm (Bk # b, a # lista)"
       
  2636 apply(simp add: wprepare_loop_start_in_middle.simps
       
  2637                wprepare_loop_goon_in_middle.simps, auto)
       
  2638 apply(rule_tac x = rn in exI, simp)
       
  2639 apply(case_tac mr, simp_all add: exp_ind_def)
       
  2640 apply(case_tac lm1, simp)
       
  2641 apply(rule_tac x = "Suc aa" in exI, simp)
       
  2642 apply(rule_tac x = list in exI)
       
  2643 apply(case_tac list, simp_all add: tape_of_nl_abv tape_of_nat_list.simps)
       
  2644 done
       
  2645 
       
  2646 lemma [simp]: "\<lbrakk>lm \<noteq> []; wprepare_loop_start m lm (b, Bk # a # lista)\<rbrakk> \<Longrightarrow> 
       
  2647   wprepare_loop_goon m lm (Bk # b, a # lista)"
       
  2648 apply(simp add: wprepare_loop_start.simps 
       
  2649                 wprepare_loop_goon.simps)
       
  2650 apply(erule_tac disjE, simp, auto)
       
  2651 done
       
  2652 
       
  2653 lemma start_2_goon:
       
  2654   "\<lbrakk>lm \<noteq> []; wprepare_loop_start m lm (b, Bk # list)\<rbrakk> \<Longrightarrow>
       
  2655    (list = [] \<longrightarrow> wprepare_loop_goon m lm (Bk # b, [])) \<and>
       
  2656   (list \<noteq> [] \<longrightarrow> wprepare_loop_goon m lm (Bk # b, list))"
       
  2657 apply(case_tac list, auto)
       
  2658 done
       
  2659 
       
  2660 lemma add_one_2_add_one: "wprepare_add_one m lm (b, Oc # list)
       
  2661   \<Longrightarrow> (hd b = Oc \<longrightarrow> (b = [] \<longrightarrow> wprepare_add_one m lm ([], Bk # Oc # list)) \<and>
       
  2662                      (b \<noteq> [] \<longrightarrow> wprepare_add_one m lm (tl b, Oc # Oc # list))) \<and>
       
  2663   (hd b \<noteq> Oc \<longrightarrow> (b = [] \<longrightarrow> wprepare_add_one m lm ([], Bk # Oc # list)) \<and>
       
  2664                  (b \<noteq> [] \<longrightarrow> wprepare_add_one m lm (tl b, hd b # Oc # list)))"
       
  2665 apply(simp only: wprepare_add_one.simps, auto)
       
  2666 done
       
  2667 
       
  2668 lemma [simp]: "wprepare_loop_start m lm (b, Oc # list) \<Longrightarrow> b \<noteq> []"
       
  2669 apply(simp)
       
  2670 done
       
  2671 
       
  2672 lemma [simp]: "wprepare_loop_start_on_rightmost m lm (b, Oc # list) \<Longrightarrow> 
       
  2673   wprepare_loop_start_on_rightmost m lm (Oc # b, list)"
       
  2674 apply(simp add: wprepare_loop_start_on_rightmost.simps, auto)
       
  2675 apply(rule_tac x = rn in exI, auto)
       
  2676 apply(case_tac mr, simp_all add: exp_ind_def)
       
  2677 apply(case_tac rn, auto simp: exp_ind_def)
       
  2678 done
       
  2679 
       
  2680 lemma [simp]: "wprepare_loop_start_in_middle m lm (b, Oc # list) \<Longrightarrow> 
       
  2681                 wprepare_loop_start_in_middle m lm (Oc # b, list)"
       
  2682 apply(simp add: wprepare_loop_start_in_middle.simps, auto)
       
  2683 apply(rule_tac x = rn in exI, auto)
       
  2684 apply(case_tac mr, simp, simp add: exp_ind_def)
       
  2685 apply(rule_tac x = nat in exI, simp)
       
  2686 apply(rule_tac x = lm1 in exI, simp)
       
  2687 done
       
  2688 
       
  2689 lemma start_2_start: "wprepare_loop_start m lm (b, Oc # list) \<Longrightarrow> 
       
  2690        wprepare_loop_start m lm (Oc # b, list)"
       
  2691 apply(simp add: wprepare_loop_start.simps)
       
  2692 apply(erule_tac disjE, simp_all )
       
  2693 done
       
  2694 
       
  2695 lemma [simp]: "wprepare_loop_goon m lm (b, Oc # list) \<Longrightarrow> b \<noteq> []"
       
  2696 apply(simp add: wprepare_loop_goon.simps     
       
  2697                 wprepare_loop_goon_in_middle.simps 
       
  2698                 wprepare_loop_goon_on_rightmost.simps)
       
  2699 apply(auto)
       
  2700 done
       
  2701 
       
  2702 lemma [simp]: "wprepare_goto_start_pos m lm (b, Oc # list) \<Longrightarrow> b \<noteq> []"
       
  2703 apply(simp add: wprepare_goto_start_pos.simps)
       
  2704 done
       
  2705 
       
  2706 lemma [simp]: "wprepare_loop_goon_on_rightmost m lm (b, Oc # list) = False"
       
  2707 apply(simp add: wprepare_loop_goon_on_rightmost.simps)
       
  2708 done
       
  2709 lemma wprepare_loop1: "\<lbrakk>rev b @ Oc\<^bsup>mr\<^esup> =  Oc\<^bsup>Suc m\<^esup> @ Bk # Bk # <lm>; 
       
  2710          b \<noteq> []; 0 < mr; Oc # list = Oc\<^bsup>mr\<^esup> @ Bk\<^bsup>rn\<^esup>\<rbrakk>
       
  2711        \<Longrightarrow> wprepare_loop_start_on_rightmost m lm (Oc # b, list)"
       
  2712 apply(simp add: wprepare_loop_start_on_rightmost.simps)
       
  2713 apply(rule_tac x = rn in exI, simp)
       
  2714 apply(case_tac mr, simp, simp add: exp_ind_def, auto)
       
  2715 done
       
  2716 
       
  2717 lemma wprepare_loop2: "\<lbrakk>rev b @ Oc\<^bsup>mr\<^esup> @ Bk # <a # lista> = Oc\<^bsup>Suc m\<^esup> @ Bk # Bk # <lm>;
       
  2718                 b \<noteq> []; Oc # list = Oc\<^bsup>mr\<^esup> @ Bk # <(a::nat) # lista> @ Bk\<^bsup>rn\<^esup>\<rbrakk>
       
  2719        \<Longrightarrow>  wprepare_loop_start_in_middle m lm (Oc # b, list)"
       
  2720 apply(simp add: wprepare_loop_start_in_middle.simps)
       
  2721 apply(rule_tac x = rn in exI, simp)
       
  2722 apply(case_tac mr, simp_all add: exp_ind_def)
       
  2723 apply(rule_tac x = nat in exI, simp)
       
  2724 apply(rule_tac x = "a#lista" in exI, simp)
       
  2725 done
       
  2726 
       
  2727 lemma [simp]: "wprepare_loop_goon_in_middle m lm (b, Oc # list) \<Longrightarrow>
       
  2728                 wprepare_loop_start_on_rightmost m lm (Oc # b, list) \<or>
       
  2729                 wprepare_loop_start_in_middle m lm (Oc # b, list)"
       
  2730 apply(simp add: wprepare_loop_goon_in_middle.simps split: if_splits)
       
  2731 apply(case_tac lm1, simp_all add: wprepare_loop1 wprepare_loop2)
       
  2732 done
       
  2733 
       
  2734 lemma [simp]: "wprepare_loop_goon m lm (b, Oc # list)
       
  2735   \<Longrightarrow>  wprepare_loop_start m lm (Oc # b, list)"
       
  2736 apply(simp add: wprepare_loop_goon.simps
       
  2737                 wprepare_loop_start.simps)
       
  2738 done
       
  2739 
       
  2740 lemma [simp]: "wprepare_add_one m lm (b, Oc # list)
       
  2741        \<Longrightarrow> b = [] \<longrightarrow> wprepare_add_one m lm ([], Bk # Oc # list)"
       
  2742 apply(auto)
       
  2743 apply(simp add: wprepare_add_one.simps)
       
  2744 done
       
  2745 
       
  2746 lemma [simp]: "wprepare_goto_start_pos m [a] (b, Oc # list)
       
  2747               \<Longrightarrow> wprepare_loop_start_on_rightmost m [a] (Oc # b, list) "
       
  2748 apply(auto simp: wprepare_goto_start_pos.simps 
       
  2749                  wprepare_loop_start_on_rightmost.simps)
       
  2750 apply(rule_tac x = rn in exI, simp)
       
  2751 apply(simp add: tape_of_nat_abv tape_of_nat_list.simps exp_ind_def, auto)
       
  2752 done
       
  2753 
       
  2754 lemma [simp]:  "wprepare_goto_start_pos m (a # aa # listaa) (b, Oc # list)
       
  2755        \<Longrightarrow>wprepare_loop_start_in_middle m (a # aa # listaa) (Oc # b, list)"
       
  2756 apply(auto simp: wprepare_goto_start_pos.simps
       
  2757                  wprepare_loop_start_in_middle.simps)
       
  2758 apply(rule_tac x = rn in exI, simp)
       
  2759 apply(simp add: tape_of_nl_abv tape_of_nat_list.simps exp_ind_def)
       
  2760 apply(rule_tac x = a in exI, rule_tac x = "aa#listaa" in exI, simp)
       
  2761 done
       
  2762 
       
  2763 lemma [simp]: "\<lbrakk>lm \<noteq> []; wprepare_goto_start_pos m lm (b, Oc # list)\<rbrakk>
       
  2764        \<Longrightarrow> wprepare_loop_start m lm (Oc # b, list)"
       
  2765 apply(case_tac lm, simp_all)
       
  2766 apply(case_tac lista, simp_all add: wprepare_loop_start.simps)
       
  2767 done
       
  2768 
       
  2769 lemma [simp]: "wprepare_add_one2 m lm (b, Oc # list) \<Longrightarrow> b \<noteq> []"
       
  2770 apply(auto simp: wprepare_add_one2.simps)
       
  2771 done
       
  2772 
       
  2773 lemma add_one_2_stop:
       
  2774   "wprepare_add_one2 m lm (b, Oc # list)      
       
  2775   \<Longrightarrow>  wprepare_stop m lm (tl b, hd b # Oc # list)"
       
  2776 apply(simp add: wprepare_stop.simps wprepare_add_one2.simps)
       
  2777 done
       
  2778 
       
  2779 declare wprepare_stop.simps[simp del]
       
  2780 
       
  2781 lemma wprepare_correctness:
       
  2782   assumes h: "lm \<noteq> []"
       
  2783   shows "let P = (\<lambda> (st, l, r). st = 0) in 
       
  2784   let Q = (\<lambda> (st, l, r). wprepare_inv st m lm (l, r)) in 
       
  2785   let f = (\<lambda> stp. steps (Suc 0, [], (<m # lm>)) t_wcode_prepare stp) in
       
  2786     \<exists> n .P (f n) \<and> Q (f n)"
       
  2787 proof -
       
  2788   let ?P = "(\<lambda> (st, l, r). st = 0)"
       
  2789   let ?Q = "(\<lambda> (st, l, r). wprepare_inv st m lm (l, r))"
       
  2790   let ?f = "(\<lambda> stp. steps (Suc 0, [], (<m # lm>)) t_wcode_prepare stp)"
       
  2791   have "\<exists> n. ?P (?f n) \<and> ?Q (?f n)"
       
  2792   proof(rule_tac halt_lemma2)
       
  2793     show "wf wcode_prepare_le" by auto
       
  2794   next
       
  2795     show "\<forall> n. \<not> ?P (?f n) \<and> ?Q (?f n) \<longrightarrow> 
       
  2796                  ?Q (?f (Suc n)) \<and> (?f (Suc n), ?f n) \<in> wcode_prepare_le"
       
  2797       using h
       
  2798       apply(rule_tac allI, rule_tac impI, case_tac "?f n", 
       
  2799             simp add: tstep_red tstep.simps)
       
  2800       apply(case_tac c, simp, case_tac [2] aa)
       
  2801       apply(simp_all add: wprepare_inv.simps wcode_prepare_le_def new_tape.simps
       
  2802                           lex_triple_def lex_pair_def
       
  2803 
       
  2804                  split: if_splits)
       
  2805       apply(simp_all add: start_2_goon  start_2_start
       
  2806                            add_one_2_add_one add_one_2_stop)
       
  2807       apply(auto simp: wprepare_add_one2.simps)
       
  2808       done   
       
  2809   next
       
  2810     show "?Q (?f 0)"
       
  2811       apply(simp add: steps.simps wprepare_inv.simps wprepare_invs)
       
  2812       done
       
  2813   next
       
  2814     show "\<not> ?P (?f 0)"
       
  2815       apply(simp add: steps.simps)
       
  2816       done
       
  2817   qed
       
  2818   thus "?thesis"
       
  2819     apply(auto)
       
  2820     done
       
  2821 qed
       
  2822 
       
  2823 lemma [intro]: "t_correct t_wcode_prepare"
       
  2824 apply(simp add: t_correct.simps t_wcode_prepare_def iseven_def)
       
  2825 apply(rule_tac x = 7 in exI, simp)
       
  2826 done
       
  2827     
       
  2828 lemma twice_len_even: "length (tm_of abc_twice) mod 2 = 0"
       
  2829 apply(simp add: tm_even)
       
  2830 done
       
  2831 
       
  2832 lemma fourtimes_len_even: "length (tm_of abc_fourtimes) mod 2 = 0"
       
  2833 apply(simp add: tm_even)
       
  2834 done
       
  2835 
       
  2836 lemma t_correct_termi: "t_correct tp \<Longrightarrow> 
       
  2837       list_all (\<lambda>(acn, st). (st \<le> Suc (length tp div 2))) (change_termi_state tp)"
       
  2838 apply(auto simp: t_correct.simps List.list_all_length)
       
  2839 apply(erule_tac x = n in allE, simp)
       
  2840 apply(case_tac "tp!n", auto simp: change_termi_state.simps split: if_splits)
       
  2841 done
       
  2842 
       
  2843 
       
  2844 lemma t_correct_shift:
       
  2845          "list_all (\<lambda>(acn, st). (st \<le> y)) tp \<Longrightarrow>
       
  2846           list_all (\<lambda>(acn, st). (st \<le> y + off)) (tshift tp off) "
       
  2847 apply(auto simp: t_correct.simps List.list_all_length)
       
  2848 apply(erule_tac x = n in allE, simp add: shift_length)
       
  2849 apply(case_tac "tp!n", auto simp: tshift.simps)
       
  2850 done
       
  2851 
       
  2852 lemma [intro]: 
       
  2853   "t_correct (tm_of abc_twice @ tMp (Suc 0) 
       
  2854         (start_of twice_ly (length abc_twice) - Suc 0))"
       
  2855 apply(rule_tac t_compiled_correct, simp_all)
       
  2856 apply(simp add: twice_ly_def)
       
  2857 done
       
  2858 
       
  2859 lemma [intro]: "t_correct (tm_of abc_fourtimes @ tMp (Suc 0) 
       
  2860    (start_of fourtimes_ly (length abc_fourtimes) - Suc 0))"
       
  2861 apply(rule_tac t_compiled_correct, simp_all)
       
  2862 apply(simp add: fourtimes_ly_def)
       
  2863 done
       
  2864 
       
  2865 
       
  2866 lemma [intro]: "t_correct t_wcode_main"
       
  2867 apply(auto simp: t_wcode_main_def t_correct.simps shift_length 
       
  2868                  t_twice_def t_fourtimes_def)
       
  2869 proof -
       
  2870   show "iseven (60 + (length (tm_of abc_twice) +
       
  2871                  length (tm_of abc_fourtimes)))"
       
  2872     using twice_len_even fourtimes_len_even
       
  2873     apply(auto simp: iseven_def)
       
  2874     apply(rule_tac x = "30 + q + qa" in exI, simp)
       
  2875     done
       
  2876 next
       
  2877   show " list_all (\<lambda>(acn, s). s \<le> (60 + (length (tm_of abc_twice) + 
       
  2878            length (tm_of abc_fourtimes))) div 2) t_wcode_main_first_part"
       
  2879     apply(auto simp: t_wcode_main_first_part_def shift_length t_twice_def)
       
  2880     done
       
  2881 next
       
  2882   have "list_all (\<lambda>(acn, s). s \<le> Suc (length (tm_of abc_twice @ tMp (Suc 0)
       
  2883     (start_of twice_ly (length abc_twice) - Suc 0)) div 2))
       
  2884     (change_termi_state (tm_of abc_twice @ tMp (Suc 0) 
       
  2885     (start_of twice_ly (length abc_twice) - Suc 0)))"
       
  2886     apply(rule_tac t_correct_termi, auto)
       
  2887     done
       
  2888   hence "list_all (\<lambda>(acn, s). s \<le>  Suc (length (tm_of abc_twice @ tMp (Suc 0)
       
  2889     (start_of twice_ly (length abc_twice) - Suc 0)) div 2) + 12)
       
  2890      (abacus.tshift (change_termi_state (tm_of abc_twice @ tMp (Suc 0) 
       
  2891            (start_of twice_ly (length abc_twice) - Suc 0))) 12)"
       
  2892     apply(rule_tac t_correct_shift, simp)
       
  2893     done
       
  2894   thus  "list_all (\<lambda>(acn, s). s \<le> 
       
  2895            (60 + (length (tm_of abc_twice) + length (tm_of abc_fourtimes))) div 2)
       
  2896      (abacus.tshift (change_termi_state (tm_of abc_twice @ tMp (Suc 0)
       
  2897                  (start_of twice_ly (length abc_twice) - Suc 0))) 12)"
       
  2898     apply(simp)
       
  2899     apply(simp add: list_all_length, auto)
       
  2900     done
       
  2901 next
       
  2902   have "list_all (\<lambda>(acn, s). s \<le> Suc (length (tm_of abc_fourtimes @ tMp (Suc 0) 
       
  2903     (start_of fourtimes_ly (length abc_fourtimes) - Suc 0)) div 2))
       
  2904       (change_termi_state (tm_of abc_fourtimes @ tMp (Suc 0) 
       
  2905     (start_of fourtimes_ly (length abc_fourtimes) - Suc 0))) "
       
  2906     apply(rule_tac t_correct_termi, auto)
       
  2907     done
       
  2908   hence "list_all (\<lambda>(acn, s). s \<le> Suc (length (tm_of abc_fourtimes @ tMp (Suc 0) 
       
  2909     (start_of fourtimes_ly (length abc_fourtimes) - Suc 0)) div 2) + (t_twice_len + 13))
       
  2910     (abacus.tshift (change_termi_state (tm_of abc_fourtimes @ tMp (Suc 0) 
       
  2911     (start_of fourtimes_ly (length abc_fourtimes) - Suc 0))) (t_twice_len + 13))"
       
  2912     apply(rule_tac t_correct_shift, simp)
       
  2913     done
       
  2914   thus "list_all (\<lambda>(acn, s). s \<le> (60 + (length (tm_of abc_twice) + length (tm_of abc_fourtimes))) div 2)
       
  2915     (abacus.tshift (change_termi_state (tm_of abc_fourtimes @ tMp (Suc 0)
       
  2916     (start_of fourtimes_ly (length abc_fourtimes) - Suc 0))) (t_twice_len + 13))"
       
  2917     apply(simp add: t_twice_len_def t_twice_def)
       
  2918     using twice_len_even fourtimes_len_even
       
  2919     apply(auto simp: list_all_length)
       
  2920     done
       
  2921 qed
       
  2922 
       
  2923 lemma [intro]: "t_correct (t_wcode_prepare |+| t_wcode_main)"
       
  2924 apply(auto intro: t_correct_add)
       
  2925 done
       
  2926 
       
  2927 lemma prepare_mainpart_lemma:
       
  2928   "args \<noteq> [] \<Longrightarrow> 
       
  2929   \<exists> stp ln rn. steps (Suc 0, [], <m # args>) (t_wcode_prepare |+| t_wcode_main) stp
       
  2930               = (0,  Bk # Oc\<^bsup>Suc m\<^esup>, Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>bl_bin (<args>)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  2931 proof -
       
  2932   let ?P1 = "\<lambda> (l, r). l = [] \<and> r = <m # args>"
       
  2933   let ?Q1 = "\<lambda> (l, r). wprepare_stop m args (l, r)"
       
  2934   let ?P2 = ?Q1
       
  2935   let ?Q2 = "\<lambda> (l, r). (\<exists> ln rn. l = Bk # Oc\<^bsup>Suc m\<^esup> \<and>
       
  2936                            r =  Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>bl_bin (<args>)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  2937   let ?P3 = "\<lambda> tp. False"
       
  2938   assume h: "args \<noteq> []"
       
  2939   have "?P1 \<turnstile>-> \<lambda> tp. (\<exists> stp tp'. steps (Suc 0, tp)
       
  2940                       (t_wcode_prepare |+| t_wcode_main) stp = (0, tp') \<and> ?Q2 tp')"
       
  2941   proof(rule_tac turing_merge.t_merge_halt[of t_wcode_prepare t_wcode_main ?P1 ?P2 ?P3 ?P3 ?Q1 ?Q2], 
       
  2942         auto simp: turing_merge_def)
       
  2943     show "\<exists>stp. case steps (Suc 0, [], <m # args>) t_wcode_prepare stp of (st, tp')
       
  2944                   \<Rightarrow> st = 0 \<and> wprepare_stop m args tp'"
       
  2945       using wprepare_correctness[of args m] h
       
  2946       apply(simp, auto)
       
  2947       apply(rule_tac x = n in exI, simp add: wprepare_inv.simps)
       
  2948       done
       
  2949   next
       
  2950     fix a b
       
  2951     assume "wprepare_stop m args (a, b)"
       
  2952     thus "\<exists>stp. case steps (Suc 0, a, b) t_wcode_main stp of
       
  2953       (st, tp') \<Rightarrow> (st = 0) \<and> (case tp' of (l, r) \<Rightarrow> l = Bk # Oc\<^bsup>Suc m\<^esup> \<and> 
       
  2954       (\<exists>ln rn. r = Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>bl_bin (<args>)\<^esup> @ Bk\<^bsup>rn\<^esup>))"
       
  2955       proof(simp only: wprepare_stop.simps, erule_tac exE)
       
  2956         fix rn
       
  2957         assume "a = Bk # <rev args> @ Bk # Bk # Oc\<^bsup>Suc m\<^esup> \<and> 
       
  2958                    b = Bk # Oc # Bk\<^bsup>rn\<^esup>"
       
  2959         thus "?thesis"
       
  2960           using t_wcode_main_lemma_pre[of "args" "<args>" 0 "Oc\<^bsup>Suc m\<^esup>" 0 rn] h
       
  2961           apply(simp)
       
  2962           apply(erule_tac exE)+
       
  2963           apply(rule_tac x = stp in exI, simp add: tape_of_nl_rev, auto)
       
  2964           done
       
  2965       qed
       
  2966   next
       
  2967     show "wprepare_stop m args \<turnstile>-> wprepare_stop m args"
       
  2968       by(simp add: t_imply_def)
       
  2969   qed
       
  2970   thus "\<exists> stp ln rn. steps (Suc 0, [], <m # args>) (t_wcode_prepare |+| t_wcode_main) stp
       
  2971               = (0,  Bk # Oc\<^bsup>Suc m\<^esup>, Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>bl_bin (<args>)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  2972     apply(simp add: t_imply_def)
       
  2973     apply(erule_tac exE)+
       
  2974     apply(auto)
       
  2975     done
       
  2976 qed
       
  2977       
       
  2978 
       
  2979 lemma [simp]:  "tinres r r' \<Longrightarrow> 
       
  2980   fetch t ss (case r of [] \<Rightarrow> Bk | x # xs \<Rightarrow> x) = 
       
  2981   fetch t ss (case r' of [] \<Rightarrow> Bk | x # xs \<Rightarrow> x)"
       
  2982 apply(simp add: fetch.simps, auto split: if_splits simp: tinres_def)
       
  2983 apply(case_tac [!] r', simp_all)
       
  2984 apply(case_tac [!] n, simp_all add: exp_ind_def)
       
  2985 apply(case_tac [!] r, simp_all)
       
  2986 done
       
  2987 
       
  2988 lemma [intro]: "\<exists> n. (a::block)\<^bsup>n\<^esup> = []"
       
  2989 by auto
       
  2990 
       
  2991 lemma [simp]: "\<lbrakk>tinres r r'; r \<noteq> []; r' \<noteq> []\<rbrakk> \<Longrightarrow> hd r = hd r'"
       
  2992 apply(auto simp: tinres_def)
       
  2993 done
       
  2994 
       
  2995 lemma [intro]: "hd (Bk\<^bsup>Suc n\<^esup>) = Bk"
       
  2996 apply(simp add: exp_ind_def)
       
  2997 done
       
  2998 
       
  2999 lemma [simp]: "\<lbrakk>tinres r []; r \<noteq> []\<rbrakk> \<Longrightarrow> hd r = Bk"
       
  3000 apply(auto simp: tinres_def)
       
  3001 apply(case_tac n, auto)
       
  3002 done
       
  3003 
       
  3004 lemma [simp]: "\<lbrakk>tinres [] r'; r' \<noteq> []\<rbrakk> \<Longrightarrow> hd r' = Bk"
       
  3005 apply(auto simp: tinres_def)
       
  3006 done
       
  3007 
       
  3008 lemma [intro]: "\<exists>na. tl r = tl (r @ Bk\<^bsup>n\<^esup>) @ Bk\<^bsup>na\<^esup> \<or> tl (r @ Bk\<^bsup>n\<^esup>) = tl r @ Bk\<^bsup>na\<^esup>"
       
  3009 apply(case_tac r, simp)
       
  3010 apply(case_tac n, simp)
       
  3011 apply(rule_tac x = 0 in exI, simp)
       
  3012 apply(rule_tac x = nat in exI, simp add: exp_ind_def)
       
  3013 apply(simp)
       
  3014 apply(rule_tac x = n in exI, simp)
       
  3015 done
       
  3016 
       
  3017 lemma [simp]: "tinres r r' \<Longrightarrow> tinres (tl r) (tl r')"
       
  3018 apply(auto simp: tinres_def)
       
  3019 apply(case_tac r', simp_all)
       
  3020 apply(case_tac n, simp_all add: exp_ind_def)
       
  3021 apply(rule_tac x = 0 in exI, simp)
       
  3022 apply(rule_tac x = nat in exI, simp_all)
       
  3023 apply(rule_tac x = n in exI, simp)
       
  3024 done
       
  3025 
       
  3026 lemma [simp]: "\<lbrakk>tinres r [];  r \<noteq> []\<rbrakk> \<Longrightarrow> tinres (tl r) []"
       
  3027 apply(case_tac r, auto simp: tinres_def)
       
  3028 apply(case_tac n, simp_all add: exp_ind_def)
       
  3029 apply(rule_tac x = nat in exI, simp)
       
  3030 done
       
  3031 
       
  3032 lemma [simp]: "\<lbrakk>tinres [] r'\<rbrakk> \<Longrightarrow> tinres [] (tl r')"
       
  3033 apply(case_tac r', auto simp: tinres_def)
       
  3034 apply(case_tac n, simp_all add: exp_ind_def)
       
  3035 apply(rule_tac x = nat in exI, simp)
       
  3036 done
       
  3037 
       
  3038 lemma [simp]: "tinres r r' \<Longrightarrow> tinres (b # r) (b # r')"
       
  3039 apply(auto simp: tinres_def)
       
  3040 done
       
  3041 
       
  3042 lemma tinres_step2: 
       
  3043   "\<lbrakk>tinres r r'; tstep (ss, l, r) t = (sa, la, ra); tstep (ss, l, r') t = (sb, lb, rb)\<rbrakk>
       
  3044     \<Longrightarrow> la = lb \<and> tinres ra rb \<and> sa = sb"
       
  3045 apply(case_tac "ss = 0", simp add: tstep_0)
       
  3046 apply(simp add: tstep.simps [simp del])
       
  3047 apply(case_tac "fetch t ss (case r of [] \<Rightarrow> Bk | x # xs \<Rightarrow> x)", simp)
       
  3048 apply(auto simp: new_tape.simps)
       
  3049 apply(simp_all split: taction.splits if_splits)
       
  3050 apply(auto)
       
  3051 done
       
  3052 
       
  3053 
       
  3054 lemma tinres_steps2: 
       
  3055   "\<lbrakk>tinres r r'; steps (ss, l, r) t stp = (sa, la, ra); steps (ss, l, r') t stp = (sb, lb, rb)\<rbrakk>
       
  3056     \<Longrightarrow> la = lb \<and> tinres ra rb \<and> sa = sb"
       
  3057 apply(induct stp arbitrary: sa la ra sb lb rb, simp add: steps.simps)
       
  3058 apply(simp add: tstep_red)
       
  3059 apply(case_tac "(steps (ss, l, r) t stp)")
       
  3060 apply(case_tac "(steps (ss, l, r') t stp)")
       
  3061 proof -
       
  3062   fix stp sa la ra sb lb rb a b c aa ba ca
       
  3063   assume ind: "\<And>sa la ra sb lb rb. \<lbrakk>steps (ss, l, r) t stp = (sa, la, ra); 
       
  3064     steps (ss, l, r') t stp = (sb, lb, rb)\<rbrakk> \<Longrightarrow> la = lb \<and> tinres ra rb \<and> sa = sb"
       
  3065   and h: " tinres r r'" "tstep (steps (ss, l, r) t stp) t = (sa, la, ra)"
       
  3066          "tstep (steps (ss, l, r') t stp) t = (sb, lb, rb)" "steps (ss, l, r) t stp = (a, b, c)" 
       
  3067          "steps (ss, l, r') t stp = (aa, ba, ca)"
       
  3068   have "b = ba \<and> tinres c ca \<and> a = aa"
       
  3069     apply(rule_tac ind, simp_all add: h)
       
  3070     done
       
  3071   thus "la = lb \<and> tinres ra rb \<and> sa = sb"
       
  3072     apply(rule_tac l = b  and r = c  and ss = a and r' = ca   
       
  3073             and t = t in tinres_step2)
       
  3074     using h
       
  3075     apply(simp, simp, simp)
       
  3076     done
       
  3077 qed
       
  3078 
       
  3079 
       
  3080 text{**************Begin: adjust***************************}   
       
  3081 definition t_wcode_adjust :: "tprog"
       
  3082   where
       
  3083   "t_wcode_adjust = [(W1, 1), (R, 2), (Nop, 2), (R, 3), (R, 3), (R, 4), 
       
  3084                    (L, 8), (L, 5), (L, 6), (W0, 5), (L, 6), (R, 7), 
       
  3085                    (W1, 2), (Nop, 7), (L, 9), (W0, 8), (L, 9), (L, 10), 
       
  3086                     (L, 11), (L, 10), (R, 0), (L, 11)]"
       
  3087                  
       
  3088 lemma [simp]: "fetch t_wcode_adjust (Suc 0) Bk = (W1, 1)"
       
  3089 apply(simp add: fetch.simps t_wcode_adjust_def nth_of.simps)
       
  3090 done
       
  3091 
       
  3092 lemma [simp]: "fetch t_wcode_adjust (Suc 0) Oc = (R, 2)"
       
  3093 apply(simp add: fetch.simps t_wcode_adjust_def nth_of.simps)
       
  3094 done
       
  3095 
       
  3096 lemma [simp]: "fetch t_wcode_adjust (Suc (Suc 0)) Oc = (R, 3)"
       
  3097 apply(simp add: fetch.simps t_wcode_adjust_def nth_of.simps)
       
  3098 done
       
  3099 
       
  3100 lemma [simp]: "fetch t_wcode_adjust (Suc (Suc (Suc 0))) Oc = (R, 4)"
       
  3101 apply(simp add: fetch.simps t_wcode_adjust_def nth_of.simps)
       
  3102 done
       
  3103 
       
  3104 lemma [simp]: "fetch t_wcode_adjust  (Suc (Suc (Suc 0))) Bk = (R, 3)"
       
  3105 apply(simp add: fetch.simps t_wcode_adjust_def nth_of.simps)
       
  3106 done
       
  3107    
       
  3108 lemma [simp]: "fetch t_wcode_adjust 4 Bk = (L, 8)"
       
  3109 apply(simp add: fetch.simps t_wcode_adjust_def nth_of.simps)
       
  3110 done
       
  3111 
       
  3112 lemma [simp]: "fetch t_wcode_adjust 4 Oc = (L, 5)"
       
  3113 apply(simp add: fetch.simps t_wcode_adjust_def nth_of.simps)
       
  3114 done
       
  3115 
       
  3116 lemma [simp]: "fetch t_wcode_adjust 5 Oc = (W0, 5)"
       
  3117 apply(simp add: fetch.simps t_wcode_adjust_def nth_of.simps)
       
  3118 done
       
  3119 
       
  3120 lemma [simp]: "fetch t_wcode_adjust 5 Bk = (L, 6)"
       
  3121 apply(simp add: fetch.simps t_wcode_adjust_def nth_of.simps)
       
  3122 done
       
  3123 
       
  3124 lemma [simp]: "fetch t_wcode_adjust 6 Oc = (R, 7)"
       
  3125 apply(simp add: fetch.simps t_wcode_adjust_def nth_of.simps)
       
  3126 done
       
  3127 
       
  3128 lemma [simp]: "fetch t_wcode_adjust 6 Bk = (L, 6)"
       
  3129 apply(simp add: fetch.simps t_wcode_adjust_def nth_of.simps)
       
  3130 done
       
  3131 
       
  3132 lemma [simp]: "fetch t_wcode_adjust 7 Bk = (W1, 2)"
       
  3133 apply(simp add: fetch.simps t_wcode_adjust_def nth_of.simps)
       
  3134 done
       
  3135 
       
  3136 lemma [simp]: "fetch t_wcode_adjust 8 Bk = (L, 9)"
       
  3137 apply(simp add: fetch.simps t_wcode_adjust_def nth_of.simps)
       
  3138 done
       
  3139 
       
  3140 lemma [simp]: "fetch t_wcode_adjust 8 Oc = (W0, 8)"
       
  3141 apply(simp add: fetch.simps t_wcode_adjust_def nth_of.simps)
       
  3142 done
       
  3143 
       
  3144 lemma [simp]: "fetch t_wcode_adjust 9 Oc = (L, 10)"
       
  3145 apply(simp add: fetch.simps t_wcode_adjust_def nth_of.simps)
       
  3146 done
       
  3147 
       
  3148 lemma [simp]: "fetch t_wcode_adjust 9 Bk = (L, 9)"
       
  3149 apply(simp add: fetch.simps t_wcode_adjust_def nth_of.simps)
       
  3150 done
       
  3151 
       
  3152 lemma [simp]: "fetch t_wcode_adjust 10 Bk = (L, 11)"
       
  3153 apply(simp add: fetch.simps t_wcode_adjust_def nth_of.simps)
       
  3154 done
       
  3155 
       
  3156 lemma [simp]: "fetch t_wcode_adjust 10 Oc = (L, 10)"
       
  3157 apply(simp add: fetch.simps t_wcode_adjust_def nth_of.simps)
       
  3158 done
       
  3159 
       
  3160 lemma [simp]: "fetch t_wcode_adjust 11 Oc = (L, 11)"
       
  3161 apply(simp add: fetch.simps t_wcode_adjust_def nth_of.simps)
       
  3162 done
       
  3163 
       
  3164 lemma [simp]: "fetch t_wcode_adjust 11 Bk = (R, 0)"
       
  3165 apply(simp add: fetch.simps t_wcode_adjust_def nth_of.simps)
       
  3166 done
       
  3167 
       
  3168 fun wadjust_start :: "nat \<Rightarrow> nat \<Rightarrow> tape \<Rightarrow> bool"
       
  3169   where
       
  3170   "wadjust_start m rs (l, r) = 
       
  3171          (\<exists> ln rn. l = Bk # Oc\<^bsup>Suc m\<^esup> \<and>
       
  3172                    tl r = Oc # Bk\<^bsup>ln\<^esup> @ Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  3173 
       
  3174 fun wadjust_loop_start :: "nat \<Rightarrow> nat \<Rightarrow> tape \<Rightarrow> bool"
       
  3175   where
       
  3176   "wadjust_loop_start m rs (l, r) = 
       
  3177           (\<exists> ln rn ml mr. l = Oc\<^bsup>ml\<^esup> @ Bk # Oc\<^bsup>Suc m\<^esup>  \<and>
       
  3178                           r = Oc # Bk\<^bsup>ln\<^esup> @ Bk # Oc\<^bsup>mr\<^esup> @ Bk\<^bsup>rn\<^esup> \<and>
       
  3179                           ml + mr = Suc (Suc rs) \<and> mr > 0)"
       
  3180 
       
  3181 fun wadjust_loop_right_move :: "nat \<Rightarrow> nat \<Rightarrow> tape \<Rightarrow> bool"
       
  3182   where
       
  3183   "wadjust_loop_right_move m rs (l, r) = 
       
  3184    (\<exists> ml mr nl nr rn. l = Bk\<^bsup>nl\<^esup> @ Oc # Oc\<^bsup>ml\<^esup> @ Bk # Oc\<^bsup>Suc m\<^esup> \<and>
       
  3185                       r = Bk\<^bsup>nr\<^esup> @ Oc\<^bsup>mr\<^esup> @ Bk\<^bsup>rn\<^esup> \<and>
       
  3186                       ml + mr = Suc (Suc rs) \<and> mr > 0 \<and>
       
  3187                       nl + nr > 0)"
       
  3188 
       
  3189 fun wadjust_loop_check :: "nat \<Rightarrow> nat \<Rightarrow> tape \<Rightarrow> bool"
       
  3190   where
       
  3191   "wadjust_loop_check m rs (l, r) = 
       
  3192   (\<exists> ml mr ln rn. l = Oc # Bk\<^bsup>ln\<^esup> @ Bk # Oc # Oc\<^bsup>ml\<^esup> @ Bk # Oc\<^bsup>Suc m\<^esup> \<and>
       
  3193                   r = Oc\<^bsup>mr\<^esup> @ Bk\<^bsup>rn\<^esup> \<and> ml + mr = (Suc rs))"
       
  3194 
       
  3195 fun wadjust_loop_erase :: "nat \<Rightarrow> nat \<Rightarrow> tape \<Rightarrow> bool"
       
  3196   where
       
  3197   "wadjust_loop_erase m rs (l, r) = 
       
  3198     (\<exists> ml mr ln rn. l = Bk\<^bsup>ln\<^esup> @ Bk # Oc # Oc\<^bsup>ml\<^esup> @ Bk # Oc\<^bsup>Suc m\<^esup> \<and>
       
  3199                     tl r = Oc\<^bsup>mr\<^esup> @ Bk\<^bsup>rn\<^esup> \<and> ml + mr = (Suc rs) \<and> mr > 0)"
       
  3200 
       
  3201 fun wadjust_loop_on_left_moving_O :: "nat \<Rightarrow> nat \<Rightarrow> tape \<Rightarrow> bool"
       
  3202   where
       
  3203   "wadjust_loop_on_left_moving_O m rs (l, r) = 
       
  3204       (\<exists> ml mr ln rn. l = Oc\<^bsup>ml\<^esup> @ Bk # Oc\<^bsup>Suc m \<^esup>\<and>
       
  3205                       r = Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>mr\<^esup> @ Bk\<^bsup>rn\<^esup> \<and>
       
  3206                       ml + mr = Suc rs \<and> mr > 0)"
       
  3207 
       
  3208 fun wadjust_loop_on_left_moving_B :: "nat \<Rightarrow> nat \<Rightarrow> tape \<Rightarrow> bool"
       
  3209   where
       
  3210   "wadjust_loop_on_left_moving_B m rs (l, r) = 
       
  3211       (\<exists> ml mr nl nr rn. l = Bk\<^bsup>nl\<^esup> @ Oc # Oc\<^bsup>ml\<^esup> @ Bk # Oc\<^bsup>Suc m\<^esup> \<and>
       
  3212                          r = Bk\<^bsup>nr\<^esup> @ Bk # Bk # Oc\<^bsup>mr\<^esup> @ Bk\<^bsup>rn\<^esup> \<and> 
       
  3213                          ml + mr = Suc rs \<and> mr > 0)"
       
  3214 
       
  3215 fun wadjust_loop_on_left_moving :: "nat \<Rightarrow> nat \<Rightarrow> tape \<Rightarrow> bool"
       
  3216   where
       
  3217   "wadjust_loop_on_left_moving m rs (l, r) = 
       
  3218        (wadjust_loop_on_left_moving_O m rs (l, r) \<or>
       
  3219        wadjust_loop_on_left_moving_B m rs (l, r))"
       
  3220 
       
  3221 fun wadjust_loop_right_move2 :: "nat \<Rightarrow> nat \<Rightarrow> tape \<Rightarrow> bool"
       
  3222   where
       
  3223   "wadjust_loop_right_move2 m rs (l, r) = 
       
  3224         (\<exists> ml mr ln rn. l = Oc # Oc\<^bsup>ml\<^esup> @ Bk # Oc\<^bsup>Suc m\<^esup> \<and>
       
  3225                         r = Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>mr\<^esup> @ Bk\<^bsup>rn\<^esup> \<and>
       
  3226                         ml + mr = Suc rs \<and> mr > 0)"
       
  3227 
       
  3228 fun wadjust_erase2 :: "nat \<Rightarrow> nat \<Rightarrow> tape \<Rightarrow> bool"
       
  3229   where
       
  3230   "wadjust_erase2 m rs (l, r) = 
       
  3231      (\<exists> ln rn. l = Bk\<^bsup>ln\<^esup> @ Bk # Oc # Oc\<^bsup>Suc rs\<^esup> @ Bk # Oc\<^bsup>Suc m\<^esup> \<and>
       
  3232                      tl r = Bk\<^bsup>rn\<^esup>)"
       
  3233 
       
  3234 fun wadjust_on_left_moving_O :: "nat \<Rightarrow> nat \<Rightarrow> tape \<Rightarrow> bool"
       
  3235   where
       
  3236   "wadjust_on_left_moving_O m rs (l, r) = 
       
  3237         (\<exists> rn. l = Oc\<^bsup>Suc rs\<^esup> @ Bk # Oc\<^bsup>Suc m\<^esup> \<and>
       
  3238                   r = Oc # Bk\<^bsup>rn\<^esup>)"
       
  3239 
       
  3240 fun wadjust_on_left_moving_B :: "nat \<Rightarrow> nat \<Rightarrow> tape \<Rightarrow> bool"
       
  3241   where
       
  3242   "wadjust_on_left_moving_B m rs (l, r) = 
       
  3243          (\<exists> ln rn. l = Bk\<^bsup>ln\<^esup> @ Oc # Oc\<^bsup>Suc rs\<^esup> @ Bk # Oc\<^bsup>Suc m\<^esup> \<and>
       
  3244                    r = Bk\<^bsup>rn\<^esup>)"
       
  3245 
       
  3246 fun wadjust_on_left_moving :: "nat \<Rightarrow> nat \<Rightarrow> tape \<Rightarrow> bool"
       
  3247   where
       
  3248   "wadjust_on_left_moving m rs (l, r) = 
       
  3249       (wadjust_on_left_moving_O m rs (l, r) \<or>
       
  3250        wadjust_on_left_moving_B m rs (l, r))"
       
  3251 
       
  3252 fun wadjust_goon_left_moving_B :: "nat \<Rightarrow> nat \<Rightarrow> tape \<Rightarrow> bool"
       
  3253   where 
       
  3254   "wadjust_goon_left_moving_B m rs (l, r) = 
       
  3255         (\<exists> rn. l = Oc\<^bsup>Suc m\<^esup> \<and> 
       
  3256                r = Bk # Oc\<^bsup>Suc (Suc rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  3257 
       
  3258 fun wadjust_goon_left_moving_O :: "nat \<Rightarrow> nat \<Rightarrow> tape \<Rightarrow> bool"
       
  3259   where
       
  3260   "wadjust_goon_left_moving_O m rs (l, r) = 
       
  3261       (\<exists> ml mr rn. l = Oc\<^bsup>ml\<^esup> @ Bk # Oc\<^bsup>Suc m\<^esup> \<and>
       
  3262                       r = Oc\<^bsup>mr\<^esup> @ Bk\<^bsup>rn\<^esup> \<and> 
       
  3263                       ml + mr = Suc (Suc rs) \<and> mr > 0)"
       
  3264 
       
  3265 fun wadjust_goon_left_moving :: "nat \<Rightarrow> nat \<Rightarrow> tape \<Rightarrow> bool"
       
  3266   where
       
  3267   "wadjust_goon_left_moving m rs (l, r) = 
       
  3268             (wadjust_goon_left_moving_B m rs (l, r) \<or>
       
  3269              wadjust_goon_left_moving_O m rs (l, r))"
       
  3270 
       
  3271 fun wadjust_backto_standard_pos_B :: "nat \<Rightarrow> nat \<Rightarrow> tape \<Rightarrow> bool"
       
  3272   where
       
  3273   "wadjust_backto_standard_pos_B m rs (l, r) =
       
  3274         (\<exists> rn. l = [] \<and> 
       
  3275                r = Bk # Oc\<^bsup>Suc m \<^esup>@ Bk # Oc\<^bsup>Suc (Suc rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  3276 
       
  3277 fun wadjust_backto_standard_pos_O :: "nat \<Rightarrow> nat \<Rightarrow> tape \<Rightarrow> bool"
       
  3278   where
       
  3279   "wadjust_backto_standard_pos_O m rs (l, r) = 
       
  3280       (\<exists> ml mr rn. l = Oc\<^bsup>ml\<^esup> \<and>
       
  3281                       r = Oc\<^bsup>mr\<^esup> @ Bk # Oc\<^bsup>Suc (Suc rs)\<^esup> @ Bk\<^bsup>rn\<^esup> \<and> 
       
  3282                       ml + mr = Suc m \<and> mr > 0)"
       
  3283 
       
  3284 fun wadjust_backto_standard_pos :: "nat \<Rightarrow> nat \<Rightarrow> tape \<Rightarrow> bool"
       
  3285   where
       
  3286   "wadjust_backto_standard_pos m rs (l, r) = 
       
  3287         (wadjust_backto_standard_pos_B m rs (l, r) \<or> 
       
  3288         wadjust_backto_standard_pos_O m rs (l, r))"
       
  3289 
       
  3290 fun wadjust_stop :: "nat \<Rightarrow> nat \<Rightarrow> tape \<Rightarrow> bool"
       
  3291 where
       
  3292   "wadjust_stop m rs (l, r) =
       
  3293         (\<exists> rn. l = [Bk] \<and> 
       
  3294                r = Oc\<^bsup>Suc m \<^esup>@ Bk # Oc\<^bsup>Suc (Suc rs)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  3295 
       
  3296 declare wadjust_start.simps[simp del]  wadjust_loop_start.simps[simp del]
       
  3297         wadjust_loop_right_move.simps[simp del]  wadjust_loop_check.simps[simp del]
       
  3298         wadjust_loop_erase.simps[simp del] wadjust_loop_on_left_moving.simps[simp del]
       
  3299         wadjust_loop_right_move2.simps[simp del] wadjust_erase2.simps[simp del]
       
  3300         wadjust_on_left_moving_O.simps[simp del] wadjust_on_left_moving_B.simps[simp del]
       
  3301         wadjust_on_left_moving.simps[simp del] wadjust_goon_left_moving_B.simps[simp del]
       
  3302         wadjust_goon_left_moving_O.simps[simp del] wadjust_goon_left_moving.simps[simp del]
       
  3303         wadjust_backto_standard_pos.simps[simp del] wadjust_backto_standard_pos_B.simps[simp del]
       
  3304         wadjust_backto_standard_pos_O.simps[simp del] wadjust_stop.simps[simp del]
       
  3305 
       
  3306 fun wadjust_inv :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> tape \<Rightarrow> bool"
       
  3307   where
       
  3308   "wadjust_inv st m rs (l, r) = 
       
  3309        (if st = Suc 0 then wadjust_start m rs (l, r) 
       
  3310         else if st = Suc (Suc 0) then wadjust_loop_start m rs (l, r)
       
  3311         else if st = Suc (Suc (Suc 0)) then wadjust_loop_right_move m rs (l, r)
       
  3312         else if st = 4 then wadjust_loop_check m rs (l, r)
       
  3313         else if st = 5 then wadjust_loop_erase m rs (l, r)
       
  3314         else if st = 6 then wadjust_loop_on_left_moving m rs (l, r)
       
  3315         else if st = 7 then wadjust_loop_right_move2 m rs (l, r)
       
  3316         else if st = 8 then wadjust_erase2 m rs (l, r)
       
  3317         else if st = 9 then wadjust_on_left_moving m rs (l, r)
       
  3318         else if st = 10 then wadjust_goon_left_moving m rs (l, r)
       
  3319         else if st = 11 then wadjust_backto_standard_pos m rs (l, r)
       
  3320         else if st = 0 then wadjust_stop m rs (l, r)
       
  3321         else False
       
  3322 )"
       
  3323 
       
  3324 declare wadjust_inv.simps[simp del]
       
  3325 
       
  3326 fun wadjust_phase :: "nat \<Rightarrow> t_conf \<Rightarrow> nat"
       
  3327   where
       
  3328   "wadjust_phase rs (st, l, r) = 
       
  3329          (if st = 1 then 3 
       
  3330           else if st \<ge> 2 \<and> st \<le> 7 then 2
       
  3331           else if st \<ge> 8 \<and> st \<le> 11 then 1
       
  3332           else 0)"
       
  3333 
       
  3334 thm dropWhile.simps
       
  3335 
       
  3336 fun wadjust_stage :: "nat \<Rightarrow> t_conf \<Rightarrow> nat"
       
  3337   where
       
  3338   "wadjust_stage rs (st, l, r) = 
       
  3339            (if st \<ge> 2 \<and> st \<le> 7 then 
       
  3340                   rs - length (takeWhile (\<lambda> a. a = Oc) 
       
  3341                           (tl (dropWhile (\<lambda> a. a = Oc) (rev l @ r))))
       
  3342             else 0)"
       
  3343 
       
  3344 fun wadjust_state :: "nat \<Rightarrow> t_conf \<Rightarrow> nat"
       
  3345   where
       
  3346   "wadjust_state rs (st, l, r) = 
       
  3347        (if st \<ge> 2 \<and> st \<le> 7 then 8 - st
       
  3348         else if st \<ge> 8 \<and> st \<le> 11 then 12 - st
       
  3349         else 0)"
       
  3350 
       
  3351 fun wadjust_step :: "nat \<Rightarrow> t_conf \<Rightarrow> nat"
       
  3352   where
       
  3353   "wadjust_step rs (st, l, r) = 
       
  3354        (if st = 1 then (if hd r = Bk then 1
       
  3355                         else 0) 
       
  3356         else if st = 3 then length r
       
  3357         else if st = 5 then (if hd r = Oc then 1
       
  3358                              else 0)
       
  3359         else if st = 6 then length l
       
  3360         else if st = 8 then (if hd r = Oc then 1
       
  3361                              else 0)
       
  3362         else if st = 9 then length l
       
  3363         else if st = 10 then length l
       
  3364         else if st = 11 then (if hd r = Bk then 0
       
  3365                               else Suc (length l))
       
  3366         else 0)"
       
  3367 
       
  3368 fun wadjust_measure :: "(nat \<times> t_conf) \<Rightarrow> nat \<times> nat \<times> nat \<times> nat"
       
  3369   where
       
  3370   "wadjust_measure (rs, (st, l, r)) = 
       
  3371      (wadjust_phase rs (st, l, r), 
       
  3372       wadjust_stage rs (st, l, r),
       
  3373       wadjust_state rs (st, l, r), 
       
  3374       wadjust_step rs (st, l, r))"
       
  3375 
       
  3376 definition wadjust_le :: "((nat \<times> t_conf) \<times> nat \<times> t_conf) set"
       
  3377   where "wadjust_le \<equiv> (inv_image lex_square wadjust_measure)"
       
  3378 
       
  3379 lemma [intro]: "wf lex_square"
       
  3380 by(auto intro:wf_lex_prod simp: abacus.lex_pair_def lex_square_def 
       
  3381   abacus.lex_triple_def)
       
  3382 
       
  3383 lemma wf_wadjust_le[intro]: "wf wadjust_le"
       
  3384 by(auto intro:wf_inv_image simp: wadjust_le_def
       
  3385            abacus.lex_triple_def abacus.lex_pair_def)
       
  3386 
       
  3387 lemma [simp]: "wadjust_start m rs (c, []) = False"
       
  3388 apply(auto simp: wadjust_start.simps)
       
  3389 done
       
  3390 
       
  3391 lemma [simp]: "wadjust_loop_right_move m rs (c, []) \<Longrightarrow> c \<noteq> []"
       
  3392 apply(auto simp: wadjust_loop_right_move.simps)
       
  3393 done
       
  3394 
       
  3395 lemma [simp]: "wadjust_loop_right_move m rs (c, [])
       
  3396         \<Longrightarrow>  wadjust_loop_check m rs (Bk # c, [])"
       
  3397 apply(simp only: wadjust_loop_right_move.simps wadjust_loop_check.simps)
       
  3398 apply(auto)
       
  3399 apply(case_tac [!] mr, simp_all add: exp_ind_def)
       
  3400 done
       
  3401 
       
  3402 lemma [simp]: "wadjust_loop_check m rs (c, []) \<Longrightarrow> c \<noteq> []"
       
  3403 apply(simp only: wadjust_loop_check.simps, auto)
       
  3404 done
       
  3405  
       
  3406 lemma [simp]: "wadjust_loop_start m rs (c, []) = False"
       
  3407 apply(simp add: wadjust_loop_start.simps)
       
  3408 done
       
  3409 
       
  3410 lemma [simp]: "wadjust_loop_right_move m rs (c, []) \<Longrightarrow> 
       
  3411   wadjust_loop_right_move m rs (Bk # c, [])"
       
  3412 apply(simp only: wadjust_loop_right_move.simps)
       
  3413 apply(erule_tac exE)+
       
  3414 apply(auto)
       
  3415 apply(case_tac [!] mr, simp_all add: exp_ind_def)
       
  3416 done
       
  3417 
       
  3418 lemma [simp]: "wadjust_loop_check m rs (c, []) \<Longrightarrow> wadjust_erase2 m rs (tl c, [hd c])"
       
  3419 apply(simp only: wadjust_loop_check.simps wadjust_erase2.simps, auto)
       
  3420 apply(case_tac mr, simp_all add: exp_ind_def, auto)
       
  3421 done
       
  3422 
       
  3423 lemma [simp]: " wadjust_loop_erase m rs (c, [])
       
  3424     \<Longrightarrow> (c = [] \<longrightarrow> wadjust_loop_on_left_moving m rs ([], [Bk])) \<and>
       
  3425         (c \<noteq> [] \<longrightarrow> wadjust_loop_on_left_moving m rs (tl c, [hd c]))"
       
  3426 apply(simp add: wadjust_loop_erase.simps, auto)
       
  3427 apply(case_tac [!] mr, simp_all add: exp_ind_def)
       
  3428 done
       
  3429 
       
  3430 lemma [simp]: "wadjust_loop_on_left_moving m rs (c, []) = False"
       
  3431 apply(auto simp: wadjust_loop_on_left_moving.simps)
       
  3432 done
       
  3433 
       
  3434 
       
  3435 lemma [simp]: "wadjust_loop_right_move2 m rs (c, []) = False"
       
  3436 apply(auto simp: wadjust_loop_right_move2.simps)
       
  3437 done
       
  3438    
       
  3439 lemma [simp]: "wadjust_erase2 m rs ([], []) = False"
       
  3440 apply(auto simp: wadjust_erase2.simps)
       
  3441 done
       
  3442 
       
  3443 lemma [simp]: "wadjust_on_left_moving_B m rs 
       
  3444                  (Oc # Oc # Oc\<^bsup>rs\<^esup> @ Bk # Oc # Oc\<^bsup>m\<^esup>, [Bk])"
       
  3445 apply(simp add: wadjust_on_left_moving_B.simps, auto)
       
  3446 apply(rule_tac x = 0 in exI, simp add: exp_ind_def)
       
  3447 done
       
  3448 
       
  3449 lemma [simp]: "wadjust_on_left_moving_B m rs 
       
  3450                  (Bk\<^bsup>n\<^esup> @ Bk # Oc # Oc # Oc\<^bsup>rs\<^esup> @ Bk # Oc # Oc\<^bsup>m\<^esup>, [Bk])"
       
  3451 apply(simp add: wadjust_on_left_moving_B.simps exp_ind_def, auto)
       
  3452 apply(rule_tac x = "Suc n" in exI, simp add: exp_ind)
       
  3453 done
       
  3454 
       
  3455 lemma [simp]: "\<lbrakk>wadjust_erase2 m rs (c, []); c \<noteq> []\<rbrakk> \<Longrightarrow>
       
  3456             wadjust_on_left_moving m rs (tl c, [hd c])"
       
  3457 apply(simp only: wadjust_erase2.simps)
       
  3458 apply(erule_tac exE)+
       
  3459 apply(case_tac ln, simp_all add: exp_ind_def wadjust_on_left_moving.simps)
       
  3460 done
       
  3461 
       
  3462 lemma [simp]: "wadjust_erase2 m rs (c, [])
       
  3463     \<Longrightarrow> (c = [] \<longrightarrow> wadjust_on_left_moving m rs ([], [Bk])) \<and> 
       
  3464        (c \<noteq> [] \<longrightarrow> wadjust_on_left_moving m rs (tl c, [hd c]))"
       
  3465 apply(auto)
       
  3466 done
       
  3467 
       
  3468 lemma [simp]: "wadjust_on_left_moving m rs ([], []) = False"
       
  3469 apply(simp add: wadjust_on_left_moving.simps 
       
  3470   wadjust_on_left_moving_O.simps wadjust_on_left_moving_B.simps)
       
  3471 done
       
  3472 
       
  3473 lemma [simp]: "wadjust_on_left_moving_O m rs (c, []) = False"
       
  3474 apply(simp add: wadjust_on_left_moving_O.simps)
       
  3475 done
       
  3476 
       
  3477 lemma [simp]: " \<lbrakk>wadjust_on_left_moving_B m rs (c, []); c \<noteq> []; hd c = Bk\<rbrakk> \<Longrightarrow>
       
  3478                                       wadjust_on_left_moving_B m rs (tl c, [Bk])"
       
  3479 apply(simp add: wadjust_on_left_moving_B.simps, auto)
       
  3480 apply(case_tac [!] ln, simp_all add: exp_ind_def, auto)
       
  3481 done
       
  3482 
       
  3483 lemma [simp]: "\<lbrakk>wadjust_on_left_moving_B m rs (c, []); c \<noteq> []; hd c = Oc\<rbrakk> \<Longrightarrow>
       
  3484                                   wadjust_on_left_moving_O m rs (tl c, [Oc])"
       
  3485 apply(simp add: wadjust_on_left_moving_B.simps wadjust_on_left_moving_O.simps, auto)
       
  3486 apply(case_tac [!] ln, simp_all add: exp_ind_def)
       
  3487 done
       
  3488 
       
  3489 lemma [simp]: "\<lbrakk>wadjust_on_left_moving m rs (c, []); c \<noteq> []\<rbrakk> \<Longrightarrow> 
       
  3490   wadjust_on_left_moving m rs (tl c, [hd c])"
       
  3491 apply(simp add: wadjust_on_left_moving.simps)
       
  3492 apply(case_tac "hd c", simp_all)
       
  3493 done
       
  3494 
       
  3495 lemma [simp]: "wadjust_on_left_moving m rs (c, [])
       
  3496     \<Longrightarrow> (c = [] \<longrightarrow> wadjust_on_left_moving m rs ([], [Bk])) \<and> 
       
  3497        (c \<noteq> [] \<longrightarrow> wadjust_on_left_moving m rs (tl c, [hd c]))"
       
  3498 apply(auto)
       
  3499 done
       
  3500 
       
  3501 lemma [simp]: "wadjust_goon_left_moving m rs (c, []) = False"
       
  3502 apply(auto simp: wadjust_goon_left_moving.simps wadjust_goon_left_moving_B.simps
       
  3503                  wadjust_goon_left_moving_O.simps)
       
  3504 done
       
  3505 
       
  3506 lemma [simp]: "wadjust_backto_standard_pos m rs (c, []) = False"
       
  3507 apply(auto simp: wadjust_backto_standard_pos.simps
       
  3508  wadjust_backto_standard_pos_B.simps wadjust_backto_standard_pos_O.simps)
       
  3509 done
       
  3510 
       
  3511 lemma [simp]:
       
  3512   "wadjust_start m rs (c, Bk # list) \<Longrightarrow> 
       
  3513   (c = [] \<longrightarrow> wadjust_start m rs ([], Oc # list)) \<and> 
       
  3514   (c \<noteq> [] \<longrightarrow> wadjust_start m rs (c, Oc # list))"
       
  3515 apply(auto simp: wadjust_start.simps)
       
  3516 done
       
  3517 
       
  3518 lemma [simp]: "wadjust_loop_start m rs (c, Bk # list) = False"
       
  3519 apply(auto simp: wadjust_loop_start.simps)
       
  3520 done
       
  3521 
       
  3522 lemma [simp]: "wadjust_loop_right_move m rs (c, b) \<Longrightarrow> c \<noteq> []"
       
  3523 apply(simp only: wadjust_loop_right_move.simps, auto)
       
  3524 done
       
  3525 
       
  3526 lemma [simp]: "wadjust_loop_right_move m rs (c, Bk # list)
       
  3527     \<Longrightarrow> wadjust_loop_right_move m rs (Bk # c, list)"
       
  3528 apply(simp only: wadjust_loop_right_move.simps)
       
  3529 apply(erule_tac exE)+
       
  3530 apply(rule_tac x = ml in exI, simp)
       
  3531 apply(rule_tac x = mr in exI, simp)
       
  3532 apply(rule_tac x = "Suc nl" in exI, simp add: exp_ind_def)
       
  3533 apply(case_tac nr, simp, case_tac mr, simp_all add: exp_ind_def)
       
  3534 apply(rule_tac x = nat in exI, auto)
       
  3535 done
       
  3536 
       
  3537 lemma [simp]: "wadjust_loop_check m rs (c, b) \<Longrightarrow> c \<noteq> []"
       
  3538 apply(simp only: wadjust_loop_check.simps, auto)
       
  3539 done
       
  3540 
       
  3541 lemma [simp]: "wadjust_loop_check m rs (c, Bk # list)
       
  3542               \<Longrightarrow>  wadjust_erase2 m rs (tl c, hd c # Bk # list)"
       
  3543 apply(auto simp: wadjust_loop_check.simps wadjust_erase2.simps)
       
  3544 apply(case_tac [!] mr, simp_all add: exp_ind_def, auto)
       
  3545 done
       
  3546 
       
  3547 lemma [simp]: "wadjust_loop_erase m rs (c, b) \<Longrightarrow> c \<noteq> []"
       
  3548 apply(simp only: wadjust_loop_erase.simps, auto)
       
  3549 done
       
  3550 
       
  3551 declare wadjust_loop_on_left_moving_O.simps[simp del]
       
  3552         wadjust_loop_on_left_moving_B.simps[simp del]
       
  3553 
       
  3554 lemma [simp]: "\<lbrakk>wadjust_loop_erase m rs (c, Bk # list); hd c = Bk\<rbrakk>
       
  3555     \<Longrightarrow> wadjust_loop_on_left_moving_B m rs (tl c, Bk # Bk # list)"
       
  3556 apply(simp only: wadjust_loop_erase.simps 
       
  3557   wadjust_loop_on_left_moving_B.simps)
       
  3558 apply(erule_tac exE)+
       
  3559 apply(rule_tac x = ml in exI, rule_tac x = mr in exI, 
       
  3560       rule_tac x = ln in exI, rule_tac x = 0 in exI, simp)
       
  3561 apply(case_tac ln, simp_all add: exp_ind_def, auto)
       
  3562 apply(simp add: exp_ind exp_ind_def[THEN sym])
       
  3563 done
       
  3564 
       
  3565 lemma [simp]: "\<lbrakk>wadjust_loop_erase m rs (c, Bk # list); c \<noteq> []; hd c = Oc\<rbrakk> \<Longrightarrow>
       
  3566              wadjust_loop_on_left_moving_O m rs (tl c, Oc # Bk # list)"
       
  3567 apply(simp only: wadjust_loop_erase.simps wadjust_loop_on_left_moving_O.simps,
       
  3568        auto)
       
  3569 apply(case_tac [!] ln, simp_all add: exp_ind_def)
       
  3570 done
       
  3571 
       
  3572 lemma [simp]: "\<lbrakk>wadjust_loop_erase m rs (c, Bk # list); c \<noteq> []\<rbrakk> \<Longrightarrow> 
       
  3573                 wadjust_loop_on_left_moving m rs (tl c, hd c # Bk # list)"
       
  3574 apply(case_tac "hd c", simp_all add:wadjust_loop_on_left_moving.simps)
       
  3575 done
       
  3576 
       
  3577 lemma [simp]: "wadjust_loop_on_left_moving m rs (c, b) \<Longrightarrow> c \<noteq> []"
       
  3578 apply(simp add: wadjust_loop_on_left_moving.simps 
       
  3579 wadjust_loop_on_left_moving_O.simps wadjust_loop_on_left_moving_B.simps, auto)
       
  3580 done
       
  3581 
       
  3582 lemma [simp]: "wadjust_loop_on_left_moving_O m rs (c, Bk # list) = False"
       
  3583 apply(simp add: wadjust_loop_on_left_moving_O.simps)
       
  3584 done
       
  3585 
       
  3586 lemma [simp]: "\<lbrakk>wadjust_loop_on_left_moving_B m rs (c, Bk # list); hd c = Bk\<rbrakk>
       
  3587     \<Longrightarrow>  wadjust_loop_on_left_moving_B m rs (tl c, Bk # Bk # list)"
       
  3588 apply(simp only: wadjust_loop_on_left_moving_B.simps)
       
  3589 apply(erule_tac exE)+
       
  3590 apply(rule_tac x = ml in exI, rule_tac x = mr in exI)
       
  3591 apply(case_tac nl, simp_all add: exp_ind_def, auto)
       
  3592 apply(rule_tac x = "Suc nr" in exI, auto simp: exp_ind_def)
       
  3593 done
       
  3594 
       
  3595 lemma [simp]: "\<lbrakk>wadjust_loop_on_left_moving_B m rs (c, Bk # list); hd c = Oc\<rbrakk>
       
  3596     \<Longrightarrow> wadjust_loop_on_left_moving_O m rs (tl c, Oc # Bk # list)"
       
  3597 apply(simp only: wadjust_loop_on_left_moving_O.simps 
       
  3598                  wadjust_loop_on_left_moving_B.simps)
       
  3599 apply(erule_tac exE)+
       
  3600 apply(rule_tac x = ml in exI, rule_tac x = mr in exI)
       
  3601 apply(case_tac nl, simp_all add: exp_ind_def, auto)
       
  3602 done
       
  3603 
       
  3604 lemma [simp]: "wadjust_loop_on_left_moving m rs (c, Bk # list)
       
  3605             \<Longrightarrow> wadjust_loop_on_left_moving m rs (tl c, hd c # Bk # list)"
       
  3606 apply(simp add: wadjust_loop_on_left_moving.simps)
       
  3607 apply(case_tac "hd c", simp_all)
       
  3608 done
       
  3609 
       
  3610 lemma [simp]: "wadjust_loop_right_move2 m rs (c, b) \<Longrightarrow> c \<noteq> []"
       
  3611 apply(simp only: wadjust_loop_right_move2.simps, auto)
       
  3612 done
       
  3613 
       
  3614 lemma [simp]: "wadjust_loop_right_move2 m rs (c, Bk # list) \<Longrightarrow>  wadjust_loop_start m rs (c, Oc # list)"
       
  3615 apply(auto simp: wadjust_loop_right_move2.simps wadjust_loop_start.simps)
       
  3616 apply(case_tac ln, simp_all add: exp_ind_def)
       
  3617 apply(rule_tac x = 0 in exI, simp)
       
  3618 apply(rule_tac x = rn in exI, simp)
       
  3619 apply(rule_tac x = "Suc ml" in exI, simp add: exp_ind_def, auto)
       
  3620 apply(rule_tac x = "Suc nat" in exI, simp add: exp_ind)
       
  3621 apply(rule_tac x = rn in exI, auto)
       
  3622 apply(rule_tac x = "Suc ml" in exI, auto simp: exp_ind_def)
       
  3623 done
       
  3624 
       
  3625 lemma [simp]: "wadjust_erase2 m rs (c, Bk # list) \<Longrightarrow> c \<noteq> []"
       
  3626 apply(auto simp:wadjust_erase2.simps )
       
  3627 done
       
  3628 
       
  3629 lemma [simp]: "wadjust_erase2 m rs (c, Bk # list) \<Longrightarrow> 
       
  3630                  wadjust_on_left_moving m rs (tl c, hd c # Bk # list)"
       
  3631 apply(auto simp: wadjust_erase2.simps)
       
  3632 apply(case_tac ln, simp_all add: exp_ind_def wadjust_on_left_moving.simps 
       
  3633         wadjust_on_left_moving_O.simps wadjust_on_left_moving_B.simps)
       
  3634 apply(auto)
       
  3635 apply(rule_tac x = "(Suc (Suc rn))" in exI, simp add: exp_ind_def)
       
  3636 apply(rule_tac x = "Suc nat" in exI, simp add: exp_ind)
       
  3637 apply(rule_tac x = "(Suc (Suc rn))" in exI, simp add: exp_ind_def)
       
  3638 done
       
  3639 
       
  3640 lemma [simp]: "wadjust_on_left_moving m rs (c,b) \<Longrightarrow> c \<noteq> []"
       
  3641 apply(simp only:wadjust_on_left_moving.simps
       
  3642                 wadjust_on_left_moving_O.simps
       
  3643                 wadjust_on_left_moving_B.simps
       
  3644              , auto)
       
  3645 done
       
  3646 
       
  3647 lemma [simp]: "wadjust_on_left_moving_O m rs (c, Bk # list) = False"
       
  3648 apply(simp add: wadjust_on_left_moving_O.simps)
       
  3649 done
       
  3650 
       
  3651 lemma [simp]: "\<lbrakk>wadjust_on_left_moving_B m rs (c, Bk # list); hd c = Bk\<rbrakk>
       
  3652     \<Longrightarrow> wadjust_on_left_moving_B m rs (tl c, Bk # Bk # list)"
       
  3653 apply(auto simp: wadjust_on_left_moving_B.simps)
       
  3654 apply(case_tac ln, simp_all add: exp_ind_def, auto)
       
  3655 done
       
  3656 
       
  3657 lemma [simp]: "\<lbrakk>wadjust_on_left_moving_B m rs (c, Bk # list); hd c = Oc\<rbrakk>
       
  3658     \<Longrightarrow> wadjust_on_left_moving_O m rs (tl c, Oc # Bk # list)"
       
  3659 apply(auto simp: wadjust_on_left_moving_O.simps
       
  3660                  wadjust_on_left_moving_B.simps)
       
  3661 apply(case_tac ln, simp_all add: exp_ind_def)
       
  3662 done
       
  3663 
       
  3664 lemma [simp]: "wadjust_on_left_moving  m rs (c, Bk # list) \<Longrightarrow>  
       
  3665                   wadjust_on_left_moving m rs (tl c, hd c # Bk # list)"
       
  3666 apply(simp add: wadjust_on_left_moving.simps)
       
  3667 apply(case_tac "hd c", simp_all)
       
  3668 done
       
  3669 
       
  3670 lemma [simp]: "wadjust_goon_left_moving m rs (c, b) \<Longrightarrow> c \<noteq> []"
       
  3671 apply(simp add: wadjust_goon_left_moving.simps
       
  3672                 wadjust_goon_left_moving_B.simps
       
  3673                 wadjust_goon_left_moving_O.simps exp_ind_def, auto)
       
  3674 done
       
  3675 
       
  3676 lemma [simp]: "wadjust_goon_left_moving_O m rs (c, Bk # list) = False"
       
  3677 apply(simp add: wadjust_goon_left_moving_O.simps, auto)
       
  3678 apply(case_tac mr, simp_all add: exp_ind_def)
       
  3679 done
       
  3680 
       
  3681 lemma [simp]: "\<lbrakk>wadjust_goon_left_moving_B m rs (c, Bk # list); hd c = Bk\<rbrakk>
       
  3682     \<Longrightarrow> wadjust_backto_standard_pos_B m rs (tl c, Bk # Bk # list)"
       
  3683 apply(auto simp: wadjust_goon_left_moving_B.simps 
       
  3684                  wadjust_backto_standard_pos_B.simps exp_ind_def)
       
  3685 done
       
  3686 
       
  3687 lemma [simp]: "\<lbrakk>wadjust_goon_left_moving_B m rs (c, Bk # list); hd c = Oc\<rbrakk>
       
  3688     \<Longrightarrow> wadjust_backto_standard_pos_O m rs (tl c, Oc # Bk # list)"
       
  3689 apply(auto simp: wadjust_goon_left_moving_B.simps 
       
  3690                  wadjust_backto_standard_pos_O.simps exp_ind_def)
       
  3691 apply(rule_tac x = m in exI, simp, auto)
       
  3692 done
       
  3693 
       
  3694 lemma [simp]: "wadjust_goon_left_moving m rs (c, Bk # list) \<Longrightarrow>
       
  3695   wadjust_backto_standard_pos m rs (tl c, hd c # Bk # list)"
       
  3696 apply(case_tac "hd c", simp_all add: wadjust_backto_standard_pos.simps 
       
  3697                                      wadjust_goon_left_moving.simps)
       
  3698 done
       
  3699 
       
  3700 lemma [simp]: "wadjust_backto_standard_pos m rs (c, Bk # list) \<Longrightarrow>
       
  3701   (c = [] \<longrightarrow> wadjust_stop m rs ([Bk], list)) \<and> (c \<noteq> [] \<longrightarrow> wadjust_stop m rs (Bk # c, list))"
       
  3702 apply(auto simp: wadjust_backto_standard_pos.simps 
       
  3703                  wadjust_backto_standard_pos_B.simps
       
  3704                  wadjust_backto_standard_pos_O.simps wadjust_stop.simps)
       
  3705 apply(case_tac [!] mr, simp_all add: exp_ind_def)
       
  3706 done
       
  3707 
       
  3708 lemma [simp]: "wadjust_start m rs (c, Oc # list)
       
  3709               \<Longrightarrow> (c = [] \<longrightarrow> wadjust_loop_start m rs ([Oc], list)) \<and>
       
  3710                 (c \<noteq> [] \<longrightarrow> wadjust_loop_start m rs (Oc # c, list))"
       
  3711 apply(auto simp:wadjust_loop_start.simps wadjust_start.simps )
       
  3712 apply(rule_tac x = ln in exI, rule_tac x = rn in exI,
       
  3713       rule_tac x = "Suc 0" in exI, simp)
       
  3714 done
       
  3715 
       
  3716 lemma [simp]: "wadjust_loop_start m rs (c, b) \<Longrightarrow> c \<noteq> []"
       
  3717 apply(simp add: wadjust_loop_start.simps, auto)
       
  3718 done
       
  3719 
       
  3720 lemma [simp]: "wadjust_loop_start m rs (c, Oc # list)
       
  3721               \<Longrightarrow> wadjust_loop_right_move m rs (Oc # c, list)"
       
  3722 apply(simp add: wadjust_loop_start.simps wadjust_loop_right_move.simps, auto)
       
  3723 apply(rule_tac x = ml in exI, rule_tac x = mr in exI, 
       
  3724       rule_tac x = 0 in exI, simp)
       
  3725 apply(rule_tac x = "Suc ln" in exI, simp add: exp_ind, auto)
       
  3726 done
       
  3727 
       
  3728 lemma [simp]: "wadjust_loop_right_move m rs (c, Oc # list) \<Longrightarrow> 
       
  3729                        wadjust_loop_check m rs (Oc # c, list)"
       
  3730 apply(simp add: wadjust_loop_right_move.simps  
       
  3731                  wadjust_loop_check.simps, auto)
       
  3732 apply(rule_tac [!] x = ml in exI, simp_all, auto)
       
  3733 apply(case_tac nl, auto simp: exp_ind_def)
       
  3734 apply(rule_tac x = "mr - 1" in exI, case_tac mr, simp_all add: exp_ind_def)
       
  3735 apply(case_tac [!] nr, simp_all add: exp_ind_def, auto)
       
  3736 done
       
  3737 
       
  3738 lemma [simp]: "wadjust_loop_check m rs (c, Oc # list) \<Longrightarrow> 
       
  3739                wadjust_loop_erase m rs (tl c, hd c # Oc # list)"
       
  3740 apply(simp only: wadjust_loop_check.simps wadjust_loop_erase.simps)
       
  3741 apply(erule_tac exE)+
       
  3742 apply(rule_tac x = ml in exI, rule_tac x = mr in exI, auto)
       
  3743 apply(case_tac mr, simp_all add: exp_ind_def)
       
  3744 apply(case_tac rn, simp_all add: exp_ind_def)
       
  3745 done
       
  3746 
       
  3747 lemma [simp]: "wadjust_loop_erase m rs (c, Oc # list) \<Longrightarrow> 
       
  3748                 wadjust_loop_erase m rs (c, Bk # list)"
       
  3749 apply(auto simp: wadjust_loop_erase.simps)
       
  3750 done
       
  3751 
       
  3752 lemma [simp]: "wadjust_loop_on_left_moving_B m rs (c, Oc # list) = False"
       
  3753 apply(auto simp: wadjust_loop_on_left_moving_B.simps)
       
  3754 apply(case_tac nr, simp_all add: exp_ind_def)
       
  3755 done
       
  3756 
       
  3757 lemma [simp]: "wadjust_loop_on_left_moving m rs (c, Oc # list)
       
  3758            \<Longrightarrow> wadjust_loop_right_move2 m rs (Oc # c, list)"
       
  3759 apply(simp add:wadjust_loop_on_left_moving.simps)
       
  3760 apply(auto simp: wadjust_loop_on_left_moving_O.simps
       
  3761                  wadjust_loop_right_move2.simps)
       
  3762 done
       
  3763 
       
  3764 lemma [simp]: "wadjust_loop_right_move2 m rs (c, Oc # list) = False"
       
  3765 apply(auto simp: wadjust_loop_right_move2.simps )
       
  3766 apply(case_tac ln, simp_all add: exp_ind_def)
       
  3767 done
       
  3768 
       
  3769 lemma [simp]: "wadjust_erase2 m rs (c, Oc # list)
       
  3770               \<Longrightarrow> (c = [] \<longrightarrow> wadjust_erase2 m rs ([], Bk # list))
       
  3771                \<and> (c \<noteq> [] \<longrightarrow> wadjust_erase2 m rs (c, Bk # list))"
       
  3772 apply(auto simp: wadjust_erase2.simps )
       
  3773 done
       
  3774 
       
  3775 lemma [simp]: "wadjust_on_left_moving_B m rs (c, Oc # list) = False"
       
  3776 apply(auto simp: wadjust_on_left_moving_B.simps)
       
  3777 done
       
  3778 
       
  3779 lemma [simp]: "\<lbrakk>wadjust_on_left_moving_O m rs (c, Oc # list); hd c = Bk\<rbrakk> \<Longrightarrow> 
       
  3780          wadjust_goon_left_moving_B m rs (tl c, Bk # Oc # list)"
       
  3781 apply(auto simp: wadjust_on_left_moving_O.simps 
       
  3782      wadjust_goon_left_moving_B.simps exp_ind_def)
       
  3783 done
       
  3784 
       
  3785 lemma [simp]: "\<lbrakk>wadjust_on_left_moving_O m rs (c, Oc # list); hd c = Oc\<rbrakk>
       
  3786     \<Longrightarrow> wadjust_goon_left_moving_O m rs (tl c, Oc # Oc # list)"
       
  3787 apply(auto simp: wadjust_on_left_moving_O.simps 
       
  3788                  wadjust_goon_left_moving_O.simps exp_ind_def)
       
  3789 apply(rule_tac x = rs in exI, simp)
       
  3790 apply(auto simp: exp_ind_def numeral_2_eq_2)
       
  3791 done
       
  3792 
       
  3793 
       
  3794 lemma [simp]: "wadjust_on_left_moving m rs (c, Oc # list) \<Longrightarrow> 
       
  3795               wadjust_goon_left_moving m rs (tl c, hd c # Oc # list)"
       
  3796 apply(simp add: wadjust_on_left_moving.simps   
       
  3797                  wadjust_goon_left_moving.simps)
       
  3798 apply(case_tac "hd c", simp_all)
       
  3799 done
       
  3800 
       
  3801 lemma [simp]: "wadjust_on_left_moving m rs (c, Oc # list) \<Longrightarrow> 
       
  3802   wadjust_goon_left_moving m rs (tl c, hd c # Oc # list)"
       
  3803 apply(simp add: wadjust_on_left_moving.simps 
       
  3804   wadjust_goon_left_moving.simps)
       
  3805 apply(case_tac "hd c", simp_all)
       
  3806 done
       
  3807 
       
  3808 lemma [simp]: "wadjust_goon_left_moving_B m rs (c, Oc # list) = False"
       
  3809 apply(auto simp: wadjust_goon_left_moving_B.simps)
       
  3810 done
       
  3811 
       
  3812 lemma [simp]: "\<lbrakk>wadjust_goon_left_moving_O m rs (c, Oc # list); hd c = Bk\<rbrakk> 
       
  3813                \<Longrightarrow> wadjust_goon_left_moving_B m rs (tl c, Bk # Oc # list)"
       
  3814 apply(auto simp: wadjust_goon_left_moving_O.simps wadjust_goon_left_moving_B.simps)
       
  3815 apply(case_tac [!] ml, auto simp: exp_ind_def)
       
  3816 done
       
  3817 
       
  3818 lemma  [simp]: "\<lbrakk>wadjust_goon_left_moving_O m rs (c, Oc # list); hd c = Oc\<rbrakk> \<Longrightarrow> 
       
  3819   wadjust_goon_left_moving_O m rs (tl c, Oc # Oc # list)"
       
  3820 apply(auto simp: wadjust_goon_left_moving_O.simps wadjust_goon_left_moving_B.simps)
       
  3821 apply(rule_tac x = "ml - 1" in exI, simp)
       
  3822 apply(case_tac ml, simp_all add: exp_ind_def)
       
  3823 apply(rule_tac x = "Suc mr" in exI, auto simp: exp_ind_def)
       
  3824 done
       
  3825 
       
  3826 lemma [simp]: "wadjust_goon_left_moving m rs (c, Oc # list) \<Longrightarrow> 
       
  3827   wadjust_goon_left_moving m rs (tl c, hd c # Oc # list)"
       
  3828 apply(simp add: wadjust_goon_left_moving.simps)
       
  3829 apply(case_tac "hd c", simp_all)
       
  3830 done
       
  3831 
       
  3832 lemma [simp]: "wadjust_backto_standard_pos_B m rs (c, Oc # list) = False"
       
  3833 apply(simp add: wadjust_backto_standard_pos_B.simps)
       
  3834 done
       
  3835 
       
  3836 lemma [simp]: "wadjust_backto_standard_pos_O m rs (c, Bk # xs) = False"
       
  3837 apply(simp add: wadjust_backto_standard_pos_O.simps, auto)
       
  3838 apply(case_tac mr, simp_all add: exp_ind_def)
       
  3839 done
       
  3840 
       
  3841 
       
  3842 
       
  3843 lemma [simp]: "wadjust_backto_standard_pos_O m rs ([], Oc # list) \<Longrightarrow> 
       
  3844   wadjust_backto_standard_pos_B m rs ([], Bk # Oc # list)"
       
  3845 apply(auto simp: wadjust_backto_standard_pos_O.simps
       
  3846                  wadjust_backto_standard_pos_B.simps)
       
  3847 apply(rule_tac x = rn in exI, simp)
       
  3848 apply(case_tac ml, simp_all add: exp_ind_def)
       
  3849 done
       
  3850 
       
  3851 
       
  3852 lemma [simp]: 
       
  3853   "\<lbrakk>wadjust_backto_standard_pos_O m rs (c, Oc # list); c \<noteq> []; hd c = Bk\<rbrakk>
       
  3854   \<Longrightarrow> wadjust_backto_standard_pos_B m rs (tl c, Bk # Oc # list)"
       
  3855 apply(simp add:wadjust_backto_standard_pos_O.simps 
       
  3856         wadjust_backto_standard_pos_B.simps, auto)
       
  3857 apply(case_tac [!] ml, simp_all add: exp_ind_def)
       
  3858 done 
       
  3859 
       
  3860 lemma [simp]: "\<lbrakk>wadjust_backto_standard_pos_O m rs (c, Oc # list); c \<noteq> []; hd c = Oc\<rbrakk>
       
  3861           \<Longrightarrow>  wadjust_backto_standard_pos_O m rs (tl c, Oc # Oc # list)"
       
  3862 apply(simp add: wadjust_backto_standard_pos_O.simps, auto)
       
  3863 apply(case_tac ml, simp_all add: exp_ind_def, auto)
       
  3864 apply(rule_tac x = nat in exI, auto simp: exp_ind_def)
       
  3865 done
       
  3866 
       
  3867 lemma [simp]: "wadjust_backto_standard_pos m rs (c, Oc # list)
       
  3868   \<Longrightarrow> (c = [] \<longrightarrow> wadjust_backto_standard_pos m rs ([], Bk # Oc # list)) \<and> 
       
  3869  (c \<noteq> [] \<longrightarrow> wadjust_backto_standard_pos m rs (tl c, hd c # Oc # list))"
       
  3870 apply(auto simp: wadjust_backto_standard_pos.simps)
       
  3871 apply(case_tac "hd c", simp_all)
       
  3872 done
       
  3873 thm wadjust_loop_right_move.simps
       
  3874 
       
  3875 lemma [simp]: "wadjust_loop_right_move m rs (c, []) = False"
       
  3876 apply(simp only: wadjust_loop_right_move.simps)
       
  3877 apply(rule_tac iffI)
       
  3878 apply(erule_tac exE)+
       
  3879 apply(case_tac nr, simp_all add: exp_ind_def)
       
  3880 apply(case_tac mr, simp_all add: exp_ind_def)
       
  3881 done
       
  3882 
       
  3883 lemma [simp]: "wadjust_loop_erase m rs (c, []) = False"
       
  3884 apply(simp only: wadjust_loop_erase.simps, auto)
       
  3885 apply(case_tac mr, simp_all add: exp_ind_def)
       
  3886 done
       
  3887 
       
  3888 lemma [simp]: "\<lbrakk>Suc (Suc rs) = a;  wadjust_loop_erase m rs (c, Bk # list)\<rbrakk>
       
  3889   \<Longrightarrow> a - length (takeWhile (\<lambda>a. a = Oc) (tl (dropWhile (\<lambda>a. a = Oc) (rev (tl c) @ hd c # Bk # list))))
       
  3890   < a - length (takeWhile (\<lambda>a. a = Oc) (tl (dropWhile (\<lambda>a. a = Oc) (rev c @ Bk # list)))) \<or>
       
  3891   a - length (takeWhile (\<lambda>a. a = Oc) (tl (dropWhile (\<lambda>a. a = Oc) (rev (tl c) @ hd c # Bk # list)))) =
       
  3892   a - length (takeWhile (\<lambda>a. a = Oc) (tl (dropWhile (\<lambda>a. a = Oc) (rev c @ Bk # list))))"
       
  3893 apply(simp only: wadjust_loop_erase.simps)
       
  3894 apply(rule_tac disjI2)
       
  3895 apply(case_tac c, simp, simp)
       
  3896 done
       
  3897 
       
  3898 lemma [simp]:
       
  3899   "\<lbrakk>Suc (Suc rs) = a;  wadjust_loop_on_left_moving m rs (c, Bk # list)\<rbrakk>
       
  3900   \<Longrightarrow> a - length (takeWhile (\<lambda>a. a = Oc) (tl (dropWhile (\<lambda>a. a = Oc) (rev (tl c) @ hd c # Bk # list))))
       
  3901   < a - length (takeWhile (\<lambda>a. a = Oc) (tl (dropWhile (\<lambda>a. a = Oc) (rev c @ Bk # list)))) \<or>
       
  3902   a - length (takeWhile (\<lambda>a. a = Oc) (tl (dropWhile (\<lambda>a. a = Oc) (rev (tl c) @ hd c # Bk # list)))) =
       
  3903   a - length (takeWhile (\<lambda>a. a = Oc) (tl (dropWhile (\<lambda>a. a = Oc) (rev c @ Bk # list))))"
       
  3904 apply(subgoal_tac "c \<noteq> []")
       
  3905 apply(case_tac c, simp_all)
       
  3906 done
       
  3907 
       
  3908 lemma dropWhile_exp1: "dropWhile (\<lambda>a. a = Oc) (Oc\<^bsup>n\<^esup> @ xs) = dropWhile (\<lambda>a. a = Oc) xs"
       
  3909 apply(induct n, simp_all add: exp_ind_def)
       
  3910 done
       
  3911 lemma takeWhile_exp1: "takeWhile (\<lambda>a. a = Oc) (Oc\<^bsup>n\<^esup> @ xs) = Oc\<^bsup>n\<^esup> @ takeWhile (\<lambda>a. a = Oc) xs"
       
  3912 apply(induct n, simp_all add: exp_ind_def)
       
  3913 done
       
  3914 
       
  3915 lemma [simp]: "\<lbrakk>Suc (Suc rs) = a;  wadjust_loop_right_move2 m rs (c, Bk # list)\<rbrakk>
       
  3916               \<Longrightarrow> a - length (takeWhile (\<lambda>a. a = Oc) (tl (dropWhile (\<lambda>a. a = Oc) (rev c @ Oc # list))))
       
  3917                  < a - length (takeWhile (\<lambda>a. a = Oc) (tl (dropWhile (\<lambda>a. a = Oc) (rev c @ Bk # list))))"
       
  3918 apply(simp add: wadjust_loop_right_move2.simps, auto)
       
  3919 apply(simp add: dropWhile_exp1 takeWhile_exp1)
       
  3920 apply(case_tac ln, simp, simp add: exp_ind_def)
       
  3921 done
       
  3922 
       
  3923 lemma [simp]: "wadjust_loop_check m rs ([], b) = False"
       
  3924 apply(simp add: wadjust_loop_check.simps)
       
  3925 done
       
  3926 
       
  3927 lemma [simp]: "\<lbrakk>Suc (Suc rs) = a;  wadjust_loop_check m rs (c, Oc # list)\<rbrakk>
       
  3928   \<Longrightarrow> a - length (takeWhile (\<lambda>a. a = Oc) (tl (dropWhile (\<lambda>a. a = Oc) (rev (tl c) @ hd c # Oc # list))))
       
  3929   < a - length (takeWhile (\<lambda>a. a = Oc) (tl (dropWhile (\<lambda>a. a = Oc) (rev c @ Oc # list)))) \<or>
       
  3930   a - length (takeWhile (\<lambda>a. a = Oc) (tl (dropWhile (\<lambda>a. a = Oc) (rev (tl c) @ hd c # Oc # list)))) =
       
  3931   a - length (takeWhile (\<lambda>a. a = Oc) (tl (dropWhile (\<lambda>a. a = Oc) (rev c @ Oc # list))))"
       
  3932 apply(case_tac "c", simp_all)
       
  3933 done
       
  3934 
       
  3935 lemma [simp]: 
       
  3936   "\<lbrakk>Suc (Suc rs) = a;  wadjust_loop_erase m rs (c, Oc # list)\<rbrakk>
       
  3937   \<Longrightarrow> a - length (takeWhile (\<lambda>a. a = Oc) (tl (dropWhile (\<lambda>a. a = Oc) (rev c @ Bk # list))))
       
  3938   < a - length (takeWhile (\<lambda>a. a = Oc) (tl (dropWhile (\<lambda>a. a = Oc) (rev c @ Oc # list)))) \<or>
       
  3939   a - length (takeWhile (\<lambda>a. a = Oc) (tl (dropWhile (\<lambda>a. a = Oc) (rev c @ Bk # list)))) =
       
  3940   a - length (takeWhile (\<lambda>a. a = Oc) (tl (dropWhile (\<lambda>a. a = Oc) (rev c @ Oc # list))))"
       
  3941 apply(simp add: wadjust_loop_erase.simps)
       
  3942 apply(rule_tac disjI2)
       
  3943 apply(auto)
       
  3944 apply(simp add: dropWhile_exp1 takeWhile_exp1)
       
  3945 done
       
  3946 
       
  3947 declare numeral_2_eq_2[simp del]
       
  3948 
       
  3949 lemma wadjust_correctness:
       
  3950   shows "let P = (\<lambda> (len, st, l, r). st = 0) in 
       
  3951   let Q = (\<lambda> (len, st, l, r). wadjust_inv st m rs (l, r)) in 
       
  3952   let f = (\<lambda> stp. (Suc (Suc rs),  steps (Suc 0, Bk # Oc\<^bsup>Suc m\<^esup>, 
       
  3953                 Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk #  Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>rn\<^esup>) t_wcode_adjust stp)) in
       
  3954     \<exists> n .P (f n) \<and> Q (f n)"
       
  3955 proof -
       
  3956   let ?P = "(\<lambda> (len, st, l, r). st = 0)"
       
  3957   let ?Q = "\<lambda> (len, st, l, r). wadjust_inv st m rs (l, r)"
       
  3958   let ?f = "\<lambda> stp. (Suc (Suc rs),  steps (Suc 0, Bk # Oc\<^bsup>Suc m\<^esup>, 
       
  3959                 Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>rn\<^esup>) t_wcode_adjust stp)"
       
  3960   have "\<exists> n. ?P (?f n) \<and> ?Q (?f n)"
       
  3961   proof(rule_tac halt_lemma2)
       
  3962     show "wf wadjust_le" by auto
       
  3963   next
       
  3964     show "\<forall> n. \<not> ?P (?f n) \<and> ?Q (?f n) \<longrightarrow> 
       
  3965                  ?Q (?f (Suc n)) \<and> (?f (Suc n), ?f n) \<in> wadjust_le"
       
  3966     proof(rule_tac allI, rule_tac impI, case_tac "?f n", 
       
  3967             simp add: tstep_red tstep.simps, rule_tac conjI, erule_tac conjE,
       
  3968           erule_tac conjE)      
       
  3969       fix n a b c d
       
  3970       assume "0 < b" "wadjust_inv b m rs (c, d)" "Suc (Suc rs) = a"
       
  3971       thus "case case fetch t_wcode_adjust b (case d of [] \<Rightarrow> Bk | x # xs \<Rightarrow> x)
       
  3972         of (ac, ns) \<Rightarrow> (ns, new_tape ac (c, d)) of (st, x) \<Rightarrow> wadjust_inv st m rs x"
       
  3973         apply(case_tac d, simp, case_tac [2] aa)
       
  3974         apply(simp_all add: wadjust_inv.simps wadjust_le_def new_tape.simps
       
  3975           abacus.lex_triple_def abacus.lex_pair_def lex_square_def
       
  3976           split: if_splits)
       
  3977         done
       
  3978     next
       
  3979       fix n a b c d
       
  3980       assume "0 < b \<and> wadjust_inv b m rs (c, d)"
       
  3981         "Suc (Suc rs) = a \<and> steps (Suc 0, Bk # Oc\<^bsup>Suc m\<^esup>,
       
  3982          Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>rn\<^esup>) t_wcode_adjust n = (b, c, d)"
       
  3983       thus "((a, case fetch t_wcode_adjust b (case d of [] \<Rightarrow> Bk | x # xs \<Rightarrow> x)
       
  3984         of (ac, ns) \<Rightarrow> (ns, new_tape ac (c, d))), a, b, c, d) \<in> wadjust_le"
       
  3985       proof(erule_tac conjE, erule_tac conjE, erule_tac conjE)
       
  3986         assume "0 < b" "wadjust_inv b m rs (c, d)" "Suc (Suc rs) = a"
       
  3987         thus "?thesis"
       
  3988           apply(case_tac d, case_tac [2] aa)
       
  3989           apply(simp_all add: wadjust_inv.simps wadjust_le_def new_tape.simps
       
  3990             abacus.lex_triple_def abacus.lex_pair_def lex_square_def
       
  3991             split: if_splits)
       
  3992           done
       
  3993       qed
       
  3994     qed
       
  3995   next
       
  3996     show "?Q (?f 0)"
       
  3997       apply(simp add: steps.simps wadjust_inv.simps wadjust_start.simps)
       
  3998       apply(rule_tac x = ln in exI,auto)
       
  3999       done
       
  4000   next
       
  4001     show "\<not> ?P (?f 0)"
       
  4002       apply(simp add: steps.simps)
       
  4003       done
       
  4004   qed
       
  4005   thus "?thesis"
       
  4006     apply(auto)
       
  4007     done
       
  4008 qed
       
  4009 
       
  4010 lemma [intro]: "t_correct t_wcode_adjust"
       
  4011 apply(auto simp: t_wcode_adjust_def t_correct.simps iseven_def)
       
  4012 apply(rule_tac x = 11 in exI, simp)
       
  4013 done
       
  4014 
       
  4015 lemma wcode_lemma_pre':
       
  4016   "args \<noteq> [] \<Longrightarrow> 
       
  4017   \<exists> stp rn. steps (Suc 0, [], <m # args>) 
       
  4018               ((t_wcode_prepare |+| t_wcode_main) |+| t_wcode_adjust) stp
       
  4019   = (0,  [Bk],  Oc\<^bsup>Suc m\<^esup> @ Bk # Oc\<^bsup>Suc (bl_bin (<args>))\<^esup> @ Bk\<^bsup>rn\<^esup>)" 
       
  4020 proof -
       
  4021   let ?P1 = "\<lambda> (l, r). l = [] \<and> r = <m # args>"
       
  4022   let ?Q1 = "\<lambda>(l, r). l = Bk # Oc\<^bsup>Suc m\<^esup> \<and>
       
  4023     (\<exists>ln rn. r = Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>bl_bin (<args>)\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  4024   let ?P2 = ?Q1
       
  4025   let ?Q2 = "\<lambda> (l, r). (wadjust_stop m (bl_bin (<args>) - 1) (l, r))"
       
  4026   let ?P3 = "\<lambda> tp. False"
       
  4027   assume h: "args \<noteq> []"
       
  4028   have "?P1 \<turnstile>-> \<lambda> tp. (\<exists> stp tp'. steps (Suc 0, tp)
       
  4029                       ((t_wcode_prepare |+| t_wcode_main) |+| t_wcode_adjust) stp = (0, tp') \<and> ?Q2 tp')"
       
  4030   proof(rule_tac turing_merge.t_merge_halt[of "t_wcode_prepare |+| t_wcode_main" 
       
  4031                t_wcode_adjust ?P1 ?P2 ?P3 ?P3 ?Q1 ?Q2], 
       
  4032         auto simp: turing_merge_def)
       
  4033 
       
  4034     show "\<exists>stp. case steps (Suc 0, [], <m # args>) (t_wcode_prepare |+| t_wcode_main) stp of
       
  4035           (st, tp') \<Rightarrow> st = 0 \<and> (case tp' of (l, r) \<Rightarrow> l = Bk # Oc\<^bsup>Suc m\<^esup> \<and>
       
  4036                 (\<exists>ln rn. r = Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # Oc\<^bsup>bl_bin (<args>)\<^esup> @ Bk\<^bsup>rn\<^esup>))"
       
  4037       using h prepare_mainpart_lemma[of args m]
       
  4038       apply(auto)
       
  4039       apply(rule_tac x = stp in exI, simp)
       
  4040       apply(rule_tac x = ln in exI, auto)
       
  4041       done
       
  4042   next
       
  4043     fix ln rn
       
  4044     show "\<exists>stp. case steps (Suc 0, Bk # Oc\<^bsup>Suc m\<^esup>, Bk # Oc # Bk\<^bsup>ln\<^esup> @ Bk # Bk # 
       
  4045                                Oc\<^bsup>bl_bin (<args>)\<^esup> @ Bk\<^bsup>rn\<^esup>) t_wcode_adjust stp of
       
  4046       (st, tp') \<Rightarrow> st = 0 \<and> wadjust_stop m (bl_bin (<args>) - Suc 0) tp'"
       
  4047       using wadjust_correctness[of m "bl_bin (<args>) - 1" "Suc ln" rn]
       
  4048       apply(subgoal_tac "bl_bin (<args>) > 0", auto simp: wadjust_inv.simps)
       
  4049       apply(rule_tac x = n in exI, simp add: exp_ind)
       
  4050       using h
       
  4051       apply(case_tac args, simp_all, case_tac list,
       
  4052             simp_all add: tape_of_nl_abv  tape_of_nat_list.simps exp_ind_def
       
  4053             bl_bin.simps)
       
  4054       done     
       
  4055   next
       
  4056     show "?Q1 \<turnstile>-> ?P2"
       
  4057       by(simp add: t_imply_def)
       
  4058   qed
       
  4059   thus "\<exists>stp rn. steps (Suc 0, [], <m # args>) ((t_wcode_prepare |+| t_wcode_main) |+| 
       
  4060         t_wcode_adjust) stp = (0, [Bk], Oc\<^bsup>Suc m\<^esup> @ Bk # Oc\<^bsup>Suc (bl_bin (<args>))\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  4061     apply(simp add: t_imply_def)
       
  4062     apply(erule_tac exE)+
       
  4063     apply(subgoal_tac "bl_bin (<args>) > 0", auto simp: wadjust_stop.simps)
       
  4064     using h
       
  4065     apply(case_tac args, simp_all, case_tac list,  
       
  4066           simp_all add: tape_of_nl_abv  tape_of_nat_list.simps exp_ind_def
       
  4067             bl_bin.simps)
       
  4068     done
       
  4069 qed
       
  4070 
       
  4071 text {*
       
  4072   The initialization TM @{text "t_wcode"}.
       
  4073   *}
       
  4074 definition t_wcode :: "tprog"
       
  4075   where
       
  4076   "t_wcode = (t_wcode_prepare |+| t_wcode_main) |+| t_wcode_adjust"
       
  4077 
       
  4078 
       
  4079 text {*
       
  4080   The correctness of @{text "t_wcode"}.
       
  4081   *}
       
  4082 lemma wcode_lemma_1:
       
  4083   "args \<noteq> [] \<Longrightarrow> 
       
  4084   \<exists> stp ln rn. steps (Suc 0, [], <m # args>)  (t_wcode) stp = 
       
  4085               (0,  [Bk],  Oc\<^bsup>Suc m\<^esup> @ Bk # Oc\<^bsup>Suc (bl_bin (<args>))\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  4086 apply(simp add: wcode_lemma_pre' t_wcode_def)
       
  4087 done
       
  4088 
       
  4089 lemma wcode_lemma: 
       
  4090   "args \<noteq> [] \<Longrightarrow> 
       
  4091   \<exists> stp ln rn. steps (Suc 0, [], <m # args>)  (t_wcode) stp = 
       
  4092               (0,  [Bk],  <[m ,bl_bin (<args>)]> @ Bk\<^bsup>rn\<^esup>)"
       
  4093 using wcode_lemma_1[of args m]
       
  4094 apply(simp add: t_wcode_def tape_of_nl_abv tape_of_nat_list.simps)
       
  4095 done
       
  4096 
       
  4097 section {* The universal TM @{text "UTM"} *}
       
  4098 
       
  4099 text {*
       
  4100   This section gives the explicit construction of {\em Universal Turing Machine}, defined as @{text "UTM"} and proves its 
       
  4101   correctness. It is pretty easy by composing the partial results we have got so far.
       
  4102   *}
       
  4103 
       
  4104 
       
  4105 definition UTM :: "tprog"
       
  4106   where
       
  4107   "UTM = (let (aprog, rs_pos, a_md) = rec_ci rec_F in 
       
  4108           let abc_F = aprog [+] dummy_abc (Suc (Suc 0)) in 
       
  4109           (t_wcode |+| (tm_of abc_F @ tMp (Suc (Suc 0)) (start_of (layout_of abc_F) 
       
  4110                                                    (length abc_F) - Suc 0))))"
       
  4111 
       
  4112 definition F_aprog :: "abc_prog"
       
  4113   where
       
  4114   "F_aprog \<equiv> (let (aprog, rs_pos, a_md) = rec_ci rec_F in 
       
  4115                        aprog [+] dummy_abc (Suc (Suc 0)))"
       
  4116 
       
  4117 definition F_tprog :: "tprog"
       
  4118   where
       
  4119   "F_tprog = tm_of (F_aprog)"
       
  4120 
       
  4121 definition t_utm :: "tprog"
       
  4122   where
       
  4123   "t_utm \<equiv>
       
  4124      (F_tprog) @ tMp (Suc (Suc 0)) (start_of (layout_of (F_aprog)) 
       
  4125                                   (length (F_aprog)) - Suc 0)"
       
  4126 
       
  4127 definition UTM_pre :: "tprog"
       
  4128   where
       
  4129   "UTM_pre = t_wcode |+| t_utm"
       
  4130 
       
  4131 lemma F_abc_halt_eq:
       
  4132   "\<lbrakk>turing_basic.t_correct tp; 
       
  4133     length lm = k;
       
  4134     steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup>@Bk\<^bsup>n\<^esup>);
       
  4135     rs > 0\<rbrakk>
       
  4136     \<Longrightarrow> \<exists> stp m. abc_steps_l (0, [code tp, bl2wc (<lm>)]) (F_aprog) stp =
       
  4137                        (length (F_aprog), code tp # bl2wc (<lm>) # (rs - 1) # 0\<^bsup>m\<^esup>)"
       
  4138 apply(drule_tac  F_t_halt_eq, simp, simp, simp)
       
  4139 apply(case_tac "rec_ci rec_F")
       
  4140 apply(frule_tac abc_append_dummy_complie, simp, simp, erule_tac exE,
       
  4141       erule_tac exE)
       
  4142 apply(rule_tac x = stp in exI, rule_tac x = m in exI)
       
  4143 apply(simp add: F_aprog_def dummy_abc_def)
       
  4144 done
       
  4145 
       
  4146 lemma F_abc_utm_halt_eq: 
       
  4147   "\<lbrakk>rs > 0; 
       
  4148   abc_steps_l (0, [code tp, bl2wc (<lm>)]) F_aprog stp =
       
  4149         (length F_aprog, code tp #  bl2wc (<lm>) # (rs - 1) # 0\<^bsup>m\<^esup>)\<rbrakk>
       
  4150   \<Longrightarrow> \<exists>stp m n.(steps (Suc 0, [Bk, Bk], <[code tp, bl2wc (<lm>)]>) t_utm stp =
       
  4151                                              (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>))"
       
  4152   thm abacus_turing_eq_halt
       
  4153   using abacus_turing_eq_halt
       
  4154   [of "layout_of F_aprog" "F_aprog" "F_tprog" "length (F_aprog)" 
       
  4155     "[code tp, bl2wc (<lm>)]" stp "code tp # bl2wc (<lm>) # (rs - 1) # 0\<^bsup>m\<^esup>" "Suc (Suc 0)"
       
  4156     "start_of (layout_of (F_aprog)) (length (F_aprog))" "[]" 0]
       
  4157 apply(simp add: F_tprog_def t_utm_def abc_lm_v.simps nth_append)
       
  4158 apply(erule_tac exE)+
       
  4159 apply(rule_tac x = stpa in exI, rule_tac x = "Suc (Suc ma)" in exI, 
       
  4160        rule_tac x = l in exI, simp add: exp_ind)
       
  4161 done
       
  4162 
       
  4163 declare tape_of_nl_abv_cons[simp del]
       
  4164 
       
  4165 lemma t_utm_halt_eq': 
       
  4166   "\<lbrakk>turing_basic.t_correct tp;
       
  4167    0 < rs;
       
  4168   steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm::nat list>) tp stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup>@Bk\<^bsup>n\<^esup>)\<rbrakk>
       
  4169   \<Longrightarrow>  \<exists>stp m n. steps (Suc 0, [Bk, Bk], <[code tp, bl2wc (<lm>)]>) t_utm stp = 
       
  4170                                                 (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>)"
       
  4171 apply(drule_tac  l = l in F_abc_halt_eq, simp, simp, simp)
       
  4172 apply(erule_tac exE, erule_tac exE)
       
  4173 apply(rule_tac F_abc_utm_halt_eq, simp_all)
       
  4174 done
       
  4175 
       
  4176 lemma [simp]: "tinres xs (xs @ Bk\<^bsup>i\<^esup>)"
       
  4177 apply(auto simp: tinres_def)
       
  4178 done
       
  4179 
       
  4180 lemma [elim]: "\<lbrakk>rs > 0; Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>na\<^esup> = c @ Bk\<^bsup>n\<^esup>\<rbrakk>
       
  4181         \<Longrightarrow> \<exists>n. c = Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>"
       
  4182 apply(case_tac "na > n")
       
  4183 apply(subgoal_tac "\<exists> d. na = d + n", auto simp: exp_add)
       
  4184 apply(rule_tac x = "na - n" in exI, simp)
       
  4185 apply(subgoal_tac "\<exists> d. n = d + na", auto simp: exp_add)
       
  4186 apply(case_tac rs, simp_all add: exp_ind, case_tac d, 
       
  4187            simp_all add: exp_ind)
       
  4188 apply(rule_tac x = "n - na" in exI, simp)
       
  4189 done
       
  4190 
       
  4191 
       
  4192 lemma t_utm_halt_eq'': 
       
  4193   "\<lbrakk>turing_basic.t_correct tp;
       
  4194    0 < rs;
       
  4195    steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm::nat list>) tp stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup>@Bk\<^bsup>n\<^esup>)\<rbrakk>
       
  4196   \<Longrightarrow>  \<exists>stp m n. steps (Suc 0, [Bk, Bk], <[code tp, bl2wc (<lm>)]> @ Bk\<^bsup>i\<^esup>) t_utm stp = 
       
  4197                                                 (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>)"
       
  4198 apply(drule_tac t_utm_halt_eq', simp_all)
       
  4199 apply(erule_tac exE)+
       
  4200 proof -
       
  4201   fix stpa ma na
       
  4202   assume "steps (Suc 0, [Bk, Bk], <[code tp, bl2wc (<lm>)]>) t_utm stpa = (0, Bk\<^bsup>ma\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>na\<^esup>)"
       
  4203   and gr: "rs > 0"
       
  4204   thus "\<exists>stp m n. steps (Suc 0, [Bk, Bk], <[code tp, bl2wc (<lm>)]> @ Bk\<^bsup>i\<^esup>) t_utm stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>)"
       
  4205     apply(rule_tac x = stpa in exI, rule_tac x = ma in exI,  simp)
       
  4206   proof(case_tac "steps (Suc 0, [Bk, Bk], <[code tp, bl2wc (<lm>)]> @ Bk\<^bsup>i\<^esup>) t_utm stpa", simp)
       
  4207     fix a b c
       
  4208     assume "steps (Suc 0, [Bk, Bk], <[code tp, bl2wc (<lm>)]>) t_utm stpa = (0, Bk\<^bsup>ma\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>na\<^esup>)"
       
  4209             "steps (Suc 0, [Bk, Bk], <[code tp, bl2wc (<lm>)]> @ Bk\<^bsup>i\<^esup>) t_utm stpa = (a, b, c)"
       
  4210     thus " a = 0 \<and> b = Bk\<^bsup>ma\<^esup> \<and> (\<exists>n. c = Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>)"
       
  4211       using tinres_steps2[of "<[code tp, bl2wc (<lm>)]>" "<[code tp, bl2wc (<lm>)]> @ Bk\<^bsup>i\<^esup>" 
       
  4212                            "Suc 0" " [Bk, Bk]" t_utm stpa 0 "Bk\<^bsup>ma\<^esup>" "Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>na\<^esup>" a b c]
       
  4213       apply(simp)
       
  4214       using gr
       
  4215       apply(simp only: tinres_def, auto)
       
  4216       apply(rule_tac x = "na + n" in exI, simp add: exp_add)
       
  4217       done
       
  4218   qed
       
  4219 qed
       
  4220 
       
  4221 lemma [simp]: "tinres [Bk, Bk] [Bk]"
       
  4222 apply(auto simp: tinres_def)
       
  4223 done
       
  4224 
       
  4225 lemma [elim]: "Bk\<^bsup>ma\<^esup> = b @ Bk\<^bsup>n\<^esup>  \<Longrightarrow> \<exists>m. b = Bk\<^bsup>m\<^esup>"
       
  4226 apply(subgoal_tac "ma = length b + n")
       
  4227 apply(rule_tac x = "ma - n" in exI, simp add: exp_add)
       
  4228 apply(drule_tac length_equal)
       
  4229 apply(simp)
       
  4230 done
       
  4231 
       
  4232 lemma t_utm_halt_eq: 
       
  4233   "\<lbrakk>turing_basic.t_correct tp;
       
  4234    0 < rs;
       
  4235    steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm::nat list>) tp stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup>@Bk\<^bsup>n\<^esup>)\<rbrakk>
       
  4236   \<Longrightarrow>  \<exists>stp m n. steps (Suc 0, [Bk], <[code tp, bl2wc (<lm>)]> @ Bk\<^bsup>i\<^esup>) t_utm stp = 
       
  4237                                                 (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>)"
       
  4238 apply(drule_tac i = i in t_utm_halt_eq'', simp_all)
       
  4239 apply(erule_tac exE)+
       
  4240 proof -
       
  4241   fix stpa ma na
       
  4242   assume "steps (Suc 0, [Bk, Bk], <[code tp, bl2wc (<lm>)]> @ Bk\<^bsup>i\<^esup>) t_utm stpa = (0, Bk\<^bsup>ma\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>na\<^esup>)"
       
  4243   and gr: "rs > 0"
       
  4244   thus "\<exists>stp m n. steps (Suc 0, [Bk], <[code tp, bl2wc (<lm>)]> @ Bk\<^bsup>i\<^esup>) t_utm stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>)"
       
  4245     apply(rule_tac x = stpa in exI)
       
  4246   proof(case_tac "steps (Suc 0, [Bk], <[code tp, bl2wc (<lm>)]> @ Bk\<^bsup>i\<^esup>) t_utm stpa", simp)
       
  4247     fix a b c
       
  4248     assume "steps (Suc 0, [Bk, Bk], <[code tp, bl2wc (<lm>)]> @ Bk\<^bsup>i\<^esup>) t_utm stpa = (0, Bk\<^bsup>ma\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>na\<^esup>)"
       
  4249             "steps (Suc 0, [Bk], <[code tp, bl2wc (<lm>)]> @ Bk\<^bsup>i\<^esup>) t_utm stpa = (a, b, c)"
       
  4250     thus "a = 0 \<and> (\<exists>m. b = Bk\<^bsup>m\<^esup>) \<and> (\<exists>n. c = Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>)"
       
  4251       using tinres_steps[of "[Bk, Bk]" "[Bk]" "Suc 0" "<[code tp, bl2wc (<lm>)]> @ Bk\<^bsup>i\<^esup>" t_utm stpa 0
       
  4252                              "Bk\<^bsup>ma\<^esup>" "Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>na\<^esup>" a b c]
       
  4253       apply(simp)
       
  4254       apply(auto simp: tinres_def)
       
  4255       apply(rule_tac x = "ma + n" in exI, simp add: exp_add)
       
  4256       done
       
  4257   qed
       
  4258 qed
       
  4259 
       
  4260 lemma [intro]: "t_correct t_wcode"
       
  4261 apply(simp add: t_wcode_def)
       
  4262 apply(auto)
       
  4263 done
       
  4264       
       
  4265 lemma [intro]: "t_correct t_utm"
       
  4266 apply(simp add: t_utm_def F_tprog_def)
       
  4267 apply(rule_tac t_compiled_correct, auto)
       
  4268 done   
       
  4269 
       
  4270 lemma UTM_halt_lemma_pre: 
       
  4271   "\<lbrakk>turing_basic.t_correct tp;
       
  4272    0 < rs;
       
  4273    args \<noteq> [];
       
  4274    steps (Suc 0, Bk\<^bsup>i\<^esup>, <args::nat list>) tp stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup>@Bk\<^bsup>k\<^esup>)\<rbrakk>
       
  4275   \<Longrightarrow>  \<exists>stp m n. steps (Suc 0, [], <code tp # args>) UTM_pre stp = 
       
  4276                                                 (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>)"
       
  4277 proof -
       
  4278   let ?Q2 = "\<lambda> (l, r). (\<exists> ln rn. l = Bk\<^bsup>ln\<^esup> \<and> r = Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>rn\<^esup>)"
       
  4279   term ?Q2
       
  4280   let ?P1 = "\<lambda> (l, r). l = [] \<and> r = <code tp # args>"
       
  4281   let ?Q1 = "\<lambda> (l, r). (l = [Bk] \<and>
       
  4282              (\<exists> rn. r = Oc\<^bsup>Suc (code tp)\<^esup> @ Bk # Oc\<^bsup>Suc (bl_bin (<args>))\<^esup> @ Bk\<^bsup>rn\<^esup>))"
       
  4283   let ?P2 = ?Q1
       
  4284   let ?P3 = "\<lambda> (l, r). False"
       
  4285   assume h: "turing_basic.t_correct tp" "0 < rs"
       
  4286             "args \<noteq> []" "steps (Suc 0, Bk\<^bsup>i\<^esup>, <args::nat list>) tp stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup>@Bk\<^bsup>k\<^esup>)"
       
  4287   have "?P1 \<turnstile>-> \<lambda> tp. (\<exists> stp tp'. steps (Suc 0, tp)
       
  4288                     (t_wcode |+| t_utm) stp = (0, tp') \<and> ?Q2 tp')"
       
  4289   proof(rule_tac turing_merge.t_merge_halt [of "t_wcode" "t_utm"
       
  4290           ?P1 ?P2 ?P3 ?P3 ?Q1 ?Q2], auto simp: turing_merge_def)
       
  4291     show "\<exists>stp. case steps (Suc 0, [], <code tp # args>) t_wcode stp of (st, tp') \<Rightarrow> 
       
  4292        st = 0 \<and> (case tp' of (l, r) \<Rightarrow> l = [Bk] \<and>
       
  4293                    (\<exists>rn. r = Oc\<^bsup>Suc (code tp)\<^esup> @ Bk # Oc\<^bsup>Suc (bl_bin (<args>))\<^esup> @ Bk\<^bsup>rn\<^esup>))"
       
  4294       using wcode_lemma_1[of args "code tp"] h
       
  4295       apply(simp, auto)
       
  4296       apply(rule_tac x = stpa in exI, auto)
       
  4297       done      
       
  4298   next
       
  4299     fix rn 
       
  4300     show "\<exists>stp. case steps (Suc 0, [Bk], Oc\<^bsup>Suc (code tp)\<^esup> @
       
  4301       Bk # Oc\<^bsup>Suc (bl_bin (<args>))\<^esup> @ Bk\<^bsup>rn\<^esup>) t_utm stp of
       
  4302       (st, tp') \<Rightarrow> st = 0 \<and> (case tp' of (l, r) \<Rightarrow>
       
  4303       (\<exists>ln. l = Bk\<^bsup>ln\<^esup>) \<and> (\<exists>rn. r = Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>rn\<^esup>))"
       
  4304       using t_utm_halt_eq[of tp rs i args stp m k rn] h
       
  4305       apply(auto)
       
  4306       apply(rule_tac x = stpa in exI, simp add: bin_wc_eq 
       
  4307         tape_of_nat_list.simps tape_of_nl_abv)
       
  4308       apply(auto)
       
  4309       done
       
  4310   next
       
  4311     show "?Q1 \<turnstile>-> ?P2"
       
  4312       apply(simp add: t_imply_def)
       
  4313       done
       
  4314   qed
       
  4315   thus "?thesis"
       
  4316     apply(simp add: t_imply_def)
       
  4317     apply(auto simp: UTM_pre_def)
       
  4318     done
       
  4319 qed
       
  4320 
       
  4321 text {*
       
  4322   The correctness of @{text "UTM"}, the halt case.
       
  4323 *}
       
  4324 theorem UTM_halt_lemma: 
       
  4325   "\<lbrakk>turing_basic.t_correct tp;
       
  4326    0 < rs;
       
  4327    args \<noteq> [];
       
  4328    steps (Suc 0, Bk\<^bsup>i\<^esup>, <args::nat list>) tp stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup>@Bk\<^bsup>k\<^esup>)\<rbrakk>
       
  4329   \<Longrightarrow>  \<exists>stp m n. steps (Suc 0, [], <code tp # args>) UTM stp = 
       
  4330                                                 (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>)"
       
  4331 using UTM_halt_lemma_pre[of tp rs args i stp m k]
       
  4332 apply(simp add: UTM_pre_def t_utm_def UTM_def F_aprog_def F_tprog_def)
       
  4333 apply(case_tac "rec_ci rec_F", simp)
       
  4334 done
       
  4335 
       
  4336 definition TSTD:: "t_conf \<Rightarrow> bool"
       
  4337   where
       
  4338   "TSTD c = (let (st, l, r) = c in 
       
  4339              st = 0 \<and> (\<exists> m. l = Bk\<^bsup>m\<^esup>) \<and> (\<exists> rs n. r = Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>))"
       
  4340 
       
  4341 thm abacus_turing_eq_uhalt
       
  4342 
       
  4343 lemma nstd_case1: "0 < a \<Longrightarrow> NSTD (trpl_code (a, b, c))"
       
  4344 apply(simp add: NSTD.simps trpl_code.simps)
       
  4345 done
       
  4346 
       
  4347 lemma [simp]: "\<forall>m. b \<noteq> Bk\<^bsup>m\<^esup> \<Longrightarrow> 0 < bl2wc b"
       
  4348 apply(rule classical, simp)
       
  4349 apply(induct b, erule_tac x = 0 in allE, simp)
       
  4350 apply(simp add: bl2wc.simps, case_tac a, simp_all 
       
  4351   add: bl2nat.simps bl2nat_double)
       
  4352 apply(case_tac "\<exists> m. b = Bk\<^bsup>m\<^esup>",  erule exE)
       
  4353 apply(erule_tac x = "Suc m" in allE, simp add: exp_ind_def, simp)
       
  4354 done
       
  4355 lemma nstd_case2: "\<forall>m. b \<noteq> Bk\<^bsup>m\<^esup> \<Longrightarrow> NSTD (trpl_code (a, b, c))"
       
  4356 apply(simp add: NSTD.simps trpl_code.simps)
       
  4357 done
       
  4358 
       
  4359 thm lg.simps
       
  4360 thm lgR.simps
       
  4361 
       
  4362 lemma [elim]: "Suc (2 * x) = 2 * y \<Longrightarrow> RR"
       
  4363 apply(induct x arbitrary: y, simp, simp)
       
  4364 apply(case_tac y, simp, simp)
       
  4365 done
       
  4366 
       
  4367 lemma bl2nat_zero_eq[simp]: "(bl2nat c 0 = 0) = (\<exists>n. c = Bk\<^bsup>n\<^esup>)"
       
  4368 apply(auto)
       
  4369 apply(induct c, simp add: bl2nat.simps)
       
  4370 apply(rule_tac x = 0 in exI, simp)
       
  4371 apply(case_tac a, auto simp: bl2nat.simps bl2nat_double)
       
  4372 done
       
  4373 
       
  4374 lemma bl2wc_exp_ex: 
       
  4375   "\<lbrakk>Suc (bl2wc c) = 2 ^  m\<rbrakk> \<Longrightarrow> \<exists> rs n. c = Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>"
       
  4376 apply(induct c arbitrary: m, simp add: bl2wc.simps bl2nat.simps)
       
  4377 apply(case_tac a, auto)
       
  4378 apply(case_tac m, simp_all add: bl2wc.simps, auto)
       
  4379 apply(rule_tac x = 0 in exI, rule_tac x = "Suc n" in exI, 
       
  4380   simp add: exp_ind_def)
       
  4381 apply(simp add: bl2wc.simps bl2nat.simps bl2nat_double)
       
  4382 apply(case_tac m, simp, simp)
       
  4383 proof -
       
  4384   fix c m nat
       
  4385   assume ind: 
       
  4386     "\<And>m. Suc (bl2nat c 0) = 2 ^ m \<Longrightarrow> \<exists>rs n. c = Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>"
       
  4387   and h: 
       
  4388     "Suc (Suc (2 * bl2nat c 0)) = 2 * 2 ^ nat"
       
  4389   have "\<exists>rs n. c = Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>"
       
  4390     apply(rule_tac m = nat in ind)
       
  4391     using h
       
  4392     apply(simp)
       
  4393     done
       
  4394   from this obtain rs n where " c = Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>" by blast 
       
  4395   thus "\<exists>rs n. Oc # c = Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>"
       
  4396     apply(rule_tac x = "Suc rs" in exI, simp add: exp_ind_def)
       
  4397     apply(rule_tac x = n in exI, simp)
       
  4398     done
       
  4399 qed
       
  4400 
       
  4401 lemma [elim]: 
       
  4402   "\<lbrakk>\<forall>rs n. c \<noteq> Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup>; 
       
  4403   bl2wc c = 2 ^ lg (Suc (bl2wc c)) 2 - Suc 0\<rbrakk> \<Longrightarrow> bl2wc c = 0"
       
  4404 apply(subgoal_tac "\<exists> m. Suc (bl2wc c) = 2^m", erule_tac exE)
       
  4405 apply(drule_tac bl2wc_exp_ex, simp, erule_tac exE, erule_tac exE)
       
  4406 apply(case_tac rs, simp, simp, erule_tac x = nat in allE,
       
  4407   erule_tac x = n in allE, simp)
       
  4408 using bl2wc_exp_ex[of c "lg (Suc (bl2wc c)) 2"]
       
  4409 apply(case_tac "(2::nat) ^ lg (Suc (bl2wc c)) 2", 
       
  4410   simp, simp, erule_tac exE, erule_tac exE, simp)
       
  4411 apply(simp add: bl2wc.simps)
       
  4412 apply(rule_tac x = rs in exI)
       
  4413 apply(case_tac "(2::nat)^rs", simp, simp)
       
  4414 done
       
  4415 
       
  4416 lemma nstd_case3: 
       
  4417   "\<forall>rs n. c \<noteq> Oc\<^bsup>Suc rs\<^esup> @ Bk\<^bsup>n\<^esup> \<Longrightarrow>  NSTD (trpl_code (a, b, c))"
       
  4418 apply(simp add: NSTD.simps trpl_code.simps)
       
  4419 apply(rule_tac impI)
       
  4420 apply(rule_tac disjI2, rule_tac disjI2, auto)
       
  4421 done
       
  4422 
       
  4423 lemma NSTD_1: "\<not> TSTD (a, b, c)
       
  4424     \<Longrightarrow> rec_exec rec_NSTD [trpl_code (a, b, c)] = Suc 0"
       
  4425   using NSTD_lemma1[of "trpl_code (a, b, c)"]
       
  4426        NSTD_lemma2[of "trpl_code (a, b, c)"]
       
  4427   apply(simp add: TSTD_def)
       
  4428   apply(erule_tac disjE, erule_tac nstd_case1)
       
  4429   apply(erule_tac disjE, erule_tac nstd_case2)
       
  4430   apply(erule_tac nstd_case3)
       
  4431   done
       
  4432  
       
  4433 lemma nonstop_t_uhalt_eq:
       
  4434       "\<lbrakk>turing_basic.t_correct tp;
       
  4435         steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp = (a, b, c);
       
  4436        \<not> TSTD (a, b, c)\<rbrakk>
       
  4437        \<Longrightarrow> rec_exec rec_nonstop [code tp, bl2wc (<lm>), stp] = Suc 0"
       
  4438 apply(simp add: rec_nonstop_def rec_exec.simps)
       
  4439 apply(subgoal_tac 
       
  4440   "rec_exec rec_conf [code tp, bl2wc (<lm>), stp] =
       
  4441   trpl_code (a, b, c)", simp)
       
  4442 apply(erule_tac NSTD_1)
       
  4443 using rec_t_eq_steps[of tp l lm stp]
       
  4444 apply(simp)
       
  4445 done
       
  4446 
       
  4447 lemma nonstop_true:
       
  4448   "\<lbrakk>turing_basic.t_correct tp;
       
  4449   \<forall> stp. (\<not> TSTD (steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp))\<rbrakk>
       
  4450      \<Longrightarrow> \<forall>y. rec_calc_rel rec_nonstop 
       
  4451                         ([code tp, bl2wc (<lm>), y]) (Suc 0)"
       
  4452 apply(rule_tac allI, erule_tac x = y in allE)
       
  4453 apply(case_tac "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp y", simp)
       
  4454 apply(rule_tac nonstop_t_uhalt_eq, simp_all)
       
  4455 done
       
  4456 
       
  4457 (*
       
  4458 lemma [simp]: 
       
  4459   "\<forall>j<Suc k. Ex (rec_calc_rel (get_fstn_args (Suc k) (Suc k) ! j)
       
  4460                                                      (code tp # lm))"
       
  4461 apply(auto simp: get_fstn_args_nth)
       
  4462 apply(rule_tac x = "(code tp # lm) ! j" in exI)
       
  4463 apply(rule_tac calc_id, simp_all)
       
  4464 done
       
  4465 *)
       
  4466 declare ci_cn_para_eq[simp]
       
  4467 
       
  4468 lemma F_aprog_uhalt: 
       
  4469   "\<lbrakk>turing_basic.t_correct tp; 
       
  4470     \<forall> stp. (\<not> TSTD (steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp)); 
       
  4471     rec_ci rec_F = (F_ap, rs_pos, a_md)\<rbrakk>
       
  4472   \<Longrightarrow> \<forall> stp. case abc_steps_l (0, [code tp, bl2wc (<lm>)] @ 0\<^bsup>a_md - rs_pos \<^esup>
       
  4473                @ suflm) (F_ap) stp of (ss, e) \<Rightarrow> ss < length (F_ap)"
       
  4474 apply(case_tac "rec_ci (Cn (Suc (Suc 0)) rec_right [Cn (Suc (Suc 0)) rec_conf 
       
  4475                ([id (Suc (Suc 0)) 0, id (Suc (Suc 0)) (Suc 0), rec_halt])])")
       
  4476 apply(simp only: rec_F_def, rule_tac i = 0  and ga = a and gb = b and 
       
  4477   gc = c in cn_gi_uhalt, simp, simp, simp, simp, simp, simp, simp)
       
  4478 apply(simp add: ci_cn_para_eq)
       
  4479 apply(case_tac "rec_ci (Cn (Suc (Suc 0)) rec_conf 
       
  4480   ([id (Suc (Suc 0)) 0, id (Suc (Suc 0)) (Suc 0), rec_halt]))")
       
  4481 apply(rule_tac rf = "(Cn (Suc (Suc 0)) rec_right [Cn (Suc (Suc 0)) rec_conf
       
  4482               ([id (Suc (Suc 0)) 0, id (Suc (Suc 0)) (Suc 0), rec_halt])])" 
       
  4483            and n = "Suc (Suc 0)" and f = rec_right and 
       
  4484           gs = "[Cn (Suc (Suc 0)) rec_conf 
       
  4485            ([id (Suc (Suc 0)) 0, id (Suc (Suc 0)) (Suc 0), rec_halt])]"
       
  4486            and i = 0 and ga = aa and gb = ba and gc = ca in 
       
  4487           cn_gi_uhalt)
       
  4488 apply(simp, simp, simp, simp, simp, simp, simp, 
       
  4489      simp add: ci_cn_para_eq)
       
  4490 apply(case_tac "rec_ci rec_halt")
       
  4491 apply(rule_tac rf = "(Cn (Suc (Suc 0)) rec_conf 
       
  4492   ([id (Suc (Suc 0)) 0, id (Suc (Suc 0)) (Suc 0), rec_halt]))" 
       
  4493   and n = "Suc (Suc 0)" and f = "rec_conf" and 
       
  4494   gs = "([id (Suc (Suc 0)) 0, id (Suc (Suc 0)) (Suc 0), rec_halt])"  and 
       
  4495   i = "Suc (Suc 0)" and gi = "rec_halt" and ga = ab and gb = bb and
       
  4496   gc = cb in cn_gi_uhalt)
       
  4497 apply(simp, simp, simp, simp, simp add: nth_append, simp, 
       
  4498   simp add: nth_append, simp add: rec_halt_def)
       
  4499 apply(simp only: rec_halt_def)
       
  4500 apply(case_tac [!] "rec_ci ((rec_nonstop))")
       
  4501 apply(rule_tac allI, rule_tac impI, simp)
       
  4502 apply(case_tac j, simp)
       
  4503 apply(rule_tac x = "code tp" in exI, rule_tac calc_id, simp, simp, simp, simp)
       
  4504 apply(rule_tac x = "bl2wc (<lm>)" in exI, rule_tac calc_id, simp, simp, simp)
       
  4505 apply(rule_tac rf = "Mn (Suc (Suc 0)) (rec_nonstop)"
       
  4506   and f = "(rec_nonstop)" and n = "Suc (Suc 0)"
       
  4507   and  aprog' = ac and rs_pos' =  bc and a_md' = cc in Mn_unhalt)
       
  4508 apply(simp, simp add: rec_halt_def , simp, simp)
       
  4509 apply(drule_tac  nonstop_true, simp_all)
       
  4510 apply(rule_tac allI)
       
  4511 apply(erule_tac x = y in allE)+
       
  4512 apply(simp)
       
  4513 done
       
  4514 
       
  4515 thm abc_list_crsp_steps
       
  4516 
       
  4517 lemma uabc_uhalt': 
       
  4518   "\<lbrakk>turing_basic.t_correct tp;
       
  4519   \<forall> stp. (\<not> TSTD (steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp));
       
  4520   rec_ci rec_F = (ap, pos, md)\<rbrakk>
       
  4521   \<Longrightarrow> \<forall> stp. case abc_steps_l (0, [code tp, bl2wc (<lm>)]) ap stp of (ss, e)
       
  4522            \<Rightarrow>  ss < length ap"
       
  4523 proof(frule_tac F_ap = ap and rs_pos = pos and a_md = md
       
  4524     and suflm = "[]" in F_aprog_uhalt, auto)
       
  4525   fix stp a b
       
  4526   assume h: 
       
  4527     "\<forall>stp. case abc_steps_l (0, code tp # bl2wc (<lm>) # 0\<^bsup>md - pos\<^esup>) ap stp of 
       
  4528     (ss, e) \<Rightarrow> ss < length ap"
       
  4529     "abc_steps_l (0, [code tp, bl2wc (<lm>)]) ap stp = (a, b)" 
       
  4530     "turing_basic.t_correct tp" 
       
  4531     "rec_ci rec_F = (ap, pos, md)"
       
  4532   moreover have "ap \<noteq> []"
       
  4533     using h apply(rule_tac rec_ci_not_null, simp)
       
  4534     done
       
  4535   ultimately show "a < length ap"
       
  4536   proof(erule_tac x = stp in allE,
       
  4537   case_tac "abc_steps_l (0, code tp # bl2wc (<lm>) # 0\<^bsup>md - pos\<^esup>) ap stp", simp)
       
  4538     fix aa ba
       
  4539     assume g: "aa < length ap" 
       
  4540       "abc_steps_l (0, code tp # bl2wc (<lm>) # 0\<^bsup>md - pos\<^esup>) ap stp = (aa, ba)" 
       
  4541       "ap \<noteq> []"
       
  4542     thus "?thesis"
       
  4543       using abc_list_crsp_steps[of "[code tp, bl2wc (<lm>)]"
       
  4544                                    "md - pos" ap stp aa ba] h
       
  4545       apply(simp)
       
  4546       done
       
  4547   qed
       
  4548 qed
       
  4549 
       
  4550 lemma uabc_uhalt: 
       
  4551   "\<lbrakk>turing_basic.t_correct tp; 
       
  4552   \<forall> stp. (\<not> TSTD (steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp))\<rbrakk>
       
  4553   \<Longrightarrow> \<forall> stp. case abc_steps_l (0, [code tp, bl2wc (<lm>)]) F_aprog 
       
  4554        stp of (ss, e) \<Rightarrow> ss < length F_aprog"
       
  4555 apply(case_tac "rec_ci rec_F", simp add: F_aprog_def)
       
  4556 thm uabc_uhalt'
       
  4557 apply(drule_tac ap = a and pos = b and md = c in uabc_uhalt', simp_all)
       
  4558 proof -
       
  4559   fix a b c
       
  4560   assume 
       
  4561     "\<forall>stp. case abc_steps_l (0, [code tp, bl2wc (<lm>)]) a stp of (ss, e) 
       
  4562                                                    \<Rightarrow> ss < length a"
       
  4563     "rec_ci rec_F = (a, b, c)"
       
  4564   thus 
       
  4565     "\<forall>stp. case abc_steps_l (0, [code tp, bl2wc (<lm>)]) 
       
  4566     (a [+] dummy_abc (Suc (Suc 0))) stp of (ss, e) \<Rightarrow> 
       
  4567            ss < Suc (Suc (Suc (length a)))"
       
  4568     using abc_append_uhalt1[of a "[code tp, bl2wc (<lm>)]" 
       
  4569       "a [+] dummy_abc (Suc (Suc 0))" "[]" "dummy_abc (Suc (Suc 0))"]  
       
  4570     apply(simp)
       
  4571     done
       
  4572 qed
       
  4573 
       
  4574 thm abacus_turing_eq_uhalt
       
  4575 lemma tutm_uhalt': 
       
  4576   "\<lbrakk>turing_basic.t_correct tp;
       
  4577     \<forall> stp. (\<not> TSTD (steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp))\<rbrakk>
       
  4578   \<Longrightarrow> \<forall> stp. \<not> isS0 (steps (Suc 0, [Bk, Bk], <[code tp, bl2wc (<lm>)]>) t_utm stp)"
       
  4579   using abacus_turing_eq_uhalt[of "layout_of (F_aprog)" 
       
  4580                "F_aprog" "F_tprog" "[code tp, bl2wc (<lm>)]" 
       
  4581                "start_of (layout_of (F_aprog )) (length (F_aprog))" 
       
  4582                "Suc (Suc 0)"]
       
  4583 apply(simp add: F_tprog_def)
       
  4584 apply(subgoal_tac "\<forall>stp. case abc_steps_l (0, [code tp, bl2wc (<lm>)])
       
  4585   (F_aprog) stp of (as, am) \<Rightarrow> as < length (F_aprog)", simp)
       
  4586 thm abacus_turing_eq_uhalt
       
  4587 apply(simp add: t_utm_def F_tprog_def)
       
  4588 apply(rule_tac uabc_uhalt, simp_all)
       
  4589 done
       
  4590 
       
  4591 lemma tinres_commute: "tinres r r' \<Longrightarrow> tinres r' r"
       
  4592 apply(auto simp: tinres_def)
       
  4593 done
       
  4594 
       
  4595 lemma inres_tape:
       
  4596   "\<lbrakk>steps (st, l, r) tp stp = (a, b, c); steps (st, l', r') tp stp = (a', b', c'); 
       
  4597   tinres l l'; tinres r r'\<rbrakk>
       
  4598   \<Longrightarrow> a = a' \<and> tinres b b' \<and> tinres c c'"
       
  4599 proof(case_tac "steps (st, l', r) tp stp")
       
  4600   fix aa ba ca
       
  4601   assume h: "steps (st, l, r) tp stp = (a, b, c)" 
       
  4602             "steps (st, l', r') tp stp = (a', b', c')"
       
  4603             "tinres l l'" "tinres r r'"
       
  4604             "steps (st, l', r) tp stp = (aa, ba, ca)"
       
  4605   have "tinres b ba \<and> c = ca \<and> a = aa"
       
  4606     using h
       
  4607     apply(rule_tac tinres_steps, auto)
       
  4608     done
       
  4609 
       
  4610   thm tinres_steps2
       
  4611   moreover have "b' = ba \<and> tinres c' ca \<and> a' =  aa"
       
  4612     using h
       
  4613     apply(rule_tac tinres_steps2, auto intro: tinres_commute)
       
  4614     done
       
  4615   ultimately show "?thesis"
       
  4616     apply(auto intro: tinres_commute)
       
  4617     done
       
  4618 qed
       
  4619 
       
  4620 lemma tape_normalize: "\<forall> stp. \<not> isS0 (steps (Suc 0, [Bk, Bk], <[code tp, bl2wc (<lm>)]>) t_utm stp)
       
  4621       \<Longrightarrow> \<forall> stp. \<not> isS0 (steps (Suc 0, Bk\<^bsup>m\<^esup>, <[code tp, bl2wc (<lm>)]> @ Bk\<^bsup>n\<^esup>) t_utm stp)"
       
  4622 apply(rule_tac allI, case_tac "(steps (Suc 0, Bk\<^bsup>m\<^esup>, 
       
  4623                <[code tp, bl2wc (<lm>)]> @ Bk\<^bsup>n\<^esup>) t_utm stp)", simp add: isS0_def)
       
  4624 apply(erule_tac x = stp in allE)
       
  4625 apply(case_tac "steps (Suc 0, [Bk, Bk], <[code tp, bl2wc (<lm>)]>) t_utm stp", simp)
       
  4626 apply(drule_tac inres_tape, auto)
       
  4627 apply(auto simp: tinres_def)
       
  4628 apply(case_tac "m > Suc (Suc 0)")
       
  4629 apply(rule_tac x = "m - Suc (Suc 0)" in exI) 
       
  4630 apply(case_tac m, simp_all add: exp_ind_def, case_tac nat, simp_all add: exp_ind_def)
       
  4631 apply(rule_tac x = "2 - m" in exI, simp add: exp_ind_def[THEN sym] exp_add[THEN sym])
       
  4632 apply(simp only: numeral_2_eq_2, simp add: exp_ind_def)
       
  4633 done
       
  4634 
       
  4635 lemma tutm_uhalt: 
       
  4636   "\<lbrakk>turing_basic.t_correct tp;
       
  4637     \<forall> stp. (\<not> TSTD (steps (Suc 0, Bk\<^bsup>l\<^esup>, <args>) tp stp))\<rbrakk>
       
  4638   \<Longrightarrow> \<forall> stp. \<not> isS0 (steps (Suc 0, Bk\<^bsup>m\<^esup>, <[code tp, bl2wc (<args>)]> @ Bk\<^bsup>n\<^esup>) t_utm stp)"
       
  4639 apply(rule_tac tape_normalize)
       
  4640 apply(rule_tac tutm_uhalt', simp_all)
       
  4641 done
       
  4642 
       
  4643 lemma UTM_uhalt_lemma_pre:
       
  4644   "\<lbrakk>turing_basic.t_correct tp;
       
  4645    \<forall> stp. (\<not> TSTD (steps (Suc 0, Bk\<^bsup>l\<^esup>, <args>) tp stp));
       
  4646    args \<noteq> []\<rbrakk>
       
  4647   \<Longrightarrow>  \<forall> stp. \<not> isS0 (steps (Suc 0, [], <code tp # args>)  UTM_pre stp)"
       
  4648 proof -
       
  4649   let ?P1 = "\<lambda> (l, r). l = [] \<and> r = <code tp # args>"
       
  4650   let ?Q1 = "\<lambda> (l, r). (l = [Bk] \<and>
       
  4651              (\<exists> rn. r = Oc\<^bsup>Suc (code tp)\<^esup> @ Bk # Oc\<^bsup>Suc (bl_bin (<args>))\<^esup> @ Bk\<^bsup>rn\<^esup>))"
       
  4652   let ?P4 = ?Q1
       
  4653   let ?P3 = "\<lambda> (l, r). False"
       
  4654   assume h: "turing_basic.t_correct tp" "\<forall>stp. \<not> TSTD (steps (Suc 0, Bk\<^bsup>l\<^esup>, <args>) tp stp)"
       
  4655             "args \<noteq> []"
       
  4656   have "?P1 \<turnstile>-> \<lambda> tp. \<not> (\<exists> stp. isS0 (steps (Suc 0, tp) (t_wcode |+| t_utm) stp))"
       
  4657   proof(rule_tac turing_merge.t_merge_uhalt [of "t_wcode" "t_utm"
       
  4658           ?P1 ?P3 ?P3 ?P4 ?Q1 ?P3], auto simp: turing_merge_def)
       
  4659     show "\<exists>stp. case steps (Suc 0, [], <code tp # args>) t_wcode stp of (st, tp') \<Rightarrow> 
       
  4660        st = 0 \<and> (case tp' of (l, r) \<Rightarrow> l = [Bk] \<and>
       
  4661                    (\<exists>rn. r = Oc\<^bsup>Suc (code tp)\<^esup> @ Bk # Oc\<^bsup>Suc (bl_bin (<args>))\<^esup> @ Bk\<^bsup>rn\<^esup>))"
       
  4662       using wcode_lemma_1[of args "code tp"] h
       
  4663       apply(simp, auto)
       
  4664       apply(rule_tac x = stp in exI, auto)
       
  4665       done      
       
  4666   next
       
  4667     fix rn  stp
       
  4668     show " isS0 (steps (Suc 0, [Bk], Oc\<^bsup>Suc (code tp)\<^esup> @ Bk # Oc\<^bsup>Suc (bl_bin (<args>))\<^esup> @ Bk\<^bsup>rn\<^esup>) t_utm stp)
       
  4669           \<Longrightarrow> False"
       
  4670       using tutm_uhalt[of tp l args "Suc 0" rn] h
       
  4671       apply(simp)
       
  4672       apply(erule_tac x = stp in allE)
       
  4673       apply(simp add: tape_of_nl_abv tape_of_nat_list.simps bin_wc_eq)
       
  4674       done
       
  4675   next
       
  4676     fix rn stp
       
  4677     show "isS0 (steps (Suc 0, [Bk], Oc\<^bsup>Suc (code tp)\<^esup> @ Bk # Oc\<^bsup>Suc (bl_bin (<args>))\<^esup> @ Bk\<^bsup>rn\<^esup>) t_utm stp) \<Longrightarrow>
       
  4678       isS0 (steps (Suc 0, [Bk], Oc\<^bsup>Suc (code tp)\<^esup> @ Bk # Oc\<^bsup>Suc (bl_bin (<args>))\<^esup> @ Bk\<^bsup>rn\<^esup>) t_utm stp)"
       
  4679       by simp
       
  4680   next
       
  4681     show "?Q1 \<turnstile>-> ?P4"
       
  4682       apply(simp add: t_imply_def)
       
  4683       done
       
  4684   qed
       
  4685   thus "?thesis"
       
  4686     apply(simp add: t_imply_def UTM_pre_def)
       
  4687     done
       
  4688 qed
       
  4689 
       
  4690 text {*
       
  4691   The correctness of @{text "UTM"}, the unhalt case.
       
  4692   *}
       
  4693 
       
  4694 theorem UTM_uhalt_lemma:
       
  4695   "\<lbrakk>turing_basic.t_correct tp;
       
  4696    \<forall> stp. (\<not> TSTD (steps (Suc 0, Bk\<^bsup>l\<^esup>, <args>) tp stp));
       
  4697    args \<noteq> []\<rbrakk>
       
  4698   \<Longrightarrow>  \<forall> stp. \<not> isS0 (steps (Suc 0, [], <code tp # args>)  UTM stp)"
       
  4699 using UTM_uhalt_lemma_pre[of tp l args]
       
  4700 apply(simp add: UTM_pre_def t_utm_def UTM_def F_aprog_def F_tprog_def)
       
  4701 apply(case_tac "rec_ci rec_F", simp)
       
  4702 done
       
  4703 
       
  4704 end