abacus.thy
changeset 0 aa8656a8dbef
child 34 22e5804b135c
equal deleted inserted replaced
-1:000000000000 0:aa8656a8dbef
       
     1 header {* 
       
     2  {\em abacus} a kind of register machine
       
     3 *}
       
     4 
       
     5 theory abacus
       
     6 imports Main turing_basic
       
     7 begin
       
     8 
       
     9 text {*
       
    10   {\em Abacus} instructions:
       
    11 *}
       
    12 
       
    13 datatype abc_inst =
       
    14   -- {* @{text "Inc n"} increments the memory cell (or register) with address @{text "n"} by one.
       
    15      *}
       
    16      Inc nat
       
    17   -- {*
       
    18      @{text "Dec n label"} decrements the memory cell with address @{text "n"} by one. 
       
    19       If cell @{text "n"} is already zero, no decrements happens and the executio jumps to
       
    20       the instruction labeled by @{text "label"}.
       
    21      *}
       
    22    | Dec nat nat
       
    23   -- {*
       
    24   @{text "Goto label"} unconditionally jumps to the instruction labeled by @{text "label"}.
       
    25   *}
       
    26    | Goto nat
       
    27   
       
    28 
       
    29 text {*
       
    30   Abacus programs are defined as lists of Abacus instructions.
       
    31 *}
       
    32 type_synonym abc_prog = "abc_inst list"
       
    33 
       
    34 section {*
       
    35   Sample Abacus programs
       
    36   *}
       
    37 
       
    38 text {*
       
    39   Abacus for addition and clearance.
       
    40 *}
       
    41 fun plus_clear :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> abc_prog"  
       
    42   where
       
    43   "plus_clear m n e = [Dec m e, Inc n, Goto 0]"
       
    44 
       
    45 text {*
       
    46   Abacus for clearing memory untis.
       
    47 *}
       
    48 fun clear :: "nat \<Rightarrow> nat \<Rightarrow> abc_prog"
       
    49   where
       
    50   "clear n e = [Dec n e, Goto 0]"
       
    51 
       
    52 fun plus:: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> abc_prog"
       
    53   where
       
    54   "plus m n p e = [Dec m 4, Inc n, Inc p,
       
    55                    Goto 0, Dec p e, Inc m, Goto 4]"
       
    56 
       
    57 fun mult :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> abc_prog"
       
    58   where
       
    59   "mult m1 m2 n p e = [Dec m1 e]@ plus m1 m2 p 1"
       
    60 
       
    61 fun expo :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> abc_prog"
       
    62   where
       
    63   "expo n m1 m2 p e = [Inc n, Dec m1 e] @ mult m2 n n p 2"
       
    64 
       
    65 
       
    66 text {*
       
    67   The state of Abacus machine.
       
    68   *}
       
    69 type_synonym abc_state = nat
       
    70 
       
    71 (* text {*
       
    72   The memory of Abacus machine is defined as a function from address to contents.
       
    73 *}
       
    74 type_synonym abc_mem = "nat \<Rightarrow> nat" *)
       
    75 
       
    76 text {*
       
    77   The memory of Abacus machine is defined as a list of contents, with 
       
    78   every units addressed by index into the list.
       
    79   *}
       
    80 type_synonym abc_lm = "nat list"
       
    81 
       
    82 text {*
       
    83   Fetching contents out of memory. Units not represented by list elements are considered
       
    84   as having content @{text "0"}.
       
    85 *}
       
    86 fun abc_lm_v :: "abc_lm \<Rightarrow> nat \<Rightarrow> nat"
       
    87   where 
       
    88     "abc_lm_v lm n = (if (n < length lm) then (lm!n) else 0)"         
       
    89 
       
    90 (*
       
    91 fun abc_l2m :: "abc_lm \<Rightarrow> abc_mem"
       
    92   where 
       
    93     "abc_l2m lm = abc_lm_v lm"
       
    94 *)
       
    95 
       
    96 text {*
       
    97   Set the content of memory unit @{text "n"} to value @{text "v"}.
       
    98   @{text "am"} is the Abacus memory before setting.
       
    99   If address @{text "n"} is outside to scope of @{text "am"}, @{text "am"} 
       
   100   is extended so that @{text "n"} becomes in scope.
       
   101 *}
       
   102 fun abc_lm_s :: "abc_lm \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> abc_lm"
       
   103   where
       
   104     "abc_lm_s am n v = (if (n < length am) then (am[n:=v]) else 
       
   105                            am@ (replicate (n - length am) 0) @ [v])"
       
   106 
       
   107 
       
   108 text {*
       
   109   The configuration of Abaucs machines consists of its current state and its
       
   110   current memory:
       
   111 *}
       
   112 type_synonym abc_conf_l = "abc_state \<times> abc_lm"
       
   113 
       
   114 text {*
       
   115   Fetch instruction out of Abacus program:
       
   116 *}
       
   117 
       
   118 fun abc_fetch :: "nat \<Rightarrow> abc_prog \<Rightarrow> abc_inst option" 
       
   119   where
       
   120   "abc_fetch s p = (if (s < length p) then Some (p ! s)
       
   121                     else None)"
       
   122 
       
   123 text {*
       
   124   Single step execution of Abacus machine. If no instruction is feteched, 
       
   125   configuration does not change.
       
   126 *}
       
   127 fun abc_step_l :: "abc_conf_l \<Rightarrow> abc_inst option \<Rightarrow> abc_conf_l"
       
   128   where
       
   129   "abc_step_l (s, lm) a = (case a of 
       
   130                None \<Rightarrow> (s, lm) |
       
   131                Some (Inc n)  \<Rightarrow> (let nv = abc_lm_v lm n in
       
   132                        (s + 1, abc_lm_s lm n (nv + 1))) |
       
   133                Some (Dec n e) \<Rightarrow> (let nv = abc_lm_v lm n in
       
   134                        if (nv = 0) then (e, abc_lm_s lm n 0) 
       
   135                        else (s + 1,  abc_lm_s lm n (nv - 1))) |
       
   136                Some (Goto n) \<Rightarrow> (n, lm) 
       
   137                )"
       
   138 
       
   139 text {*
       
   140   Multi-step execution of Abacus machine.
       
   141 *}
       
   142 fun abc_steps_l :: "abc_conf_l \<Rightarrow> abc_prog \<Rightarrow> nat \<Rightarrow> abc_conf_l"
       
   143   where
       
   144   "abc_steps_l (s, lm) p 0 = (s, lm)" |
       
   145   "abc_steps_l (s, lm) p (Suc n) = abc_steps_l (abc_step_l (s, lm) (abc_fetch s p)) p n"
       
   146 
       
   147 section {*
       
   148   Compiling Abacus machines into Truing machines
       
   149 *}
       
   150 
       
   151 
       
   152 subsection {*
       
   153   Compiling functions
       
   154 *}
       
   155 
       
   156 text {*
       
   157   @{text "findnth n"} returns the TM which locates the represention of
       
   158   memory cell @{text "n"} on the tape and changes representation of zero
       
   159   on the way.
       
   160 *}
       
   161 
       
   162 fun findnth :: "nat \<Rightarrow> tprog"
       
   163   where
       
   164   "findnth 0 = []" |
       
   165   "findnth (Suc n) = (findnth n @ [(W1, 2 * n + 1), 
       
   166            (R, 2 * n + 2), (R, 2 * n + 3), (R, 2 * n + 2)])"
       
   167 
       
   168 text {*
       
   169   @{text "tinc_b"} returns the TM which increments the representation 
       
   170   of the memory cell under rw-head by one and move the representation 
       
   171   of cells afterwards to the right accordingly.
       
   172   *}
       
   173 
       
   174 definition tinc_b :: "tprog"
       
   175   where
       
   176   "tinc_b \<equiv> [(W1, 1), (R, 2), (W1, 3), (R, 2), (W1, 3), (R, 4), 
       
   177              (L, 7), (W0, 5), (R, 6), (W0, 5), (W1, 3), (R, 6),
       
   178              (L, 8), (L, 7), (R, 9), (L, 7), (R, 10), (W0, 9)]" 
       
   179 
       
   180 text {*
       
   181   @{text "tshift tm off"} shifts @{text "tm"} by offset @{text "off"}, leaving 
       
   182   instructions concerning state @{text "0"} unchanged, because state @{text "0"} 
       
   183   is the end state, which needs not be changed with shift operation.
       
   184   *}
       
   185 
       
   186 fun tshift :: "tprog \<Rightarrow> nat \<Rightarrow> tprog"
       
   187   where
       
   188   "tshift tp off = (map (\<lambda> (action, state). 
       
   189        (action, (if state = 0 then 0
       
   190                  else state + off))) tp)"
       
   191 
       
   192 text {*
       
   193   @{text "tinc ss n"} returns the TM which simulates the execution of 
       
   194   Abacus instruction @{text "Inc n"}, assuming that TM is located at
       
   195   location @{text "ss"} in the final TM complied from the whole
       
   196   Abacus program.
       
   197 *}
       
   198 
       
   199 fun tinc :: "nat \<Rightarrow> nat \<Rightarrow> tprog"
       
   200   where
       
   201   "tinc ss n = tshift (findnth n @ tshift tinc_b (2 * n)) (ss - 1)"
       
   202 
       
   203 text {*
       
   204   @{text "tinc_b"} returns the TM which decrements the representation 
       
   205   of the memory cell under rw-head by one and move the representation 
       
   206   of cells afterwards to the left accordingly.
       
   207   *}
       
   208 
       
   209 definition tdec_b :: "tprog"
       
   210   where
       
   211   "tdec_b \<equiv>  [(W1, 1), (R, 2), (L, 14), (R, 3), (L, 4), (R, 3),
       
   212               (R, 5), (W0, 4), (R, 6), (W0, 5), (L, 7), (L, 8),
       
   213               (L, 11), (W0, 7), (W1, 8), (R, 9), (L, 10), (R, 9),
       
   214               (R, 5), (W0, 10), (L, 12), (L, 11), (R, 13), (L, 11),
       
   215               (R, 17), (W0, 13), (L, 15), (L, 14), (R, 16), (L, 14),
       
   216               (R, 0), (W0, 16)]"
       
   217 
       
   218 text {*
       
   219   @{text "sete tp e"} attaches the termination edges (edges leading to state @{text "0"}) 
       
   220   of TM @{text "tp"} to the intruction labelled by @{text "e"}.
       
   221   *}
       
   222 
       
   223 fun sete :: "tprog \<Rightarrow> nat \<Rightarrow> tprog"
       
   224   where
       
   225   "sete tp e = map (\<lambda> (action, state). (action, if state = 0 then e else state)) tp"
       
   226 
       
   227 text {*
       
   228   @{text "tdec ss n label"} returns the TM which simulates the execution of 
       
   229   Abacus instruction @{text "Dec n label"}, assuming that TM is located at
       
   230   location @{text "ss"} in the final TM complied from the whole
       
   231   Abacus program.
       
   232 *}
       
   233 
       
   234 fun tdec :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> tprog"
       
   235   where
       
   236   "tdec ss n e = sete (tshift (findnth n @ tshift tdec_b (2 * n)) 
       
   237                  (ss - 1)) e"
       
   238  
       
   239 text {*
       
   240   @{text "tgoto f(label)"} returns the TM simulating the execution of Abacus instruction
       
   241   @{text "Goto label"}, where @{text "f(label)"} is the corresponding location of
       
   242   @{text "label"} in the final TM compiled from the overall Abacus program.
       
   243 *}
       
   244 
       
   245 fun tgoto :: "nat \<Rightarrow> tprog"
       
   246   where
       
   247   "tgoto n = [(Nop, n), (Nop, n)]"
       
   248 
       
   249 text {*
       
   250   The layout of the final TM compiled from an Abacus program is represented
       
   251   as a list of natural numbers, where the list element at index @{text "n"} represents the 
       
   252   starting state of the TM simulating the execution of @{text "n"}-th instruction
       
   253   in the Abacus program.
       
   254 *}
       
   255 
       
   256 type_synonym layout = "nat list"
       
   257 
       
   258 text {*
       
   259   @{text "length_of i"} is the length of the 
       
   260   TM simulating the Abacus instruction @{text "i"}.
       
   261 *}
       
   262 fun length_of :: "abc_inst \<Rightarrow> nat"
       
   263   where
       
   264   "length_of i = (case i of 
       
   265                     Inc n   \<Rightarrow> 2 * n + 9 |
       
   266                     Dec n e \<Rightarrow> 2 * n + 16 |
       
   267                     Goto n  \<Rightarrow> 1)"
       
   268 
       
   269 text {*
       
   270   @{text "layout_of ap"} returns the layout of Abacus program @{text "ap"}.
       
   271 *}
       
   272 fun layout_of :: "abc_prog \<Rightarrow> layout"
       
   273   where "layout_of ap = map length_of ap"
       
   274 
       
   275 
       
   276 text {*
       
   277   @{text "start_of layout n"} looks out the starting state of @{text "n"}-th
       
   278   TM in the finall TM.
       
   279 *}
       
   280 
       
   281 fun start_of :: "nat list \<Rightarrow> nat \<Rightarrow> nat"
       
   282   where
       
   283   "start_of ly 0 = Suc 0" |
       
   284   "start_of ly (Suc as) = 
       
   285         (if as < length ly then start_of ly as + (ly ! as)
       
   286          else start_of ly as)"
       
   287 
       
   288 text {*
       
   289   @{text "ci lo ss i"} complies Abacus instruction @{text "i"}
       
   290   assuming the TM of @{text "i"} starts from state @{text "ss"} 
       
   291   within the overal layout @{text "lo"}.
       
   292 *}
       
   293 
       
   294 fun ci :: "layout \<Rightarrow> nat \<Rightarrow> abc_inst \<Rightarrow> tprog"
       
   295   where
       
   296   "ci ly ss i = (case i of 
       
   297                     Inc n   \<Rightarrow> tinc ss n |
       
   298                     Dec n e \<Rightarrow> tdec ss n (start_of ly e) |
       
   299                     Goto n  \<Rightarrow> tgoto (start_of ly n))"
       
   300 
       
   301 text {*
       
   302   @{text "tpairs_of ap"} transfroms Abacus program @{text "ap"} pairing
       
   303   every instruction with its starting state.
       
   304 *}
       
   305 fun tpairs_of :: "abc_prog \<Rightarrow> (nat \<times> abc_inst) list"
       
   306   where "tpairs_of ap = (zip (map (start_of (layout_of ap)) 
       
   307                          [0..<(length ap)]) ap)"
       
   308 
       
   309 
       
   310 text {*
       
   311   @{text "tms_of ap"} returns the list of TMs, where every one of them simulates
       
   312   the corresponding Abacus intruction in @{text "ap"}.
       
   313 *}
       
   314 
       
   315 fun tms_of :: "abc_prog \<Rightarrow> tprog list"
       
   316   where "tms_of ap = map (\<lambda> (n, tm). ci (layout_of ap) n tm) 
       
   317                          (tpairs_of ap)"
       
   318 
       
   319 text {*
       
   320   @{text "tm_of ap"} returns the final TM machine compiled from Abacus program @{text "ap"}.
       
   321 *}
       
   322 fun tm_of :: "abc_prog \<Rightarrow> tprog"
       
   323   where "tm_of ap = concat (tms_of ap)"
       
   324 
       
   325 text {*
       
   326   The following two functions specify the well-formedness of complied TM.
       
   327 *}
       
   328 fun t_ncorrect :: "tprog \<Rightarrow> bool"
       
   329   where
       
   330   "t_ncorrect tp = (length tp mod 2 = 0)"
       
   331 
       
   332 fun abc2t_correct :: "abc_prog \<Rightarrow> bool"
       
   333   where 
       
   334   "abc2t_correct ap = list_all (\<lambda> (n, tm). 
       
   335              t_ncorrect (ci (layout_of ap) n tm)) (tpairs_of ap)"
       
   336 
       
   337 lemma findnth_length: "length (findnth n) div 2 = 2 * n"
       
   338 apply(induct n, simp, simp)
       
   339 done
       
   340 
       
   341 lemma ci_length : "length (ci ns n ai) div 2 = length_of ai"
       
   342 apply(auto simp: ci.simps tinc_b_def tdec_b_def findnth_length
       
   343                  split: abc_inst.splits)
       
   344 done
       
   345 
       
   346 subsection {*
       
   347   Representation of Abacus memory by TM tape
       
   348 *}
       
   349 
       
   350 consts tape_of :: "'a \<Rightarrow> block list" ("<_>" 100)
       
   351 
       
   352 text {*
       
   353   @{text "tape_of_nat_list am"} returns the TM tape representing
       
   354   Abacus memory @{text "am"}.
       
   355   *}
       
   356 
       
   357 fun tape_of_nat_list :: "nat list \<Rightarrow> block list"
       
   358   where 
       
   359   "tape_of_nat_list [] = []" |
       
   360   "tape_of_nat_list [n] = Oc\<^bsup>n+1\<^esup>" |
       
   361   "tape_of_nat_list (n#ns) = (Oc\<^bsup>n+1\<^esup>) @ [Bk] @ (tape_of_nat_list ns)"
       
   362 
       
   363 defs (overloaded)
       
   364   tape_of_nl_abv: "<am> \<equiv> tape_of_nat_list am"
       
   365   tape_of_nat_abv : "<(n::nat)> \<equiv> Oc\<^bsup>n+1\<^esup>"
       
   366 
       
   367 text {*
       
   368   @{text "crsp_l acf tcf"} meams the abacus configuration @{text "acf"}
       
   369   is corretly represented by the TM configuration @{text "tcf"}.
       
   370 *}
       
   371 
       
   372 fun crsp_l :: "layout \<Rightarrow> abc_conf_l \<Rightarrow> t_conf \<Rightarrow> block list \<Rightarrow> bool"
       
   373   where 
       
   374   "crsp_l ly (as, lm) (ts, (l, r)) inres = 
       
   375            (ts = start_of ly as \<and> (\<exists> rn. r = <lm> @ Bk\<^bsup>rn\<^esup>)
       
   376             \<and> l = Bk # Bk # inres)"
       
   377 
       
   378 declare crsp_l.simps[simp del]
       
   379 
       
   380 subsection {*
       
   381   A more general definition of TM execution. 
       
   382 *}
       
   383 
       
   384 (*
       
   385 fun nnth_of :: "(taction \<times> nat) list \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> (taction \<times> nat)"
       
   386   where
       
   387   "nnth_of p s b = (if 2*s < length p 
       
   388                     then (p ! (2*s + b)) else (Nop, 0))"
       
   389 
       
   390 thm nth_of.simps
       
   391 
       
   392 fun nfetch :: "tprog \<Rightarrow> nat \<Rightarrow> block \<Rightarrow> taction \<times> nat"
       
   393   where
       
   394   "nfetch p 0 b = (Nop, 0)" |
       
   395   "nfetch p (Suc s) b = 
       
   396              (case b of 
       
   397                 Bk \<Rightarrow> nnth_of p s 0 |
       
   398                 Oc \<Rightarrow> nnth_of p s 1)"
       
   399 *)
       
   400 
       
   401 text {*
       
   402   @{text "t_step tcf (tp, ss)"} returns the result of one step exection of TM @{text "tp"}
       
   403   assuming @{text "tp"} starts from instial state @{text "ss"}.
       
   404 *}
       
   405 
       
   406 fun t_step :: "t_conf \<Rightarrow> (tprog \<times> nat) \<Rightarrow> t_conf"
       
   407   where 
       
   408   "t_step c (p, off) = 
       
   409            (let (state, leftn, rightn) = c in
       
   410             let (action, next_state) = fetch p (state-off)
       
   411                              (case rightn of 
       
   412                                 [] \<Rightarrow> Bk | 
       
   413                                 Bk # xs \<Rightarrow> Bk |
       
   414                                 Oc # xs \<Rightarrow> Oc
       
   415                              ) 
       
   416              in 
       
   417             (next_state, new_tape action (leftn, rightn)))"
       
   418 
       
   419 
       
   420 text {*
       
   421   @{text "t_steps tcf (tp, ss) n"} returns the result of @{text "n"}-step exection 
       
   422   of TM @{text "tp"} assuming @{text "tp"} starts from instial state @{text "ss"}.
       
   423 *}
       
   424 
       
   425 fun t_steps :: "t_conf \<Rightarrow> (tprog \<times> nat) \<Rightarrow> nat \<Rightarrow> t_conf"
       
   426   where
       
   427   "t_steps c (p, off) 0 = c" |
       
   428   "t_steps c (p, off) (Suc n) = t_steps 
       
   429                      (t_step c (p, off)) (p, off) n" 
       
   430 
       
   431 lemma stepn: "t_steps c (p, off) (Suc n) = 
       
   432               t_step (t_steps c (p, off) n) (p, off)"
       
   433 apply(induct n arbitrary: c, simp add: t_steps.simps)
       
   434 apply(simp add: t_steps.simps)
       
   435 done
       
   436 
       
   437 text {*
       
   438   The type of invarints expressing correspondence between 
       
   439   Abacus configuration and TM configuration.
       
   440 *}
       
   441 
       
   442 type_synonym inc_inv_t = "abc_conf_l \<Rightarrow> t_conf \<Rightarrow> block list \<Rightarrow> bool"
       
   443 
       
   444 declare tms_of.simps[simp del] tm_of.simps[simp del]
       
   445         layout_of.simps[simp del] abc_fetch.simps [simp del]  
       
   446         t_step.simps[simp del] t_steps.simps[simp del] 
       
   447         tpairs_of.simps[simp del] start_of.simps[simp del]
       
   448         fetch.simps [simp del] t_ncorrect.simps[simp del]
       
   449         new_tape.simps [simp del] ci.simps [simp del] length_of.simps[simp del] 
       
   450         layout_of.simps[simp del] crsp_l.simps[simp del]
       
   451         abc2t_correct.simps[simp del]
       
   452 
       
   453 lemma tct_div2: "t_ncorrect tp \<Longrightarrow> (length tp) mod 2 = 0"
       
   454 apply(simp add: t_ncorrect.simps)
       
   455 done
       
   456 
       
   457 lemma t_shift_fetch: 
       
   458     "\<lbrakk>t_ncorrect tp1; t_ncorrect tp; 
       
   459       length tp1 div 2 < a \<and> a \<le> length tp1 div 2 + length tp div 2\<rbrakk>
       
   460     \<Longrightarrow> fetch tp (a - length tp1 div 2) b = 
       
   461          fetch (tp1 @ tp @ tp2) a b"
       
   462 apply(subgoal_tac "\<exists> x. a = length tp1 div 2 + x", erule exE, simp)
       
   463 apply(case_tac x, simp)
       
   464 apply(subgoal_tac "length tp1 div 2 + Suc nat = 
       
   465              Suc (length tp1 div 2 + nat)")
       
   466 apply(simp only: fetch.simps nth_of.simps, auto)
       
   467 apply(case_tac b, simp)
       
   468 apply(subgoal_tac "2 * (length tp1 div 2) = length tp1", simp)
       
   469 apply(subgoal_tac "2 * nat < length tp", simp add: nth_append, simp)
       
   470 apply(simp add: t_ncorrect.simps, auto)
       
   471 apply(subgoal_tac "2 * (length tp1 div 2) = length tp1", simp)
       
   472 apply(subgoal_tac "2 * nat < length tp", simp add: nth_append, auto)
       
   473 apply(simp add: t_ncorrect.simps, auto)
       
   474 apply(rule_tac x = "a - length tp1 div 2" in exI, simp)
       
   475 done
       
   476 
       
   477 lemma t_shift_in_step:
       
   478       "\<lbrakk>t_step (a, aa, ba) (tp, length tp1 div 2) = (s, l, r);
       
   479         t_ncorrect tp1; t_ncorrect tp;
       
   480         length tp1 div 2 < a \<and> a \<le> length tp1 div 2 + length tp div 2\<rbrakk>
       
   481        \<Longrightarrow> t_step (a, aa, ba) (tp1 @ tp @ tp2, 0) = (s, l, r)"
       
   482 apply(simp add: t_step.simps)
       
   483 apply(subgoal_tac "fetch tp (a - length tp1 div 2) (case ba of [] \<Rightarrow> 
       
   484                    Bk | x # xs \<Rightarrow> x)
       
   485              = fetch (tp1 @ tp @ tp2) a (case ba of [] \<Rightarrow> Bk | x # xs
       
   486                    \<Rightarrow> x)")
       
   487 apply(case_tac "fetch tp (a - length tp1 div 2) (case ba of [] \<Rightarrow> Bk
       
   488                 | x # xs \<Rightarrow> x)")
       
   489 apply(auto intro: t_shift_fetch)
       
   490 apply(case_tac ba, simp, simp)
       
   491 apply(case_tac aaa, simp, simp)
       
   492 done
       
   493 
       
   494 declare add_Suc_right[simp del]
       
   495 lemma t_step_add: "t_steps c (p, off) (m + n) = 
       
   496           t_steps (t_steps c (p, off) m) (p, off) n"
       
   497 apply(induct m arbitrary: n,  simp add: t_steps.simps, simp)
       
   498 apply(subgoal_tac "t_steps c (p, off) (Suc (m + n)) = 
       
   499                          t_steps c (p, off) (m + Suc n)", simp)
       
   500 apply(subgoal_tac "t_steps (t_steps c (p, off) m) (p, off) (Suc n) =
       
   501                 t_steps (t_step (t_steps c (p, off) m) (p, off)) 
       
   502                          (p, off) n")
       
   503 apply(simp, simp add: stepn)
       
   504 apply(simp only: t_steps.simps)
       
   505 apply(simp only: add_Suc_right)
       
   506 done
       
   507 declare add_Suc_right[simp]
       
   508 
       
   509 lemma s_out_fetch: "\<lbrakk>t_ncorrect tp; 
       
   510         \<not> (length tp1 div 2 < a \<and> a \<le> length tp1 div 2 + 
       
   511          length tp div 2)\<rbrakk>
       
   512       \<Longrightarrow> fetch tp (a - length tp1 div 2) b = (Nop, 0)"
       
   513 apply(auto)
       
   514 apply(simp add: fetch.simps)
       
   515 apply(subgoal_tac "\<exists> x. a - length tp1 div 2 = length tp div 2 + x")
       
   516 apply(erule exE, simp)
       
   517 apply(case_tac x, simp)
       
   518 apply(auto simp add: fetch.simps)
       
   519 apply(subgoal_tac "2 * (length tp div 2) =  length tp")
       
   520 apply(auto simp: t_ncorrect.simps split: block.splits)
       
   521 apply(rule_tac x = "a - length tp1 div 2 - length tp div 2" in exI
       
   522      , simp)
       
   523 done 
       
   524 
       
   525 lemma conf_keep_step: 
       
   526       "\<lbrakk>t_ncorrect tp; 
       
   527         \<not> (length tp1 div 2 < a \<and> a \<le> length tp1 div 2 + 
       
   528        length tp div 2)\<rbrakk>
       
   529       \<Longrightarrow> t_step (a, aa, ba) (tp, length tp1 div 2) = (0, aa, ba)"
       
   530 apply(simp add: t_step.simps)
       
   531 apply(subgoal_tac "fetch tp (a - length tp1 div 2) (case ba of [] \<Rightarrow> 
       
   532   Bk | Bk # xs \<Rightarrow> Bk | Oc # xs \<Rightarrow> Oc) = (Nop, 0)")
       
   533 apply(simp add: new_tape.simps)
       
   534 apply(rule s_out_fetch, simp, simp)
       
   535 done
       
   536 
       
   537 lemma conf_keep: 
       
   538       "\<lbrakk>t_ncorrect tp; 
       
   539         \<not> (length tp1 div 2 < a \<and>
       
   540         a \<le> length tp1 div 2 + length tp div 2); n > 0\<rbrakk>
       
   541       \<Longrightarrow> t_steps (a, aa, ba) (tp, length tp1 div 2) n = (0, aa, ba)"
       
   542 apply(induct n, simp)
       
   543 apply(case_tac n, simp add: t_steps.simps)
       
   544 apply(rule_tac conf_keep_step, simp+)
       
   545 apply(subgoal_tac " t_steps (a, aa, ba) 
       
   546                (tp, length tp1 div 2) (Suc (Suc nat))
       
   547          = t_step (t_steps (a, aa, ba) 
       
   548             (tp, length tp1 div 2) (Suc nat)) (tp, length tp1 div 2)")
       
   549 apply(simp)
       
   550 apply(rule_tac conf_keep_step, simp, simp)
       
   551 apply(rule stepn)
       
   552 done
       
   553 
       
   554 lemma state_bef_inside: 
       
   555     "\<lbrakk>t_ncorrect tp1; t_ncorrect tp; 
       
   556       t_steps (s0, l0, r0) (tp, length tp1 div 2) stp = (s, l, r);
       
   557       length tp1 div 2 < s0 \<and> 
       
   558          s0 \<le> length tp1 div 2 + length tp div 2;
       
   559       length tp1 div 2 < s \<and> s \<le> length tp1 div 2 + length tp div 2; 
       
   560       n < stp; t_steps (s0, l0, r0) (tp, length tp1 div 2) n = 
       
   561       (a, aa, ba)\<rbrakk>
       
   562       \<Longrightarrow>  length tp1 div 2 < a \<and> 
       
   563          a \<le> length tp1 div 2 + length tp div 2"
       
   564 apply(subgoal_tac "\<exists> x. stp = n + x", erule exE)
       
   565 apply(simp only: t_step_add)
       
   566 apply(rule classical)
       
   567 apply(subgoal_tac "t_steps (a, aa, ba) 
       
   568           (tp, length tp1 div 2) x = (0, aa, ba)")
       
   569 apply(simp)
       
   570 apply(rule conf_keep, simp, simp, simp)
       
   571 apply(rule_tac x = "stp - n" in exI, simp)
       
   572 done
       
   573 
       
   574 lemma turing_shift_inside: 
       
   575        "\<lbrakk>t_steps (s0, l0, r0) (tp, length tp1 div 2) stp = (s, l, r);
       
   576          length tp1 div 2 < s0 \<and> 
       
   577          s0 \<le> length tp1 div 2 + length tp div 2; 
       
   578          t_ncorrect tp1; t_ncorrect tp;
       
   579          length tp1 div 2 < s \<and> 
       
   580          s \<le> length tp1 div 2 + length tp div 2\<rbrakk>
       
   581        \<Longrightarrow> t_steps (s0, l0, r0) (tp1 @ tp @ tp2, 0) stp = (s, l, r)"
       
   582 apply(induct stp arbitrary: s l r)
       
   583 apply(simp add: t_steps.simps)
       
   584 apply(subgoal_tac " t_steps (s0, l0, r0) 
       
   585         (tp, length tp1 div 2) (Suc stp)
       
   586                   = t_step (t_steps (s0, l0, r0) 
       
   587         (tp, length tp1 div 2) stp) (tp, length tp1 div 2)")
       
   588 apply(case_tac "t_steps (s0, l0, r0) (tp, length tp1 div 2) stp")
       
   589 apply(subgoal_tac "length tp1 div 2 < a \<and> 
       
   590             a \<le> length tp1 div 2 + length tp div 2")
       
   591 apply(subgoal_tac "t_steps (s0, l0, r0) 
       
   592            (tp1 @ tp @ tp2, 0) stp = (a, b, c)")
       
   593 apply(simp only: stepn, simp)
       
   594 apply(rule_tac t_shift_in_step, simp+)
       
   595 defer
       
   596 apply(rule stepn)
       
   597 apply(rule_tac n = stp and stp = "Suc stp" and a = a 
       
   598                and aa = b and ba = c in state_bef_inside, simp+)
       
   599 done
       
   600 
       
   601 lemma take_Suc_last[elim]: "Suc as \<le> length xs \<Longrightarrow> 
       
   602             take (Suc as) xs = take as xs @ [xs ! as]"
       
   603 apply(induct xs arbitrary: as, simp, simp)
       
   604 apply(case_tac as, simp, simp)
       
   605 done
       
   606 
       
   607 lemma concat_suc: "Suc as \<le> length xs \<Longrightarrow> 
       
   608        concat (take (Suc as) xs) = concat (take as xs) @ xs! as"
       
   609 apply(subgoal_tac "take (Suc as) xs = take as xs @ [xs ! as]", simp)
       
   610 by auto
       
   611 
       
   612 lemma concat_take_suc_iff: "Suc n \<le> length tps \<Longrightarrow> 
       
   613        concat (take n tps) @ (tps ! n) = concat (take (Suc n) tps)"
       
   614 apply(drule_tac concat_suc, simp)
       
   615 done
       
   616 
       
   617 lemma concat_drop_suc_iff: 
       
   618    "Suc n < length tps \<Longrightarrow> concat (drop (Suc n) tps) = 
       
   619            tps ! Suc n @ concat (drop (Suc (Suc n)) tps)"
       
   620 apply(induct tps arbitrary: n, simp, simp)
       
   621 apply(case_tac tps, simp, simp)
       
   622 apply(case_tac n, simp, simp)
       
   623 done
       
   624 
       
   625 declare append_assoc[simp del]
       
   626 
       
   627 lemma  tm_append: "\<lbrakk>n < length tps; tp = tps ! n\<rbrakk> \<Longrightarrow> 
       
   628            \<exists> tp1 tp2. concat tps = tp1 @ tp @ tp2 \<and> tp1 = 
       
   629               concat (take n tps) \<and> tp2 = concat (drop (Suc n) tps)"
       
   630 apply(rule_tac x = "concat (take n tps)" in exI)
       
   631 apply(rule_tac x = "concat (drop (Suc n) tps)" in exI)
       
   632 apply(auto)
       
   633 apply(induct n, simp)
       
   634 apply(case_tac tps, simp, simp, simp)
       
   635 apply(subgoal_tac "concat (take n tps) @ (tps ! n) = 
       
   636                concat (take (Suc n) tps)")
       
   637 apply(simp only: append_assoc[THEN sym], simp only: append_assoc)
       
   638 apply(subgoal_tac " concat (drop (Suc n) tps) = tps ! Suc n @ 
       
   639                   concat (drop (Suc (Suc n)) tps)", simp)
       
   640 apply(rule_tac concat_drop_suc_iff, simp)
       
   641 apply(rule_tac concat_take_suc_iff, simp)
       
   642 done
       
   643 
       
   644 declare append_assoc[simp]
       
   645 
       
   646 lemma map_of:  "n < length xs \<Longrightarrow> (map f xs) ! n = f (xs ! n)"
       
   647 by(auto)
       
   648 
       
   649 lemma [simp]: "length (tms_of aprog) = length aprog"
       
   650 apply(auto simp: tms_of.simps tpairs_of.simps)
       
   651 done
       
   652 
       
   653 lemma ci_nth: "\<lbrakk>ly = layout_of aprog; as < length aprog; 
       
   654                 abc_fetch as aprog = Some ins\<rbrakk>
       
   655     \<Longrightarrow> ci ly (start_of ly as) ins = tms_of aprog ! as"
       
   656 apply(simp add: tms_of.simps tpairs_of.simps 
       
   657       abc_fetch.simps  map_of del: map_append)
       
   658 done
       
   659 
       
   660 lemma t_split:"\<lbrakk>
       
   661         ly = layout_of aprog;
       
   662         as < length aprog; abc_fetch as aprog = Some ins\<rbrakk>
       
   663       \<Longrightarrow> \<exists> tp1 tp2. concat (tms_of aprog) = 
       
   664             tp1 @ (ci ly (start_of ly as) ins) @ tp2
       
   665             \<and> tp1 = concat (take as (tms_of aprog)) \<and> 
       
   666               tp2 = concat (drop (Suc as) (tms_of aprog))"
       
   667 apply(insert tm_append[of "as" "tms_of aprog" 
       
   668                              "ci ly (start_of ly as) ins"], simp)
       
   669 apply(subgoal_tac "ci ly (start_of ly as) ins = (tms_of aprog) ! as")
       
   670 apply(subgoal_tac "length (tms_of aprog) = length aprog", simp, simp)
       
   671 apply(rule_tac ci_nth, auto)
       
   672 done
       
   673 
       
   674 lemma math_sub: "\<lbrakk>x >= Suc 0; x - 1 = z\<rbrakk> \<Longrightarrow> x + y - Suc 0 = z + y"
       
   675 by auto
       
   676 
       
   677 lemma start_more_one: "as \<noteq> 0 \<Longrightarrow> start_of ly as >= Suc 0"
       
   678 apply(induct as, simp add: start_of.simps)
       
   679 apply(case_tac as, auto simp: start_of.simps)
       
   680 done
       
   681 
       
   682 lemma tm_ct: "\<lbrakk>abc2t_correct aprog; tp \<in> set (tms_of aprog)\<rbrakk> \<Longrightarrow> 
       
   683                            t_ncorrect tp"
       
   684 apply(simp add: abc2t_correct.simps tms_of.simps)
       
   685 apply(auto)
       
   686 apply(simp add:list_all_iff, auto)
       
   687 done
       
   688 
       
   689 lemma div_apart: "\<lbrakk>x mod (2::nat) = 0; y mod 2 = 0\<rbrakk> 
       
   690           \<Longrightarrow> (x + y) div 2 = x div 2 + y div 2"
       
   691 apply(drule mod_eqD)+
       
   692 apply(auto)
       
   693 done
       
   694 
       
   695 lemma div_apart_iff: "\<lbrakk>x mod (2::nat) = 0; y mod 2 = 0\<rbrakk> \<Longrightarrow> 
       
   696            (x + y) mod 2 = 0"
       
   697 apply(auto)
       
   698 done
       
   699 
       
   700 lemma tms_ct: "\<lbrakk>abc2t_correct aprog; n < length aprog\<rbrakk> \<Longrightarrow> 
       
   701          t_ncorrect (concat (take n (tms_of aprog)))"
       
   702 apply(induct n, simp add: t_ncorrect.simps, simp)
       
   703 apply(subgoal_tac "concat (take (Suc n) (tms_of aprog)) = 
       
   704         concat (take n (tms_of aprog)) @ (tms_of aprog ! n)", simp)
       
   705 apply(simp add: t_ncorrect.simps)
       
   706 apply(rule_tac div_apart_iff, simp)
       
   707 apply(subgoal_tac "t_ncorrect (tms_of aprog ! n)", 
       
   708             simp add: t_ncorrect.simps)
       
   709 apply(rule_tac tm_ct, simp)
       
   710 apply(rule_tac nth_mem, simp add: tms_of.simps tpairs_of.simps)
       
   711 apply(rule_tac concat_suc, simp add: tms_of.simps tpairs_of.simps)
       
   712 done
       
   713 
       
   714 lemma tcorrect_div2: "\<lbrakk>abc2t_correct aprog; Suc as < length aprog\<rbrakk>
       
   715   \<Longrightarrow> (length (concat (take as (tms_of aprog))) + length (tms_of aprog
       
   716  ! as)) div 2 = length (concat (take as (tms_of aprog))) div 2 + 
       
   717                  length (tms_of aprog ! as) div 2"
       
   718 apply(subgoal_tac "t_ncorrect (tms_of aprog ! as)")
       
   719 apply(subgoal_tac "t_ncorrect (concat (take as (tms_of aprog)))")
       
   720 apply(rule_tac div_apart)
       
   721 apply(rule tct_div2, simp)+
       
   722 apply(erule_tac tms_ct, simp)
       
   723 apply(rule_tac tm_ct, simp)
       
   724 apply(rule_tac nth_mem)
       
   725 apply(simp add: tms_of.simps tpairs_of.simps)
       
   726 done
       
   727 
       
   728 lemma [simp]: "length (layout_of aprog) = length aprog"
       
   729 apply(auto simp: layout_of.simps)
       
   730 done
       
   731 
       
   732 lemma start_of_ind: "\<lbrakk>as < length aprog; ly = layout_of aprog\<rbrakk> \<Longrightarrow> 
       
   733        start_of ly (Suc as) = start_of ly as + 
       
   734                           length ((tms_of aprog) ! as) div 2"
       
   735 apply(simp only: start_of.simps, simp)
       
   736 apply(auto simp: start_of.simps tms_of.simps layout_of.simps 
       
   737                  tpairs_of.simps)
       
   738 apply(simp add: ci_length)
       
   739 done
       
   740 
       
   741 lemma concat_take_suc: "Suc n \<le> length xs \<Longrightarrow>
       
   742   concat (take (Suc n) xs) = concat (take n xs) @ (xs ! n)"
       
   743 apply(subgoal_tac "take (Suc n) xs =
       
   744                    take n xs @ [xs ! n]")
       
   745 apply(auto)
       
   746 done
       
   747 
       
   748 lemma ci_length_not0: "Suc 0 <= length (ci ly as i) div 2"
       
   749 apply(subgoal_tac "length (ci ly as i) div 2 = length_of i")
       
   750 apply(simp add: length_of.simps split: abc_inst.splits)
       
   751 apply(rule ci_length)
       
   752 done
       
   753  
       
   754 lemma findnth_length2: "length (findnth n) = 4 * n"
       
   755 apply(induct n, simp)
       
   756 apply(simp)
       
   757 done
       
   758 
       
   759 lemma ci_length2: "length (ci ly as i) = 2 * (length_of i)"
       
   760 apply(simp add: ci.simps length_of.simps tinc_b_def tdec_b_def
       
   761               split: abc_inst.splits, auto)
       
   762 apply(simp add: findnth_length2)+
       
   763 done
       
   764 
       
   765 lemma tm_mod2: "as < length aprog \<Longrightarrow> 
       
   766              length (tms_of aprog ! as) mod 2 = 0"
       
   767 apply(simp add: tms_of.simps)
       
   768 apply(subgoal_tac "map (\<lambda>(x, y). ci (layout_of aprog) x y) 
       
   769               (tpairs_of aprog) ! as
       
   770                 = (\<lambda>(x, y). ci (layout_of aprog) x y) 
       
   771               ((tpairs_of aprog) ! as)", simp)
       
   772 apply(case_tac "(tpairs_of aprog ! as)", simp)
       
   773 apply(subgoal_tac "length (ci (layout_of aprog) a b) =
       
   774                  2 * (length_of b)", simp)
       
   775 apply(rule ci_length2)
       
   776 apply(rule map_of, simp add: tms_of.simps tpairs_of.simps)
       
   777 done
       
   778 
       
   779 lemma tms_mod2: "as \<le> length aprog \<Longrightarrow> 
       
   780         length (concat (take as (tms_of aprog))) mod 2 = 0"
       
   781 apply(induct as, simp, simp)
       
   782 apply(subgoal_tac "concat (take (Suc as) (tms_of aprog))
       
   783                   = concat (take as (tms_of aprog)) @ 
       
   784                        (tms_of aprog ! as)", auto)
       
   785 apply(rule div_apart_iff, simp, rule tm_mod2, simp)
       
   786 apply(rule concat_take_suc, simp add: tms_of.simps tpairs_of.simps)
       
   787 done
       
   788 
       
   789 lemma [simp]: "\<lbrakk>as < length aprog; (abc_fetch as aprog) = Some ins\<rbrakk>
       
   790        \<Longrightarrow> ci (layout_of aprog) 
       
   791           (start_of (layout_of aprog) as) (ins) \<in> set (tms_of aprog)"
       
   792 apply(insert ci_nth[of "layout_of aprog" aprog as], simp)
       
   793 done
       
   794 
       
   795 lemma startof_not0: "start_of ly as > 0"
       
   796 apply(induct as, simp add: start_of.simps)
       
   797 apply(case_tac as, auto simp: start_of.simps)
       
   798 done
       
   799 
       
   800 declare abc_step_l.simps[simp del]
       
   801 lemma pre_lheq: "\<lbrakk>tp = concat (take as (tms_of aprog));
       
   802    abc2t_correct aprog; as \<le> length aprog\<rbrakk> \<Longrightarrow> 
       
   803          start_of (layout_of aprog) as - Suc 0 = length tp div 2"
       
   804 apply(induct as arbitrary: tp, simp add: start_of.simps, simp)
       
   805 proof - 
       
   806   fix as tp
       
   807   assume h1: "\<And>tp. tp = concat (take as (tms_of aprog)) \<Longrightarrow> 
       
   808      start_of (layout_of aprog) as - Suc 0 = 
       
   809             length (concat (take as (tms_of aprog))) div 2"
       
   810   and h2: " abc2t_correct aprog" "Suc as \<le> length aprog" 
       
   811   from h2 show "start_of (layout_of aprog) (Suc as) - Suc 0 = 
       
   812           length (concat (take (Suc as) (tms_of aprog))) div 2"
       
   813     apply(insert h1[of "concat (take as (tms_of aprog))"], simp)
       
   814     apply(insert start_of_ind[of as aprog "layout_of aprog"], simp)
       
   815     apply(subgoal_tac "(take (Suc as) (tms_of aprog)) = 
       
   816             take as (tms_of aprog) @ [(tms_of aprog) ! as]", simp)
       
   817     apply(subgoal_tac "(length (concat (take as (tms_of aprog))) + 
       
   818                        length (tms_of aprog ! as)) div 2
       
   819             = length (concat (take as (tms_of aprog))) div 2 + 
       
   820               length (tms_of aprog ! as) div 2", simp)
       
   821     apply(subgoal_tac "start_of (layout_of aprog) as = 
       
   822        length (concat (take as (tms_of aprog))) div 2 + Suc 0", simp)
       
   823     apply(subgoal_tac "start_of (layout_of aprog) as > 0", simp, 
       
   824            rule_tac startof_not0)
       
   825     apply(insert tm_mod2[of as aprog], simp)
       
   826     apply(insert tms_mod2[of as aprog], simp, arith)
       
   827     apply(rule take_Suc_last, simp)
       
   828     done
       
   829 qed
       
   830 
       
   831 lemma crsp2stateq: 
       
   832   "\<lbrakk>as < length aprog; abc2t_correct aprog;
       
   833        crsp_l (layout_of aprog) (as, am) (a, aa, ba) inres\<rbrakk> \<Longrightarrow> 
       
   834         a = length (concat (take as (tms_of aprog))) div 2 + 1"
       
   835 apply(simp add: crsp_l.simps)
       
   836 apply(insert pre_lheq[of "(concat (take as (tms_of aprog)))" as aprog]
       
   837 , simp)   
       
   838 apply(subgoal_tac "start_of (layout_of aprog) as > 0", 
       
   839       auto intro: startof_not0)
       
   840 done
       
   841 
       
   842 lemma turing_shift_outside: 
       
   843      "\<lbrakk>t_steps (s0, l0, r0) (tp, length tp1 div 2) stp = (s, l, r); 
       
   844        s \<noteq> 0; stp > 0;
       
   845        length tp1 div 2 < s0 \<and> 
       
   846        s0 \<le> length tp1 div 2 + length tp div 2; 
       
   847        t_ncorrect tp1; t_ncorrect tp;
       
   848        \<not> (length tp1 div 2 < s \<and> 
       
   849       s \<le> length tp1 div 2 + length tp div 2)\<rbrakk>
       
   850     \<Longrightarrow> \<exists>stp' > 0. t_steps (s0, l0, r0) (tp1 @ tp @ tp2, 0) stp' 
       
   851                 = (s, l, r)"
       
   852 apply(rule_tac x = stp in exI)
       
   853 apply(case_tac stp, simp add: t_steps.simps)
       
   854 apply(simp only: stepn)
       
   855 apply(case_tac "t_steps (s0, l0, r0) (tp, length tp1 div 2) nat")
       
   856 apply(subgoal_tac "length tp1 div 2 < a \<and> 
       
   857                    a \<le> length tp1 div 2 + length tp div 2")
       
   858 apply(subgoal_tac "t_steps (s0, l0, r0) (tp1 @ tp @ tp2, 0) nat 
       
   859                    = (a, b, c)", simp)
       
   860 apply(rule_tac t_shift_in_step, simp+)
       
   861 apply(rule_tac turing_shift_inside, simp+)
       
   862 apply(rule classical)
       
   863 apply(subgoal_tac "t_step (a,b,c) 
       
   864             (tp, length tp1 div 2) = (0, b, c)", simp)
       
   865 apply(rule_tac conf_keep_step, simp+)
       
   866 done
       
   867 
       
   868 lemma turing_shift: 
       
   869   "\<lbrakk>t_steps (s0, (l0, r0)) (tp, (length tp1 div 2)) stp
       
   870    = (s, (l, r)); s \<noteq> 0; stp > 0;
       
   871   (length tp1 div 2 < s0 \<and> s0 <= length tp1 div 2 + length tp div 2);
       
   872   t_ncorrect tp1; t_ncorrect tp\<rbrakk> \<Longrightarrow> 
       
   873          \<exists> stp' > 0. t_steps (s0, (l0, r0)) (tp1 @ tp @ tp2, 0) stp' =
       
   874                     (s, (l, r))"
       
   875 apply(case_tac "s > length tp1 div 2 \<and> 
       
   876               s <= length tp1 div 2 + length tp div 2")
       
   877 apply(subgoal_tac " t_steps (s0, l0, r0) (tp1 @ tp @ tp2, 0) stp = 
       
   878                    (s, l, r)")
       
   879 apply(rule_tac x = stp in exI, simp)
       
   880 apply(rule_tac turing_shift_inside, simp+)
       
   881 apply(rule_tac turing_shift_outside, simp+)
       
   882 done
       
   883 
       
   884 lemma inc_startof_not0:  "start_of ly as \<ge> Suc 0"
       
   885 apply(induct as, simp add: start_of.simps)
       
   886 apply(simp add: start_of.simps)
       
   887 done
       
   888 
       
   889 lemma s_crsp:
       
   890   "\<lbrakk>as < length aprog; abc_fetch as aprog = Some ins;
       
   891   abc2t_correct aprog;
       
   892   crsp_l (layout_of aprog) (as, am) (a, aa, ba) inres\<rbrakk> \<Longrightarrow>  
       
   893   length (concat (take as (tms_of aprog))) div 2 < a 
       
   894       \<and> a \<le> length (concat (take as (tms_of aprog))) div 2 + 
       
   895          length (ci (layout_of aprog) (start_of (layout_of aprog) as)
       
   896          ins) div 2"
       
   897 apply(subgoal_tac "a = length (concat (take as (tms_of aprog))) div 
       
   898                    2 + 1", simp)
       
   899 apply(rule_tac ci_length_not0)
       
   900 apply(rule crsp2stateq, simp+)
       
   901 done
       
   902 
       
   903 lemma tms_out_ex:
       
   904   "\<lbrakk>ly = layout_of aprog; tprog = tm_of aprog;
       
   905   abc2t_correct aprog;
       
   906   crsp_l ly (as, am) tc inres; as < length aprog;
       
   907   abc_fetch as aprog = Some ins;
       
   908   t_steps tc (ci ly (start_of ly as) ins, 
       
   909   (start_of ly as) - 1) n = (s, l, r);
       
   910   n > 0; 
       
   911   abc_step_l (as, am) (abc_fetch as aprog) = (as', am');
       
   912   s = start_of ly as'
       
   913   \<rbrakk>
       
   914   \<Longrightarrow> \<exists> stp > 0. (t_steps tc (tprog, 0) stp = (s, (l, r)))"
       
   915 apply(simp only: tm_of.simps)
       
   916 apply(subgoal_tac "\<exists> tp1 tp2. concat (tms_of aprog) = 
       
   917       tp1 @ (ci ly (start_of ly as) ins) @ tp2
       
   918     \<and> tp1 = concat (take as (tms_of aprog)) \<and> 
       
   919       tp2 = concat (drop (Suc as) (tms_of aprog))")
       
   920 apply(erule exE, erule exE, erule conjE, erule conjE,
       
   921       case_tac tc, simp)
       
   922 apply(rule turing_shift)
       
   923 apply(subgoal_tac "start_of (layout_of aprog) as - Suc 0 
       
   924                 = length tp1 div 2", simp)
       
   925 apply(rule_tac pre_lheq, simp, simp, simp)
       
   926 apply(simp add: startof_not0, simp)
       
   927 apply(rule_tac s_crsp, simp, simp, simp, simp)
       
   928 apply(rule tms_ct, simp, simp)
       
   929 apply(rule tm_ct, simp)
       
   930 apply(subgoal_tac "ci (layout_of aprog) 
       
   931                  (start_of (layout_of aprog) as) ins
       
   932                 = (tms_of aprog ! as)", simp)
       
   933 apply(simp add: tms_of.simps tpairs_of.simps)
       
   934 apply(simp add: tms_of.simps tpairs_of.simps abc_fetch.simps)
       
   935 apply(erule_tac t_split, auto simp: tm_of.simps)
       
   936 done
       
   937 
       
   938 (*
       
   939 subsection {* The compilation of @{text "Inc n"} *}
       
   940 *)
       
   941 
       
   942 text {*
       
   943   The lemmas in this section lead to the correctness of 
       
   944   the compilation of @{text "Inc n"} instruction.
       
   945 *}
       
   946 
       
   947 fun at_begin_fst_bwtn :: "inc_inv_t"
       
   948   where
       
   949   "at_begin_fst_bwtn (as, lm) (s, l, r) ires = 
       
   950       (\<exists> lm1 tn rn. lm1 = (lm @ (0\<^bsup>tn\<^esup>)) \<and> length lm1 = s \<and> 
       
   951           (if lm1 = [] then l = Bk # Bk # ires
       
   952            else l = [Bk]@<rev lm1>@Bk#Bk#ires) \<and> r = (Bk\<^bsup>rn\<^esup>))" 
       
   953 
       
   954 
       
   955 fun at_begin_fst_awtn :: "inc_inv_t"
       
   956   where
       
   957   "at_begin_fst_awtn (as, lm) (s, l, r) ires = 
       
   958       (\<exists> lm1 tn rn. lm1 = (lm @ (0\<^bsup>tn\<^esup>)) \<and> length lm1 = s \<and>
       
   959          (if lm1 = []  then l = Bk # Bk # ires
       
   960           else l = [Bk]@<rev lm1>@Bk#Bk#ires) \<and> r = [Oc]@Bk\<^bsup>rn\<^esup>
       
   961   )"
       
   962 
       
   963 fun at_begin_norm :: "inc_inv_t"
       
   964   where
       
   965   "at_begin_norm (as, lm) (s, l, r) ires= 
       
   966       (\<exists> lm1 lm2 rn. lm = lm1 @ lm2 \<and> length lm1 = s \<and> 
       
   967         (if lm1 = [] then l = Bk # Bk # ires
       
   968          else l = Bk # <rev lm1> @ Bk# Bk # ires ) \<and> r = <lm2> @ (Bk\<^bsup>rn\<^esup>))"
       
   969 
       
   970 fun in_middle :: "inc_inv_t"
       
   971   where
       
   972   "in_middle (as, lm) (s, l, r) ires = 
       
   973       (\<exists> lm1 lm2 tn m ml mr rn. lm @ 0\<^bsup>tn\<^esup> = lm1 @ [m] @ lm2
       
   974        \<and> length lm1 = s \<and> m + 1 = ml + mr \<and>  
       
   975          ml \<noteq> 0 \<and> tn = s + 1 - length lm \<and> 
       
   976        (if lm1 = [] then l = Oc\<^bsup>ml\<^esup> @ Bk # Bk # ires 
       
   977         else l = (Oc\<^bsup>ml\<^esup>)@[Bk]@<rev lm1>@
       
   978                  Bk # Bk # ires) \<and> (r = (Oc\<^bsup>mr\<^esup>) @ [Bk] @ <lm2>@ (Bk\<^bsup>rn\<^esup>) \<or> 
       
   979       (lm2 = [] \<and> r = (Oc\<^bsup>mr\<^esup>)))
       
   980       )"
       
   981 
       
   982 fun inv_locate_a :: "inc_inv_t"
       
   983   where "inv_locate_a (as, lm) (s, l, r) ires = 
       
   984      (at_begin_norm (as, lm) (s, l, r) ires \<or>
       
   985       at_begin_fst_bwtn (as, lm) (s, l, r) ires \<or>
       
   986       at_begin_fst_awtn (as, lm) (s, l, r) ires
       
   987       )"
       
   988 
       
   989 fun inv_locate_b :: "inc_inv_t"
       
   990   where "inv_locate_b (as, lm) (s, l, r) ires = 
       
   991         (in_middle (as, lm) (s, l, r)) ires "
       
   992 
       
   993 fun inv_after_write :: "inc_inv_t"
       
   994   where "inv_after_write (as, lm) (s, l, r) ires = 
       
   995            (\<exists> rn m lm1 lm2. lm = lm1 @ m # lm2 \<and>
       
   996              (if lm1 = [] then l = Oc\<^bsup>m\<^esup> @ Bk # Bk # ires
       
   997               else Oc # l = Oc\<^bsup>Suc m \<^esup>@ Bk # <rev lm1> @ 
       
   998                       Bk # Bk # ires) \<and> r = [Oc] @ <lm2> @ (Bk\<^bsup>rn\<^esup>))"
       
   999 
       
  1000 fun inv_after_move :: "inc_inv_t"
       
  1001   where "inv_after_move (as, lm) (s, l, r) ires = 
       
  1002       (\<exists> rn m lm1 lm2. lm = lm1 @ m # lm2 \<and>
       
  1003         (if lm1 = [] then l = Oc\<^bsup>Suc m\<^esup> @ Bk # Bk # ires
       
  1004          else l = Oc\<^bsup>Suc m\<^esup>@ Bk # <rev lm1> @ Bk # Bk # ires) \<and> 
       
  1005         r = <lm2> @ (Bk\<^bsup>rn\<^esup>))"
       
  1006 
       
  1007 fun inv_after_clear :: "inc_inv_t"
       
  1008   where "inv_after_clear (as, lm) (s, l, r) ires =
       
  1009        (\<exists> rn m lm1 lm2 r'. lm = lm1 @ m # lm2 \<and> 
       
  1010         (if lm1 = [] then l = Oc\<^bsup>Suc m\<^esup> @ Bk # Bk # ires
       
  1011          else l = Oc\<^bsup>Suc m\<^esup>@ Bk # <rev lm1> @ Bk # Bk # ires) \<and> 
       
  1012           r = Bk # r' \<and> Oc # r' = <lm2> @ (Bk\<^bsup>rn\<^esup>))"
       
  1013 
       
  1014 fun inv_on_right_moving :: "inc_inv_t"
       
  1015   where "inv_on_right_moving (as, lm) (s, l, r) ires = 
       
  1016        (\<exists> lm1 lm2 m ml mr rn. lm = lm1 @ [m] @ lm2 \<and> 
       
  1017             ml + mr = m \<and> 
       
  1018           (if lm1 = [] then l = Oc\<^bsup>ml\<^esup> @ Bk # Bk # ires
       
  1019           else l = (Oc\<^bsup>ml\<^esup>) @ [Bk] @ <rev lm1> @ Bk # Bk # ires) \<and> 
       
  1020          ((r = (Oc\<^bsup>mr\<^esup>) @ [Bk] @ <lm2> @ (Bk\<^bsup>rn\<^esup>)) \<or> 
       
  1021           (r = (Oc\<^bsup>mr\<^esup>) \<and> lm2 = [])))"
       
  1022 
       
  1023 fun inv_on_left_moving_norm :: "inc_inv_t"
       
  1024   where "inv_on_left_moving_norm (as, lm) (s, l, r) ires =
       
  1025       (\<exists> lm1 lm2 m ml mr rn. lm = lm1 @ [m] @ lm2 \<and>  
       
  1026              ml + mr = Suc m \<and> mr > 0 \<and> (if lm1 = [] then l = Oc\<^bsup>ml\<^esup> @ Bk # Bk # ires
       
  1027                                          else l = (Oc\<^bsup>ml\<^esup>) @ Bk # <rev lm1> @ Bk # Bk # ires)
       
  1028         \<and> (r = (Oc\<^bsup>mr\<^esup>) @ Bk # <lm2> @ (Bk\<^bsup>rn\<^esup>) \<or> 
       
  1029            (lm2 = [] \<and> r = Oc\<^bsup>mr\<^esup>)))"
       
  1030 
       
  1031 fun inv_on_left_moving_in_middle_B:: "inc_inv_t"
       
  1032   where "inv_on_left_moving_in_middle_B (as, lm) (s, l, r) ires =
       
  1033                 (\<exists> lm1 lm2 rn. lm = lm1 @ lm2 \<and>  
       
  1034                      (if lm1 = [] then l = Bk # ires
       
  1035                       else l = <rev lm1> @ Bk # Bk # ires) \<and> 
       
  1036                       r = Bk # <lm2> @ (Bk\<^bsup>rn\<^esup>))"
       
  1037 
       
  1038 fun inv_on_left_moving :: "inc_inv_t"
       
  1039   where "inv_on_left_moving (as, lm) (s, l, r) ires = 
       
  1040        (inv_on_left_moving_norm  (as, lm) (s, l, r) ires \<or>
       
  1041         inv_on_left_moving_in_middle_B (as, lm) (s, l, r) ires)"
       
  1042 
       
  1043 
       
  1044 fun inv_check_left_moving_on_leftmost :: "inc_inv_t"
       
  1045   where "inv_check_left_moving_on_leftmost (as, lm) (s, l, r) ires = 
       
  1046                 (\<exists> rn. l = ires \<and> r = [Bk, Bk] @ <lm> @ (Bk\<^bsup>rn\<^esup>))"
       
  1047 
       
  1048 fun inv_check_left_moving_in_middle :: "inc_inv_t"
       
  1049   where "inv_check_left_moving_in_middle (as, lm) (s, l, r) ires = 
       
  1050 
       
  1051               (\<exists> lm1 lm2 r' rn. lm = lm1 @ lm2 \<and>
       
  1052                  (Oc # l = <rev lm1> @ Bk # Bk # ires) \<and> r = Oc # Bk # r' \<and> 
       
  1053                            r' = <lm2> @ (Bk\<^bsup>rn\<^esup>))"
       
  1054 
       
  1055 fun inv_check_left_moving :: "inc_inv_t"
       
  1056   where "inv_check_left_moving (as, lm) (s, l, r) ires = 
       
  1057              (inv_check_left_moving_on_leftmost (as, lm) (s, l, r) ires \<or>
       
  1058              inv_check_left_moving_in_middle (as, lm) (s, l, r) ires)"
       
  1059 
       
  1060 fun inv_after_left_moving :: "inc_inv_t"
       
  1061   where "inv_after_left_moving (as, lm) (s, l, r) ires= 
       
  1062               (\<exists> rn. l = Bk # ires \<and> r = Bk # <lm> @ (Bk\<^bsup>rn\<^esup>))"
       
  1063 
       
  1064 fun inv_stop :: "inc_inv_t"
       
  1065   where "inv_stop (as, lm) (s, l, r) ires= 
       
  1066               (\<exists> rn. l = Bk # Bk # ires \<and> r = <lm> @ (Bk\<^bsup>rn\<^esup>))"
       
  1067 
       
  1068 
       
  1069 fun inc_inv :: "layout \<Rightarrow> nat \<Rightarrow> inc_inv_t"
       
  1070   where
       
  1071   "inc_inv ly n (as, lm) (s, l, r) ires =
       
  1072               (let ss = start_of ly as in
       
  1073                let lm' = abc_lm_s lm n ((abc_lm_v lm n)+1) in
       
  1074                 if s = 0 then False
       
  1075                 else if s < ss then False
       
  1076                 else if s < ss + 2 * n then 
       
  1077                    if (s - ss) mod 2 = 0 then 
       
  1078                        inv_locate_a (as, lm) ((s - ss) div 2, l, r) ires
       
  1079                    else inv_locate_b (as, lm) ((s - ss) div 2, l, r) ires
       
  1080                 else if s = ss + 2 * n then 
       
  1081                         inv_locate_a (as, lm) (n, l, r) ires
       
  1082                 else if s = ss + 2 * n + 1 then 
       
  1083                    inv_locate_b (as, lm) (n, l, r) ires
       
  1084                 else if s = ss + 2 * n + 2 then 
       
  1085                    inv_after_write (as, lm') (s - ss, l, r) ires
       
  1086                 else if s = ss + 2 * n + 3 then 
       
  1087                    inv_after_move (as, lm') (s - ss, l, r) ires
       
  1088                 else if s = ss + 2 * n + 4 then 
       
  1089                    inv_after_clear (as, lm') (s - ss, l, r) ires
       
  1090                 else if s = ss + 2 * n + 5 then 
       
  1091                    inv_on_right_moving (as, lm') (s - ss, l, r) ires
       
  1092                 else if s = ss + 2 * n + 6 then 
       
  1093                    inv_on_left_moving (as, lm') (s - ss, l, r) ires
       
  1094                 else if s = ss + 2 * n + 7 then 
       
  1095                    inv_check_left_moving (as, lm') (s - ss, l, r) ires
       
  1096                 else if s = ss + 2 * n + 8 then 
       
  1097                    inv_after_left_moving (as, lm') (s - ss, l, r) ires
       
  1098                 else if s = ss + 2 * n + 9 then 
       
  1099                    inv_stop (as, lm') (s - ss, l, r) ires
       
  1100                 else False) "
       
  1101 
       
  1102 lemma fetch_intro: 
       
  1103   "\<lbrakk>\<And>xs.\<lbrakk>ba = Oc # xs\<rbrakk> \<Longrightarrow> P (fetch prog i Oc);
       
  1104    \<And>xs.\<lbrakk>ba = Bk # xs\<rbrakk> \<Longrightarrow> P (fetch prog i Bk);
       
  1105    ba = [] \<Longrightarrow> P (fetch prog i Bk)
       
  1106    \<rbrakk> \<Longrightarrow> P (fetch prog i 
       
  1107              (case ba of [] \<Rightarrow> Bk | Bk # xs \<Rightarrow> Bk | Oc # xs \<Rightarrow> Oc))"
       
  1108 by (auto split:list.splits block.splits)
       
  1109 
       
  1110 lemma length_findnth[simp]: "length (findnth n) = 4 * n"
       
  1111 apply(induct n, simp)
       
  1112 apply(simp)
       
  1113 done
       
  1114 
       
  1115 declare tshift.simps[simp del]
       
  1116 declare findnth.simps[simp del]
       
  1117 
       
  1118 lemma findnth_nth: 
       
  1119  "\<lbrakk>n > q; x < 4\<rbrakk> \<Longrightarrow> 
       
  1120         (findnth n) ! (4 * q + x) = (findnth (Suc q) ! (4 * q + x))"
       
  1121 apply(induct n, simp)
       
  1122 apply(case_tac "q < n", simp add: findnth.simps, auto)
       
  1123 apply(simp add: nth_append)
       
  1124 apply(subgoal_tac "q = n", simp)
       
  1125 apply(arith)
       
  1126 done
       
  1127 
       
  1128 lemma Suc_pre[simp]: "\<not> a < start_of ly as \<Longrightarrow> 
       
  1129           (Suc a - start_of ly as) = Suc (a - start_of ly as)"
       
  1130 apply(arith)
       
  1131 done
       
  1132 
       
  1133 lemma fetch_locate_a_o: "
       
  1134 \<And>a  q xs.
       
  1135     \<lbrakk>\<not> a < start_of (layout_of aprog) as; 
       
  1136       a < start_of (layout_of aprog) as + 2 * n; 
       
  1137       a - start_of (layout_of aprog) as = 2 * q; 
       
  1138       start_of (layout_of aprog) as > 0\<rbrakk>
       
  1139     \<Longrightarrow> (fetch (ci (layout_of aprog) (start_of (layout_of aprog) as)
       
  1140          (Inc n)) (Suc (2 * q)) Oc) = (R, a+1)"
       
  1141 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  1142                   nth_of.simps tshift.simps nth_append Suc_pre)
       
  1143 apply(subgoal_tac "(findnth n ! Suc (4 * q)) = 
       
  1144                  findnth (Suc q) ! (4 * q + 1)")
       
  1145 apply(simp add: findnth.simps nth_append)
       
  1146 apply(subgoal_tac " findnth n !(4 * q + 1) = 
       
  1147                  findnth (Suc q) ! (4 * q + 1)", simp)
       
  1148 apply(rule_tac findnth_nth, auto)
       
  1149 done
       
  1150 
       
  1151 lemma fetch_locate_a_b: "
       
  1152 \<And>a  q xs.
       
  1153     \<lbrakk>abc_fetch as aprog = Some (Inc n);  
       
  1154      \<not> a < start_of (layout_of aprog) as; 
       
  1155      a < start_of (layout_of aprog) as + 2 * n; 
       
  1156      a - start_of (layout_of aprog) as = 2 * q; 
       
  1157      start_of (layout_of aprog) as > 0\<rbrakk>
       
  1158     \<Longrightarrow> (fetch (ci (layout_of aprog) 
       
  1159       (start_of (layout_of aprog) as) (Inc n)) (Suc (2 * q)) Bk)
       
  1160        = (W1, a)"
       
  1161 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  1162                  tshift.simps nth_append)
       
  1163 apply(subgoal_tac "(findnth n ! (4 * q)) = 
       
  1164                            findnth (Suc q) ! (4 * q )")
       
  1165 apply(simp add: findnth.simps nth_append)
       
  1166 apply(subgoal_tac " findnth n !(4 * q + 0) =
       
  1167                             findnth (Suc q) ! (4 * q + 0)", simp)
       
  1168 apply(rule_tac findnth_nth, auto)
       
  1169 done
       
  1170 
       
  1171 lemma [intro]: "x mod 2 = Suc 0 \<Longrightarrow> \<exists> q. x = Suc (2 * q)"
       
  1172 apply(drule mod_eqD, auto)
       
  1173 done
       
  1174 
       
  1175 lemma  add3_Suc: "x + 3 = Suc (Suc (Suc x))"
       
  1176 apply(arith)
       
  1177 done
       
  1178 
       
  1179 declare start_of.simps[simp]
       
  1180 (*
       
  1181 lemma layout_not0: "start_of ly as > 0"
       
  1182 by(induct as, auto)
       
  1183 *)
       
  1184 lemma [simp]: 
       
  1185  "\<lbrakk>\<not> a < start_of (layout_of aprog) as; 
       
  1186    a - start_of (layout_of aprog) as = Suc (2 * q); 
       
  1187    abc_fetch as aprog = Some (Inc n); 
       
  1188    start_of (layout_of aprog) as > 0\<rbrakk>
       
  1189     \<Longrightarrow> Suc (Suc (2 * q + start_of (layout_of aprog) as - Suc 0)) = a"
       
  1190 apply(subgoal_tac 
       
  1191 "Suc (Suc (2 * q + start_of (layout_of aprog) as - Suc 0)) 
       
  1192               = 2 + 2 * q + start_of (layout_of aprog) as - Suc 0", 
       
  1193   simp, simp add: inc_startof_not0)
       
  1194 done
       
  1195 
       
  1196 lemma fetch_locate_b_o: "
       
  1197 \<And>a  xs.
       
  1198     \<lbrakk>0 < a; \<not> a < start_of (layout_of aprog) as; 
       
  1199   a < start_of (layout_of aprog) as + 2 * n; 
       
  1200  (a - start_of (layout_of aprog) as) mod 2 = Suc 0; 
       
  1201  start_of (layout_of aprog) as > 0\<rbrakk>
       
  1202     \<Longrightarrow> (fetch (ci (layout_of aprog) (start_of (layout_of aprog) as) 
       
  1203       (Inc n)) (Suc (a - start_of (layout_of aprog) as)) Oc) = (R, a)"
       
  1204 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  1205                  nth_of.simps tshift.simps nth_append)
       
  1206 apply(subgoal_tac "\<exists> q. (a - start_of (layout_of aprog) as) = 
       
  1207                          2 * q + 1", auto)
       
  1208 apply(subgoal_tac "(findnth n ! Suc (Suc (Suc (4 * q)))) 
       
  1209                   = findnth (Suc q) ! (4 * q + 3)")
       
  1210 apply(simp add: findnth.simps nth_append)
       
  1211 apply(subgoal_tac " findnth n ! (4 * q + 3) = 
       
  1212                  findnth (Suc q) ! (4 * q + 3)", simp add: add3_Suc)
       
  1213 apply(rule_tac findnth_nth, auto)
       
  1214 done
       
  1215 
       
  1216 lemma fetch_locate_b_b: "
       
  1217 \<And>a  xs.
       
  1218     \<lbrakk>0 < a;  \<not> a < start_of (layout_of aprog) as; 
       
  1219      a < start_of (layout_of aprog) as + 2 * n; 
       
  1220      (a - start_of (layout_of aprog) as) mod 2 = Suc 0; 
       
  1221      start_of (layout_of aprog) as > 0\<rbrakk>
       
  1222     \<Longrightarrow> (fetch (ci (layout_of aprog) (start_of (layout_of aprog) as)
       
  1223         (Inc n)) (Suc (a - start_of (layout_of aprog) as)) Bk) 
       
  1224         = (R, a + 1)"
       
  1225 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  1226                   nth_of.simps tshift.simps nth_append)
       
  1227 apply(subgoal_tac "\<exists> q. (a - start_of (layout_of aprog) as) = 
       
  1228                   2 * q + 1", auto)
       
  1229 apply(subgoal_tac "(findnth n ! Suc ((Suc (4 * q)))) = 
       
  1230                     findnth (Suc q) ! (4 * q + 2)")
       
  1231 apply(simp add: findnth.simps nth_append)
       
  1232 apply(subgoal_tac " findnth n ! (4 * q + 2) = 
       
  1233                     findnth (Suc q) ! (4 * q + 2)", simp)
       
  1234 apply(rule_tac findnth_nth, auto)
       
  1235 done
       
  1236 
       
  1237 lemma fetch_locate_n_a_o: 
       
  1238        "start_of (layout_of aprog) as > 0
       
  1239        \<Longrightarrow> (fetch (ci (layout_of aprog) 
       
  1240       (start_of (layout_of aprog) as) (Inc n)) (Suc (2 * n)) Oc) = 
       
  1241              (R, start_of (layout_of aprog) as + 2 * n + 1)"
       
  1242 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  1243                   nth_of.simps tshift.simps nth_append tinc_b_def)
       
  1244 done
       
  1245 
       
  1246 lemma fetch_locate_n_a_b: "
       
  1247        start_of (layout_of aprog) as > 0
       
  1248       \<Longrightarrow> (fetch (ci (layout_of aprog) 
       
  1249     (start_of (layout_of aprog) as) (Inc n)) (Suc (2 * n)) Bk) 
       
  1250    = (W1, start_of (layout_of aprog) as + 2 * n)"
       
  1251 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  1252                   nth_of.simps tshift.simps nth_append tinc_b_def)
       
  1253 done
       
  1254 
       
  1255 lemma fetch_locate_n_b_o: "
       
  1256     start_of (layout_of aprog) as > 0
       
  1257     \<Longrightarrow> (fetch (ci (layout_of aprog) (start_of (layout_of aprog) as) 
       
  1258      (Inc n)) (Suc (Suc (2 * n))) Oc) = 
       
  1259                       (R, start_of (layout_of aprog) as + 2 * n + 1)"
       
  1260 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  1261                   nth_of.simps tshift.simps nth_append tinc_b_def)
       
  1262 done
       
  1263 
       
  1264 lemma fetch_locate_n_b_b: "
       
  1265     start_of (layout_of aprog) as > 0
       
  1266    \<Longrightarrow> (fetch (ci (layout_of aprog) (start_of (layout_of aprog) as) 
       
  1267    (Inc n)) (Suc (Suc (2 * n))) Bk) = 
       
  1268        (W1, start_of (layout_of aprog) as + 2 * n + 2)"
       
  1269 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  1270                   nth_of.simps tshift.simps nth_append tinc_b_def)
       
  1271 done
       
  1272 
       
  1273 lemma fetch_after_write_o: "
       
  1274     start_of (layout_of aprog) as > 0
       
  1275     \<Longrightarrow> (fetch (ci (layout_of aprog) (start_of (layout_of aprog) as) 
       
  1276             (Inc n)) (Suc (Suc (Suc (2 * n)))) Oc) = 
       
  1277         (R, start_of (layout_of aprog) as + 2*n + 3)"
       
  1278 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  1279                   nth_of.simps tshift.simps nth_append tinc_b_def)
       
  1280 done
       
  1281 
       
  1282 lemma fetch_after_move_o: "
       
  1283       start_of (layout_of aprog) as > 0
       
  1284       \<Longrightarrow> (fetch (ci (layout_of aprog) 
       
  1285               (start_of (layout_of aprog) as) (Inc n)) (4 + 2 * n) Oc)
       
  1286         = (W0, start_of (layout_of aprog) as + 2 * n + 4)"
       
  1287 apply(auto simp: ci.simps findnth.simps tshift.simps 
       
  1288                  tinc_b_def add3_Suc)
       
  1289 apply(subgoal_tac "4 + 2*n = Suc (2*n + 3)", simp only: fetch.simps)
       
  1290 apply(auto simp: nth_of.simps nth_append)
       
  1291 done
       
  1292 
       
  1293 lemma fetch_after_move_b: "
       
  1294       start_of (layout_of aprog) as > 0
       
  1295       \<Longrightarrow>(fetch (ci (layout_of aprog) 
       
  1296             (start_of (layout_of aprog) as) (Inc n)) (4 + 2 * n) Bk)
       
  1297        = (L, start_of (layout_of aprog) as + 2 * n + 6)"
       
  1298 apply(auto simp: ci.simps findnth.simps tshift.simps 
       
  1299                  tinc_b_def add3_Suc)
       
  1300 apply(subgoal_tac "4 + 2*n = Suc (2*n + 3)", simp only: fetch.simps)
       
  1301 apply(auto simp: nth_of.simps nth_append)
       
  1302 done
       
  1303 
       
  1304 lemma fetch_clear_b: "
       
  1305      start_of (layout_of aprog) as > 0
       
  1306       \<Longrightarrow> (fetch (ci (layout_of aprog) 
       
  1307               (start_of (layout_of aprog) as) (Inc n)) (5 + 2 * n) Bk)
       
  1308       = (R, start_of (layout_of aprog) as + 2 * n + 5)"
       
  1309 apply(auto simp: ci.simps findnth.simps 
       
  1310                      tshift.simps tinc_b_def add3_Suc)
       
  1311 apply(subgoal_tac "5 + 2*n = Suc (2*n + 4)", simp only: fetch.simps)
       
  1312 apply(auto simp: nth_of.simps nth_append)
       
  1313 done
       
  1314 
       
  1315 lemma fetch_right_move_o: "
       
  1316       start_of (layout_of aprog) as > 0
       
  1317       \<Longrightarrow> (fetch (ci (layout_of aprog) 
       
  1318                 (start_of (layout_of aprog) as) (Inc n)) (6 + 2*n) Oc)
       
  1319       = (R, start_of (layout_of aprog) as + 2 * n + 5)"
       
  1320 apply(auto simp: ci.simps findnth.simps tshift.simps 
       
  1321                  tinc_b_def add3_Suc)
       
  1322 apply(subgoal_tac "6 + 2*n = Suc (2*n + 5)", simp only: fetch.simps)
       
  1323 apply(auto simp: nth_of.simps nth_append)
       
  1324 done
       
  1325 
       
  1326 lemma fetch_right_move_b: "
       
  1327       start_of (layout_of aprog) as > 0
       
  1328       \<Longrightarrow> (fetch (ci (layout_of aprog) 
       
  1329                 (start_of (layout_of aprog) as) (Inc n)) (6 + 2*n) Bk)
       
  1330       = (W1, start_of (layout_of aprog) as + 2 * n + 2)"
       
  1331 apply(auto simp: ci.simps findnth.simps 
       
  1332                  tshift.simps tinc_b_def add3_Suc)
       
  1333 apply(subgoal_tac "6 + 2*n = Suc (2*n + 5)", simp only: fetch.simps)
       
  1334 apply(auto simp: nth_of.simps nth_append)
       
  1335 done
       
  1336 
       
  1337 lemma fetch_left_move_o: "
       
  1338       start_of (layout_of aprog) as > 0
       
  1339       \<Longrightarrow> (fetch (ci (layout_of aprog) 
       
  1340                (start_of (layout_of aprog) as) (Inc n)) (7 + 2*n) Oc)
       
  1341       = (L, start_of (layout_of aprog) as + 2 * n + 6)"
       
  1342 apply(auto simp: ci.simps findnth.simps tshift.simps 
       
  1343                  tinc_b_def add3_Suc)
       
  1344 apply(subgoal_tac "7 + 2*n = Suc (2*n + 6)", simp only: fetch.simps)
       
  1345 apply(auto simp: nth_of.simps nth_append)
       
  1346 done
       
  1347 
       
  1348 lemma fetch_left_move_b: "
       
  1349       start_of (layout_of aprog) as > 0
       
  1350       \<Longrightarrow> (fetch (ci (layout_of aprog) 
       
  1351                (start_of (layout_of aprog) as) (Inc n)) (7 + 2*n) Bk)
       
  1352       = (L, start_of (layout_of aprog) as + 2 * n + 7)"
       
  1353 apply(auto simp: ci.simps findnth.simps 
       
  1354                  tshift.simps tinc_b_def add3_Suc)
       
  1355 apply(subgoal_tac "7 + 2*n = Suc (2*n + 6)", simp only: fetch.simps)
       
  1356 apply(auto simp: nth_of.simps nth_append)
       
  1357 done
       
  1358 
       
  1359 lemma fetch_check_left_move_o: "
       
  1360       start_of (layout_of aprog) as > 0
       
  1361       \<Longrightarrow> (fetch (ci (layout_of aprog) 
       
  1362                (start_of (layout_of aprog) as) (Inc n)) (8 + 2*n) Oc)
       
  1363       = (L, start_of (layout_of aprog) as + 2 * n + 6)"
       
  1364 apply(auto simp: ci.simps findnth.simps tshift.simps tinc_b_def)
       
  1365 apply(subgoal_tac "8 + 2 * n = Suc (2 * n + 7)", 
       
  1366                                   simp only: fetch.simps)
       
  1367 apply(auto simp: nth_of.simps nth_append)
       
  1368 done
       
  1369 
       
  1370 lemma fetch_check_left_move_b: "
       
  1371       start_of (layout_of aprog) as > 0
       
  1372       \<Longrightarrow> (fetch (ci (layout_of aprog) 
       
  1373               (start_of (layout_of aprog) as) (Inc n)) (8 + 2*n) Bk)
       
  1374       = (R, start_of (layout_of aprog) as + 2 * n + 8)  "
       
  1375 apply(auto simp: ci.simps findnth.simps 
       
  1376                  tshift.simps tinc_b_def add3_Suc)
       
  1377 apply(subgoal_tac "8 + 2*n= Suc (2*n + 7)", simp only: fetch.simps)
       
  1378 apply(auto simp: nth_of.simps nth_append)
       
  1379 done
       
  1380 
       
  1381 lemma fetch_after_left_move: "
       
  1382       start_of (layout_of aprog) as > 0
       
  1383       \<Longrightarrow> (fetch (ci (layout_of aprog) 
       
  1384               (start_of (layout_of aprog) as) (Inc n)) (9 + 2*n) Bk)
       
  1385      = (R, start_of (layout_of aprog) as + 2 * n + 9)"
       
  1386 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  1387                   nth_of.simps tshift.simps nth_append tinc_b_def)
       
  1388 done
       
  1389 
       
  1390 lemma fetch_stop: "
       
  1391        start_of (layout_of aprog) as > 0
       
  1392       \<Longrightarrow> (fetch (ci (layout_of aprog) 
       
  1393              (start_of (layout_of aprog) as) (Inc n)) (10 + 2 *n)  b)
       
  1394      = (Nop, 0)"
       
  1395 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  1396                   nth_of.simps tshift.simps nth_append tinc_b_def
       
  1397             split: block.splits)
       
  1398 done
       
  1399 
       
  1400 lemma fetch_state0: "
       
  1401        (fetch (ci (layout_of aprog) 
       
  1402                (start_of (layout_of aprog) as) (Inc n)) 0 b)
       
  1403      = (Nop, 0)"
       
  1404 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  1405                   nth_of.simps tshift.simps nth_append tinc_b_def)
       
  1406 done
       
  1407 
       
  1408 lemmas fetch_simps = 
       
  1409   fetch_locate_a_o fetch_locate_a_b fetch_locate_b_o fetch_locate_b_b 
       
  1410   fetch_locate_n_a_b fetch_locate_n_a_o fetch_locate_n_b_o 
       
  1411   fetch_locate_n_b_b fetch_after_write_o fetch_after_move_o 
       
  1412   fetch_after_move_b fetch_clear_b fetch_right_move_o 
       
  1413   fetch_right_move_b fetch_left_move_o fetch_left_move_b
       
  1414   fetch_after_left_move fetch_check_left_move_o fetch_stop 
       
  1415   fetch_state0 fetch_check_left_move_b
       
  1416 
       
  1417 text {* *}
       
  1418 declare exponent_def[simp del] tape_of_nat_list.simps[simp del] 
       
  1419    at_begin_norm.simps[simp del] at_begin_fst_bwtn.simps[simp del] 
       
  1420    at_begin_fst_awtn.simps[simp del] in_middle.simps[simp del] 
       
  1421    abc_lm_s.simps[simp del] abc_lm_v.simps[simp del]  
       
  1422    ci.simps[simp del] t_step.simps[simp del]
       
  1423    inv_after_move.simps[simp del] 
       
  1424    inv_on_left_moving_norm.simps[simp del] 
       
  1425    inv_on_left_moving_in_middle_B.simps[simp del]
       
  1426    inv_after_clear.simps[simp del] 
       
  1427    inv_after_write.simps[simp del] inv_on_left_moving.simps[simp del]
       
  1428    inv_on_right_moving.simps[simp del] 
       
  1429    inv_check_left_moving.simps[simp del] 
       
  1430    inv_check_left_moving_in_middle.simps[simp del]
       
  1431    inv_check_left_moving_on_leftmost.simps[simp del] 
       
  1432    inv_after_left_moving.simps[simp del]
       
  1433    inv_stop.simps[simp del] inv_locate_a.simps[simp del] 
       
  1434    inv_locate_b.simps[simp del]
       
  1435 declare tms_of.simps[simp del] tm_of.simps[simp del]
       
  1436         layout_of.simps[simp del] abc_fetch.simps [simp del] 
       
  1437         t_step.simps[simp del] t_steps.simps[simp del] 
       
  1438         tpairs_of.simps[simp del] start_of.simps[simp del]
       
  1439         fetch.simps [simp del] new_tape.simps [simp del] 
       
  1440         nth_of.simps [simp del] ci.simps [simp del]
       
  1441         length_of.simps[simp del]
       
  1442 
       
  1443 (*! Start point *)
       
  1444 lemma [simp]: "Suc (2 * q) mod 2 = Suc 0"
       
  1445 by arith
       
  1446 
       
  1447 lemma [simp]: "Suc (2 * q) div 2 = q"
       
  1448 by arith
       
  1449 
       
  1450 lemma [simp]: "\<lbrakk> \<not> a < start_of ly as; 
       
  1451           a < start_of ly as + 2 * n; a - start_of ly as = 2 * q\<rbrakk>
       
  1452              \<Longrightarrow> Suc a < start_of ly as + 2 * n"
       
  1453 apply(arith)
       
  1454 done
       
  1455 
       
  1456 lemma [simp]: "x mod 2 = Suc 0 \<Longrightarrow> (Suc x) mod 2 = 0"
       
  1457 by arith
       
  1458 
       
  1459 lemma [simp]: "x mod 2 = Suc 0 \<Longrightarrow> (Suc x) div 2 = Suc (x div 2)"
       
  1460 by arith
       
  1461 lemma exp_def[simp]: "a\<^bsup>Suc n \<^esup>= a # a\<^bsup>n\<^esup>"
       
  1462 by(simp add: exponent_def)
       
  1463 lemma [intro]: "Bk # r = Oc\<^bsup>mr\<^esup> @ r' \<Longrightarrow> mr = 0"
       
  1464 by(case_tac mr, auto simp: exponent_def)
       
  1465 
       
  1466 lemma [intro]: "Bk # r = replicate mr Oc \<Longrightarrow> mr = 0"
       
  1467 by(case_tac mr, auto)
       
  1468 lemma tape_of_nl_abv_cons[simp]: "xs \<noteq> [] \<Longrightarrow> 
       
  1469                    <x # xs> = Oc\<^bsup>Suc x\<^esup>@ Bk # <xs>"
       
  1470 apply(simp add: tape_of_nl_abv tape_of_nat_list.simps)
       
  1471 apply(case_tac xs, simp, simp add: tape_of_nat_list.simps)
       
  1472 done
       
  1473 
       
  1474 lemma [simp]: "<[]::nat list> = []"
       
  1475 by(auto simp: tape_of_nl_abv tape_of_nat_list.simps)
       
  1476 lemma [simp]: "Oc # r = <(lm::nat list)> @ Bk\<^bsup>rn\<^esup>\<Longrightarrow> lm \<noteq> []"
       
  1477 apply(auto simp: tape_of_nl_abv tape_of_nat_list.simps)
       
  1478 apply(case_tac rn, auto simp: exponent_def)
       
  1479 done
       
  1480 lemma BkCons_nil: "Bk # xs = <lm::nat list> @ Bk\<^bsup>rn\<^esup>\<Longrightarrow> lm = []"
       
  1481 apply(case_tac lm, simp)
       
  1482 apply(case_tac list, auto simp: tape_of_nl_abv tape_of_nat_list.simps)
       
  1483 done
       
  1484 lemma BkCons_nil': "Bk # xs = <lm::nat list> @ Bk\<^bsup>ln\<^esup>\<Longrightarrow> lm = []"
       
  1485 by(auto intro: BkCons_nil)
       
  1486 
       
  1487 lemma hd_tl_tape_of_nat_list:  
       
  1488    "tl (lm::nat list) \<noteq> [] \<Longrightarrow> <lm> = <hd lm> @ Bk # <tl lm>"
       
  1489 apply(frule tape_of_nl_abv_cons[of "tl lm" "hd lm"])
       
  1490 apply(simp add: tape_of_nat_abv Bk_def del: tape_of_nl_abv_cons)
       
  1491 apply(subgoal_tac "lm = hd lm # tl lm", auto)
       
  1492 apply(case_tac lm, auto)
       
  1493 done
       
  1494 lemma [simp]: "Oc # xs = Oc\<^bsup>mr\<^esup> @ Bk # <lm2> @ Bk\<^bsup>rn\<^esup>\<Longrightarrow> mr > 0"
       
  1495 apply(case_tac mr, auto simp: exponent_def)
       
  1496 done
       
  1497 
       
  1498 lemma tape_of_nat_list_cons: "xs \<noteq> [] \<Longrightarrow> tape_of_nat_list (x # xs) =
       
  1499               replicate (Suc x) Oc @ Bk # tape_of_nat_list xs"
       
  1500 apply(drule tape_of_nl_abv_cons[of xs x])
       
  1501 apply(auto simp: tape_of_nl_abv tape_of_nat_abv Oc_def Bk_def exponent_def)
       
  1502 done
       
  1503 
       
  1504 lemma rev_eq: "rev xs = rev ys \<Longrightarrow> xs = ys"
       
  1505 by simp
       
  1506 
       
  1507 lemma tape_of_nat_list_eq: " xs = ys \<Longrightarrow> 
       
  1508         tape_of_nat_list xs = tape_of_nat_list ys"
       
  1509 by simp
       
  1510 
       
  1511 lemma tape_of_nl_nil_eq: "<(lm::nat list)> = [] = (lm = [])"
       
  1512 apply(simp add: tape_of_nl_abv tape_of_nat_list.simps)
       
  1513 apply(case_tac lm, simp add: tape_of_nat_list.simps)
       
  1514 apply(case_tac "list")
       
  1515 apply(auto simp: tape_of_nat_list.simps)
       
  1516 done
       
  1517 
       
  1518 lemma rep_ind: "replicate (Suc n) a = replicate n a @ [a]"
       
  1519 apply(induct n, simp, simp)
       
  1520 done
       
  1521 
       
  1522 lemma [simp]: "Oc # r = <lm::nat list> @ replicate rn Bk \<Longrightarrow> Suc 0 \<le> length lm"
       
  1523 apply(rule_tac classical, auto)
       
  1524 apply(case_tac lm, simp, case_tac rn, auto)
       
  1525 done
       
  1526 lemma Oc_Bk_Cons: "Oc # Bk # list = <lm::nat list> @ Bk\<^bsup>ln\<^esup> \<Longrightarrow> 
       
  1527                    lm \<noteq> [] \<and> hd lm = 0"
       
  1528 apply(case_tac lm, simp, case_tac ln, simp add: exponent_def, simp add: exponent_def, simp)
       
  1529 apply(case_tac lista, auto simp: tape_of_nl_abv tape_of_nat_list.simps)
       
  1530 done 
       
  1531 (*lemma Oc_Oc_Cons: "Oc # Oc # list = <lm::nat list> @ Bk\<^bsup>ln\<^esup> \<Longrightarrow> 
       
  1532                   lm \<noteq> [] \<and> hd lm > 0"
       
  1533 apply(case_tac lm, simp add: exponent_def, case_tac ln, simp, simp)
       
  1534 apply(case_tac lista, 
       
  1535         auto simp: tape_of_nl_abv tape_of_nat_list.simps exponent_def)
       
  1536 apply(case_tac [!] a, auto)
       
  1537 apply(case_tac ln, auto)
       
  1538 done
       
  1539 *)
       
  1540 lemma Oc_nil_zero[simp]: "[Oc] = <lm::nat list> @ Bk\<^bsup>ln\<^esup> 
       
  1541                  \<Longrightarrow> lm = [0] \<and> ln = 0"
       
  1542 apply(case_tac lm, simp)
       
  1543 apply(case_tac ln, auto simp: exponent_def)
       
  1544 apply(case_tac [!] list, 
       
  1545         auto simp: tape_of_nl_abv tape_of_nat_list.simps)
       
  1546 done
       
  1547 
       
  1548 lemma  [simp]: "Oc # r = <lm2> @ replicate rn Bk \<Longrightarrow> 
       
  1549        (\<exists>rn. r = replicate (hd lm2) Oc @ Bk # <tl lm2> @ 
       
  1550                       replicate rn Bk) \<or> 
       
  1551           tl lm2 = [] \<and> r = replicate (hd lm2) Oc"
       
  1552 apply(rule_tac disjCI, simp)
       
  1553 apply(case_tac "tl lm2 = []", simp)
       
  1554 apply(case_tac lm2, simp add: tape_of_nl_abv tape_of_nat_list.simps)
       
  1555 apply(case_tac rn, simp, simp, simp)
       
  1556 apply(simp add: tape_of_nl_abv tape_of_nat_list.simps exponent_def)
       
  1557 apply(case_tac rn, simp, simp)
       
  1558 apply(rule_tac x = rn in exI)
       
  1559 apply(simp add: hd_tl_tape_of_nat_list)
       
  1560 apply(simp add: tape_of_nat_abv Oc_def exponent_def)
       
  1561 done
       
  1562 
       
  1563 (*inv: from locate_a to locate_b*)
       
  1564 lemma [simp]: 
       
  1565       "inv_locate_a (as, lm) (q, l, Oc # r) ires
       
  1566        \<Longrightarrow> inv_locate_b (as, lm) (q, Oc # l, r) ires"
       
  1567 apply(simp only: inv_locate_a.simps inv_locate_b.simps in_middle.simps
       
  1568           at_begin_norm.simps at_begin_fst_bwtn.simps
       
  1569           at_begin_fst_awtn.simps)
       
  1570 apply(erule disjE, erule exE, erule exE, erule exE)
       
  1571 apply(rule_tac x = lm1 in exI, rule_tac x = "tl lm2" in exI, simp)
       
  1572 apply(rule_tac x = "0" in exI, rule_tac x = "hd lm2" in exI, 
       
  1573                 auto simp: exponent_def)
       
  1574 apply(rule_tac x = "Suc 0" in exI, simp add:exponent_def)
       
  1575 apply(rule_tac x = "lm @ replicate tn 0" in exI, 
       
  1576       rule_tac x = "[]" in exI,    
       
  1577       rule_tac x = "Suc tn" in exI, rule_tac x = 0 in exI)
       
  1578 apply(simp only: rep_ind, simp)
       
  1579 apply(rule_tac x = "Suc 0" in exI, auto)
       
  1580 apply(case_tac [1-3] rn, simp_all )
       
  1581 apply(rule_tac x = "lm @ replicate tn 0" in exI, 
       
  1582       rule_tac x = "[]" in exI, 
       
  1583       rule_tac x = "Suc tn" in exI, 
       
  1584       rule_tac x = 0 in exI, simp add: rep_ind del: replicate_Suc split:if_splits)
       
  1585 apply(rule_tac x = "Suc 0" in exI, auto)
       
  1586 apply(case_tac rn, simp, simp)
       
  1587 apply(rule_tac [!] x = "Suc 0" in exI, auto)
       
  1588 apply(case_tac [!] rn, simp_all)
       
  1589 done
       
  1590 
       
  1591 (*inv: from locate_a to _locate_a*)
       
  1592 lemma locate_a_2_locate_a[simp]: "inv_locate_a (as, am) (q, aaa, Bk # xs) ires
       
  1593        \<Longrightarrow> inv_locate_a (as, am) (q, aaa, Oc # xs) ires"
       
  1594 apply(simp only: inv_locate_a.simps at_begin_norm.simps 
       
  1595                  at_begin_fst_bwtn.simps at_begin_fst_awtn.simps)
       
  1596 apply(erule_tac disjE, erule exE, erule exE, erule exE, 
       
  1597       rule disjI2, rule disjI2)
       
  1598 defer
       
  1599 apply(erule_tac disjE, erule exE, erule exE, 
       
  1600       erule exE, rule disjI2, rule disjI2)
       
  1601 prefer 2
       
  1602 apply(simp)
       
  1603 proof-
       
  1604   fix lm1 tn rn
       
  1605   assume k: "lm1 = am @ 0\<^bsup>tn\<^esup> \<and> length lm1 = q \<and> (if lm1 = [] then aaa = Bk # Bk # 
       
  1606     ires else aaa = [Bk] @ <rev lm1> @ Bk # Bk # ires) \<and> Bk # xs = Bk\<^bsup>rn\<^esup>"
       
  1607   thus "\<exists>lm1 tn rn. lm1 = am @ 0\<^bsup>tn\<^esup> \<and> length lm1 = q \<and> (if lm1 = [] then 
       
  1608     aaa = Bk # Bk # ires else aaa = [Bk] @ <rev lm1> @ Bk # Bk # ires) \<and> Oc # xs = [Oc] @ Bk\<^bsup>rn\<^esup>"
       
  1609     (is "\<exists>lm1 tn rn. ?P lm1 tn rn")
       
  1610   proof -
       
  1611     from k have "?P lm1 tn (rn - 1)"
       
  1612       apply(auto simp: Oc_def)
       
  1613       by(case_tac [!] "rn::nat", auto simp: exponent_def)
       
  1614     thus ?thesis by blast
       
  1615   qed
       
  1616 next
       
  1617   fix lm1 lm2 rn
       
  1618   assume h1: "am = lm1 @ lm2 \<and> length lm1 = q \<and> (if lm1 = [] 
       
  1619     then aaa = Bk # Bk # ires else aaa = Bk # <rev lm1> @ Bk # Bk # ires) \<and>
       
  1620     Bk # xs = <lm2> @ Bk\<^bsup>rn\<^esup>"
       
  1621   from h1 have h2: "lm2 = []"
       
  1622   proof(rule_tac xs = xs and rn = rn in BkCons_nil, simp)
       
  1623   qed
       
  1624   from h1 and h2 show "\<exists>lm1 tn rn. lm1 = am @ 0\<^bsup>tn\<^esup> \<and> length lm1 = q \<and> 
       
  1625     (if lm1 = [] then aaa = Bk # Bk # ires else aaa = [Bk] @ <rev lm1> @ Bk # Bk # ires) \<and>
       
  1626     Oc # xs = [Oc] @ Bk\<^bsup>rn\<^esup>" 
       
  1627     (is "\<exists>lm1 tn rn. ?P lm1 tn rn")
       
  1628   proof -
       
  1629     from h1 and h2  have "?P lm1 0 (rn - 1)"
       
  1630       apply(auto simp: Oc_def exponent_def 
       
  1631                       tape_of_nl_abv tape_of_nat_list.simps)
       
  1632       by(case_tac "rn::nat", simp, simp)
       
  1633     thus ?thesis by blast
       
  1634   qed
       
  1635 qed
       
  1636 
       
  1637 lemma [intro]: "\<exists>rn. [a] = a\<^bsup>rn\<^esup>"
       
  1638 by(rule_tac x = "Suc 0" in exI, simp add: exponent_def)
       
  1639 
       
  1640 lemma [intro]: "\<exists>tn. [] = a\<^bsup>tn\<^esup>"
       
  1641 apply(rule_tac x = 0 in exI, simp add: exponent_def)
       
  1642 done
       
  1643 
       
  1644 lemma [intro]:  "at_begin_norm (as, am) (q, aaa, []) ires
       
  1645              \<Longrightarrow> at_begin_norm (as, am) (q, aaa, [Bk]) ires"
       
  1646 apply(simp add: at_begin_norm.simps, erule_tac exE, erule_tac exE)
       
  1647 apply(rule_tac x = lm1 in exI, simp, auto)
       
  1648 done
       
  1649 
       
  1650 lemma [intro]: "at_begin_fst_bwtn (as, am) (q, aaa, []) ires 
       
  1651             \<Longrightarrow> at_begin_fst_bwtn (as, am) (q, aaa, [Bk]) ires"
       
  1652 apply(simp only: at_begin_fst_bwtn.simps, erule_tac exE, erule_tac exE, erule_tac exE)
       
  1653 apply(rule_tac x = "am @ 0\<^bsup>tn\<^esup>" in exI, auto)
       
  1654 done
       
  1655 
       
  1656 lemma [intro]: "at_begin_fst_awtn (as, am) (q, aaa, []) ires
       
  1657            \<Longrightarrow> at_begin_fst_awtn (as, am) (q, aaa, [Bk]) ires"
       
  1658 apply(auto simp: at_begin_fst_awtn.simps)
       
  1659 done 
       
  1660 
       
  1661 lemma [intro]: "inv_locate_a (as, am) (q, aaa, []) ires
       
  1662             \<Longrightarrow> inv_locate_a (as, am) (q, aaa, [Bk]) ires"
       
  1663 apply(simp only: inv_locate_a.simps)
       
  1664 apply(erule disj_forward)
       
  1665 defer
       
  1666 apply(erule disj_forward, auto)
       
  1667 done
       
  1668 
       
  1669 lemma [simp]: "inv_locate_a (as, am) (q, aaa, []) ires \<Longrightarrow> 
       
  1670                inv_locate_a (as, am) (q, aaa, [Oc]) ires"
       
  1671 apply(insert locate_a_2_locate_a [of as am q aaa "[]"])
       
  1672 apply(subgoal_tac "inv_locate_a (as, am) (q, aaa, [Bk]) ires", auto)
       
  1673 done
       
  1674 
       
  1675 (*inv: from locate_b to locate_b*)
       
  1676 lemma [simp]: "inv_locate_b (as, am) (q, aaa, Oc # xs) ires
       
  1677          \<Longrightarrow> inv_locate_b (as, am) (q, Oc # aaa, xs) ires"
       
  1678 apply(simp only: inv_locate_b.simps in_middle.simps)
       
  1679 apply(erule exE)+
       
  1680 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  1681       rule_tac x = tn in exI, rule_tac x = m in exI)
       
  1682 apply(rule_tac x = "Suc ml" in exI, rule_tac x = "mr - 1" in exI,
       
  1683       rule_tac x = rn in exI)
       
  1684 apply(case_tac mr, simp_all add: exponent_def, auto)
       
  1685 done
       
  1686 lemma zero_and_nil[intro]: "(Bk # Bk\<^bsup>n\<^esup> = Oc\<^bsup>mr\<^esup> @ Bk # <lm::nat list> @ 
       
  1687                              Bk\<^bsup>rn \<^esup>) \<or> (lm2 = [] \<and> Bk # Bk\<^bsup>n\<^esup> = Oc\<^bsup>mr\<^esup>)
       
  1688        \<Longrightarrow> mr = 0 \<and> lm = []"
       
  1689 apply(rule context_conjI)
       
  1690 apply(case_tac mr, auto simp:exponent_def)
       
  1691 apply(insert BkCons_nil[of "replicate (n - 1) Bk" lm rn])
       
  1692 apply(case_tac n, auto simp: exponent_def Bk_def  tape_of_nl_nil_eq)
       
  1693 done
       
  1694 
       
  1695 lemma tape_of_nat_def: "<[m::nat]> =  Oc # Oc\<^bsup>m\<^esup>"
       
  1696 apply(simp add: tape_of_nl_abv tape_of_nat_list.simps)
       
  1697 done
       
  1698 lemma [simp]: "\<lbrakk>inv_locate_b (as, am) (q, aaa, Bk # xs) ires; \<exists>n. xs = Bk\<^bsup>n\<^esup>\<rbrakk>
       
  1699             \<Longrightarrow> inv_locate_a (as, am) (Suc q, Bk # aaa, xs) ires"
       
  1700 apply(simp add: inv_locate_b.simps inv_locate_a.simps)
       
  1701 apply(rule_tac disjI2, rule_tac disjI1)
       
  1702 apply(simp only: in_middle.simps at_begin_fst_bwtn.simps)
       
  1703 apply(erule_tac exE)+
       
  1704 apply(rule_tac x = "lm1 @ [m]" in exI, rule_tac x = tn in exI, simp)
       
  1705 apply(subgoal_tac "mr = 0 \<and> lm2 = []")
       
  1706 defer
       
  1707 apply(rule_tac n = n and mr = mr and lm = "lm2" 
       
  1708                and rn = rn and n = n in zero_and_nil)
       
  1709 apply(auto simp: exponent_def)
       
  1710 apply(case_tac "lm1 = []", auto simp: tape_of_nat_def)
       
  1711 done
       
  1712 
       
  1713 lemma length_equal: "xs = ys \<Longrightarrow> length xs = length ys"
       
  1714 by auto
       
  1715 lemma [simp]: "a\<^bsup>0\<^esup> = []" 
       
  1716 by(simp add: exp_zero)
       
  1717 (*inv: from locate_b to locate_a*)
       
  1718 lemma [simp]: "length (a\<^bsup>b\<^esup>) = b"
       
  1719 apply(simp add: exponent_def)
       
  1720 done
       
  1721 
       
  1722 lemma [simp]: "\<lbrakk>inv_locate_b (as, am) (q, aaa, Bk # xs) ires; 
       
  1723                 \<not> (\<exists>n. xs = Bk\<^bsup>n\<^esup>)\<rbrakk> 
       
  1724        \<Longrightarrow> inv_locate_a (as, am) (Suc q, Bk # aaa, xs) ires"
       
  1725 apply(simp add: inv_locate_b.simps inv_locate_a.simps)
       
  1726 apply(rule_tac disjI1)
       
  1727 apply(simp only: in_middle.simps at_begin_norm.simps)
       
  1728 apply(erule_tac exE)+
       
  1729 apply(rule_tac x = "lm1 @ [m]" in exI, rule_tac x = lm2 in exI, simp)
       
  1730 apply(subgoal_tac "tn = 0", simp add: exponent_def , auto split: if_splits)
       
  1731 apply(case_tac [!] mr, simp_all add: tape_of_nat_def, auto)
       
  1732 apply(case_tac lm2, simp, erule_tac x = rn in allE, simp)
       
  1733 apply(case_tac am, simp, simp)
       
  1734 apply(case_tac lm2, simp, erule_tac x = rn in allE, simp)
       
  1735 apply(drule_tac length_equal, simp)
       
  1736 done
       
  1737 
       
  1738 lemma locate_b_2_a[intro]: 
       
  1739        "inv_locate_b (as, am) (q, aaa, Bk # xs) ires
       
  1740     \<Longrightarrow> inv_locate_a (as, am) (Suc q, Bk # aaa, xs) ires"
       
  1741 apply(case_tac "\<exists> n. xs = Bk\<^bsup>n\<^esup>", simp, simp)
       
  1742 done
       
  1743 
       
  1744 lemma locate_b_2_locate_a[simp]: 
       
  1745     "\<lbrakk>\<not> a < start_of ly as; 
       
  1746       a < start_of ly as + 2 * n; 
       
  1747       (a - start_of ly as) mod 2 = Suc 0; 
       
  1748      inv_locate_b (as, am) ((a - start_of ly as) div 2, aaa, Bk # xs) ires\<rbrakk>
       
  1749    \<Longrightarrow> (Suc a < start_of ly as + 2 * n \<longrightarrow> inv_locate_a (as, am)
       
  1750        (Suc ((a - start_of ly as) div 2), Bk # aaa, xs) ires) \<and>
       
  1751        (\<not> Suc a < start_of ly as + 2 * n \<longrightarrow> 
       
  1752                 inv_locate_a (as, am) (n, Bk # aaa, xs) ires)"
       
  1753 apply(auto)
       
  1754 apply(subgoal_tac "n > 0")
       
  1755 apply(subgoal_tac "(a - start_of ly as) div 2 = n - 1")
       
  1756 apply(insert locate_b_2_a [of as am "n - 1" aaa xs], simp)
       
  1757 apply(arith)
       
  1758 apply(case_tac n, simp, simp)
       
  1759 done
       
  1760 
       
  1761 lemma [simp]:  "inv_locate_b (as, am) (q, l, []) ires 
       
  1762            \<Longrightarrow>  inv_locate_b (as, am) (q, l, [Bk]) ires"
       
  1763 apply(simp only: inv_locate_b.simps in_middle.simps)
       
  1764 apply(erule exE)+
       
  1765 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  1766       rule_tac x = tn in exI, rule_tac x = m in exI, 
       
  1767       rule_tac x = ml in exI, rule_tac x = mr in exI)
       
  1768 apply(auto)
       
  1769 done
       
  1770 
       
  1771 lemma locate_b_2_locate_a_B[simp]: 
       
  1772  "\<lbrakk>\<not> a < start_of ly as; 
       
  1773    a < start_of ly as + 2 * n; 
       
  1774    (a - start_of ly as) mod 2 = Suc 0; 
       
  1775    inv_locate_b (as, am) ((a - start_of ly as) div 2, aaa, []) ires\<rbrakk>
       
  1776    \<Longrightarrow> (Suc a < start_of ly as + 2 * n \<longrightarrow> 
       
  1777      inv_locate_a (as, am) 
       
  1778             (Suc ((a - start_of ly as) div 2), Bk # aaa, []) ires) 
       
  1779     \<and> (\<not> Suc a < start_of ly as + 2 * n \<longrightarrow> 
       
  1780                   inv_locate_a (as, am) (n, Bk # aaa, []) ires)"
       
  1781 apply(insert locate_b_2_locate_a [of a ly as n am aaa "[]"], simp)
       
  1782 done
       
  1783 
       
  1784 (*inv: from locate_b to after_write*)
       
  1785 lemma inv_locate_b_2_after_write[simp]: 
       
  1786       "inv_locate_b (as, am) (n, aaa, Bk # xs) ires
       
  1787       \<Longrightarrow> inv_after_write (as, abc_lm_s am n (Suc (abc_lm_v am n)))
       
  1788           (Suc (Suc (2 * n)), aaa, Oc # xs) ires"
       
  1789 apply(auto simp: in_middle.simps inv_after_write.simps 
       
  1790                  abc_lm_v.simps abc_lm_s.simps  inv_locate_b.simps)
       
  1791 apply(subgoal_tac [!] "mr = 0", auto simp: exponent_def split: if_splits)
       
  1792 apply(subgoal_tac "lm2 = []", simp)
       
  1793 apply(rule_tac x = rn in exI, rule_tac x = "Suc m" in exI,
       
  1794       rule_tac x = "lm1" in exI, simp, rule_tac x = "[]" in exI, simp)
       
  1795 apply(case_tac "Suc (length lm1) - length am", simp, simp only: rep_ind, simp)
       
  1796 apply(subgoal_tac "length lm1 - length am = nat", simp, arith)
       
  1797 apply(drule_tac length_equal, simp)
       
  1798 done
       
  1799 
       
  1800 lemma [simp]: "inv_locate_b (as, am) (n, aaa, []) ires \<Longrightarrow> 
       
  1801      inv_after_write (as, abc_lm_s am n (Suc (abc_lm_v am n))) 
       
  1802                      (Suc (Suc (2 * n)), aaa, [Oc]) ires"
       
  1803 apply(insert inv_locate_b_2_after_write [of as am n aaa "[]"])
       
  1804 by(simp)
       
  1805 
       
  1806 (*inv: from after_write to after_move*)
       
  1807 lemma [simp]: "inv_after_write (as, lm) (Suc (Suc (2 * n)), l, Oc # r) ires
       
  1808                 \<Longrightarrow> inv_after_move (as, lm) (2 * n + 3, Oc # l, r) ires"
       
  1809 apply(auto simp:inv_after_move.simps inv_after_write.simps split: if_splits)
       
  1810 done
       
  1811 
       
  1812 lemma [simp]: "inv_after_write (as, abc_lm_s am n (Suc (abc_lm_v am n)
       
  1813                 )) (Suc (Suc (2 * n)), aaa, Bk # xs) ires = False"
       
  1814 apply(simp add: inv_after_write.simps )
       
  1815 done
       
  1816 
       
  1817 lemma [simp]: 
       
  1818  "inv_after_write (as, abc_lm_s am n (Suc (abc_lm_v am n))) 
       
  1819                         (Suc (Suc (2 * n)), aaa, []) ires = False"
       
  1820 apply(simp add: inv_after_write.simps )
       
  1821 done
       
  1822 
       
  1823 (*inv: from after_move to after_clear*)
       
  1824 lemma [simp]: "inv_after_move (as, lm) (s, l, Oc # r) ires
       
  1825                 \<Longrightarrow> inv_after_clear (as, lm) (s', l, Bk # r) ires"
       
  1826 apply(auto simp: inv_after_move.simps inv_after_clear.simps split: if_splits)
       
  1827 done
       
  1828 
       
  1829 (*inv: from after_move to on_leftmoving*)
       
  1830 lemma inv_after_move_2_inv_on_left_moving[simp]:  
       
  1831    "inv_after_move (as, lm) (s, l, Bk # r) ires
       
  1832    \<Longrightarrow> (l = [] \<longrightarrow> 
       
  1833          inv_on_left_moving (as, lm) (s', [], Bk # Bk # r) ires) \<and>
       
  1834       (l \<noteq> [] \<longrightarrow> 
       
  1835          inv_on_left_moving (as, lm) (s', tl l, hd l # Bk # r) ires)"
       
  1836 apply(simp only: inv_after_move.simps inv_on_left_moving.simps)
       
  1837 apply(subgoal_tac "l \<noteq> []", rule conjI, simp, rule impI, 
       
  1838                 rule disjI1, simp only: inv_on_left_moving_norm.simps)
       
  1839 apply(erule exE)+
       
  1840 apply(subgoal_tac "lm2 = []")
       
  1841 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI,  
       
  1842     rule_tac x = m in exI, rule_tac x = m in exI, 
       
  1843     rule_tac x = 1 in exI,  
       
  1844     rule_tac x = "rn - 1" in exI, simp, case_tac rn)
       
  1845 apply(auto simp: exponent_def  intro: BkCons_nil split: if_splits)
       
  1846 done
       
  1847 
       
  1848 lemma [elim]: "[] = <lm::nat list> \<Longrightarrow> lm = []"
       
  1849 using tape_of_nl_nil_eq[of lm]
       
  1850 by simp
       
  1851 
       
  1852 lemma inv_after_move_2_inv_on_left_moving_B[simp]: 
       
  1853     "inv_after_move (as, lm) (s, l, []) ires
       
  1854       \<Longrightarrow> (l = [] \<longrightarrow> inv_on_left_moving (as, lm) (s', [], [Bk]) ires) \<and>
       
  1855           (l \<noteq> [] \<longrightarrow> inv_on_left_moving (as, lm) (s', tl l, [hd l]) ires)"
       
  1856 apply(simp only: inv_after_move.simps inv_on_left_moving.simps)
       
  1857 apply(subgoal_tac "l \<noteq> []", rule conjI, simp, rule impI, rule disjI1,
       
  1858         simp only: inv_on_left_moving_norm.simps)
       
  1859 apply(erule exE)+
       
  1860 apply(subgoal_tac "lm2 = []")
       
  1861 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI,  
       
  1862       rule_tac x = m in exI, rule_tac x = m in exI, 
       
  1863       rule_tac x = 1 in exI, rule_tac x = "rn - 1" in exI, simp, case_tac rn)
       
  1864 apply(auto simp: exponent_def  tape_of_nl_nil_eq  intro: BkCons_nil  split: if_splits)
       
  1865 done
       
  1866 
       
  1867 (*inv: from after_clear to on_right_moving*)
       
  1868 lemma [simp]: "Oc # r = replicate rn Bk = False"
       
  1869 apply(case_tac rn, simp, simp)
       
  1870 done
       
  1871 
       
  1872 lemma inv_after_clear_2_inv_on_right_moving[simp]: 
       
  1873      "inv_after_clear (as, lm) (2 * n + 4, l, Bk # r) ires
       
  1874       \<Longrightarrow> inv_on_right_moving (as, lm) (2 * n + 5, Bk # l, r) ires"
       
  1875 apply(auto simp: inv_after_clear.simps inv_on_right_moving.simps )
       
  1876 apply(subgoal_tac "lm2 \<noteq> []")
       
  1877 apply(rule_tac x = "lm1 @ [m]" in exI, rule_tac x = "tl lm2" in exI, 
       
  1878       rule_tac x = "hd lm2" in exI, simp)
       
  1879 apply(rule_tac x = 0 in exI, rule_tac x = "hd lm2" in exI)
       
  1880 apply(simp add: exponent_def, rule conjI)
       
  1881 apply(case_tac [!] "lm2::nat list", auto simp: exponent_def)
       
  1882 apply(case_tac rn, auto split: if_splits simp: tape_of_nat_def)
       
  1883 apply(case_tac list, 
       
  1884      simp add:  tape_of_nl_abv tape_of_nat_list.simps exponent_def)
       
  1885 apply(erule_tac x = "rn - 1" in allE, 
       
  1886       case_tac rn, auto simp: exponent_def)
       
  1887 apply(case_tac list, 
       
  1888      simp add:  tape_of_nl_abv tape_of_nat_list.simps exponent_def)
       
  1889 apply(erule_tac x = "rn - 1" in allE, 
       
  1890       case_tac rn, auto simp: exponent_def)
       
  1891 done
       
  1892 
       
  1893 
       
  1894 lemma [simp]: "inv_after_clear (as, lm) (2 * n + 4, l, []) ires\<Longrightarrow> 
       
  1895                inv_after_clear (as, lm) (2 * n + 4, l, [Bk]) ires" 
       
  1896 by(auto simp: inv_after_clear.simps)
       
  1897 
       
  1898 lemma [simp]: "inv_after_clear (as, lm) (2 * n + 4, l, []) ires
       
  1899              \<Longrightarrow> inv_on_right_moving (as, lm) (2 * n + 5, Bk # l, []) ires"
       
  1900 by(insert 
       
  1901     inv_after_clear_2_inv_on_right_moving[of as lm n l "[]"], simp)
       
  1902 
       
  1903 (*inv: from on_right_moving to on_right_movign*)
       
  1904 lemma [simp]: "inv_on_right_moving (as, lm) (2 * n + 5, l, Oc # r) ires
       
  1905       \<Longrightarrow> inv_on_right_moving (as, lm) (2 * n + 5, Oc # l, r) ires"
       
  1906 apply(auto simp: inv_on_right_moving.simps)
       
  1907 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  1908            rule_tac x = "ml + mr" in exI, simp)
       
  1909 apply(rule_tac x = "Suc ml" in exI, 
       
  1910            rule_tac x = "mr - 1" in exI, simp)
       
  1911 apply(case_tac mr, auto simp: exponent_def )
       
  1912 apply(rule_tac x = lm1 in exI, rule_tac x = "[]" in exI, 
       
  1913       rule_tac x = "ml + mr" in exI, simp)
       
  1914 apply(rule_tac x = "Suc ml" in exI, 
       
  1915       rule_tac x = "mr - 1" in exI, simp)
       
  1916 apply(case_tac mr, auto split: if_splits simp: exponent_def)
       
  1917 done
       
  1918 
       
  1919 lemma inv_on_right_moving_2_inv_on_right_moving[simp]: 
       
  1920      "inv_on_right_moving (as, lm) (2 * n + 5, l, Bk # r) ires
       
  1921      \<Longrightarrow> inv_after_write (as, lm) (Suc (Suc (2 * n)), l, Oc # r) ires"
       
  1922 apply(auto simp: inv_on_right_moving.simps inv_after_write.simps )
       
  1923 apply(case_tac mr, auto simp: exponent_def split: if_splits)
       
  1924 apply(case_tac [!] mr, simp_all)
       
  1925 done
       
  1926       
       
  1927 lemma [simp]: "inv_on_right_moving (as, lm) (2 * n + 5, l, []) ires\<Longrightarrow> 
       
  1928              inv_on_right_moving (as, lm) (2 * n + 5, l, [Bk]) ires"
       
  1929 apply(auto simp: inv_on_right_moving.simps exponent_def)
       
  1930 apply(rule_tac x = lm1 in exI, rule_tac x = "[]" in exI, simp)
       
  1931 apply (rule_tac x = m in exI, auto split: if_splits simp: exponent_def)
       
  1932 done
       
  1933 
       
  1934 (*inv: from on_right_moving to after_write*)
       
  1935 lemma [simp]: "inv_on_right_moving (as, lm) (2 * n + 5, l, []) ires
       
  1936        \<Longrightarrow> inv_after_write (as, lm) (Suc (Suc (2 * n)), l, [Oc]) ires"
       
  1937 apply(rule_tac inv_on_right_moving_2_inv_on_right_moving, simp)
       
  1938 done
       
  1939 
       
  1940 (*inv: from on_left_moving to on_left_moving*)
       
  1941 lemma [simp]: "inv_on_left_moving_in_middle_B (as, lm) 
       
  1942                (s, l, Oc # r) ires = False"
       
  1943 apply(auto simp: inv_on_left_moving_in_middle_B.simps )
       
  1944 done
       
  1945 
       
  1946 lemma [simp]: "inv_on_left_moving_norm (as, lm) (s, l, Bk # r) ires 
       
  1947              = False"
       
  1948 apply(auto simp: inv_on_left_moving_norm.simps)
       
  1949 apply(case_tac [!] mr, auto simp: )
       
  1950 done
       
  1951 
       
  1952 lemma [intro]: "\<exists>rna. Oc # Oc\<^bsup>m\<^esup> @ Bk # <lm> @ Bk\<^bsup>rn\<^esup> = <m # lm> @ Bk\<^bsup>rna\<^esup>"
       
  1953 apply(case_tac lm, simp add: tape_of_nl_abv tape_of_nat_list.simps)
       
  1954 apply(rule_tac x = "Suc rn" in exI, simp)
       
  1955 apply(case_tac list, simp_all add: tape_of_nl_abv tape_of_nat_list.simps, auto)
       
  1956 done
       
  1957 
       
  1958 
       
  1959 lemma [simp]: 
       
  1960   "\<lbrakk>inv_on_left_moving_norm (as, lm) (s, l, Oc # r) ires;
       
  1961     hd l = Bk; l \<noteq> []\<rbrakk> \<Longrightarrow> 
       
  1962      inv_on_left_moving_in_middle_B (as, lm) (s, tl l, Bk # Oc # r) ires"
       
  1963 apply(case_tac l, simp, simp)
       
  1964 apply(simp only: inv_on_left_moving_norm.simps 
       
  1965                  inv_on_left_moving_in_middle_B.simps)
       
  1966 apply(erule_tac exE)+
       
  1967 apply(rule_tac x = lm1 in exI, rule_tac x = "m # lm2" in exI, auto)
       
  1968 apply(case_tac [!] ml, auto)
       
  1969 apply(rule_tac [!] x = 0 in exI, simp_all add: tape_of_nl_abv tape_of_nat_list.simps)
       
  1970 done
       
  1971 
       
  1972 lemma [simp]: "\<lbrakk>inv_on_left_moving_norm (as, lm) (s, l, Oc # r) ires; 
       
  1973                 hd l = Oc; l \<noteq> []\<rbrakk>
       
  1974             \<Longrightarrow> inv_on_left_moving_norm (as, lm) 
       
  1975                                         (s, tl l, Oc # Oc # r) ires"
       
  1976 apply(simp only: inv_on_left_moving_norm.simps)
       
  1977 apply(erule exE)+
       
  1978 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  1979       rule_tac x = m in exI, rule_tac x = "ml - 1" in exI,
       
  1980       rule_tac x = "Suc mr" in exI, rule_tac x = rn in exI, simp)
       
  1981 apply(case_tac ml, auto simp: exponent_def split: if_splits)
       
  1982 done
       
  1983 
       
  1984 lemma [simp]: "inv_on_left_moving_norm (as, lm) (s, [], Oc # r) ires
       
  1985      \<Longrightarrow> inv_on_left_moving_in_middle_B (as, lm) (s, [], Bk # Oc # r) ires"
       
  1986 apply(auto simp: inv_on_left_moving_norm.simps 
       
  1987                  inv_on_left_moving_in_middle_B.simps split: if_splits)
       
  1988 done
       
  1989 
       
  1990 lemma [simp]:"inv_on_left_moving (as, lm) (s, l, Oc # r) ires
       
  1991     \<Longrightarrow> (l = [] \<longrightarrow> inv_on_left_moving (as, lm) (s, [], Bk # Oc # r) ires)
       
  1992  \<and>  (l \<noteq> [] \<longrightarrow> inv_on_left_moving (as, lm) (s, tl l, hd l # Oc # r) ires)"
       
  1993 apply(simp add: inv_on_left_moving.simps)
       
  1994 apply(case_tac "l \<noteq> []", rule conjI, simp, simp)
       
  1995 apply(case_tac "hd l", simp, simp, simp)
       
  1996 done
       
  1997 
       
  1998 (*inv: from on_left_moving to check_left_moving*)
       
  1999 lemma [simp]: "inv_on_left_moving_in_middle_B (as, lm) 
       
  2000                                       (s, Bk # list, Bk # r) ires
       
  2001           \<Longrightarrow> inv_check_left_moving_on_leftmost (as, lm) 
       
  2002                                       (s', list, Bk # Bk # r) ires"
       
  2003 apply(auto simp: inv_on_left_moving_in_middle_B.simps 
       
  2004                  inv_check_left_moving_on_leftmost.simps split: if_splits)
       
  2005 apply(case_tac [!] "rev lm1", simp_all)
       
  2006 apply(case_tac [!] lista, simp_all add: tape_of_nl_abv tape_of_nat_list.simps)
       
  2007 done
       
  2008 
       
  2009 lemma [simp]:
       
  2010     "inv_check_left_moving_in_middle (as, lm) (s, l, Bk # r) ires= False"
       
  2011 by(auto simp: inv_check_left_moving_in_middle.simps )
       
  2012 
       
  2013 lemma [simp]: 
       
  2014  "inv_on_left_moving_in_middle_B (as, lm) (s, [], Bk # r) ires\<Longrightarrow> 
       
  2015   inv_check_left_moving_on_leftmost (as, lm) (s', [], Bk # Bk # r) ires"
       
  2016 apply(auto simp: inv_on_left_moving_in_middle_B.simps 
       
  2017                  inv_check_left_moving_on_leftmost.simps split: if_splits)
       
  2018 done
       
  2019 
       
  2020 
       
  2021 lemma [simp]: "inv_check_left_moving_on_leftmost (as, lm) 
       
  2022                                        (s, list, Oc # r) ires= False"
       
  2023 by(auto simp: inv_check_left_moving_on_leftmost.simps split: if_splits)
       
  2024 
       
  2025 lemma [simp]: "inv_on_left_moving_in_middle_B (as, lm) 
       
  2026                                          (s, Oc # list, Bk # r) ires
       
  2027  \<Longrightarrow> inv_check_left_moving_in_middle (as, lm) (s', list, Oc # Bk # r) ires"
       
  2028 apply(auto simp: inv_on_left_moving_in_middle_B.simps 
       
  2029                  inv_check_left_moving_in_middle.simps  split: if_splits)
       
  2030 done
       
  2031 
       
  2032 lemma inv_on_left_moving_2_check_left_moving[simp]:
       
  2033  "inv_on_left_moving (as, lm) (s, l, Bk # r) ires
       
  2034  \<Longrightarrow> (l = [] \<longrightarrow> inv_check_left_moving (as, lm) (s', [], Bk # Bk # r) ires)
       
  2035  \<and> (l \<noteq> [] \<longrightarrow> 
       
  2036       inv_check_left_moving (as, lm) (s', tl l, hd l # Bk # r) ires)"
       
  2037 apply(simp add: inv_on_left_moving.simps inv_check_left_moving.simps)
       
  2038 apply(case_tac l, simp, simp)
       
  2039 apply(case_tac a, simp, simp)
       
  2040 done
       
  2041 
       
  2042 lemma [simp]: "inv_on_left_moving_norm (as, lm) (s, l, []) ires = False"
       
  2043 apply(auto simp: inv_on_left_moving_norm.simps)
       
  2044 by(case_tac [!] mr, auto)
       
  2045 
       
  2046 lemma [simp]: "inv_on_left_moving (as, lm) (s, l, []) ires\<Longrightarrow> 
       
  2047      inv_on_left_moving (as, lm) (6 + 2 * n, l, [Bk]) ires"
       
  2048 apply(simp add: inv_on_left_moving.simps)
       
  2049 apply(auto simp: inv_on_left_moving_in_middle_B.simps)
       
  2050 done
       
  2051 
       
  2052 lemma [simp]: "inv_on_left_moving (as, lm) (s, l, []) ires = False"
       
  2053 apply(simp add: inv_on_left_moving.simps)
       
  2054 apply(simp add: inv_on_left_moving_in_middle_B.simps)
       
  2055 done
       
  2056 
       
  2057 lemma [simp]: "inv_on_left_moving (as, lm) (s, l, []) ires
       
  2058  \<Longrightarrow> (l = [] \<longrightarrow> inv_check_left_moving (as, lm) (s', [], [Bk]) ires) \<and>
       
  2059     (l \<noteq> [] \<longrightarrow> inv_check_left_moving (as, lm) (s', tl l, [hd l]) ires)"
       
  2060 by simp
       
  2061 
       
  2062 lemma Oc_Bk_Cons_ex[simp]: 
       
  2063  "Oc # Bk # list = <lm::nat list> @ Bk\<^bsup>ln\<^esup> \<Longrightarrow> 
       
  2064                              \<exists>ln. list = <tl (lm)> @ Bk\<^bsup>ln\<^esup>"
       
  2065 apply(case_tac "lm", simp)
       
  2066 apply(case_tac ln, simp_all add: exponent_def)
       
  2067 apply(case_tac lista, 
       
  2068       auto simp: tape_of_nl_abv tape_of_nat_list.simps exponent_def)
       
  2069 apply(case_tac [!] a, auto simp: )
       
  2070 apply(case_tac ln, simp, rule_tac x = nat in exI, simp)
       
  2071 done
       
  2072 
       
  2073 lemma [simp]:
       
  2074   "Oc # Bk # list = <rev lm1::nat list> @ Bk\<^bsup>ln\<^esup> \<Longrightarrow> 
       
  2075       \<exists>rna. Oc # Bk # <lm2> @ Bk\<^bsup>rn\<^esup> = <hd (rev lm1) # lm2> @ Bk\<^bsup>rna\<^esup>"
       
  2076 apply(frule Oc_Bk_Cons, simp)
       
  2077 apply(case_tac lm2, 
       
  2078      auto simp: tape_of_nl_abv tape_of_nat_list.simps  exponent_def )
       
  2079 apply(rule_tac x = "Suc rn" in exI, simp)
       
  2080 done
       
  2081 
       
  2082 (*inv: from check_left_moving to on_left_moving*)
       
  2083 lemma [intro]: "\<exists>rna. a # a\<^bsup>rn\<^esup> = a\<^bsup>rna\<^esup>"
       
  2084 apply(rule_tac x = "Suc rn" in exI, simp)
       
  2085 done
       
  2086 
       
  2087 lemma 
       
  2088 inv_check_left_moving_in_middle_2_on_left_moving_in_middle_B[simp]:
       
  2089 "inv_check_left_moving_in_middle (as, lm) (s, Bk # list, Oc # r) ires
       
  2090   \<Longrightarrow> inv_on_left_moving_in_middle_B (as, lm) (s', list, Bk # Oc # r) ires"
       
  2091 apply(simp only: inv_check_left_moving_in_middle.simps 
       
  2092                  inv_on_left_moving_in_middle_B.simps)
       
  2093 apply(erule_tac exE)+
       
  2094 apply(rule_tac x = "rev (tl (rev lm1))" in exI, 
       
  2095       rule_tac x = "[hd (rev lm1)] @ lm2" in exI, auto)
       
  2096 apply(case_tac [!] "rev lm1",simp_all add: tape_of_nl_abv tape_of_nat_list.simps)
       
  2097 apply(case_tac [!] a, simp_all)
       
  2098 apply(case_tac [1] lm2, simp_all add: tape_of_nat_list.simps, auto)
       
  2099 apply(case_tac [3] lm2, simp_all add: tape_of_nat_list.simps, auto)
       
  2100 apply(case_tac [!] lista, simp_all add: tape_of_nat_list.simps)
       
  2101 done
       
  2102 
       
  2103 lemma [simp]: 
       
  2104  "inv_check_left_moving_in_middle (as, lm) (s, [], Oc # r) ires\<Longrightarrow>
       
  2105      inv_check_left_moving_in_middle (as, lm) (s', [Bk], Oc # r) ires"
       
  2106 apply(auto simp: inv_check_left_moving_in_middle.simps )
       
  2107 done
       
  2108 
       
  2109 lemma [simp]: 
       
  2110  "inv_check_left_moving_in_middle (as, lm) (s, [], Oc # r) ires
       
  2111    \<Longrightarrow> inv_on_left_moving_in_middle_B (as, lm) (s', [], Bk # Oc # r) ires"
       
  2112 apply(insert 
       
  2113 inv_check_left_moving_in_middle_2_on_left_moving_in_middle_B[of 
       
  2114                   as lm n "[]" r], simp)
       
  2115 done 
       
  2116 
       
  2117 lemma [simp]: "a\<^bsup>0\<^esup> = []"
       
  2118 apply(simp add: exponent_def)
       
  2119 done
       
  2120 
       
  2121 lemma [simp]: "inv_check_left_moving_in_middle (as, lm) 
       
  2122                        (s, Oc # list, Oc # r) ires
       
  2123    \<Longrightarrow> inv_on_left_moving_norm (as, lm) (s', list, Oc # Oc # r) ires"
       
  2124 apply(auto simp: inv_check_left_moving_in_middle.simps 
       
  2125                  inv_on_left_moving_norm.simps)
       
  2126 apply(rule_tac x = "rev (tl (rev lm1))" in exI, 
       
  2127       rule_tac x = lm2 in exI, rule_tac x = "hd (rev lm1)" in exI)
       
  2128 apply(rule_tac conjI)
       
  2129 apply(case_tac "rev lm1", simp, simp)
       
  2130 apply(rule_tac x = "hd (rev lm1) - 1" in exI, auto)
       
  2131 apply(rule_tac [!] x = "Suc (Suc 0)" in exI, simp)
       
  2132 apply(case_tac [!] "rev lm1", simp_all)
       
  2133 apply(case_tac [!] a, simp_all add: tape_of_nl_abv tape_of_nat_list.simps, auto)
       
  2134 done 
       
  2135 
       
  2136 lemma [simp]: "inv_check_left_moving (as, lm) (s, l, Oc # r) ires
       
  2137 \<Longrightarrow> (l = [] \<longrightarrow> inv_on_left_moving (as, lm) (s', [], Bk # Oc # r) ires) \<and>
       
  2138    (l \<noteq> [] \<longrightarrow> inv_on_left_moving (as, lm) (s', tl l, hd l # Oc # r) ires)"
       
  2139 apply(case_tac l, 
       
  2140       auto simp: inv_check_left_moving.simps inv_on_left_moving.simps)
       
  2141 apply(case_tac a, simp, simp)
       
  2142 done
       
  2143 
       
  2144 (*inv: check_left_moving to after_left_moving*)
       
  2145 lemma [simp]: "inv_check_left_moving (as, lm) (s, l, Bk # r) ires
       
  2146                 \<Longrightarrow> inv_after_left_moving (as, lm) (s', Bk # l, r) ires"
       
  2147 apply(auto simp: inv_check_left_moving.simps 
       
  2148  inv_check_left_moving_on_leftmost.simps inv_after_left_moving.simps)
       
  2149 done
       
  2150 
       
  2151 
       
  2152 lemma [simp]:"inv_check_left_moving (as, lm) (s, l, []) ires
       
  2153       \<Longrightarrow> inv_after_left_moving (as, lm) (s', Bk # l, []) ires"
       
  2154 by(simp add: inv_check_left_moving.simps  
       
  2155 inv_check_left_moving_in_middle.simps 
       
  2156 inv_check_left_moving_on_leftmost.simps)
       
  2157 
       
  2158 (*inv: after_left_moving to inv_stop*)
       
  2159 lemma [simp]: "inv_after_left_moving (as, lm) (s, l, Bk # r) ires
       
  2160        \<Longrightarrow> inv_stop (as, lm) (s', Bk # l, r) ires"
       
  2161 apply(auto simp: inv_after_left_moving.simps inv_stop.simps)
       
  2162 done
       
  2163 
       
  2164 lemma [simp]: "inv_after_left_moving (as, lm) (s, l, []) ires
       
  2165              \<Longrightarrow> inv_stop (as, lm) (s', Bk # l, []) ires"
       
  2166 by(auto simp: inv_after_left_moving.simps)
       
  2167 
       
  2168 (*inv: stop to stop*)
       
  2169 lemma [simp]: "inv_stop (as, lm) (x, l, r) ires \<Longrightarrow> 
       
  2170                inv_stop (as, lm) (y, l, r) ires"
       
  2171 apply(simp add: inv_stop.simps)
       
  2172 done
       
  2173 
       
  2174 lemma [simp]: "inv_after_clear (as, lm) (s, aaa, Oc # xs) ires= False"
       
  2175 apply(auto simp: inv_after_clear.simps )
       
  2176 done
       
  2177 
       
  2178 lemma [simp]: 
       
  2179   "inv_after_left_moving (as, lm) (s, aaa, Oc # xs) ires = False"
       
  2180 by(auto simp: inv_after_left_moving.simps  )
       
  2181 
       
  2182 lemma start_of_not0: "as \<noteq> 0 \<Longrightarrow> start_of ly as > 0"
       
  2183 apply(rule startof_not0)
       
  2184 done
       
  2185 
       
  2186 text {*
       
  2187   The single step currectness of the TM complied from Abacus instruction @{text "Inc n"}.
       
  2188   It shows every single step execution of this TM keeps the invariant.
       
  2189 *}
       
  2190 
       
  2191 lemma inc_inv_step: 
       
  2192   assumes 
       
  2193   -- {* Invariant holds on the start *}
       
  2194       h11: "inc_inv ly n (as, am) tc ires" 
       
  2195   -- {* The layout of Abacus program @{text "aprog"} is @{text "ly"} *}
       
  2196   and h12: "ly = layout_of aprog" 
       
  2197   -- {* The instruction at position @{text "as"} is @{text "Inc n"} *}
       
  2198   and h21: "abc_fetch as aprog = Some (Inc n)" 
       
  2199   -- {* TM not yet reach the final state, where @{text "start_of ly as + 2*n + 9"} is the state
       
  2200         where the current TM stops and the next TM starts. *}
       
  2201   and h22: "(\<lambda> (s, l, r). s \<noteq> start_of ly as + 2*n + 9) tc"
       
  2202   shows 
       
  2203   -- {* 
       
  2204   Single step execution of the TM keeps the invaraint, where 
       
  2205   the TM compiled from @{text "Inc n"} is @{text "(ci ly (start_of ly as) (Inc n))"}
       
  2206   @{text "start_of ly as - Suc 0)"} is the offset used to execute this {\em shifted}
       
  2207   TM.
       
  2208   *}
       
  2209   "inc_inv ly n (as, am) (t_step tc (ci ly (start_of ly as) (Inc n), start_of ly as - Suc 0)) ires"
       
  2210 proof -
       
  2211   from h21 h22  have h3 : "start_of (layout_of aprog) as > 0"
       
  2212     apply(case_tac as, simp add: start_of.simps abc_fetch.simps)
       
  2213     apply(insert start_of_not0[of as "layout_of aprog"], simp)
       
  2214     done    
       
  2215   from h11 h12 and h21 h22 and this show ?thesis 
       
  2216     apply(case_tac tc, simp)
       
  2217     apply(case_tac "a = 0", 
       
  2218       auto split:if_splits simp add:t_step.simps,
       
  2219       tactic {* ALLGOALS (resolve_tac [@{thm fetch_intro}]) *})
       
  2220     apply (simp_all add:fetch_simps new_tape.simps)
       
  2221     done
       
  2222 qed
       
  2223 
       
  2224 
       
  2225 lemma t_steps_ind: "t_steps tc (p, off) (Suc n)
       
  2226                  = t_step (t_steps tc (p, off) n) (p, off)"
       
  2227 apply(induct n arbitrary: tc)
       
  2228 apply(simp add: t_steps.simps)
       
  2229 apply(simp add: t_steps.simps)
       
  2230 done
       
  2231 
       
  2232 definition lex_pair :: "((nat \<times> nat) \<times> (nat \<times> nat)) set"
       
  2233   where 
       
  2234   "lex_pair \<equiv> less_than <*lex*> less_than"
       
  2235 
       
  2236 definition lex_triple :: 
       
  2237    "((nat \<times> (nat \<times> nat)) \<times> (nat \<times> (nat \<times> nat))) set"
       
  2238   where "lex_triple \<equiv> less_than <*lex*> lex_pair"
       
  2239 
       
  2240 definition lex_square :: 
       
  2241     "((nat \<times> nat \<times> nat \<times> nat) \<times> (nat \<times> nat \<times> nat \<times> nat)) set"
       
  2242   where "lex_square \<equiv> less_than <*lex*> lex_triple"
       
  2243 
       
  2244 fun abc_inc_stage1 :: "t_conf \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
  2245   where
       
  2246   "abc_inc_stage1 (s, l, r) ss n = 
       
  2247             (if s = 0 then 0
       
  2248              else if s \<le> ss+2*n+1 then 5
       
  2249              else if s\<le> ss+2*n+5 then 4
       
  2250              else if s \<le> ss+2*n+7 then 3
       
  2251              else if s = ss+2*n+8 then 2
       
  2252              else 1)"
       
  2253 
       
  2254 fun abc_inc_stage2 :: "t_conf \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
  2255   where
       
  2256   "abc_inc_stage2 (s, l, r) ss n =
       
  2257                 (if s \<le> ss + 2*n + 1 then 0
       
  2258                  else if s = ss + 2*n + 2 then length r
       
  2259                  else if s = ss + 2*n + 3 then length r
       
  2260                  else if s = ss + 2*n + 4 then length r
       
  2261                  else if s = ss + 2*n + 5 then 
       
  2262                                   if r \<noteq> [] then length r
       
  2263                                   else 1
       
  2264                  else if s = ss+2*n+6 then length l
       
  2265                  else if s = ss+2*n+7 then length l
       
  2266                  else 0)"
       
  2267 
       
  2268 fun abc_inc_stage3 :: "t_conf \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> block list \<Rightarrow>  nat"
       
  2269   where
       
  2270   "abc_inc_stage3 (s, l, r) ss n ires = (
       
  2271               if s = ss + 2*n + 3 then 4
       
  2272               else if s = ss + 2*n + 4 then 3
       
  2273               else if s = ss + 2*n + 5 then 
       
  2274                    if r \<noteq> [] \<and> hd r = Oc then 2
       
  2275                    else 1
       
  2276               else if s = ss + 2*n + 2 then 0
       
  2277               else if s = ss + 2*n + 6 then 
       
  2278                       if l = Bk # ires \<and> r \<noteq> [] \<and>  hd r = Oc then 2
       
  2279                       else 1
       
  2280               else if s = ss + 2*n + 7 then 
       
  2281                       if r \<noteq> [] \<and> hd r = Oc then 3
       
  2282                       else 0
       
  2283               else ss+2*n+9 - s)"
       
  2284 
       
  2285 fun abc_inc_stage4 :: "t_conf \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> block list \<Rightarrow> nat"
       
  2286   where
       
  2287   "abc_inc_stage4 (s, l, r) ss n ires = 
       
  2288             (if s \<le> ss+2*n+1 \<and> (s - ss) mod 2 = 0 then 
       
  2289                 if (r\<noteq>[] \<and> hd r = Oc) then 0
       
  2290                 else 1
       
  2291              else if (s \<le> ss+2*n+1 \<and> (s - ss) mod 2 = Suc 0) 
       
  2292                                                  then length r
       
  2293              else if s = ss + 2*n + 6 then 
       
  2294                   if l = Bk # ires \<and> hd r = Bk then 0
       
  2295                   else Suc (length l)
       
  2296              else 0)"
       
  2297  
       
  2298 fun abc_inc_measure :: "(t_conf \<times> nat \<times> nat \<times> block list) \<Rightarrow> 
       
  2299                         (nat \<times> nat \<times> nat \<times> nat)"
       
  2300   where
       
  2301   "abc_inc_measure (c, ss, n, ires) = 
       
  2302      (abc_inc_stage1 c ss n, abc_inc_stage2 c ss n, 
       
  2303       abc_inc_stage3 c ss n ires, abc_inc_stage4 c ss n ires)"
       
  2304 
       
  2305 definition abc_inc_LE :: "(((nat \<times> block list \<times> block list) \<times> nat \<times> 
       
  2306        nat \<times> block list) \<times> ((nat \<times> block list \<times> block list) \<times> nat \<times> nat \<times> block list)) set"
       
  2307   where "abc_inc_LE \<equiv> (inv_image lex_square abc_inc_measure)"
       
  2308 
       
  2309 lemma wf_lex_triple: "wf lex_triple"
       
  2310 by (auto intro:wf_lex_prod simp:lex_triple_def lex_pair_def)
       
  2311 
       
  2312 lemma wf_lex_square: "wf lex_square"
       
  2313 by (auto intro:wf_lex_triple simp:lex_triple_def lex_square_def lex_pair_def)
       
  2314 
       
  2315 lemma wf_abc_inc_le[intro]: "wf abc_inc_LE"
       
  2316 by(auto intro:wf_inv_image wf_lex_square simp:abc_inc_LE_def)
       
  2317 
       
  2318 (********************************************************************)
       
  2319 declare inc_inv.simps[simp del]
       
  2320 
       
  2321 lemma halt_lemma2': 
       
  2322   "\<lbrakk>wf LE;  \<forall> n. ((\<not> P (f n) \<and> Q (f n)) \<longrightarrow> 
       
  2323     (Q (f (Suc n)) \<and> (f (Suc n), (f n)) \<in> LE)); Q (f 0)\<rbrakk> 
       
  2324       \<Longrightarrow> \<exists> n. P (f n)"
       
  2325 apply(intro exCI, simp)
       
  2326 apply(subgoal_tac "\<forall> n. Q (f n)", simp)
       
  2327 apply(drule_tac f = f in wf_inv_image)
       
  2328 apply(simp add: inv_image_def)
       
  2329 apply(erule wf_induct, simp)
       
  2330 apply(erule_tac x = x in allE)
       
  2331 apply(erule_tac x = n in allE, erule_tac x = n in allE)
       
  2332 apply(erule_tac x = "Suc x" in allE, simp)
       
  2333 apply(rule_tac allI)
       
  2334 apply(induct_tac n, simp)
       
  2335 apply(erule_tac x = na in allE, simp)
       
  2336 done
       
  2337 
       
  2338 lemma halt_lemma2'': 
       
  2339   "\<lbrakk>P (f n); \<not> P (f (0::nat))\<rbrakk> \<Longrightarrow> 
       
  2340          \<exists> n. (P (f n) \<and> (\<forall> i < n. \<not> P (f i)))"
       
  2341 apply(induct n rule: nat_less_induct, auto)
       
  2342 done
       
  2343 
       
  2344 lemma halt_lemma2''':
       
  2345  "\<lbrakk>\<forall>n. \<not> P (f n) \<and> Q (f n) \<longrightarrow> Q (f (Suc n)) \<and> (f (Suc n), f n) \<in> LE;
       
  2346                  Q (f 0);  \<forall>i<na. \<not> P (f i)\<rbrakk> \<Longrightarrow> Q (f na)"
       
  2347 apply(induct na, simp, simp)
       
  2348 done
       
  2349 
       
  2350 lemma halt_lemma2: 
       
  2351   "\<lbrakk>wf LE;  
       
  2352     \<forall> n. ((\<not> P (f n) \<and> Q (f n)) \<longrightarrow> (Q (f (Suc n)) \<and> (f (Suc n), (f n)) \<in> LE)); 
       
  2353     Q (f 0); \<not> P (f 0)\<rbrakk> 
       
  2354   \<Longrightarrow> \<exists> n. P (f n) \<and> Q (f n)"
       
  2355 apply(insert halt_lemma2' [of LE P f Q], simp, erule_tac exE)
       
  2356 apply(subgoal_tac "\<exists> n. (P (f n) \<and> (\<forall> i < n. \<not> P (f i)))")
       
  2357 apply(erule_tac exE)+
       
  2358 apply(rule_tac x = na in exI, auto)
       
  2359 apply(rule halt_lemma2''', simp, simp, simp)
       
  2360 apply(erule_tac halt_lemma2'', simp)
       
  2361 done
       
  2362 
       
  2363 lemma [simp]: 
       
  2364   "\<lbrakk>ly = layout_of aprog; abc_fetch as aprog = Some (Inc n)\<rbrakk>
       
  2365     \<Longrightarrow> start_of ly (Suc as) = start_of ly as + 2*n +9"
       
  2366 apply(case_tac as, auto simp: abc_fetch.simps start_of.simps 
       
  2367           layout_of.simps length_of.simps split: if_splits)
       
  2368 done
       
  2369 
       
  2370 lemma inc_inv_init: 
       
  2371  "\<lbrakk>abc_fetch as aprog = Some (Inc n); 
       
  2372    crsp_l ly (as, am) (start_of ly as, l, r) ires; ly = layout_of aprog\<rbrakk>
       
  2373   \<Longrightarrow> inc_inv ly n (as, am) (start_of ly as, l, r) ires"
       
  2374 apply(auto simp: crsp_l.simps inc_inv.simps 
       
  2375       inv_locate_a.simps at_begin_fst_bwtn.simps 
       
  2376       at_begin_fst_awtn.simps at_begin_norm.simps )
       
  2377 apply(auto intro: startof_not0)
       
  2378 done
       
  2379      
       
  2380 lemma inc_inv_stop_pre[simp]: 
       
  2381    "\<lbrakk>ly = layout_of aprog; inc_inv ly n (as, am) (s, l, r) ires; 
       
  2382      s = start_of ly as; abc_fetch as aprog = Some (Inc n)\<rbrakk>
       
  2383     \<Longrightarrow>  (\<forall>na. \<not> (\<lambda>((s, l, r), ss, n', ires'). s = start_of ly (Suc as)) 
       
  2384          (t_steps (s, l, r) (ci ly (start_of ly as) 
       
  2385           (Inc n), start_of ly as - Suc 0) na, s, n, ires) \<and>
       
  2386        (\<lambda>((s, l, r), ss, n', ires'). inc_inv ly n (as, am) (s, l, r) ires')
       
  2387          (t_steps (s, l, r) (ci ly (start_of ly as) 
       
  2388              (Inc n), start_of ly as - Suc 0) na, s, n, ires) \<longrightarrow>
       
  2389        (\<lambda>((s, l, r), ss, n', ires'). inc_inv ly n (as, am) (s, l, r) ires') 
       
  2390       (t_steps (s, l, r) (ci ly (start_of ly as) 
       
  2391               (Inc n), start_of ly as - Suc 0) (Suc na), s, n, ires) \<and>
       
  2392      ((t_steps (s, l, r) (ci ly (start_of ly as) (Inc n), 
       
  2393         start_of ly as - Suc 0) (Suc na), s, n, ires), 
       
  2394       t_steps (s, l, r) (ci ly (start_of ly as) 
       
  2395         (Inc n), start_of ly as - Suc 0) na, s, n, ires) \<in> abc_inc_LE)"
       
  2396 apply(rule allI, rule impI, simp add: t_steps_ind,
       
  2397        rule conjI, erule_tac conjE)
       
  2398 apply(rule_tac inc_inv_step, simp, simp, simp)
       
  2399 apply(case_tac "t_steps (start_of (layout_of aprog) as, l, r) (ci (layout_of aprog) 
       
  2400   (start_of (layout_of aprog) as) (Inc n), start_of (layout_of aprog) as - Suc 0) na", simp)
       
  2401 proof -
       
  2402   fix na
       
  2403   assume h1: "abc_fetch as aprog = Some (Inc n)"
       
  2404     "\<not> (\<lambda>(s, l, r) (ss, n', ires'). s = start_of (layout_of aprog) as + 2 * n + 9)
       
  2405     (t_steps (start_of (layout_of aprog) as, l, r) (ci (layout_of aprog) 
       
  2406     (start_of (layout_of aprog) as) (Inc n), start_of (layout_of aprog) as - Suc 0) na) 
       
  2407     (start_of (layout_of aprog) as, n, ires) \<and>
       
  2408     inc_inv (layout_of aprog) n (as, am) (t_steps (start_of (layout_of aprog) as, l, r)
       
  2409     (ci (layout_of aprog) (start_of (layout_of aprog) as) (Inc n), start_of (layout_of aprog) as - Suc 0) na) ires"
       
  2410   from h1 have h2: "start_of (layout_of aprog) as > 0"
       
  2411     apply(rule_tac startof_not0)
       
  2412     done
       
  2413   from h1 and h2 show "((t_step (t_steps (start_of (layout_of aprog) as, l, r) (ci (layout_of aprog)
       
  2414     (start_of (layout_of aprog) as) (Inc n), start_of (layout_of aprog) as - Suc 0) na)
       
  2415     (ci (layout_of aprog) (start_of (layout_of aprog) as) (Inc n), start_of (layout_of aprog) as - Suc 0),
       
  2416     start_of (layout_of aprog) as, n, ires),
       
  2417     t_steps (start_of (layout_of aprog) as, l, r) 
       
  2418     (ci (layout_of aprog) (start_of (layout_of aprog) as) (Inc n), start_of (layout_of aprog) as - Suc 0) na, 
       
  2419     start_of (layout_of aprog) as, n, ires)
       
  2420             \<in> abc_inc_LE"
       
  2421     apply(case_tac "(t_steps (start_of (layout_of aprog) as, l, r) 
       
  2422                (ci (layout_of aprog)
       
  2423          (start_of (layout_of aprog) as) (Inc n), 
       
  2424            start_of (layout_of aprog) as - Suc 0) na)", simp)
       
  2425     apply(case_tac "a = 0", 
       
  2426      auto split:if_splits simp add:t_step.simps inc_inv.simps, 
       
  2427        tactic {* ALLGOALS (resolve_tac [@{thm fetch_intro}]) *})
       
  2428     apply(simp_all add:fetch_simps new_tape.simps)
       
  2429     apply(auto simp add: abc_inc_LE_def  
       
  2430     lex_square_def lex_triple_def lex_pair_def
       
  2431       inv_after_write.simps inv_after_move.simps inv_after_clear.simps
       
  2432       inv_on_left_moving.simps inv_on_left_moving_norm.simps split: if_splits)
       
  2433     done
       
  2434 qed
       
  2435 
       
  2436 lemma inc_inv_stop_pre1: 
       
  2437   "\<lbrakk>
       
  2438   ly = layout_of aprog; 
       
  2439   abc_fetch as aprog = Some (Inc n);
       
  2440   s = start_of ly as; 
       
  2441   inc_inv ly n (as, am) (s, l, r) ires
       
  2442   \<rbrakk> \<Longrightarrow> 
       
  2443   (\<exists> stp > 0. (\<lambda> (s', l', r').
       
  2444            s' = start_of ly (Suc as) \<and> 
       
  2445            inc_inv ly n (as, am) (s', l', r') ires) 
       
  2446                (t_steps (s, l, r) (ci ly (start_of ly as) (Inc n), 
       
  2447                         start_of ly as - Suc 0) stp))"
       
  2448 apply(insert halt_lemma2[of abc_inc_LE 
       
  2449     "\<lambda> ((s, l, r), ss, n', ires'). s = start_of ly (Suc as)" 
       
  2450     "(\<lambda> stp. (t_steps (s, l, r) 
       
  2451      (ci ly (start_of ly as) (Inc n), 
       
  2452      start_of ly as - Suc 0) stp, s, n, ires))" 
       
  2453     "\<lambda> ((s, l, r), ss, n'). inc_inv ly n (as, am) (s, l, r) ires"])
       
  2454 apply(insert  wf_abc_inc_le)
       
  2455 apply(insert inc_inv_stop_pre[of ly aprog n as am s l r ires], simp)
       
  2456 apply(simp only: t_steps.simps, auto)
       
  2457 apply(rule_tac x = na in exI)
       
  2458 apply(case_tac "(t_steps (start_of (layout_of aprog) as, l, r) 
       
  2459    (ci (layout_of aprog) (start_of (layout_of aprog) as) 
       
  2460    (Inc n), start_of (layout_of aprog) as - Suc 0) na)", simp)
       
  2461 apply(case_tac na, simp add: t_steps.simps, simp)
       
  2462 done
       
  2463 
       
  2464 lemma inc_inv_stop: 
       
  2465   assumes program_and_layout: 
       
  2466   -- {* There is an Abacus program @{text "aprog"} and its layout is @{text "ly"}: *}
       
  2467   "ly = layout_of aprog"
       
  2468   and an_instruction:
       
  2469   -- {* There is an instruction @{text "Inc n"} at postion @{text "as"} of @{text "aprog"} *}
       
  2470   "abc_fetch as aprog = Some (Inc n)"
       
  2471   and the_start_state:
       
  2472   -- {* According to @{text "ly"} and @{text "as"}, 
       
  2473         the start state of the TM compiled from this
       
  2474         @{text "Inc n"} instruction should be @{text "s"}:
       
  2475      *}
       
  2476   "s = start_of ly as"
       
  2477   and inv:
       
  2478   -- {* Invariant holds on configuration @{text "(s, l, r)"} *}
       
  2479   "inc_inv ly n (as, am) (s, l, r) ires"
       
  2480   shows  -- {* After @{text "stp"} steps of execution, the compiled 
       
  2481             TM reaches the start state of next compiled TM and the invariant 
       
  2482             still holds.
       
  2483             *}
       
  2484       "(\<exists> stp > 0. (\<lambda> (s', l', r').
       
  2485            s' = start_of ly (Suc as) \<and> 
       
  2486            inc_inv ly n (as, am) (s', l', r') ires) 
       
  2487                (t_steps (s, l, r) (ci ly (start_of ly as) (Inc n), 
       
  2488                         start_of ly as - Suc 0) stp))"
       
  2489 proof -
       
  2490   from inc_inv_stop_pre1 [OF  program_and_layout an_instruction the_start_state inv] 
       
  2491   show ?thesis .
       
  2492 qed
       
  2493 
       
  2494 lemma inc_inv_stop_cond: 
       
  2495   "\<lbrakk>ly = layout_of aprog; 
       
  2496     s' = start_of ly (as + 1); 
       
  2497     inc_inv ly n (as, lm) (s', (l', r')) ires; 
       
  2498     abc_fetch as aprog = Some (Inc n)\<rbrakk> \<Longrightarrow>
       
  2499     crsp_l ly (Suc as, abc_lm_s lm n (Suc (abc_lm_v lm n))) 
       
  2500                                                 (s', l', r') ires"
       
  2501 apply(subgoal_tac "s' = start_of ly as + 2*n + 9", simp)
       
  2502 apply(auto simp: inc_inv.simps inv_stop.simps crsp_l.simps )
       
  2503 done
       
  2504 
       
  2505 lemma inc_crsp_ex_pre:
       
  2506   "\<lbrakk>ly = layout_of aprog; 
       
  2507     crsp_l ly (as, am) tc ires;  
       
  2508     abc_fetch as aprog = Some (Inc n)\<rbrakk>
       
  2509  \<Longrightarrow> \<exists>stp > 0. crsp_l ly (abc_step_l (as, am) (Some (Inc n))) 
       
  2510                 (t_steps tc (ci ly (start_of ly as) (Inc n), 
       
  2511                                 start_of ly as - Suc 0) stp) ires"
       
  2512 proof(case_tac tc, simp add: abc_step_l.simps)
       
  2513   fix a b c
       
  2514   assume h1: "ly = layout_of aprog" 
       
  2515          "crsp_l (layout_of aprog) (as, am) (a, b, c) ires"
       
  2516          "abc_fetch as aprog = Some (Inc n)"
       
  2517   hence h2: "a = start_of ly as"
       
  2518     by(auto simp: crsp_l.simps)
       
  2519   from h1 and h2 have h3: 
       
  2520        "inc_inv ly n (as, am) (start_of ly as, b, c) ires"
       
  2521     by(rule_tac inc_inv_init, simp, simp, simp)
       
  2522   from h1 and h2 and h3 have h4:
       
  2523        "(\<exists> stp > 0. (\<lambda> (s', l', r'). s' = 
       
  2524            start_of ly (Suc as) \<and> inc_inv ly n (as, am) (s', l', r') ires)
       
  2525          (t_steps (a, b, c) (ci ly (start_of ly as) 
       
  2526                  (Inc n), start_of ly as - Suc 0) stp))"
       
  2527     apply(rule_tac inc_inv_stop, auto)
       
  2528     done
       
  2529   from h1 and h2 and h3 and h4 show 
       
  2530      "\<exists>stp > 0. crsp_l (layout_of aprog) 
       
  2531         (Suc as, abc_lm_s am n (Suc (abc_lm_v am n)))
       
  2532        (t_steps (a, b, c) (ci (layout_of aprog) 
       
  2533           (start_of (layout_of aprog) as) (Inc n), 
       
  2534               start_of (layout_of aprog) as - Suc 0) stp) ires"
       
  2535     apply(erule_tac exE)
       
  2536     apply(rule_tac x = stp in exI)
       
  2537     apply(case_tac "(t_steps (a, b, c) (ci (layout_of aprog) 
       
  2538          (start_of (layout_of aprog) as) (Inc n), 
       
  2539              start_of (layout_of aprog) as - Suc 0) stp)", simp)
       
  2540     apply(rule_tac inc_inv_stop_cond, auto)
       
  2541     done
       
  2542 qed
       
  2543 
       
  2544 text {*
       
  2545   The total correctness of the compilaton of @{text "Inc n"} instruction.
       
  2546 *}
       
  2547 
       
  2548 lemma inc_crsp_ex:
       
  2549   assumes layout: 
       
  2550   -- {* For any Abacus program @{text "aprog"}, assuming its layout is @{text "ly"} *}
       
  2551   "ly = layout_of aprog"
       
  2552   and corresponds: 
       
  2553   -- {* Abacus configuration @{text "(as, am)"} is in correspondence with 
       
  2554         TM configuration @{text "tc"} *}
       
  2555   "crsp_l ly (as, am) tc ires"
       
  2556   and inc:
       
  2557   -- {* There is an instruction @{text "Inc n"} at postion @{text "as"} of @{text "aprog"} *}
       
  2558   "abc_fetch as aprog = Some (Inc n)"
       
  2559   shows
       
  2560   -- {* 
       
  2561   After @{text "stp"} steps of execution, the TM compiled from this @{text "Inc n"}
       
  2562   stops with a configuration which corresponds to the Abacus configuration obtained
       
  2563   from the execution of this @{text "Inc n"} instruction.
       
  2564   *} 
       
  2565   "\<exists>stp > 0. crsp_l ly (abc_step_l (as, am) (Some (Inc n))) 
       
  2566                        (t_steps tc (ci ly (start_of ly as) (Inc n), 
       
  2567                                 start_of ly as - Suc 0) stp) ires"
       
  2568 proof -
       
  2569   from inc_crsp_ex_pre [OF layout corresponds inc] show ?thesis .
       
  2570 qed
       
  2571 
       
  2572 (*
       
  2573 subsection {* The compilation of @{text "Dec n e"} *}
       
  2574 *)
       
  2575 
       
  2576 text {*
       
  2577   The lemmas in this section lead to the correctness of the compilation 
       
  2578   of @{text "Dec n e"} instruction using the same techniques as 
       
  2579   @{text "Inc n"}.
       
  2580 *}
       
  2581 
       
  2582 type_synonym dec_inv_t = "(nat * nat list) \<Rightarrow> t_conf \<Rightarrow> block list \<Rightarrow>  bool"
       
  2583 
       
  2584 fun dec_first_on_right_moving :: "nat \<Rightarrow> dec_inv_t"
       
  2585   where
       
  2586   "dec_first_on_right_moving n (as, lm) (s, l, r) ires = 
       
  2587                (\<exists> lm1 lm2 m ml mr rn. lm = lm1 @ [m] @ lm2 \<and> 
       
  2588          ml + mr = Suc m \<and> length lm1 = n \<and> ml > 0 \<and> m > 0 \<and>
       
  2589              (if lm1 = [] then l = Oc\<^bsup>ml\<^esup> @ Bk # Bk # ires
       
  2590                           else  l = (Oc\<^bsup>ml\<^esup>) @ [Bk] @ <rev lm1> @ Bk # Bk # ires) \<and> 
       
  2591     ((r = (Oc\<^bsup>mr\<^esup>) @ [Bk] @ <lm2> @ (Bk\<^bsup>rn\<^esup>)) \<or> (r = (Oc\<^bsup>mr\<^esup>) \<and> lm2 = [])))"
       
  2592 
       
  2593 fun dec_on_right_moving :: "dec_inv_t"
       
  2594   where
       
  2595   "dec_on_right_moving (as, lm) (s, l, r) ires =  
       
  2596    (\<exists> lm1 lm2 m ml mr rn. lm = lm1 @ [m] @ lm2 \<and> 
       
  2597                              ml + mr = Suc (Suc m) \<and>
       
  2598    (if lm1 = [] then l = Oc\<^bsup>ml\<^esup> @ Bk # Bk # ires
       
  2599                 else  l = (Oc\<^bsup>ml\<^esup>) @ [Bk] @ <rev lm1> @ Bk # Bk # ires) \<and> 
       
  2600    ((r = (Oc\<^bsup>mr\<^esup>) @ [Bk] @ <lm2> @ (Bk\<^bsup>rn\<^esup>)) \<or> (r = (Oc\<^bsup>mr\<^esup>) \<and> lm2 = [])))"
       
  2601 
       
  2602 fun dec_after_clear :: "dec_inv_t"
       
  2603   where
       
  2604   "dec_after_clear (as, lm) (s, l, r) ires = 
       
  2605               (\<exists> lm1 lm2 m ml mr rn. lm = lm1 @ [m] @ lm2 \<and> 
       
  2606                 ml + mr = Suc m \<and> ml = Suc m \<and> r \<noteq> [] \<and> r \<noteq> [] \<and>
       
  2607                (if lm1 = [] then l = Oc\<^bsup>ml\<^esup> @ Bk # Bk # ires
       
  2608                             else l = (Oc\<^bsup>ml \<^esup>) @ [Bk] @ <rev lm1> @ Bk # Bk # ires) \<and> 
       
  2609                (tl r = Bk # <lm2> @ (Bk\<^bsup>rn\<^esup>) \<or> tl r = [] \<and> lm2 = []))"
       
  2610 
       
  2611 fun dec_after_write :: "dec_inv_t"
       
  2612   where
       
  2613   "dec_after_write (as, lm) (s, l, r) ires = 
       
  2614          (\<exists> lm1 lm2 m ml mr rn. lm = lm1 @ [m] @ lm2 \<and> 
       
  2615        ml + mr = Suc m \<and> ml = Suc m \<and> lm2 \<noteq> [] \<and>
       
  2616        (if lm1 = [] then l = Bk # Oc\<^bsup>ml\<^esup> @ Bk # Bk # ires
       
  2617                     else l = Bk # (Oc\<^bsup>ml \<^esup>) @ [Bk] @ <rev lm1> @ Bk # Bk # ires) \<and> 
       
  2618        tl r = <lm2> @ (Bk\<^bsup>rn\<^esup>))"
       
  2619 
       
  2620 fun dec_right_move :: "dec_inv_t"
       
  2621   where
       
  2622   "dec_right_move (as, lm) (s, l, r) ires = 
       
  2623         (\<exists> lm1 lm2 m ml mr rn. lm = lm1 @ [m] @ lm2 
       
  2624             \<and> ml = Suc m \<and> mr = (0::nat) \<and> 
       
  2625               (if lm1 = [] then l = Bk # Oc\<^bsup>ml\<^esup> @ Bk # Bk # ires
       
  2626                           else l = Bk # Oc\<^bsup>ml\<^esup>@ [Bk] @ <rev lm1> @ Bk # Bk # ires) 
       
  2627            \<and> (r = Bk # <lm2> @ Bk\<^bsup>rn\<^esup>\<or> r = [] \<and> lm2 = []))"
       
  2628 
       
  2629 fun dec_check_right_move :: "dec_inv_t"
       
  2630   where
       
  2631   "dec_check_right_move (as, lm) (s, l, r) ires = 
       
  2632         (\<exists> lm1 lm2 m ml mr rn. lm = lm1 @ [m] @ lm2 \<and> 
       
  2633            ml = Suc m \<and> mr = (0::nat) \<and> 
       
  2634            (if lm1 = [] then l = Bk # Bk # Oc\<^bsup>ml\<^esup> @ Bk # Bk # ires
       
  2635                        else l = Bk # Bk # Oc\<^bsup>ml \<^esup>@ [Bk] @ <rev lm1> @ Bk # Bk # ires) \<and> 
       
  2636            r = <lm2> @ Bk\<^bsup>rn\<^esup>)"
       
  2637 
       
  2638 fun dec_left_move :: "dec_inv_t"
       
  2639   where
       
  2640   "dec_left_move (as, lm) (s, l, r) ires = 
       
  2641     (\<exists> lm1 m rn. (lm::nat list) = lm1 @ [m::nat] \<and>   
       
  2642     rn > 0 \<and> 
       
  2643    (if lm1 = [] then l = Bk # Oc\<^bsup>Suc m\<^esup> @ Bk # Bk # ires
       
  2644     else l = Bk # Oc\<^bsup>Suc m\<^esup> @ Bk # <rev lm1> @ Bk # Bk # ires) \<and> r = Bk\<^bsup>rn\<^esup>)"
       
  2645 
       
  2646 declare
       
  2647   dec_on_right_moving.simps[simp del] dec_after_clear.simps[simp del] 
       
  2648   dec_after_write.simps[simp del] dec_left_move.simps[simp del] 
       
  2649   dec_check_right_move.simps[simp del] dec_right_move.simps[simp del] 
       
  2650   dec_first_on_right_moving.simps[simp del]
       
  2651 
       
  2652 fun inv_locate_n_b :: "inc_inv_t"
       
  2653   where
       
  2654   "inv_locate_n_b (as, lm) (s, l, r) ires= 
       
  2655     (\<exists> lm1 lm2 tn m ml mr rn. lm @ 0\<^bsup>tn\<^esup> = lm1 @ [m] @ lm2 \<and> 
       
  2656      length lm1 = s \<and> m + 1 = ml + mr \<and> 
       
  2657      ml = 1 \<and> tn = s + 1 - length lm \<and>
       
  2658      (if lm1 = [] then l = Oc\<^bsup>ml\<^esup> @ Bk # Bk # ires
       
  2659       else l = Oc\<^bsup>ml\<^esup>@Bk#<rev lm1>@Bk#Bk#ires) \<and> 
       
  2660      (r = (Oc\<^bsup>mr\<^esup>) @ [Bk] @ <lm2>@ (Bk\<^bsup>rn\<^esup>) \<or> (lm2 = [] \<and> r = (Oc\<^bsup>mr\<^esup>)))
       
  2661   )"
       
  2662 
       
  2663 fun dec_inv_1 :: "layout \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> dec_inv_t"
       
  2664   where
       
  2665   "dec_inv_1 ly n e (as, am) (s, l, r) ires = 
       
  2666            (let ss = start_of ly as in
       
  2667             let am' = abc_lm_s am n (abc_lm_v am n - Suc 0) in
       
  2668             let am'' = abc_lm_s am n (abc_lm_v am n) in
       
  2669               if s = start_of ly e then  inv_stop (as, am'') (s, l, r) ires
       
  2670               else if s = ss then False
       
  2671               else if ss \<le> s \<and> s < ss + 2*n then
       
  2672                    if (s - ss) mod 2 = 0 then 
       
  2673                         inv_locate_a (as, am) ((s - ss) div 2, l, r) ires
       
  2674                     \<or> inv_locate_a (as, am'') ((s - ss) div 2, l, r) ires
       
  2675                    else 
       
  2676                      inv_locate_b (as, am) ((s - ss) div 2, l, r) ires
       
  2677                   \<or> inv_locate_b (as, am'') ((s - ss) div 2, l, r) ires
       
  2678               else if s = ss + 2 * n then 
       
  2679                   inv_locate_a (as, am) (n, l, r) ires
       
  2680                 \<or> inv_locate_a (as, am'') (n, l, r) ires
       
  2681               else if s = ss + 2 * n + 1 then 
       
  2682                   inv_locate_b (as, am) (n, l, r) ires
       
  2683               else if s = ss + 2 * n + 13 then 
       
  2684                   inv_on_left_moving (as, am'') (s, l, r) ires
       
  2685               else if s = ss + 2 * n + 14 then 
       
  2686                   inv_check_left_moving (as, am'') (s, l, r) ires
       
  2687               else if s = ss + 2 * n + 15 then 
       
  2688                   inv_after_left_moving (as, am'') (s, l, r) ires
       
  2689               else False)"
       
  2690 
       
  2691 fun dec_inv_2 :: "layout \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> dec_inv_t"
       
  2692   where
       
  2693   "dec_inv_2 ly n e (as, am) (s, l, r) ires =
       
  2694            (let ss = start_of ly as in
       
  2695             let am' = abc_lm_s am n (abc_lm_v am n - Suc 0) in
       
  2696             let am'' = abc_lm_s am n (abc_lm_v am n) in
       
  2697               if s = 0 then False
       
  2698               else if s = ss then False
       
  2699               else if ss \<le> s \<and> s < ss + 2*n then
       
  2700                    if (s - ss) mod 2 = 0 then 
       
  2701                       inv_locate_a (as, am) ((s - ss) div 2, l, r) ires
       
  2702                    else inv_locate_b (as, am) ((s - ss) div 2, l, r) ires
       
  2703               else if s = ss + 2 * n then 
       
  2704                       inv_locate_a (as, am) (n, l, r) ires
       
  2705               else if s = ss + 2 * n + 1 then 
       
  2706                       inv_locate_n_b (as, am) (n, l, r) ires
       
  2707               else if s = ss + 2 * n + 2 then 
       
  2708                       dec_first_on_right_moving n (as, am'') (s, l, r) ires
       
  2709               else if s = ss + 2 * n + 3 then 
       
  2710                       dec_after_clear (as, am') (s, l, r) ires
       
  2711               else if s = ss + 2 * n + 4 then 
       
  2712                       dec_right_move (as, am') (s, l, r) ires
       
  2713               else if s = ss + 2 * n + 5 then 
       
  2714                       dec_check_right_move (as, am') (s, l, r) ires
       
  2715               else if s = ss + 2 * n + 6 then 
       
  2716                       dec_left_move (as, am') (s, l, r) ires
       
  2717               else if s = ss + 2 * n + 7 then 
       
  2718                       dec_after_write (as, am') (s, l, r) ires
       
  2719               else if s = ss + 2 * n + 8 then 
       
  2720                       dec_on_right_moving (as, am') (s, l, r) ires
       
  2721               else if s = ss + 2 * n + 9 then 
       
  2722                       dec_after_clear (as, am') (s, l, r) ires
       
  2723               else if s = ss + 2 * n + 10 then 
       
  2724                       inv_on_left_moving (as, am') (s, l, r) ires
       
  2725               else if s = ss + 2 * n + 11 then 
       
  2726                       inv_check_left_moving (as, am') (s, l, r) ires
       
  2727               else if s = ss + 2 * n + 12 then 
       
  2728                       inv_after_left_moving (as, am') (s, l, r) ires
       
  2729               else if s = ss + 2 * n + 16 then 
       
  2730                       inv_stop (as, am') (s, l, r) ires
       
  2731               else False)"
       
  2732 
       
  2733 (*begin: dec_fetch lemmas*)
       
  2734 
       
  2735 lemma dec_fetch_locate_a_o: 
       
  2736       "\<lbrakk>start_of ly as \<le> a;
       
  2737         a < start_of ly as + 2 * n; start_of ly as > 0;
       
  2738         a - start_of ly as = 2 * q\<rbrakk>
       
  2739        \<Longrightarrow> fetch (ci (layout_of aprog) 
       
  2740          (start_of ly as) (Dec n e)) (Suc (2 * q))  Oc = (R, a + 1)"
       
  2741 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2742                   nth_of.simps tshift.simps nth_append Suc_pre)
       
  2743 apply(subgoal_tac "(findnth n ! Suc (4 * q)) = 
       
  2744                           findnth (Suc q) ! (4 * q + 1)")
       
  2745 apply(simp add: findnth.simps nth_append)
       
  2746 apply(subgoal_tac " findnth n !(4 * q + 1) = 
       
  2747                           findnth (Suc q) ! (4 * q + 1)", simp)
       
  2748 apply(rule_tac findnth_nth, auto)
       
  2749 done
       
  2750 
       
  2751 lemma  dec_fetch_locate_a_b:
       
  2752        "\<lbrakk>start_of ly as \<le> a; 
       
  2753          a < start_of ly as + 2 * n; 
       
  2754          start_of ly as > 0;
       
  2755          a - start_of ly as = 2 * q\<rbrakk>
       
  2756        \<Longrightarrow> fetch (ci (layout_of aprog) (start_of ly as) (Dec n e)) 
       
  2757               (Suc (2 * q))  Bk = (W1, a)"
       
  2758 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2759                   nth_of.simps tshift.simps nth_append)
       
  2760 apply(subgoal_tac "(findnth n ! (4 * q)) = 
       
  2761                        findnth (Suc q) ! (4 * q )")
       
  2762 apply(simp add: findnth.simps nth_append)
       
  2763 apply(subgoal_tac " findnth n !(4 * q + 0) = 
       
  2764                        findnth (Suc q) ! (4 * q + 0)", simp)
       
  2765 apply(rule_tac findnth_nth, auto)
       
  2766 done
       
  2767 
       
  2768 lemma dec_fetch_locate_b_o:
       
  2769       "\<lbrakk>start_of ly as \<le> a; 
       
  2770         a < start_of ly as + 2 * n; 
       
  2771         (a - start_of ly as) mod 2 = Suc 0; 
       
  2772         start_of ly as> 0\<rbrakk>
       
  2773        \<Longrightarrow> fetch (ci (layout_of aprog) (start_of ly as) (Dec n e)) 
       
  2774                        (Suc (a - start_of ly as)) Oc = (R, a)"
       
  2775 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2776                   nth_of.simps tshift.simps nth_append)
       
  2777 apply(subgoal_tac "\<exists> q. (a - start_of ly as) = 2 * q + 1", auto)
       
  2778 apply(subgoal_tac "(findnth n ! Suc (Suc (Suc (4 * q)))) = 
       
  2779                                 findnth (Suc q) ! (4 * q + 3)")
       
  2780 apply(simp add: findnth.simps nth_append)
       
  2781 apply(subgoal_tac " findnth n ! (4 * q + 3) = 
       
  2782                  findnth (Suc q) ! (4 * q + 3)", simp add: add3_Suc)
       
  2783 apply(rule_tac findnth_nth, auto)
       
  2784 done
       
  2785 
       
  2786 lemma dec_fetch_locate_b_b: 
       
  2787       "\<lbrakk>\<not> a < start_of ly as; 
       
  2788         a < start_of ly as + 2 * n; 
       
  2789        (a - start_of ly as) mod 2 = Suc 0; 
       
  2790         start_of ly as > 0\<rbrakk>
       
  2791        \<Longrightarrow> fetch (ci (layout_of aprog) (start_of ly as) (Dec n e)) 
       
  2792               (Suc (a - start_of ly as))  Bk = (R, a + 1)"
       
  2793 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2794                   nth_of.simps tshift.simps nth_append)
       
  2795 apply(subgoal_tac "\<exists> q. (a - start_of ly as) = 2 * q + 1", auto)
       
  2796 apply(subgoal_tac "(findnth n ! Suc ((Suc (4 * q)))) = 
       
  2797                           findnth (Suc q) ! (4 * q + 2)")
       
  2798 apply(simp add: findnth.simps nth_append)
       
  2799 apply(subgoal_tac " findnth n ! (4 * q + 2) = 
       
  2800                           findnth (Suc q) ! (4 * q + 2)", simp)
       
  2801 apply(rule_tac findnth_nth, auto)
       
  2802 done
       
  2803 
       
  2804 lemma dec_fetch_locate_n_a_o: 
       
  2805        "start_of ly as > 0 \<Longrightarrow> fetch (ci (layout_of aprog) 
       
  2806                        (start_of ly as) (Dec n e)) (Suc (2 * n))  Oc
       
  2807        = (R, start_of ly as + 2*n + 1)"
       
  2808 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2809                   nth_of.simps tshift.simps nth_append tdec_b_def)
       
  2810 done
       
  2811 
       
  2812 lemma dec_fetch_locate_n_a_b: 
       
  2813        "start_of ly as > 0 \<Longrightarrow> fetch (ci (layout_of aprog) 
       
  2814                        (start_of ly as) (Dec n e)) (Suc (2 * n))  Bk
       
  2815        = (W1, start_of ly as + 2*n)"
       
  2816 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2817                   nth_of.simps tshift.simps nth_append tdec_b_def)
       
  2818 done
       
  2819 
       
  2820 lemma dec_fetch_locate_n_b_o: 
       
  2821        "start_of ly as > 0 \<Longrightarrow> 
       
  2822             fetch (ci (layout_of aprog) 
       
  2823                 (start_of ly as) (Dec n e)) (Suc (Suc (2 * n)))  Oc
       
  2824       = (R, start_of ly as + 2*n + 2)"
       
  2825 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2826                   nth_of.simps tshift.simps nth_append tdec_b_def)
       
  2827 done
       
  2828 
       
  2829 
       
  2830 lemma dec_fetch_locate_n_b_b: 
       
  2831        "start_of ly as > 0 \<Longrightarrow> 
       
  2832        fetch (ci (layout_of aprog) 
       
  2833                   (start_of ly as) (Dec n e)) (Suc (Suc (2 * n))) Bk
       
  2834       = (L, start_of ly as + 2*n + 13)"
       
  2835 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2836                   nth_of.simps tshift.simps nth_append tdec_b_def)
       
  2837 done
       
  2838 
       
  2839 lemma dec_fetch_first_on_right_move_o: 
       
  2840       "start_of ly as > 0 \<Longrightarrow> 
       
  2841        fetch (ci (layout_of aprog) 
       
  2842              (start_of ly as) (Dec n e)) (Suc (Suc (Suc (2 * n))))  Oc
       
  2843      = (R, start_of ly as + 2*n + 2)"
       
  2844 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2845                   nth_of.simps tshift.simps nth_append tdec_b_def)
       
  2846 done
       
  2847 
       
  2848 lemma dec_fetch_first_on_right_move_b: 
       
  2849       "start_of ly as > 0 \<Longrightarrow> 
       
  2850       fetch (ci (layout_of aprog) (start_of ly as) (Dec n e)) 
       
  2851                              (Suc (Suc (Suc (2 * n))))  Bk
       
  2852      = (L, start_of ly as + 2*n + 3)"
       
  2853 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2854                   nth_of.simps tshift.simps nth_append tdec_b_def)
       
  2855 done
       
  2856 
       
  2857 lemma [simp]: "fetch x (a + 2 * n) b = fetch x (2 * n + a) b"
       
  2858 thm arg_cong
       
  2859 apply(rule_tac x = "a + 2*n" and y = "2*n + a" in arg_cong, simp)
       
  2860 done
       
  2861 
       
  2862 lemma dec_fetch_first_after_clear_o: 
       
  2863      "start_of ly as > 0 \<Longrightarrow> fetch (ci (layout_of aprog) 
       
  2864                       (start_of ly as) (Dec n e)) (2 * n + 4) Oc
       
  2865     = (W0, start_of ly as + 2*n + 3)"
       
  2866 apply(auto simp: ci.simps findnth.simps tshift.simps 
       
  2867                           tdec_b_def add3_Suc)
       
  2868 apply(subgoal_tac "2*n + 4 = Suc (2*n + 3)", simp only: fetch.simps)
       
  2869 apply(auto simp: nth_of.simps nth_append)
       
  2870 done
       
  2871 
       
  2872 lemma dec_fetch_first_after_clear_b: 
       
  2873      "start_of ly as > 0 \<Longrightarrow> 
       
  2874      fetch (ci (layout_of aprog) 
       
  2875                    (start_of ly as) (Dec n e)) (2 * n + 4) Bk
       
  2876     = (R, start_of ly as + 2*n + 4)"
       
  2877 apply(auto simp: ci.simps findnth.simps 
       
  2878                tshift.simps tdec_b_def add3_Suc)
       
  2879 apply(subgoal_tac "2*n + 4= Suc (2*n + 3)", simp only: fetch.simps)
       
  2880 apply(auto simp: nth_of.simps nth_append)
       
  2881 done
       
  2882 
       
  2883 lemma dec_fetch_right_move_b: 
       
  2884      "start_of ly as > 0 \<Longrightarrow> fetch (ci (layout_of aprog) 
       
  2885                           (start_of ly as) (Dec n e)) (2 * n + 5) Bk
       
  2886     = (R, start_of ly as + 2*n + 5)"
       
  2887 apply(auto simp: ci.simps findnth.simps 
       
  2888                  tshift.simps tdec_b_def add3_Suc)
       
  2889 apply(subgoal_tac "2*n + 5= Suc (2*n + 4)", simp only: fetch.simps)
       
  2890 apply(auto simp: nth_of.simps nth_append)
       
  2891 done
       
  2892 
       
  2893 lemma dec_fetch_check_right_move_b: 
       
  2894      "start_of ly as > 0 \<Longrightarrow> 
       
  2895       fetch (ci (layout_of aprog)
       
  2896                 (start_of ly as) (Dec n e)) (2 * n + 6) Bk
       
  2897     = (L, start_of ly as + 2*n + 6)"
       
  2898 apply(auto simp: ci.simps findnth.simps 
       
  2899                tshift.simps tdec_b_def add3_Suc)
       
  2900 apply(subgoal_tac "2*n + 6 = Suc (2*n + 5)", simp only: fetch.simps)
       
  2901 apply(auto simp: nth_of.simps nth_append)
       
  2902 done
       
  2903 
       
  2904 lemma dec_fetch_check_right_move_o: 
       
  2905      "start_of ly as > 0 \<Longrightarrow> 
       
  2906     fetch (ci (layout_of aprog) (start_of ly as) 
       
  2907                       (Dec n e)) (2 * n + 6) Oc
       
  2908     = (L, start_of ly as + 2*n + 7)"
       
  2909 apply(auto simp: ci.simps findnth.simps 
       
  2910                  tshift.simps tdec_b_def add3_Suc)
       
  2911 apply(subgoal_tac "2*n + 6 = Suc (2*n + 5)", simp only: fetch.simps)
       
  2912 apply(auto simp: nth_of.simps nth_append)
       
  2913 done
       
  2914 
       
  2915 lemma dec_fetch_left_move_b: 
       
  2916      "start_of ly as > 0 \<Longrightarrow> 
       
  2917      fetch (ci (layout_of aprog) 
       
  2918              (start_of ly as) (Dec n e)) (2 * n + 7) Bk
       
  2919     = (L, start_of ly as + 2*n + 10)"
       
  2920 apply(auto simp: ci.simps findnth.simps 
       
  2921                  tshift.simps tdec_b_def add3_Suc)
       
  2922 apply(subgoal_tac "2*n + 7 = Suc (2*n + 6)", simp only: fetch.simps)
       
  2923 apply(auto simp: nth_of.simps nth_append)
       
  2924 done
       
  2925 
       
  2926 lemma dec_fetch_after_write_b: 
       
  2927      "start_of ly as > 0 \<Longrightarrow> 
       
  2928     fetch (ci (layout_of aprog) 
       
  2929                    (start_of ly as) (Dec n e)) (2 * n + 8) Bk
       
  2930     = (W1, start_of ly as + 2*n + 7)"
       
  2931 apply(auto simp: ci.simps findnth.simps 
       
  2932                  tshift.simps tdec_b_def add3_Suc)
       
  2933 apply(subgoal_tac "2*n + 8 = Suc (2*n + 7)", simp only: fetch.simps)
       
  2934 apply(auto simp: nth_of.simps nth_append)
       
  2935 done
       
  2936 
       
  2937 lemma dec_fetch_after_write_o: 
       
  2938      "start_of ly as > 0 \<Longrightarrow> 
       
  2939      fetch (ci (layout_of aprog) 
       
  2940                    (start_of ly as) (Dec n e)) (2 * n + 8) Oc
       
  2941     = (R, start_of ly as + 2*n + 8)"
       
  2942 apply(auto simp: ci.simps findnth.simps 
       
  2943                  tshift.simps tdec_b_def add3_Suc)
       
  2944 apply(subgoal_tac "2*n + 8 = Suc (2*n + 7)", simp only: fetch.simps)
       
  2945 apply(auto simp: nth_of.simps nth_append)
       
  2946 done
       
  2947 
       
  2948 lemma dec_fetch_on_right_move_b: 
       
  2949      "start_of ly as > 0 \<Longrightarrow> 
       
  2950      fetch (ci (layout_of aprog) 
       
  2951                    (start_of ly as) (Dec n e)) (2 * n + 9) Bk
       
  2952     = (L, start_of ly as + 2*n + 9)"
       
  2953 apply(auto simp: ci.simps findnth.simps 
       
  2954                  tshift.simps tdec_b_def add3_Suc)
       
  2955 apply(subgoal_tac "2*n + 9 = Suc (2*n + 8)", simp only: fetch.simps)
       
  2956 apply(auto simp: nth_of.simps nth_append)
       
  2957 done
       
  2958 
       
  2959 lemma dec_fetch_on_right_move_o: 
       
  2960      "start_of ly as > 0 \<Longrightarrow> 
       
  2961      fetch (ci (layout_of aprog) 
       
  2962              (start_of ly as) (Dec n e)) (2 * n + 9) Oc
       
  2963     = (R, start_of ly as + 2*n + 8)"
       
  2964 apply(auto simp: ci.simps findnth.simps 
       
  2965                  tshift.simps tdec_b_def add3_Suc)
       
  2966 apply(subgoal_tac "2*n + 9 = Suc (2*n + 8)", simp only: fetch.simps)
       
  2967 apply(auto simp: nth_of.simps nth_append)
       
  2968 done
       
  2969 
       
  2970 lemma dec_fetch_after_clear_b: 
       
  2971      "start_of ly as > 0 \<Longrightarrow> 
       
  2972      fetch (ci (layout_of aprog) 
       
  2973             (start_of ly as) (Dec n e)) (2 * n + 10) Bk
       
  2974     = (R, start_of ly as + 2*n + 4)" 
       
  2975 apply(auto simp: ci.simps findnth.simps 
       
  2976                  tshift.simps tdec_b_def add3_Suc)
       
  2977 apply(subgoal_tac "2*n + 10 = Suc (2*n + 9)", simp only: fetch.simps)
       
  2978 apply(auto simp: nth_of.simps nth_append)
       
  2979 done
       
  2980 
       
  2981 lemma dec_fetch_after_clear_o: 
       
  2982      "start_of ly as > 0 \<Longrightarrow> 
       
  2983     fetch (ci (layout_of aprog) 
       
  2984              (start_of ly as) (Dec n e)) (2 * n + 10) Oc
       
  2985     = (W0, start_of ly as + 2*n + 9)"
       
  2986 apply(auto simp: ci.simps findnth.simps 
       
  2987                  tshift.simps tdec_b_def add3_Suc)
       
  2988 apply(subgoal_tac "2*n + 10= Suc (2*n + 9)", simp only: fetch.simps)
       
  2989 apply(auto simp: nth_of.simps nth_append)
       
  2990 done
       
  2991 
       
  2992 lemma dec_fetch_on_left_move1_o:
       
  2993       "start_of ly as > 0 \<Longrightarrow> 
       
  2994     fetch (ci (layout_of aprog) 
       
  2995            (start_of ly as) (Dec n e)) (2 * n + 11) Oc
       
  2996     = (L, start_of ly as + 2*n + 10)"
       
  2997 apply(auto simp: ci.simps findnth.simps 
       
  2998                  tshift.simps tdec_b_def add3_Suc)
       
  2999 apply(subgoal_tac "2*n + 11= Suc (2*n + 10)", simp only: fetch.simps)
       
  3000 apply(auto simp: nth_of.simps nth_append)
       
  3001 done
       
  3002 
       
  3003 lemma dec_fetch_on_left_move1_b:
       
  3004      "start_of ly as > 0 \<Longrightarrow> 
       
  3005     fetch (ci (layout_of aprog) 
       
  3006              (start_of ly as) (Dec n e)) (2 * n + 11) Bk
       
  3007     = (L, start_of ly as + 2*n + 11)"
       
  3008 apply(auto simp: ci.simps findnth.simps 
       
  3009                  tshift.simps tdec_b_def add3_Suc)
       
  3010 apply(subgoal_tac "2*n + 11 = Suc (2*n + 10)", 
       
  3011       simp only: fetch.simps)
       
  3012 apply(auto simp: nth_of.simps nth_append)
       
  3013 done
       
  3014 
       
  3015 lemma dec_fetch_check_left_move1_o: 
       
  3016     "start_of ly as > 0 \<Longrightarrow> 
       
  3017   fetch (ci (layout_of aprog) 
       
  3018              (start_of ly as) (Dec n e)) (2 * n + 12) Oc
       
  3019     = (L, start_of ly as + 2*n + 10)"
       
  3020 apply(auto simp: ci.simps findnth.simps 
       
  3021                  tshift.simps tdec_b_def add3_Suc)
       
  3022 apply(subgoal_tac "2*n + 12= Suc (2*n + 11)", simp only: fetch.simps)
       
  3023 apply(auto simp: nth_of.simps nth_append)
       
  3024 done
       
  3025 
       
  3026 lemma dec_fetch_check_left_move1_b: 
       
  3027     "start_of ly as > 0 \<Longrightarrow> 
       
  3028    fetch (ci (layout_of aprog) 
       
  3029                   (start_of ly as) (Dec n e)) (2 * n + 12) Bk
       
  3030     = (R, start_of ly as + 2*n + 12)"
       
  3031 apply(auto simp: ci.simps findnth.simps 
       
  3032                  tshift.simps tdec_b_def add3_Suc)
       
  3033 apply(subgoal_tac "2*n + 12 = Suc (2*n + 11)", 
       
  3034       simp only: fetch.simps)
       
  3035 apply(auto simp: nth_of.simps nth_append)
       
  3036 done
       
  3037 
       
  3038 lemma dec_fetch_after_left_move1_b: 
       
  3039   "start_of ly as > 0 \<Longrightarrow> 
       
  3040   fetch (ci (layout_of aprog) 
       
  3041                 (start_of ly as) (Dec n e)) (2 * n + 13) Bk
       
  3042     = (R, start_of ly as + 2*n + 16)"
       
  3043 apply(auto simp: ci.simps findnth.simps 
       
  3044                  tshift.simps tdec_b_def add3_Suc)
       
  3045 apply(subgoal_tac "2*n + 13 = Suc (2*n + 12)", 
       
  3046       simp only: fetch.simps)
       
  3047 apply(auto simp: nth_of.simps nth_append)
       
  3048 done
       
  3049 
       
  3050 lemma dec_fetch_on_left_move2_o:
       
  3051   "start_of ly as > 0 \<Longrightarrow> 
       
  3052   fetch (ci (layout_of aprog) 
       
  3053            (start_of ly as) (Dec n e)) (2 * n + 14) Oc
       
  3054    = (L, start_of ly as + 2*n + 13)"
       
  3055 apply(auto simp: ci.simps findnth.simps 
       
  3056                  tshift.simps tdec_b_def add3_Suc)
       
  3057 apply(subgoal_tac "2*n + 14 = Suc (2*n + 13)", 
       
  3058       simp only: fetch.simps)
       
  3059 apply(auto simp: nth_of.simps nth_append)
       
  3060 done
       
  3061 
       
  3062 lemma dec_fetch_on_left_move2_b:
       
  3063   "start_of ly as > 0 \<Longrightarrow> 
       
  3064   fetch (ci (layout_of aprog) 
       
  3065               (start_of ly as) (Dec n e)) (2 * n + 14) Bk
       
  3066  = (L, start_of ly as + 2*n + 14)"
       
  3067 apply(auto simp: ci.simps findnth.simps 
       
  3068                  tshift.simps tdec_b_def add3_Suc)
       
  3069 apply(subgoal_tac "2*n + 14 = Suc (2*n + 13)", 
       
  3070       simp only: fetch.simps)
       
  3071 apply(auto simp: nth_of.simps nth_append)
       
  3072 done
       
  3073 
       
  3074 lemma dec_fetch_check_left_move2_o:
       
  3075   "start_of ly as > 0 \<Longrightarrow> 
       
  3076   fetch (ci (layout_of aprog) 
       
  3077                 (start_of ly as) (Dec n e)) (2 * n + 15)  Oc
       
  3078  = (L, start_of ly as + 2*n + 13)"
       
  3079 apply(auto simp: ci.simps findnth.simps 
       
  3080                  tshift.simps tdec_b_def add3_Suc)
       
  3081 apply(subgoal_tac "2*n + 15 = Suc (2*n + 14)", 
       
  3082       simp only: fetch.simps)
       
  3083 apply(auto simp: nth_of.simps nth_append)
       
  3084 done
       
  3085 
       
  3086 lemma dec_fetch_check_left_move2_b:
       
  3087   "start_of ly as > 0 \<Longrightarrow> 
       
  3088   fetch (ci (layout_of aprog) 
       
  3089                 (start_of ly as) (Dec n e)) (2 * n + 15)  Bk
       
  3090  = (R, start_of ly as + 2*n + 15)"
       
  3091 apply(auto simp: ci.simps findnth.simps 
       
  3092                  tshift.simps tdec_b_def add3_Suc)
       
  3093 apply(subgoal_tac "2*n + 15= Suc (2*n + 14)", simp only: fetch.simps)
       
  3094 apply(auto simp: nth_of.simps nth_append)
       
  3095 done
       
  3096 
       
  3097 lemma dec_fetch_after_left_move2_b: 
       
  3098   "\<lbrakk>ly = layout_of aprog; 
       
  3099     abc_fetch as aprog = Some (Dec n e); 
       
  3100     start_of ly as > 0\<rbrakk> \<Longrightarrow> 
       
  3101      fetch (ci (layout_of aprog) (start_of ly as) 
       
  3102               (Dec n e)) (2 * n + 16)  Bk
       
  3103  = (R, start_of ly e)" 
       
  3104 apply(auto simp: ci.simps findnth.simps 
       
  3105                  tshift.simps tdec_b_def add3_Suc)
       
  3106 apply(subgoal_tac "2*n + 16 = Suc (2*n + 15)",
       
  3107       simp only: fetch.simps)
       
  3108 apply(auto simp: nth_of.simps nth_append)
       
  3109 done
       
  3110 
       
  3111 lemma dec_fetch_next_state: 
       
  3112     "start_of ly as > 0 \<Longrightarrow> 
       
  3113     fetch (ci (layout_of aprog) 
       
  3114            (start_of ly as) (Dec n e)) (2* n + 17)  b
       
  3115     = (Nop, 0)"
       
  3116 apply(case_tac b)
       
  3117 apply(auto simp: ci.simps findnth.simps 
       
  3118                  tshift.simps tdec_b_def add3_Suc)
       
  3119 apply(subgoal_tac [!] "2*n + 17 = Suc (2*n + 16)", 
       
  3120       simp_all only: fetch.simps)
       
  3121 apply(auto simp: nth_of.simps nth_append)
       
  3122 done
       
  3123 
       
  3124 (*End: dec_fetch lemmas*)
       
  3125 lemmas dec_fetch_simps = 
       
  3126  dec_fetch_locate_a_o dec_fetch_locate_a_b dec_fetch_locate_b_o 
       
  3127  dec_fetch_locate_b_b dec_fetch_locate_n_a_o 
       
  3128  dec_fetch_locate_n_a_b dec_fetch_locate_n_b_o 
       
  3129  dec_fetch_locate_n_b_b dec_fetch_first_on_right_move_o 
       
  3130  dec_fetch_first_on_right_move_b dec_fetch_first_after_clear_b
       
  3131  dec_fetch_first_after_clear_o dec_fetch_right_move_b 
       
  3132  dec_fetch_on_right_move_b dec_fetch_on_right_move_o 
       
  3133  dec_fetch_after_clear_b dec_fetch_after_clear_o
       
  3134  dec_fetch_check_right_move_b dec_fetch_check_right_move_o 
       
  3135  dec_fetch_left_move_b dec_fetch_on_left_move1_b 
       
  3136  dec_fetch_on_left_move1_o dec_fetch_check_left_move1_b 
       
  3137  dec_fetch_check_left_move1_o dec_fetch_after_left_move1_b 
       
  3138  dec_fetch_on_left_move2_b dec_fetch_on_left_move2_o
       
  3139  dec_fetch_check_left_move2_o dec_fetch_check_left_move2_b 
       
  3140  dec_fetch_after_left_move2_b dec_fetch_after_write_b 
       
  3141  dec_fetch_after_write_o dec_fetch_next_state
       
  3142 
       
  3143 lemma [simp]:
       
  3144   "\<lbrakk>start_of ly as \<le> a; 
       
  3145     a < start_of ly as + 2 * n; 
       
  3146     (a - start_of ly as) mod 2 = Suc 0; 
       
  3147     inv_locate_b (as, am) ((a - start_of ly as) div 2, aaa, Bk # xs) ires\<rbrakk>
       
  3148      \<Longrightarrow> \<not> Suc a < start_of ly as + 2 * n \<longrightarrow> 
       
  3149                 inv_locate_a (as, am) (n, Bk # aaa, xs) ires"
       
  3150 apply(insert locate_b_2_locate_a[of a ly as n am aaa xs], simp)
       
  3151 done
       
  3152  
       
  3153 lemma [simp]: 
       
  3154   "\<lbrakk>start_of ly as \<le> a; 
       
  3155     a < start_of ly as + 2 * n; 
       
  3156     (a - start_of ly as) mod 2 = Suc 0; 
       
  3157     inv_locate_b (as, am) ((a - start_of ly as) div 2, aaa, []) ires\<rbrakk>
       
  3158    \<Longrightarrow> \<not> Suc a < start_of ly as + 2 * n \<longrightarrow> 
       
  3159                   inv_locate_a (as, am) (n, Bk # aaa, []) ires"
       
  3160 apply(insert locate_b_2_locate_a_B[of a ly as n am aaa], simp)
       
  3161 done
       
  3162 
       
  3163 (*
       
  3164 lemma [simp]: "a\<^bsup>0\<^esup>=[]"
       
  3165 apply(simp add: exponent_def)
       
  3166 done
       
  3167 *)
       
  3168 
       
  3169 lemma exp_ind: "a\<^bsup>Suc b\<^esup> =  a\<^bsup>b\<^esup> @ [a]"
       
  3170 apply(simp only: exponent_def rep_ind)
       
  3171 done
       
  3172 
       
  3173 lemma [simp]:
       
  3174   "inv_locate_b (as, am) (n, l, Oc # r) ires
       
  3175   \<Longrightarrow> dec_first_on_right_moving n (as,  abc_lm_s am n (abc_lm_v am n))
       
  3176                       (Suc (Suc (start_of ly as + 2 * n)), Oc # l, r) ires"
       
  3177 apply(simp only: inv_locate_b.simps 
       
  3178      dec_first_on_right_moving.simps in_middle.simps 
       
  3179      abc_lm_s.simps abc_lm_v.simps)
       
  3180 apply(erule_tac exE)+
       
  3181 apply(erule conjE)+
       
  3182 apply(case_tac "n < length am", simp)
       
  3183 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  3184       rule_tac x = m in exI, simp)
       
  3185 apply(rule_tac x = "Suc ml" in exI, rule_tac conjI, rule_tac [1-2] impI)
       
  3186 prefer 3
       
  3187 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  3188       rule_tac x = m in exI, simp)
       
  3189 apply(subgoal_tac "Suc n - length am = Suc (n - length am)",
       
  3190       simp only:exponent_def rep_ind, simp)
       
  3191 apply(rule_tac x = "Suc ml" in exI, simp_all)
       
  3192 apply(rule_tac [!] x = "mr - 1" in exI, simp_all)
       
  3193 apply(case_tac [!] mr, auto)
       
  3194 done
       
  3195 
       
  3196 lemma [simp]: 
       
  3197   "\<lbrakk>inv_locate_b (as, am) (n, l, r) ires; l \<noteq> []\<rbrakk> \<Longrightarrow> 
       
  3198   \<not> inv_on_left_moving_in_middle_B (as, abc_lm_s am n (abc_lm_v am n)) 
       
  3199     (s, tl l, hd l # r) ires"
       
  3200 apply(auto simp: inv_locate_b.simps 
       
  3201                  inv_on_left_moving_in_middle_B.simps in_middle.simps)
       
  3202 apply(case_tac [!] ml, auto split: if_splits)
       
  3203 done
       
  3204 
       
  3205 lemma [simp]: "inv_locate_b (as, am) (n, l, r) ires \<Longrightarrow> l \<noteq> []"
       
  3206 apply(auto simp: inv_locate_b.simps in_middle.simps split: if_splits)
       
  3207 done
       
  3208 
       
  3209 lemma [simp]: "\<lbrakk>inv_locate_b (as, am) (n, l, Bk # r) ires; n < length am\<rbrakk>
       
  3210      \<Longrightarrow> inv_on_left_moving_norm (as, am) (s, tl l, hd l # Bk # r) ires"
       
  3211 apply(simp only: inv_locate_b.simps inv_on_left_moving_norm.simps 
       
  3212                  in_middle.simps)
       
  3213 apply(erule_tac exE)+
       
  3214 apply(erule_tac conjE)+
       
  3215 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  3216       rule_tac x = m in exI, simp)
       
  3217 apply(rule_tac x = "ml - 1" in exI, auto)
       
  3218 apply(rule_tac [!] x = "Suc mr" in exI)
       
  3219 apply(case_tac [!] mr, auto)
       
  3220 done
       
  3221 
       
  3222 lemma [simp]: "\<lbrakk>inv_locate_b (as, am) (n, l, Bk # r) ires; \<not> n < length am\<rbrakk>
       
  3223     \<Longrightarrow> inv_on_left_moving_norm (as, am @ 
       
  3224         replicate (n - length am) 0 @ [0]) (s, tl l, hd l # Bk # r) ires"
       
  3225 apply(simp only: inv_locate_b.simps inv_on_left_moving_norm.simps 
       
  3226                  in_middle.simps)
       
  3227 apply(erule_tac exE)+
       
  3228 apply(erule_tac conjE)+
       
  3229 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  3230       rule_tac x = m in exI, simp)
       
  3231 apply(subgoal_tac "Suc n - length am = Suc (n - length am)", simp only: rep_ind exponent_def, simp_all)
       
  3232 apply(rule_tac x = "Suc mr" in exI, auto)
       
  3233 done
       
  3234 
       
  3235 lemma inv_locate_b_2_on_left_moving[simp]: 
       
  3236   "\<lbrakk>inv_locate_b (as, am) (n, l, Bk # r) ires\<rbrakk>
       
  3237    \<Longrightarrow> (l = [] \<longrightarrow> inv_on_left_moving (as,  
       
  3238             abc_lm_s am n (abc_lm_v am n)) (s, [], Bk # Bk # r) ires) \<and>
       
  3239        (l \<noteq> [] \<longrightarrow> inv_on_left_moving (as,  
       
  3240             abc_lm_s am n (abc_lm_v am n)) (s, tl l, hd l # Bk # r) ires)"
       
  3241 apply(subgoal_tac "l\<noteq>[]")
       
  3242 apply(subgoal_tac "\<not> inv_on_left_moving_in_middle_B 
       
  3243       (as,  abc_lm_s am n (abc_lm_v am n)) (s, tl l, hd l # Bk # r) ires")
       
  3244 apply(simp add:inv_on_left_moving.simps 
       
  3245           abc_lm_s.simps abc_lm_v.simps split: if_splits, auto)
       
  3246 done
       
  3247 
       
  3248 lemma [simp]: 
       
  3249   "inv_locate_b (as, am) (n, l, []) ires \<Longrightarrow> 
       
  3250                    inv_locate_b (as, am) (n, l, [Bk]) ires" 
       
  3251 apply(auto simp: inv_locate_b.simps in_middle.simps)
       
  3252 apply(rule_tac x = lm1 in exI, rule_tac x = "[]" in exI,
       
  3253       rule_tac x = "Suc (length lm1) - length am" in exI, 
       
  3254       rule_tac x = m in exI, simp)
       
  3255 apply(rule_tac x = ml in exI, rule_tac x = mr in exI)
       
  3256 apply(auto)
       
  3257 done
       
  3258 
       
  3259 lemma nil_2_nil: "<lm::nat list> = [] \<Longrightarrow> lm = []"
       
  3260 apply(auto simp: tape_of_nl_abv)
       
  3261 apply(case_tac lm, simp)
       
  3262 apply(case_tac list, auto simp: tape_of_nat_list.simps)
       
  3263 done
       
  3264 
       
  3265 lemma  inv_locate_b_2_on_left_moving_b[simp]: 
       
  3266    "inv_locate_b (as, am) (n, l, []) ires
       
  3267      \<Longrightarrow> (l = [] \<longrightarrow> inv_on_left_moving (as, 
       
  3268                   abc_lm_s am n (abc_lm_v am n)) (s, [], [Bk]) ires) \<and>
       
  3269          (l \<noteq> [] \<longrightarrow> inv_on_left_moving (as, abc_lm_s am n 
       
  3270                   (abc_lm_v am n)) (s, tl l, [hd l]) ires)"
       
  3271 apply(insert inv_locate_b_2_on_left_moving[of as am n l "[]" ires s])
       
  3272 apply(simp only: inv_on_left_moving.simps, simp)
       
  3273 apply(subgoal_tac "\<not> inv_on_left_moving_in_middle_B 
       
  3274          (as, abc_lm_s am n (abc_lm_v am n)) (s, tl l, [hd l]) ires", simp)
       
  3275 apply(simp only: inv_on_left_moving_norm.simps)
       
  3276 apply(erule_tac exE)+
       
  3277 apply(erule_tac conjE)+
       
  3278 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  3279       rule_tac x = m in exI, rule_tac x = ml in exI, 
       
  3280       rule_tac x = mr in exI, simp)
       
  3281 apply(case_tac mr, simp, simp, case_tac nat, auto intro: nil_2_nil)
       
  3282 done
       
  3283 
       
  3284 lemma [simp]: 
       
  3285  "\<lbrakk>dec_first_on_right_moving n (as, am) (s, aaa, Oc # xs) ires\<rbrakk>
       
  3286    \<Longrightarrow> dec_first_on_right_moving n (as, am) (s', Oc # aaa, xs) ires"
       
  3287 apply(simp only: dec_first_on_right_moving.simps)
       
  3288 apply(erule exE)+
       
  3289 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  3290       rule_tac x = m in exI, simp)
       
  3291 apply(rule_tac x = "Suc ml" in exI, 
       
  3292       rule_tac x = "mr - 1" in exI, auto)
       
  3293 apply(case_tac [!] mr, auto)
       
  3294 done
       
  3295 
       
  3296 lemma [simp]: 
       
  3297   "dec_first_on_right_moving n (as, am) (s, l, Bk # xs) ires \<Longrightarrow> l \<noteq> []"
       
  3298 apply(auto simp: dec_first_on_right_moving.simps split: if_splits)
       
  3299 done
       
  3300 
       
  3301 lemma [elim]: 
       
  3302   "\<lbrakk>\<not> length lm1 < length am; 
       
  3303     am @ replicate (length lm1 - length am) 0 @ [0::nat] = 
       
  3304                                                 lm1 @ m # lm2;
       
  3305     0 < m\<rbrakk>
       
  3306    \<Longrightarrow> RR"
       
  3307 apply(subgoal_tac "lm2 = []", simp)
       
  3308 apply(drule_tac length_equal, simp)
       
  3309 done
       
  3310 
       
  3311 lemma [simp]: 
       
  3312  "\<lbrakk>dec_first_on_right_moving n (as, 
       
  3313                    abc_lm_s am n (abc_lm_v am n)) (s, l, Bk # xs) ires\<rbrakk>
       
  3314 \<Longrightarrow> dec_after_clear (as, abc_lm_s am n 
       
  3315                  (abc_lm_v am n - Suc 0)) (s', tl l, hd l # Bk # xs) ires"
       
  3316 apply(simp only: dec_first_on_right_moving.simps 
       
  3317                  dec_after_clear.simps abc_lm_s.simps abc_lm_v.simps)
       
  3318 apply(erule_tac exE)+
       
  3319 apply(case_tac "n < length am")
       
  3320 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  3321       rule_tac x = "m - 1" in exI, auto simp: )
       
  3322 apply(case_tac [!] mr, auto)
       
  3323 done
       
  3324 
       
  3325 lemma [simp]: 
       
  3326  "\<lbrakk>dec_first_on_right_moving n (as, 
       
  3327                    abc_lm_s am n (abc_lm_v am n)) (s, l, []) ires\<rbrakk>
       
  3328 \<Longrightarrow> (l = [] \<longrightarrow> dec_after_clear (as, 
       
  3329              abc_lm_s am n (abc_lm_v am n - Suc 0)) (s', [], [Bk]) ires) \<and>
       
  3330     (l \<noteq> [] \<longrightarrow> dec_after_clear (as, abc_lm_s am n 
       
  3331                       (abc_lm_v am n - Suc 0)) (s', tl l, [hd l]) ires)"
       
  3332 apply(subgoal_tac "l \<noteq> []", 
       
  3333       simp only: dec_first_on_right_moving.simps 
       
  3334                  dec_after_clear.simps abc_lm_s.simps abc_lm_v.simps)
       
  3335 apply(erule_tac exE)+
       
  3336 apply(case_tac "n < length am", simp)
       
  3337 apply(rule_tac x = lm1 in exI, rule_tac x = "m - 1" in exI, auto)
       
  3338 apply(case_tac [1-2] mr, auto)
       
  3339 apply(case_tac [1-2] m, auto simp: dec_first_on_right_moving.simps split: if_splits)
       
  3340 done
       
  3341 
       
  3342 lemma [simp]: "\<lbrakk>dec_after_clear (as, am) (s, l, Oc # r) ires\<rbrakk>
       
  3343                 \<Longrightarrow> dec_after_clear (as, am) (s', l, Bk # r) ires"
       
  3344 apply(auto simp: dec_after_clear.simps)
       
  3345 done
       
  3346 
       
  3347 lemma [simp]: "\<lbrakk>dec_after_clear (as, am) (s, l, Bk # r) ires\<rbrakk>
       
  3348                 \<Longrightarrow> dec_right_move (as, am) (s', Bk # l, r) ires"
       
  3349 apply(auto simp: dec_after_clear.simps dec_right_move.simps split: if_splits)
       
  3350 done
       
  3351 
       
  3352 lemma [simp]: "\<lbrakk>dec_after_clear (as, am) (s, l, []) ires\<rbrakk>
       
  3353              \<Longrightarrow> dec_right_move (as, am) (s', Bk # l, []) ires"
       
  3354 apply(auto simp: dec_after_clear.simps dec_right_move.simps )
       
  3355 done
       
  3356 
       
  3357 lemma [simp]: "\<exists>rn. a::block\<^bsup>rn\<^esup> = []"
       
  3358 apply(rule_tac x = 0 in exI, simp)
       
  3359 done
       
  3360 
       
  3361 lemma [simp]: "\<lbrakk>dec_after_clear (as, am) (s, l, []) ires\<rbrakk>
       
  3362              \<Longrightarrow> dec_right_move (as, am) (s', Bk # l, [Bk]) ires"
       
  3363 apply(auto simp: dec_after_clear.simps dec_right_move.simps split: if_splits)
       
  3364 done
       
  3365 
       
  3366 lemma [simp]:"dec_right_move (as, am) (s, l, Oc # r) ires = False"
       
  3367 apply(auto simp: dec_right_move.simps)
       
  3368 done
       
  3369               
       
  3370 lemma dec_right_move_2_check_right_move[simp]:
       
  3371      "\<lbrakk>dec_right_move (as, am) (s, l, Bk # r) ires\<rbrakk>
       
  3372       \<Longrightarrow> dec_check_right_move (as, am) (s', Bk # l, r) ires"
       
  3373 apply(auto simp: dec_right_move.simps dec_check_right_move.simps split: if_splits)
       
  3374 done
       
  3375 
       
  3376 lemma [simp]: 
       
  3377  "dec_right_move (as, am) (s, l, []) ires= 
       
  3378   dec_right_move (as, am) (s, l, [Bk]) ires"
       
  3379 apply(simp add: dec_right_move.simps)
       
  3380 apply(rule_tac iffI)
       
  3381 apply(erule_tac [!] exE)+
       
  3382 apply(erule_tac [2] exE)
       
  3383 apply(rule_tac [!] x = lm1 in exI, rule_tac x = "[]" in exI, 
       
  3384       rule_tac [!] x = m in exI, auto)
       
  3385 apply(auto intro: nil_2_nil)
       
  3386 done
       
  3387 
       
  3388 lemma [simp]: "\<lbrakk>dec_right_move (as, am) (s, l, []) ires\<rbrakk>
       
  3389              \<Longrightarrow> dec_check_right_move (as, am) (s, Bk # l, []) ires"
       
  3390 apply(insert dec_right_move_2_check_right_move[of as am s l "[]" s'], 
       
  3391       simp)
       
  3392 done
       
  3393 
       
  3394 lemma [simp]: "dec_check_right_move (as, am) (s, l, r) ires\<Longrightarrow> l \<noteq> []"
       
  3395 apply(auto simp: dec_check_right_move.simps split: if_splits)
       
  3396 done
       
  3397  
       
  3398 lemma [simp]: "\<lbrakk>dec_check_right_move (as, am) (s, l, Oc # r) ires\<rbrakk>
       
  3399              \<Longrightarrow> dec_after_write (as, am) (s', tl l, hd l # Oc # r) ires"
       
  3400 apply(auto simp: dec_check_right_move.simps dec_after_write.simps)
       
  3401 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  3402       rule_tac x = m in exI, auto)
       
  3403 done
       
  3404 
       
  3405 lemma [simp]: "\<lbrakk>dec_check_right_move (as, am) (s, l, Bk # r) ires\<rbrakk>
       
  3406                 \<Longrightarrow> dec_left_move (as, am) (s', tl l, hd l # Bk # r) ires"
       
  3407 apply(auto simp: dec_check_right_move.simps 
       
  3408                  dec_left_move.simps inv_after_move.simps)
       
  3409 apply(rule_tac x = lm1 in exI, rule_tac x = m in exI, auto)
       
  3410 apply(auto intro: BkCons_nil nil_2_nil dest: BkCons_nil)
       
  3411 apply(rule_tac x = "Suc rn" in exI)
       
  3412 apply(auto intro: BkCons_nil nil_2_nil dest: BkCons_nil)
       
  3413 done
       
  3414 
       
  3415 lemma [simp]: "\<lbrakk>dec_check_right_move (as, am) (s, l, []) ires\<rbrakk>
       
  3416              \<Longrightarrow> dec_left_move (as, am) (s', tl l, [hd l]) ires"
       
  3417 apply(auto simp: dec_check_right_move.simps 
       
  3418                  dec_left_move.simps inv_after_move.simps)
       
  3419 apply(rule_tac x = lm1 in exI, rule_tac x = m in exI, auto)
       
  3420 apply(auto intro: BkCons_nil nil_2_nil dest: BkCons_nil)
       
  3421 done
       
  3422 
       
  3423 lemma [simp]: "dec_left_move (as, am) (s, aaa, Oc # xs) ires = False"
       
  3424 apply(auto simp: dec_left_move.simps inv_after_move.simps)
       
  3425 apply(case_tac [!] rn, auto)
       
  3426 done
       
  3427 
       
  3428 lemma [simp]: "dec_left_move (as, am) (s, l, r) ires
       
  3429              \<Longrightarrow> l \<noteq> []"
       
  3430 apply(auto simp: dec_left_move.simps split: if_splits)
       
  3431 done
       
  3432 
       
  3433 lemma tape_of_nl_abv_cons_ex[simp]: 
       
  3434    "\<exists>lna. Oc # Oc\<^bsup>m\<^esup> @ Bk # <rev lm1> @ Bk\<^bsup>ln\<^esup> = <m # rev lm1> @ Bk\<^bsup>lna\<^esup>"
       
  3435 apply(case_tac "lm1=[]", auto simp: tape_of_nl_abv 
       
  3436                                     tape_of_nat_list.simps)
       
  3437 apply(rule_tac x = "ln" in exI, simp)
       
  3438 apply(simp add:  tape_of_nat_list_cons exponent_def)
       
  3439 done
       
  3440 
       
  3441 (*
       
  3442 lemma [simp]: "inv_on_left_moving_in_middle_B (as, lm1 @ [m])
       
  3443                  (s', Oc # Oc\<^bsup>m\<^esup> @ Bk # <rev lm1> @ Bk\<^bsup>ln\<^esup>, Bk # Bk\<^bsup>rn\<^esup>) ires"
       
  3444 apply(simp only: inv_on_left_moving_in_middle_B.simps)
       
  3445 apply(rule_tac x = "lm1 @ [m]" in exI, rule_tac x = "[]" in exI, auto)
       
  3446 done    
       
  3447 *)
       
  3448 lemma [simp]: "inv_on_left_moving_in_middle_B (as, [m])
       
  3449   (s', Oc # Oc\<^bsup>m\<^esup> @ Bk # Bk # ires, Bk # Bk\<^bsup>rn\<^esup>) ires"
       
  3450 apply(simp add: inv_on_left_moving_in_middle_B.simps)
       
  3451 apply(rule_tac x = "[m]" in exI, simp, auto simp: tape_of_nat_def)
       
  3452 done
       
  3453 
       
  3454 lemma [simp]: "inv_on_left_moving_in_middle_B (as, [m])
       
  3455   (s', Oc # Oc\<^bsup>m\<^esup> @ Bk # Bk # ires, [Bk]) ires"
       
  3456 apply(simp add: inv_on_left_moving_in_middle_B.simps)
       
  3457 apply(rule_tac x = "[m]" in exI, simp, auto simp: tape_of_nat_def)
       
  3458 done
       
  3459 
       
  3460 lemma [simp]: "lm1 \<noteq> [] \<Longrightarrow> 
       
  3461   inv_on_left_moving_in_middle_B (as, lm1 @ [m]) (s', 
       
  3462   Oc # Oc\<^bsup>m\<^esup> @ Bk # <rev lm1> @ Bk # Bk # ires, Bk # Bk\<^bsup>rn\<^esup>) ires"
       
  3463 apply(simp only: inv_on_left_moving_in_middle_B.simps)
       
  3464 apply(rule_tac x = "lm1 @ [m ]" in exI, rule_tac x = "[]" in exI, simp, auto)
       
  3465 done
       
  3466 
       
  3467 lemma [simp]: "lm1 \<noteq> [] \<Longrightarrow> 
       
  3468   inv_on_left_moving_in_middle_B (as, lm1 @ [m]) (s', 
       
  3469   Oc # Oc\<^bsup>m\<^esup> @ Bk # <rev lm1> @ Bk # Bk # ires, [Bk]) ires"
       
  3470 apply(simp only: inv_on_left_moving_in_middle_B.simps)
       
  3471 apply(rule_tac x = "lm1 @ [m ]" in exI, rule_tac x = "[]" in exI, simp, auto)
       
  3472 done
       
  3473 
       
  3474 lemma [simp]: "dec_left_move (as, am) (s, l, Bk # r) ires
       
  3475        \<Longrightarrow> inv_on_left_moving (as, am) (s', tl l, hd l # Bk # r) ires"
       
  3476 apply(auto simp: dec_left_move.simps inv_on_left_moving.simps split: if_splits)
       
  3477 done
       
  3478 
       
  3479 (*
       
  3480 lemma [simp]: "inv_on_left_moving_in_middle_B (as, lm1 @ [m]) 
       
  3481                         (s', Oc # Oc\<^bsup>m\<^esup> @ Bk # <rev lm1> @ Bk\<^bsup>ln\<^esup>, [Bk])  ires"
       
  3482 apply(auto simp: inv_on_left_moving_in_middle_B.simps)
       
  3483 apply(rule_tac x = "lm1 @ [m]" in exI, rule_tac x = "[]" in exI, auto)
       
  3484 done
       
  3485 *)
       
  3486 
       
  3487 lemma [simp]: "dec_left_move (as, am) (s, l, []) ires
       
  3488              \<Longrightarrow> inv_on_left_moving (as, am) (s', tl l, [hd l]) ires"
       
  3489 apply(auto simp: dec_left_move.simps inv_on_left_moving.simps split: if_splits)
       
  3490 done
       
  3491 
       
  3492 lemma [simp]: "dec_after_write (as, am) (s, l, Oc # r) ires
       
  3493        \<Longrightarrow> dec_on_right_moving (as, am) (s', Oc # l, r) ires"
       
  3494 apply(auto simp: dec_after_write.simps dec_on_right_moving.simps)
       
  3495 apply(rule_tac x = "lm1 @ [m]" in exI, rule_tac x = "tl lm2" in exI, 
       
  3496       rule_tac x = "hd lm2" in exI, simp)
       
  3497 apply(rule_tac x = "Suc 0" in exI,rule_tac x =  "Suc (hd lm2)" in exI)
       
  3498 apply(case_tac lm2, simp, simp)
       
  3499 apply(case_tac "list = []", 
       
  3500       auto simp: tape_of_nl_abv tape_of_nat_list.simps split: if_splits )
       
  3501 apply(case_tac rn, auto)
       
  3502 apply(case_tac "rev lm1", simp, simp add: tape_of_nat_list.simps)
       
  3503 apply(case_tac rn, auto)
       
  3504 apply(case_tac list, simp_all add: tape_of_nat_list.simps, auto)
       
  3505 apply(case_tac "rev lm1", simp, simp add: tape_of_nat_list.simps)
       
  3506 apply(case_tac list, simp_all add: tape_of_nat_list.simps, auto)
       
  3507 done
       
  3508 
       
  3509 lemma [simp]: "dec_after_write (as, am) (s, l, Bk # r) ires
       
  3510        \<Longrightarrow> dec_after_write (as, am) (s', l, Oc # r) ires"
       
  3511 apply(auto simp: dec_after_write.simps)
       
  3512 done
       
  3513 
       
  3514 lemma [simp]: "dec_after_write (as, am) (s, aaa, []) ires
       
  3515              \<Longrightarrow> dec_after_write (as, am) (s', aaa, [Oc]) ires"
       
  3516 apply(auto simp: dec_after_write.simps)
       
  3517 done
       
  3518 
       
  3519 lemma [simp]: "dec_on_right_moving (as, am) (s, l, Oc # r) ires
       
  3520        \<Longrightarrow> dec_on_right_moving (as, am) (s', Oc # l, r) ires"
       
  3521 apply(simp only: dec_on_right_moving.simps)
       
  3522 apply(erule_tac exE)+
       
  3523 apply(erule conjE)+
       
  3524 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI,
       
  3525       rule_tac x = "m" in exI, rule_tac x = "Suc ml" in exI, 
       
  3526       rule_tac x = "mr - 1" in exI, simp)
       
  3527 apply(case_tac mr, auto)
       
  3528 done
       
  3529 
       
  3530 lemma [simp]: "dec_on_right_moving (as, am) (s, l, r) ires\<Longrightarrow>  l \<noteq> []"
       
  3531 apply(auto simp: dec_on_right_moving.simps split: if_splits)
       
  3532 done
       
  3533 
       
  3534 lemma [simp]: "dec_on_right_moving (as, am) (s, l, Bk # r) ires
       
  3535       \<Longrightarrow>  dec_after_clear (as, am) (s', tl l, hd l # Bk # r) ires"
       
  3536 apply(auto simp: dec_on_right_moving.simps dec_after_clear.simps)
       
  3537 apply(case_tac [!] mr, auto split: if_splits)
       
  3538 done
       
  3539 
       
  3540 lemma [simp]: "dec_on_right_moving (as, am) (s, l, []) ires
       
  3541              \<Longrightarrow> dec_after_clear (as, am) (s', tl l, [hd l]) ires"
       
  3542 apply(auto simp: dec_on_right_moving.simps dec_after_clear.simps)
       
  3543 apply(case_tac mr, simp_all split: if_splits)
       
  3544 apply(rule_tac x = lm1 in exI, simp)
       
  3545 done
       
  3546 
       
  3547 lemma start_of_le: "a < b \<Longrightarrow> start_of ly a \<le> start_of ly b"
       
  3548 proof(induct b arbitrary: a, simp, case_tac "a = b", simp)
       
  3549   fix b a
       
  3550   show "start_of ly b \<le> start_of ly (Suc b)"
       
  3551     apply(case_tac "b::nat", 
       
  3552           simp add: start_of.simps, simp add: start_of.simps)
       
  3553     done
       
  3554 next
       
  3555   fix b a
       
  3556   assume h1: "\<And>a. a < b \<Longrightarrow> start_of ly a \<le> start_of ly b" 
       
  3557              "a < Suc b" "a \<noteq> b"
       
  3558   hence "a < b"
       
  3559     by(simp)
       
  3560   from h1 and this have h2: "start_of ly a \<le> start_of ly b"
       
  3561     by(drule_tac h1, simp)
       
  3562   from h2 show "start_of ly a \<le> start_of ly (Suc b)"
       
  3563   proof -
       
  3564     have "start_of ly b \<le> start_of ly (Suc b)"
       
  3565       apply(case_tac "b::nat", 
       
  3566             simp add: start_of.simps, simp add: start_of.simps)
       
  3567       done
       
  3568     from h2 and this show "start_of ly a \<le> start_of ly (Suc b)"
       
  3569       by simp
       
  3570   qed
       
  3571 qed
       
  3572 
       
  3573 lemma start_of_dec_length[simp]: 
       
  3574   "\<lbrakk>abc_fetch a aprog = Some (Dec n e)\<rbrakk> \<Longrightarrow> 
       
  3575     start_of (layout_of aprog) (Suc a)
       
  3576           = start_of (layout_of aprog) a + 2*n + 16"
       
  3577 apply(case_tac a, auto simp: abc_fetch.simps start_of.simps 
       
  3578                              layout_of.simps length_of.simps 
       
  3579                        split: if_splits)
       
  3580 done
       
  3581 
       
  3582 lemma start_of_ge: 
       
  3583  "\<lbrakk>abc_fetch a aprog = Some (Dec n e); a < e\<rbrakk> \<Longrightarrow>
       
  3584   start_of (layout_of aprog) e > 
       
  3585               start_of (layout_of aprog) a + 2*n + 15"
       
  3586 apply(case_tac "e = Suc a", 
       
  3587       simp add: start_of.simps abc_fetch.simps layout_of.simps 
       
  3588                 length_of.simps split: if_splits)
       
  3589 apply(subgoal_tac "Suc a < e", drule_tac a = "Suc a" 
       
  3590              and ly = "layout_of aprog" in start_of_le)
       
  3591 apply(subgoal_tac "start_of (layout_of aprog) (Suc a)
       
  3592          = start_of (layout_of aprog) a + 2*n + 16", simp)
       
  3593 apply(rule_tac start_of_dec_length, simp)
       
  3594 apply(arith)
       
  3595 done
       
  3596 
       
  3597 lemma starte_not_equal[simp]: 
       
  3598  "\<lbrakk>abc_fetch as aprog = Some (Dec n e); ly = layout_of aprog\<rbrakk>
       
  3599    \<Longrightarrow> (start_of ly e \<noteq> Suc (Suc (start_of ly as + 2 * n)) \<and>  
       
  3600         start_of ly e \<noteq> start_of ly as + 2 * n + 3 \<and> 
       
  3601         start_of ly e \<noteq> start_of ly as + 2 * n + 4 \<and>
       
  3602         start_of ly e \<noteq> start_of ly as + 2 * n + 5 \<and> 
       
  3603         start_of ly e \<noteq> start_of ly as + 2 * n + 6 \<and> 
       
  3604         start_of ly e \<noteq> start_of ly as + 2 * n + 7 \<and>
       
  3605         start_of ly e \<noteq> start_of ly as + 2 * n + 8 \<and> 
       
  3606         start_of ly e \<noteq> start_of ly as + 2 * n + 9 \<and> 
       
  3607         start_of ly e \<noteq> start_of ly as + 2 * n + 10 \<and>
       
  3608         start_of ly e \<noteq> start_of ly as + 2 * n + 11 \<and> 
       
  3609         start_of ly e \<noteq> start_of ly as + 2 * n + 12 \<and> 
       
  3610         start_of ly e \<noteq> start_of ly as + 2 * n + 13 \<and>
       
  3611         start_of ly e \<noteq> start_of ly as + 2 * n + 14 \<and> 
       
  3612         start_of ly e \<noteq> start_of ly as + 2 * n + 15)" 
       
  3613 apply(case_tac "e = as", simp) 
       
  3614 apply(case_tac "e < as")
       
  3615 apply(drule_tac a = e and b = as and ly = ly in start_of_le, simp)
       
  3616 apply(drule_tac a = as and e = e in start_of_ge, simp, simp)
       
  3617 done
       
  3618 
       
  3619 lemma [simp]: "\<lbrakk>abc_fetch as aprog = Some (Dec n e); ly = layout_of aprog\<rbrakk>
       
  3620       \<Longrightarrow> (Suc (Suc (start_of ly as + 2 * n)) \<noteq> start_of ly e \<and> 
       
  3621           start_of ly as + 2 * n + 3 \<noteq> start_of ly e \<and> 
       
  3622           start_of ly as + 2 * n + 4 \<noteq> start_of ly e \<and>
       
  3623           start_of ly as + 2 * n + 5 \<noteq>start_of ly e \<and> 
       
  3624           start_of ly as + 2 * n + 6 \<noteq> start_of ly e \<and>
       
  3625           start_of ly as + 2 * n + 7 \<noteq> start_of ly e \<and> 
       
  3626           start_of ly as + 2 * n + 8 \<noteq> start_of ly e \<and> 
       
  3627           start_of ly as + 2 * n + 9 \<noteq> start_of ly e \<and> 
       
  3628           start_of ly as + 2 * n + 10 \<noteq> start_of ly e \<and>
       
  3629           start_of ly as + 2 * n + 11 \<noteq> start_of ly e \<and> 
       
  3630           start_of ly as + 2 * n + 12 \<noteq> start_of ly e \<and> 
       
  3631           start_of ly as + 2 * n + 13 \<noteq> start_of ly e \<and> 
       
  3632           start_of ly as + 2 * n + 14 \<noteq> start_of ly e \<and> 
       
  3633           start_of ly as + 2 * n + 15 \<noteq> start_of ly e)"
       
  3634 apply(insert starte_not_equal[of as aprog n e ly], 
       
  3635                             simp del: starte_not_equal)
       
  3636 apply(erule_tac conjE)+
       
  3637 apply(rule_tac conjI, simp del: starte_not_equal)+
       
  3638 apply(rule not_sym, simp)
       
  3639 done
       
  3640 
       
  3641 lemma [simp]: "start_of (layout_of aprog) as > 0 \<Longrightarrow> 
       
  3642   fetch (ci (layout_of aprog) (start_of (layout_of aprog) as)
       
  3643                        (Dec n as)) (Suc 0) Oc =
       
  3644  (R, Suc (start_of (layout_of aprog) as))"
       
  3645 
       
  3646 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  3647                  nth_of.simps tshift.simps nth_append 
       
  3648                  Suc_pre tdec_b_def)
       
  3649 apply(insert findnth_nth[of 0 n "Suc 0"], simp)
       
  3650 apply(simp add: findnth.simps)
       
  3651 done
       
  3652 
       
  3653 lemma start_of_inj[simp]: 
       
  3654   "\<lbrakk>abc_fetch as aprog = Some (Dec n e); e \<noteq> as; ly = layout_of aprog\<rbrakk>
       
  3655    \<Longrightarrow> start_of ly as \<noteq> start_of ly e"
       
  3656 apply(case_tac "e < as")
       
  3657 apply(case_tac "as", simp, simp)
       
  3658 apply(case_tac "e = nat", simp add: start_of.simps 
       
  3659                                     layout_of.simps length_of.simps)
       
  3660 apply(subgoal_tac "e < length aprog", simp add: length_of.simps 
       
  3661                                          split: abc_inst.splits)
       
  3662 apply(simp add: abc_fetch.simps split: if_splits)
       
  3663 apply(subgoal_tac "e < nat", drule_tac a = e and b = nat 
       
  3664                                    and ly =ly in start_of_le, simp)
       
  3665 apply(subgoal_tac "start_of ly nat < start_of ly (Suc nat)", 
       
  3666           simp, simp add: start_of.simps layout_of.simps)
       
  3667 apply(subgoal_tac "nat < length aprog", simp)
       
  3668 apply(case_tac "aprog ! nat", auto simp: length_of.simps)
       
  3669 apply(simp add: abc_fetch.simps split: if_splits)
       
  3670 apply(subgoal_tac "e > as", drule_tac start_of_ge, auto)
       
  3671 done
       
  3672 
       
  3673 lemma [simp]: "\<lbrakk>abc_fetch as aprog = Some (Dec n e); e < as\<rbrakk>
       
  3674     \<Longrightarrow> Suc (start_of (layout_of aprog) e) - 
       
  3675                                start_of (layout_of aprog) as = 0"
       
  3676 apply(frule_tac ly = "layout_of aprog" in start_of_le, simp)
       
  3677 apply(subgoal_tac "start_of (layout_of aprog) as \<noteq> 
       
  3678                             start_of (layout_of aprog) e", arith)
       
  3679 apply(rule start_of_inj, auto)
       
  3680 done
       
  3681 
       
  3682 lemma [simp]:
       
  3683    "\<lbrakk>abc_fetch as aprog = Some (Dec n e); 
       
  3684      0 < start_of (layout_of aprog) as\<rbrakk>
       
  3685  \<Longrightarrow> (fetch (ci (layout_of aprog) (start_of (layout_of aprog) as) 
       
  3686      (Dec n e)) (Suc (start_of (layout_of aprog) e) - 
       
  3687                  start_of (layout_of aprog) as) Oc)
       
  3688     = (if e = as then (R, start_of (layout_of aprog) as + 1)
       
  3689                  else (Nop, 0))"
       
  3690 apply(auto split: if_splits)
       
  3691 apply(case_tac "e < as", simp add: fetch.simps)
       
  3692 apply(subgoal_tac " e > as")
       
  3693 apply(drule start_of_ge, simp,
       
  3694       auto simp: fetch.simps ci_length nth_of.simps)
       
  3695 apply(subgoal_tac 
       
  3696  "length (ci (layout_of aprog) (start_of (layout_of aprog) as) 
       
  3697                         (Dec n e)) div 2= length_of (Dec n e)")
       
  3698 defer
       
  3699 apply(simp add: ci_length)
       
  3700 apply(subgoal_tac 
       
  3701  "length (ci (layout_of aprog) (start_of (layout_of aprog) as)
       
  3702                   (Dec n e)) mod 2 = 0", auto simp: length_of.simps)
       
  3703 done
       
  3704 
       
  3705 lemma [simp]:
       
  3706     "start_of (layout_of aprog) as > 0 \<Longrightarrow> 
       
  3707  fetch (ci (layout_of aprog) (start_of (layout_of aprog) as) 
       
  3708                                           (Dec n as)) (Suc 0)  Bk 
       
  3709       = (W1, start_of (layout_of aprog) as)"
       
  3710 apply(auto simp: ci.simps findnth.simps fetch.simps nth_of.simps 
       
  3711                  tshift.simps nth_append Suc_pre tdec_b_def)
       
  3712 apply(insert findnth_nth[of 0 n "0"], simp)
       
  3713 apply(simp add: findnth.simps)
       
  3714 done
       
  3715 
       
  3716 lemma [simp]: 
       
  3717  "\<lbrakk>abc_fetch as aprog = Some (Dec n e); 
       
  3718    0 < start_of (layout_of aprog) as\<rbrakk>
       
  3719 \<Longrightarrow> (fetch (ci (layout_of aprog) (start_of (layout_of aprog) as)
       
  3720          (Dec n e)) (Suc (start_of (layout_of aprog) e) - 
       
  3721               start_of (layout_of aprog) as)  Bk)
       
  3722    = (if e = as then (W1, start_of (layout_of aprog) as)
       
  3723                   else (Nop, 0))"
       
  3724 apply(auto split: if_splits)
       
  3725 apply(case_tac "e < as", simp add: fetch.simps)
       
  3726 apply(subgoal_tac " e > as")
       
  3727 apply(drule start_of_ge, simp, auto simp: fetch.simps 
       
  3728                                           ci_length nth_of.simps)
       
  3729 apply(subgoal_tac 
       
  3730  "length (ci (layout_of aprog) (start_of (layout_of aprog) as) 
       
  3731                             (Dec n e)) div 2= length_of (Dec n e)")
       
  3732 defer
       
  3733 apply(simp add: ci_length)
       
  3734 apply(subgoal_tac 
       
  3735  "length (ci (layout_of aprog) (start_of (layout_of aprog) as) 
       
  3736                    (Dec n e)) mod 2 = 0", auto simp: length_of.simps)
       
  3737 apply(simp add: ci.simps tshift.simps tdec_b_def)
       
  3738 done
       
  3739 
       
  3740 lemma [simp]: 
       
  3741  "inv_stop (as, abc_lm_s am n (abc_lm_v am n)) (s, l, r) ires \<Longrightarrow> l \<noteq> []"
       
  3742 apply(auto simp: inv_stop.simps)
       
  3743 done
       
  3744 
       
  3745 lemma [simp]: 
       
  3746  "\<lbrakk>abc_fetch as aprog = Some (Dec n e); e \<noteq> as; ly = layout_of aprog\<rbrakk>
       
  3747   \<Longrightarrow> (\<not> (start_of ly as \<le> start_of ly e \<and> 
       
  3748       start_of ly e < start_of ly as + 2 * n))
       
  3749     \<and> start_of ly e \<noteq> start_of ly as + 2*n \<and> 
       
  3750       start_of ly e \<noteq> Suc (start_of ly as + 2*n) "
       
  3751 apply(case_tac "e < as")
       
  3752 apply(drule_tac ly = ly in start_of_le, simp)
       
  3753 apply(case_tac n, simp, drule start_of_inj, simp, simp, simp, simp)
       
  3754 apply(drule_tac start_of_ge, simp, simp)
       
  3755 done
       
  3756 
       
  3757 lemma [simp]: 
       
  3758    "\<lbrakk>abc_fetch as aprog = Some (Dec n e); start_of ly as \<le> s; 
       
  3759      s < start_of ly as + 2 * n; ly = layout_of aprog\<rbrakk>
       
  3760      \<Longrightarrow> Suc s \<noteq> start_of ly e "
       
  3761 apply(case_tac "e = as", simp)
       
  3762 apply(case_tac "e < as")
       
  3763 apply(drule_tac a = e and b = as and ly = ly in start_of_le, simp)
       
  3764 apply(drule_tac start_of_ge, auto)
       
  3765 done
       
  3766 
       
  3767 lemma [simp]: "\<lbrakk>abc_fetch as aprog = Some (Dec n e); 
       
  3768                 ly = layout_of aprog\<rbrakk>
       
  3769          \<Longrightarrow> Suc (start_of ly as + 2 * n) \<noteq> start_of ly e"
       
  3770 apply(case_tac "e = as", simp)
       
  3771 apply(case_tac "e < as")
       
  3772 apply(drule_tac a = e and b = as and ly = ly in start_of_le, simp)
       
  3773 apply(drule_tac start_of_ge, auto)
       
  3774 done
       
  3775 
       
  3776 lemma dec_false_1[simp]:
       
  3777  "\<lbrakk>abc_lm_v am n = 0; inv_locate_b (as, am) (n, aaa, Oc # xs) ires\<rbrakk>
       
  3778   \<Longrightarrow> False"
       
  3779 apply(auto simp: inv_locate_b.simps in_middle.simps exponent_def)
       
  3780 apply(case_tac "length lm1 \<ge> length am", auto)
       
  3781 apply(subgoal_tac "lm2 = []", simp, subgoal_tac "m = 0", simp)
       
  3782 apply(case_tac mr, auto simp: )
       
  3783 apply(subgoal_tac "Suc (length lm1) - length am = 
       
  3784                    Suc (length lm1 - length am)", 
       
  3785       simp add: rep_ind del: replicate.simps, simp)
       
  3786 apply(drule_tac xs = "am @ replicate (Suc (length lm1) - length am) 0"
       
  3787                 and ys = "lm1 @ m # lm2" in length_equal, simp)
       
  3788 apply(case_tac mr, auto simp: abc_lm_v.simps)
       
  3789 apply(case_tac "mr = 0", simp_all add:  exponent_def split: if_splits)
       
  3790 apply(subgoal_tac "Suc (length lm1) - length am = 
       
  3791                        Suc (length lm1 - length am)", 
       
  3792       simp add: rep_ind del: replicate.simps, simp)
       
  3793 done
       
  3794 
       
  3795 lemma [simp]: 
       
  3796  "\<lbrakk>inv_locate_b (as, am) (n, aaa, Bk # xs) ires; 
       
  3797    abc_lm_v am n = 0\<rbrakk>
       
  3798    \<Longrightarrow> inv_on_left_moving (as, abc_lm_s am n 0) 
       
  3799                          (s, tl aaa, hd aaa # Bk # xs) ires" 
       
  3800 apply(insert inv_locate_b_2_on_left_moving[of as am n aaa xs ires s], simp)
       
  3801 done
       
  3802 
       
  3803 lemma [simp]:
       
  3804  "\<lbrakk>abc_lm_v am n = 0; inv_locate_b (as, am) (n, aaa, []) ires\<rbrakk>
       
  3805    \<Longrightarrow> inv_on_left_moving (as, abc_lm_s am n 0) (s, tl aaa, [hd aaa]) ires"
       
  3806 apply(insert inv_locate_b_2_on_left_moving_b[of as am n aaa ires s], simp)
       
  3807 done
       
  3808 
       
  3809 lemma [simp]: "\<lbrakk>am ! n = (0::nat); n < length am\<rbrakk> \<Longrightarrow> am[n := 0] = am"
       
  3810 apply(simp add: list_update_same_conv)
       
  3811 done
       
  3812 
       
  3813 lemma [simp]: "\<lbrakk>abc_lm_v am n = 0; 
       
  3814                 inv_locate_b (as, abc_lm_s am n 0) (n, Oc # aaa, xs) ires\<rbrakk>
       
  3815      \<Longrightarrow> inv_locate_b (as, am) (n, Oc # aaa, xs) ires"
       
  3816 apply(simp only: inv_locate_b.simps in_middle.simps abc_lm_s.simps 
       
  3817                  abc_lm_v.simps)
       
  3818 apply(erule_tac exE)+
       
  3819 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, simp)
       
  3820 apply(case_tac "n < length am", simp_all)
       
  3821 apply(erule_tac conjE)+
       
  3822 apply(rule_tac x = tn in exI, rule_tac x = m in exI, simp)
       
  3823 apply(rule_tac x = ml in exI, rule_tac x = mr in exI, simp)
       
  3824 defer
       
  3825 apply(rule_tac x = "Suc n - length am" in exI, rule_tac x = m in exI)
       
  3826 apply(subgoal_tac "Suc n - length am = Suc (n - length am)")
       
  3827 apply(simp add: exponent_def rep_ind del: replicate.simps, auto)
       
  3828 done
       
  3829 
       
  3830 lemma  [intro]: "\<lbrakk>abc_lm_v (a # list) 0 = 0\<rbrakk> \<Longrightarrow> a = 0"
       
  3831 apply(simp add: abc_lm_v.simps split: if_splits)
       
  3832 done
       
  3833 
       
  3834 lemma [simp]: 
       
  3835  "inv_stop (as, abc_lm_s am n 0) 
       
  3836           (start_of (layout_of aprog) e, aaa, Oc # xs) ires
       
  3837   \<Longrightarrow> inv_locate_a (as, abc_lm_s am n 0) (0, aaa, Oc # xs) ires"
       
  3838 apply(simp add: inv_locate_a.simps)
       
  3839 apply(rule disjI1)
       
  3840 apply(auto simp: inv_stop.simps at_begin_norm.simps)
       
  3841 done
       
  3842 
       
  3843 lemma [simp]: 
       
  3844  "\<lbrakk>abc_lm_v am 0 = 0; 
       
  3845   inv_stop (as, abc_lm_s am 0 0) 
       
  3846       (start_of (layout_of aprog) e, aaa, Oc # xs) ires\<rbrakk> \<Longrightarrow> 
       
  3847   inv_locate_b (as, am) (0, Oc # aaa, xs) ires"
       
  3848 apply(auto simp: inv_stop.simps inv_locate_b.simps 
       
  3849                  in_middle.simps abc_lm_s.simps)
       
  3850 apply(case_tac "am = []", simp)
       
  3851 apply(rule_tac x = "[]" in exI, rule_tac x = "Suc 0" in exI, 
       
  3852       rule_tac x = 0 in exI, simp)
       
  3853 apply(rule_tac x = "Suc 0" in exI, rule_tac x = 0 in exI, 
       
  3854   simp add: tape_of_nl_abv tape_of_nat_list.simps, auto)
       
  3855 apply(case_tac rn, auto)
       
  3856 apply(rule_tac x = "tl am" in exI, rule_tac x = 0 in exI, 
       
  3857       rule_tac x = "hd am" in exI, simp)
       
  3858 apply(rule_tac x = "Suc 0" in exI, rule_tac x = "hd am" in exI, simp)
       
  3859 apply(case_tac am, simp, simp)
       
  3860 apply(subgoal_tac "a = 0", case_tac list, 
       
  3861       auto simp: tape_of_nat_list.simps tape_of_nl_abv)
       
  3862 apply(case_tac rn, auto)
       
  3863 done
       
  3864 
       
  3865 lemma [simp]: 
       
  3866  "\<lbrakk>inv_stop (as, abc_lm_s am n 0) 
       
  3867           (start_of (layout_of aprog) e, aaa, Oc # xs) ires\<rbrakk>
       
  3868   \<Longrightarrow> inv_locate_b (as, am) (0, Oc # aaa, xs) ires \<or> 
       
  3869       inv_locate_b (as, abc_lm_s am n 0) (0, Oc # aaa, xs) ires"
       
  3870 apply(simp)
       
  3871 done
       
  3872 
       
  3873 lemma [simp]: 
       
  3874 "\<lbrakk>abc_lm_v am n = 0; 
       
  3875   inv_stop (as, abc_lm_s am n 0) 
       
  3876           (start_of (layout_of aprog) e, aaa, Oc # xs) ires\<rbrakk>
       
  3877  \<Longrightarrow> \<not> Suc 0 < 2 * n \<longrightarrow> e = as \<longrightarrow> 
       
  3878             inv_locate_b (as, am) (n, Oc # aaa, xs) ires"
       
  3879 apply(case_tac n, simp, simp)
       
  3880 done
       
  3881 
       
  3882 lemma dec_false2: 
       
  3883  "inv_stop (as, abc_lm_s am n 0) 
       
  3884   (start_of (layout_of aprog) e, aaa, Bk # xs) ires = False"
       
  3885 apply(auto simp: inv_stop.simps abc_lm_s.simps)
       
  3886 apply(case_tac "am", simp, case_tac n, simp add: tape_of_nl_abv)
       
  3887 apply(case_tac list, simp add: tape_of_nat_list.simps )
       
  3888 apply(simp add: tape_of_nat_list.simps , simp)
       
  3889 apply(case_tac "list[nat := 0]", 
       
  3890       simp add: tape_of_nat_list.simps  tape_of_nl_abv)
       
  3891 apply(simp add: tape_of_nat_list.simps )
       
  3892 apply(case_tac "am @ replicate (n - length am) 0 @ [0]", simp)
       
  3893 apply(case_tac list, auto simp: tape_of_nl_abv 
       
  3894                                 tape_of_nat_list.simps )
       
  3895 done	
       
  3896 
       
  3897 lemma dec_false3:
       
  3898    "inv_stop (as, abc_lm_s am n 0) 
       
  3899               (start_of (layout_of aprog) e, aaa, []) ires = False"
       
  3900 apply(auto simp: inv_stop.simps abc_lm_s.simps)
       
  3901 apply(case_tac "am", case_tac n, auto)
       
  3902 apply(case_tac n, auto simp: tape_of_nl_abv)
       
  3903 apply(case_tac "list::nat list",
       
  3904             simp add: tape_of_nat_list.simps tape_of_nat_list.simps)
       
  3905 apply(simp add: tape_of_nat_list.simps)
       
  3906 apply(case_tac "list[nat := 0]", 
       
  3907             simp add: tape_of_nat_list.simps tape_of_nat_list.simps)
       
  3908 apply(simp add: tape_of_nat_list.simps)
       
  3909 apply(case_tac "(am @ replicate (n - length am) 0 @ [0])", simp)
       
  3910 apply(case_tac list, auto simp: tape_of_nat_list.simps)
       
  3911 done
       
  3912 
       
  3913 lemma [simp]:
       
  3914   "fetch (ci (layout_of aprog) 
       
  3915        (start_of (layout_of aprog) as) (Dec n e)) 0 b = (Nop, 0)"
       
  3916 by(simp add: fetch.simps)
       
  3917 
       
  3918 declare dec_inv_1.simps[simp del]
       
  3919 
       
  3920 declare inv_locate_n_b.simps [simp del]
       
  3921 
       
  3922 lemma [simp]:
       
  3923 "\<lbrakk>0 < abc_lm_v am n; 0 < n; 
       
  3924   at_begin_norm (as, am) (n, aaa, Oc # xs) ires\<rbrakk>
       
  3925   \<Longrightarrow> inv_locate_n_b (as, am) (n, Oc # aaa, xs) ires"
       
  3926 apply(simp only: at_begin_norm.simps inv_locate_n_b.simps)
       
  3927 apply(erule_tac exE)+
       
  3928 apply(rule_tac x = lm1 in exI, simp)
       
  3929 apply(case_tac "length lm2", simp)
       
  3930 apply(case_tac rn, simp, simp)
       
  3931 apply(rule_tac x = "tl lm2" in exI, rule_tac x = "hd lm2" in exI, simp)
       
  3932 apply(rule conjI)
       
  3933 apply(case_tac "lm2", simp, simp)
       
  3934 apply(case_tac "lm2", auto simp: tape_of_nl_abv tape_of_nat_list.simps)
       
  3935 apply(case_tac [!] "list", auto simp: tape_of_nl_abv tape_of_nat_list.simps)
       
  3936 apply(case_tac rn, auto)
       
  3937 done 
       
  3938 lemma [simp]: "(\<exists>rn. Oc # xs = Bk\<^bsup>rn\<^esup>) = False"
       
  3939 apply(auto)
       
  3940 apply(case_tac rn, auto simp: )
       
  3941 done
       
  3942 
       
  3943 lemma [simp]:
       
  3944   "\<lbrakk>0 < abc_lm_v am n; 0 < n; 
       
  3945     at_begin_fst_bwtn (as, am) (n, aaa, Oc # xs) ires\<rbrakk>
       
  3946  \<Longrightarrow> inv_locate_n_b (as, am) (n, Oc # aaa, xs) ires"
       
  3947 apply(simp add: at_begin_fst_bwtn.simps inv_locate_n_b.simps )
       
  3948 done
       
  3949  
       
  3950 lemma Suc_minus:"length am + tn = n
       
  3951        \<Longrightarrow> Suc tn = Suc n - length am "
       
  3952 apply(arith)
       
  3953 done
       
  3954 
       
  3955 lemma [simp]: 
       
  3956  "\<lbrakk>0 < abc_lm_v am n; 0 < n; 
       
  3957    at_begin_fst_awtn (as, am) (n, aaa, Oc # xs) ires\<rbrakk>
       
  3958  \<Longrightarrow> inv_locate_n_b (as, am) (n, Oc # aaa, xs) ires"
       
  3959 apply(simp only: at_begin_fst_awtn.simps inv_locate_n_b.simps )
       
  3960 apply(erule exE)+
       
  3961 apply(erule conjE)+
       
  3962 apply(rule_tac x = lm1 in exI, rule_tac x = "[]" in exI, 
       
  3963       rule_tac x = "Suc tn" in exI, rule_tac x = 0 in exI)
       
  3964 apply(simp add: exponent_def rep_ind del: replicate.simps)
       
  3965 apply(rule conjI)+
       
  3966 apply(auto)
       
  3967 apply(case_tac [!] rn, auto)
       
  3968 done
       
  3969 
       
  3970 lemma [simp]: 
       
  3971  "\<lbrakk>0 < abc_lm_v am n; 0 < n; inv_locate_a (as, am) (n, aaa, Oc # xs) ires\<rbrakk>
       
  3972  \<Longrightarrow> inv_locate_n_b (as, am) (n, Oc#aaa, xs) ires"
       
  3973 apply(auto simp: inv_locate_a.simps)
       
  3974 done
       
  3975 
       
  3976 lemma [simp]:
       
  3977  "\<lbrakk>inv_locate_n_b (as, am) (n, aaa, Oc # xs) ires\<rbrakk>
       
  3978  \<Longrightarrow> dec_first_on_right_moving n (as, abc_lm_s am n (abc_lm_v am n))  
       
  3979                                       (s, Oc # aaa, xs) ires"
       
  3980 apply(auto simp: inv_locate_n_b.simps dec_first_on_right_moving.simps 
       
  3981                  abc_lm_s.simps abc_lm_v.simps)
       
  3982 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  3983       rule_tac x = m in exI, simp)
       
  3984 apply(rule_tac x = "Suc (Suc 0)" in exI, 
       
  3985       rule_tac x = "m - 1" in exI, simp)
       
  3986 apply(case_tac m, auto simp:  exponent_def)
       
  3987 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  3988       rule_tac x = m in exI, 
       
  3989       simp add: Suc_diff_le rep_ind del: replicate.simps)
       
  3990 apply(rule_tac x = "Suc (Suc 0)" in exI, 
       
  3991       rule_tac x = "m - 1" in exI, simp)
       
  3992 apply(case_tac m, auto simp:  exponent_def)
       
  3993 apply(rule_tac x = lm1 in exI, rule_tac x = "[]" in exI, 
       
  3994       rule_tac x = m in exI, simp)
       
  3995 apply(rule_tac x = "Suc (Suc 0)" in exI, 
       
  3996       rule_tac x = "m - 1" in exI, simp)
       
  3997 apply(case_tac m, auto)
       
  3998 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  3999       rule_tac x = m in exI, 
       
  4000       simp add: Suc_diff_le rep_ind del: replicate.simps, simp)
       
  4001 done
       
  4002 
       
  4003 lemma dec_false_2: 
       
  4004  "\<lbrakk>0 < abc_lm_v am n; inv_locate_n_b (as, am) (n, aaa, Bk # xs) ires\<rbrakk> 
       
  4005  \<Longrightarrow> False"
       
  4006 apply(auto simp: inv_locate_n_b.simps abc_lm_v.simps split: if_splits)
       
  4007 apply(case_tac [!] m, auto)
       
  4008 done
       
  4009  
       
  4010 lemma dec_false_2_b:
       
  4011  "\<lbrakk>0 < abc_lm_v am n; inv_locate_n_b (as, am) 
       
  4012                                 (n, aaa, []) ires\<rbrakk> \<Longrightarrow> False"
       
  4013 apply(auto simp: inv_locate_n_b.simps abc_lm_v.simps split: if_splits)
       
  4014 apply(case_tac [!] m, auto simp: )
       
  4015 done
       
  4016 
       
  4017 
       
  4018 (*begin: dec halt1 lemmas*)
       
  4019 thm abc_inc_stage1.simps
       
  4020 fun abc_dec_1_stage1:: "t_conf \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
  4021   where
       
  4022   "abc_dec_1_stage1 (s, l, r) ss n = 
       
  4023        (if s > ss \<and> s \<le> ss + 2*n + 1 then 4
       
  4024         else if s = ss + 2 * n + 13 \<or> s = ss + 2*n + 14 then 3
       
  4025         else if s = ss + 2*n + 15 then 2
       
  4026         else 0)"
       
  4027 
       
  4028 fun abc_dec_1_stage2:: "t_conf \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
  4029   where
       
  4030   "abc_dec_1_stage2 (s, l, r) ss n = 
       
  4031        (if s \<le> ss + 2 * n + 1 then (ss + 2 * n + 16 - s)
       
  4032         else if s = ss + 2*n + 13 then length l
       
  4033         else if s = ss + 2*n + 14 then length l
       
  4034         else 0)"
       
  4035 
       
  4036 fun abc_dec_1_stage3 :: "t_conf \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> block list \<Rightarrow> nat"
       
  4037   where
       
  4038   "abc_dec_1_stage3 (s, l, r) ss n ires = 
       
  4039         (if s \<le> ss + 2*n + 1 then 
       
  4040              if (s - ss) mod 2 = 0 then 
       
  4041                          if r \<noteq> [] \<and> hd r = Oc then 0 else 1  
       
  4042                          else length r
       
  4043          else if s = ss + 2 * n + 13 then 
       
  4044              if l = Bk # ires \<and> r \<noteq> [] \<and> hd r = Oc then 2 
       
  4045              else 1
       
  4046          else if s = ss + 2 * n + 14 then 
       
  4047              if r \<noteq> [] \<and> hd r = Oc then 3 else 0 
       
  4048          else 0)"
       
  4049 
       
  4050 fun abc_dec_1_measure :: "(t_conf \<times> nat \<times> nat \<times> block list) \<Rightarrow> (nat \<times> nat \<times> nat)"
       
  4051   where
       
  4052   "abc_dec_1_measure (c, ss, n, ires) = (abc_dec_1_stage1 c ss n, 
       
  4053                    abc_dec_1_stage2 c ss n, abc_dec_1_stage3 c ss n ires)"
       
  4054 
       
  4055 definition abc_dec_1_LE ::
       
  4056   "(((nat \<times> block list \<times> block list) \<times> nat \<times>
       
  4057   nat \<times> block list) \<times> ((nat \<times> block list \<times> block list) \<times> nat \<times> nat \<times> block list)) set"
       
  4058   where "abc_dec_1_LE \<equiv> (inv_image lex_triple abc_dec_1_measure)"
       
  4059 
       
  4060 lemma wf_dec_le: "wf abc_dec_1_LE"
       
  4061 by(auto intro:wf_inv_image wf_lex_triple simp:abc_dec_1_LE_def)
       
  4062 
       
  4063 declare dec_inv_1.simps[simp del] dec_inv_2.simps[simp del]
       
  4064 
       
  4065 lemma [elim]: 
       
  4066  "\<lbrakk>abc_fetch as aprog = Some (Dec n e); 
       
  4067    start_of (layout_of aprog) as < start_of (layout_of aprog) e;
       
  4068    start_of (layout_of aprog) e \<le> 
       
  4069          Suc (start_of (layout_of aprog) as + 2 * n)\<rbrakk> \<Longrightarrow> False"
       
  4070 apply(case_tac "e = as", simp)
       
  4071 apply(case_tac "e < as")
       
  4072 apply(drule_tac a = e and b = as and ly = "layout_of aprog" in 
       
  4073                                                  start_of_le, simp)
       
  4074 apply(drule_tac start_of_ge, auto)
       
  4075 done
       
  4076 
       
  4077 lemma [elim]: "\<lbrakk>abc_fetch as aprog = Some (Dec n e); 
       
  4078                                 start_of (layout_of aprog) e 
       
  4079     = start_of (layout_of aprog) as + 2 * n + 13\<rbrakk>
       
  4080          \<Longrightarrow> False"
       
  4081 apply(insert starte_not_equal[of as aprog n e "layout_of aprog"], 
       
  4082       simp)
       
  4083 done
       
  4084 
       
  4085 lemma [elim]: "\<lbrakk>abc_fetch as aprog = Some (Dec n e);
       
  4086                  start_of (layout_of aprog) e = 
       
  4087                start_of (layout_of aprog) as + 2 * n + 14\<rbrakk>
       
  4088         \<Longrightarrow> False"
       
  4089 apply(insert starte_not_equal[of as aprog n e "layout_of aprog"],
       
  4090       simp)
       
  4091 done
       
  4092 
       
  4093 lemma [elim]: 
       
  4094  "\<lbrakk>abc_fetch as aprog = Some (Dec n e);
       
  4095    start_of (layout_of aprog) as < start_of (layout_of aprog) e;
       
  4096    start_of (layout_of aprog) e \<le> 
       
  4097               Suc (start_of (layout_of aprog) as + 2 * n)\<rbrakk>
       
  4098    \<Longrightarrow> False"
       
  4099 apply(case_tac "e = as", simp)
       
  4100 apply(case_tac "e < as")
       
  4101 apply(drule_tac a = e and b = as and ly = "layout_of aprog" in 
       
  4102                                                     start_of_le, simp)
       
  4103 apply(drule_tac start_of_ge, auto)
       
  4104 done
       
  4105 
       
  4106 lemma [elim]: 
       
  4107  "\<lbrakk>abc_fetch as aprog = Some (Dec n e); 
       
  4108    start_of (layout_of aprog) e = 
       
  4109                start_of (layout_of aprog) as + 2 * n + 13\<rbrakk>
       
  4110     \<Longrightarrow> False"
       
  4111 apply(insert starte_not_equal[of as aprog n e "layout_of aprog"], 
       
  4112       simp)
       
  4113 done
       
  4114 
       
  4115 lemma [simp]: 
       
  4116  "abc_fetch as aprog = Some (Dec n e) \<Longrightarrow> 
       
  4117    Suc (start_of (layout_of aprog) as) \<noteq> start_of (layout_of aprog) e"
       
  4118 apply(case_tac "e = as", simp) 
       
  4119 apply(case_tac "e < as")
       
  4120 apply(drule_tac a = e and b = as and ly = "(layout_of aprog)" in 
       
  4121                                                  start_of_le, simp)
       
  4122 apply(drule_tac a = as and e = e in start_of_ge, simp, simp)
       
  4123 done
       
  4124 
       
  4125 lemma [simp]: "inv_on_left_moving (as, am) (s, [], r) ires 
       
  4126   = False"
       
  4127 apply(simp add: inv_on_left_moving.simps inv_on_left_moving_norm.simps
       
  4128                 inv_on_left_moving_in_middle_B.simps)
       
  4129 done
       
  4130 
       
  4131 lemma [simp]: 
       
  4132   "inv_check_left_moving (as, abc_lm_s am n 0)
       
  4133   (start_of (layout_of aprog) as + 2 * n + 14, [], Oc # xs) ires
       
  4134  = False"
       
  4135 apply(simp add: inv_check_left_moving.simps inv_check_left_moving_in_middle.simps)
       
  4136 done
       
  4137 
       
  4138 lemma dec_inv_stop1_pre: 
       
  4139     "\<lbrakk>abc_fetch as aprog = Some (Dec n e); abc_lm_v am n = 0;
       
  4140       start_of (layout_of aprog) as > 0\<rbrakk>
       
  4141  \<Longrightarrow> \<forall>na. \<not> (\<lambda>(s, l, r) (ss, n', ires'). s = start_of (layout_of aprog) e)
       
  4142             (t_steps (Suc (start_of (layout_of aprog) as), l, r) 
       
  4143               (ci (layout_of aprog) (start_of (layout_of aprog) as) 
       
  4144                  (Dec n e), start_of (layout_of aprog) as - Suc 0) na)
       
  4145                       (start_of (layout_of aprog) as, n, ires) \<and>
       
  4146            dec_inv_1 (layout_of aprog) n e (as, am)
       
  4147             (t_steps (Suc (start_of (layout_of aprog) as), l, r) 
       
  4148               (ci (layout_of aprog) (start_of (layout_of aprog) as) 
       
  4149                 (Dec n e), start_of (layout_of aprog) as - Suc 0) na) ires
       
  4150        \<longrightarrow> dec_inv_1 (layout_of aprog) n e (as, am)
       
  4151             (t_steps (Suc (start_of (layout_of aprog) as), l, r) 
       
  4152               (ci (layout_of aprog) (start_of (layout_of aprog) as)
       
  4153                  (Dec n e), start_of (layout_of aprog) as - Suc 0) 
       
  4154                     (Suc na)) ires \<and>
       
  4155             ((t_steps (Suc (start_of (layout_of aprog) as), l, r) 
       
  4156             (ci (layout_of aprog) (start_of (layout_of aprog) as) 
       
  4157            (Dec n e), start_of (layout_of aprog) as - Suc 0) (Suc na),
       
  4158              start_of (layout_of aprog) as, n, ires),
       
  4159          t_steps (Suc (start_of (layout_of aprog) as), l, r) 
       
  4160             (ci (layout_of aprog) (start_of (layout_of aprog) as) 
       
  4161                (Dec n e), start_of (layout_of aprog) as - Suc 0) na,
       
  4162             start_of (layout_of aprog) as, n, ires)
       
  4163            \<in> abc_dec_1_LE"
       
  4164 apply(rule allI, rule impI, simp add: t_steps_ind)
       
  4165 apply(case_tac "(t_steps (Suc (start_of (layout_of aprog) as), l, r) 
       
  4166 (ci (layout_of aprog) (start_of (layout_of aprog) as) (Dec n e), 
       
  4167 start_of (layout_of aprog) as - Suc 0) na)", simp)
       
  4168 apply(auto split:if_splits simp add:t_step.simps dec_inv_1.simps, 
       
  4169           tactic {* ALLGOALS (resolve_tac [@{thm fetch_intro}]) *})
       
  4170 apply(simp_all add:dec_fetch_simps new_tape.simps dec_inv_1.simps)
       
  4171 apply(auto simp add: abc_dec_1_LE_def lex_square_def 
       
  4172                      lex_triple_def lex_pair_def  
       
  4173                 split: if_splits)
       
  4174 apply(rule dec_false_1, simp, simp)
       
  4175 done
       
  4176 
       
  4177 lemma dec_inv_stop1: 
       
  4178   "\<lbrakk>ly = layout_of aprog; 
       
  4179     dec_inv_1 ly n e (as, am) (start_of ly as + 1, l, r) ires; 
       
  4180     abc_fetch as aprog = Some (Dec n e); abc_lm_v am n = 0\<rbrakk> \<Longrightarrow> 
       
  4181   (\<exists> stp. (\<lambda> (s', l', r'). s' = start_of ly e \<and> 
       
  4182            dec_inv_1 ly n e (as, am) (s', l' , r') ires) 
       
  4183   (t_steps (start_of ly as + 1, l, r)
       
  4184      (ci ly (start_of ly as) (Dec n e), start_of ly as - Suc 0) stp))"
       
  4185 apply(insert halt_lemma2[of abc_dec_1_LE 
       
  4186     "\<lambda> ((s, l, r), ss, n', ires'). s = start_of ly e" 
       
  4187      "(\<lambda> stp. (t_steps (start_of ly as + 1, l, r) 
       
  4188           (ci ly (start_of ly as) (Dec n e), start_of ly as - Suc 0) 
       
  4189                stp, start_of ly as, n, ires))"
       
  4190      "\<lambda> ((s, l, r), ss, n, ires'). dec_inv_1 ly n e (as, am) (s, l, r) ires'"],
       
  4191      simp)
       
  4192 apply(insert wf_dec_le, simp)
       
  4193 apply(insert dec_inv_stop1_pre[of as aprog n e am l r], simp)
       
  4194 apply(subgoal_tac "start_of (layout_of aprog) as > 0", 
       
  4195                                       simp add: t_steps.simps)
       
  4196 apply(erule_tac exE, rule_tac x = na in exI)
       
  4197 apply(case_tac
       
  4198      "(t_steps (Suc (start_of (layout_of aprog) as), l, r) 
       
  4199          (ci (layout_of aprog) (start_of (layout_of aprog) as)
       
  4200            (Dec n e), start_of (layout_of aprog) as - Suc 0) na)",
       
  4201       case_tac b, auto)
       
  4202 apply(rule startof_not0)
       
  4203 done
       
  4204 
       
  4205 (*begin: dec halt2 lemmas*)
       
  4206 
       
  4207 lemma [simp]:
       
  4208   "\<lbrakk>abc_fetch as aprog = Some (Dec n e); 
       
  4209     ly = layout_of aprog\<rbrakk> \<Longrightarrow> 
       
  4210               start_of ly (Suc as) = start_of ly as + 2*n + 16"
       
  4211 by simp
       
  4212 
       
  4213 fun abc_dec_2_stage1 :: "t_conf \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
  4214   where
       
  4215   "abc_dec_2_stage1 (s, l, r) ss n = 
       
  4216               (if s \<le> ss + 2*n + 1 then 7
       
  4217                else if s = ss + 2*n + 2 then 6 
       
  4218                else if s = ss + 2*n + 3 then 5
       
  4219                else if s \<ge> ss + 2*n + 4 \<and> s \<le> ss + 2*n + 9 then 4
       
  4220                else if s = ss + 2*n + 6 then 3
       
  4221                else if s = ss + 2*n + 10 \<or> s = ss + 2*n + 11 then 2
       
  4222                else if s = ss + 2*n + 12 then 1
       
  4223                else 0)"
       
  4224 
       
  4225 thm new_tape.simps
       
  4226 
       
  4227 fun abc_dec_2_stage2 :: "t_conf \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
  4228   where
       
  4229   "abc_dec_2_stage2 (s, l, r) ss n = 
       
  4230        (if s \<le> ss + 2 * n + 1 then (ss + 2 * n + 16 - s)
       
  4231         else if s = ss + 2*n + 10 then length l
       
  4232         else if s = ss + 2*n + 11 then length l
       
  4233         else if s = ss + 2*n + 4 then length r - 1
       
  4234         else if s = ss + 2*n + 5 then length r 
       
  4235         else if s = ss + 2*n + 7 then length r - 1
       
  4236         else if s = ss + 2*n + 8 then  
       
  4237               length r + length (takeWhile (\<lambda> a. a = Oc) l) - 1
       
  4238         else if s = ss + 2*n + 9 then 
       
  4239               length r + length (takeWhile (\<lambda> a. a = Oc) l) - 1
       
  4240         else 0)"
       
  4241 
       
  4242 fun abc_dec_2_stage3 :: "t_conf \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> block list \<Rightarrow> nat"
       
  4243   where
       
  4244   "abc_dec_2_stage3 (s, l, r) ss n ires =
       
  4245         (if s \<le> ss + 2*n + 1 then 
       
  4246             if (s - ss) mod 2 = 0 then if r \<noteq> [] \<and> 
       
  4247                                           hd r = Oc then 0 else 1  
       
  4248             else length r
       
  4249          else if s = ss + 2 * n + 10 then 
       
  4250              if l = Bk # ires \<and> r \<noteq> [] \<and> hd r = Oc then 2
       
  4251              else 1
       
  4252          else if s = ss + 2 * n + 11 then 
       
  4253              if r \<noteq> [] \<and> hd r = Oc then 3 
       
  4254              else 0 
       
  4255          else (ss + 2 * n + 16 - s))"
       
  4256 
       
  4257 fun abc_dec_2_stage4 :: "t_conf \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
  4258   where
       
  4259   "abc_dec_2_stage4 (s, l, r) ss n = 
       
  4260           (if s = ss + 2*n + 2 then length r
       
  4261            else if s = ss + 2*n + 8 then length r
       
  4262            else if s = ss + 2*n + 3 then 
       
  4263                if r \<noteq> [] \<and> hd r = Oc then 1
       
  4264                else 0
       
  4265            else if s = ss + 2*n + 7 then 
       
  4266                if r \<noteq> [] \<and> hd r = Oc then 0 
       
  4267                else 1
       
  4268            else if s = ss + 2*n + 9 then 
       
  4269                if r \<noteq> [] \<and> hd r = Oc then 1
       
  4270                else 0 
       
  4271            else 0)"
       
  4272 
       
  4273 fun abc_dec_2_measure :: "(t_conf \<times> nat \<times> nat \<times> block list) \<Rightarrow> 
       
  4274                                     (nat \<times> nat \<times> nat \<times> nat)"
       
  4275   where
       
  4276   "abc_dec_2_measure (c, ss, n, ires) = 
       
  4277        (abc_dec_2_stage1 c ss n, abc_dec_2_stage2 c ss n,
       
  4278         abc_dec_2_stage3 c ss n ires, abc_dec_2_stage4 c ss n)"
       
  4279 
       
  4280 definition abc_dec_2_LE :: 
       
  4281        "(((nat \<times> block list \<times> block list) \<times> nat \<times> nat \<times> block list) \<times> 
       
  4282         ((nat \<times> block list \<times> block list) \<times> nat \<times> nat \<times> block list)) set"
       
  4283   where "abc_dec_2_LE \<equiv> (inv_image lex_square abc_dec_2_measure)"
       
  4284 
       
  4285 lemma wf_dec_2_le: "wf abc_dec_2_LE"
       
  4286 by(auto intro:wf_inv_image wf_lex_triple wf_lex_square 
       
  4287    simp:abc_dec_2_LE_def)
       
  4288 
       
  4289 lemma [simp]: "dec_after_write (as, am) (s, aa, r) ires
       
  4290            \<Longrightarrow> takeWhile (\<lambda>a. a = Oc) aa = []"
       
  4291 apply(simp only : dec_after_write.simps)
       
  4292 apply(erule exE)+
       
  4293 apply(erule_tac conjE)+
       
  4294 apply(case_tac aa, simp)
       
  4295 apply(case_tac a, simp only: takeWhile.simps , simp, simp split: if_splits)
       
  4296 done
       
  4297 
       
  4298 lemma [simp]: 
       
  4299      "\<lbrakk>dec_on_right_moving (as, lm) (s, aa, []) ires; 
       
  4300        length (takeWhile (\<lambda>a. a = Oc) (tl aa)) 
       
  4301            \<noteq> length (takeWhile (\<lambda>a. a = Oc) aa) - Suc 0\<rbrakk>
       
  4302     \<Longrightarrow> length (takeWhile (\<lambda>a. a = Oc) (tl aa)) < 
       
  4303                        length (takeWhile (\<lambda>a. a = Oc) aa) - Suc 0"
       
  4304 apply(simp only: dec_on_right_moving.simps)
       
  4305 apply(erule_tac exE)+
       
  4306 apply(erule_tac conjE)+
       
  4307 apply(case_tac mr, auto split: if_splits)
       
  4308 done
       
  4309 
       
  4310 lemma [simp]: 
       
  4311   "dec_after_clear (as, abc_lm_s am n (abc_lm_v am n - Suc 0)) 
       
  4312              (start_of (layout_of aprog) as + 2 * n + 9, aa, Bk # xs) ires
       
  4313  \<Longrightarrow> length xs - Suc 0 < length xs + 
       
  4314                              length (takeWhile (\<lambda>a. a = Oc) aa)"
       
  4315 apply(simp only: dec_after_clear.simps)
       
  4316 apply(erule_tac exE)+
       
  4317 apply(erule conjE)+
       
  4318 apply(simp split: if_splits )
       
  4319 done
       
  4320 
       
  4321 lemma [simp]: 
       
  4322  "\<lbrakk>dec_after_clear (as, abc_lm_s am n (abc_lm_v am n - Suc 0))
       
  4323        (start_of (layout_of aprog) as + 2 * n + 9, aa, []) ires\<rbrakk>
       
  4324     \<Longrightarrow> Suc 0 < length (takeWhile (\<lambda>a. a = Oc) aa)"
       
  4325 apply(simp add: dec_after_clear.simps split: if_splits)
       
  4326 done
       
  4327 
       
  4328 lemma [simp]: 
       
  4329  "\<lbrakk>dec_on_right_moving (as, am) (s, aa, Bk # xs) ires; 
       
  4330    Suc (length (takeWhile (\<lambda>a. a = Oc) (tl aa)))
       
  4331    \<noteq> length (takeWhile (\<lambda>a. a = Oc) aa)\<rbrakk>
       
  4332   \<Longrightarrow> Suc (length (takeWhile (\<lambda>a. a = Oc) (tl aa))) 
       
  4333     < length (takeWhile (\<lambda>a. a = Oc) aa)"
       
  4334 apply(simp only: dec_on_right_moving.simps)
       
  4335 apply(erule exE)+
       
  4336 apply(erule conjE)+
       
  4337 apply(case_tac ml, auto split: if_splits )
       
  4338 done
       
  4339 
       
  4340 (*
       
  4341 lemma abc_dec_2_wf: 
       
  4342      "\<lbrakk>ly = layout_of aprog; dec_inv_2 ly n e (as, am) (start_of ly as + 1, l, r);  abc_fetch as aprog = Dec n e; abc_lm_v am n > 0\<rbrakk>
       
  4343        \<Longrightarrow> \<forall>na. \<not> (\<lambda>(s, l, r) (ss, n'). s = start_of (layout_of aprog) as + 2*n + 16)
       
  4344         (t_steps (Suc (start_of (layout_of aprog) as), l, r) (ci (layout_of aprog) (start_of (layout_of aprog) as) (Dec n e), start_of (layout_of aprog) as - Suc 0) na)
       
  4345            (start_of (layout_of aprog) as, n) \<longrightarrow>
       
  4346         ((t_steps (Suc (start_of (layout_of aprog) as), l, r) (ci (layout_of aprog) (start_of (layout_of aprog) as) (Dec n e), start_of (layout_of aprog) as - Suc 0) (Suc na),
       
  4347             start_of (layout_of aprog) as, n),
       
  4348           t_steps (Suc (start_of (layout_of aprog) as), l, r) (ci (layout_of aprog) (start_of (layout_of aprog) as) (Dec n e), start_of (layout_of aprog) as - Suc 0) na,
       
  4349            start_of (layout_of aprog) as, n)
       
  4350         \<in> abc_dec_2_LE"
       
  4351 proof(rule allI, rule impI, simp add: t_steps_ind)
       
  4352   fix na
       
  4353   assume h1 :"ly = layout_of aprog" "dec_inv_2 (layout_of aprog) n e (as, am) (Suc (start_of (layout_of aprog) as), l, r)" 
       
  4354           "abc_fetch as aprog = Dec n e" "abc_lm_v am n > 0"
       
  4355          "\<not> (\<lambda>(s, l, r) (ss, n'). s = start_of (layout_of aprog) as + 2*n + 16)
       
  4356              (t_steps (Suc (start_of (layout_of aprog) as), l, r) (ci (layout_of aprog) (start_of (layout_of aprog) as) (Dec n e), start_of (layout_of aprog) as - Suc 0) na)
       
  4357              (start_of (layout_of aprog) as, n)"
       
  4358   thus "((t_step (t_steps (Suc (start_of (layout_of aprog) as), l, r) (ci (layout_of aprog) (start_of (layout_of aprog) as) (Dec n e), start_of (layout_of aprog) as - Suc 0) na)
       
  4359                (ci (layout_of aprog) (start_of (layout_of aprog) as) (Dec n e), start_of (layout_of aprog) as - Suc 0),
       
  4360               start_of (layout_of aprog) as, n),
       
  4361              t_steps (Suc (start_of (layout_of aprog) as), l, r) (ci (layout_of aprog) (start_of (layout_of aprog) as) (Dec n e), start_of (layout_of aprog) as - Suc 0) na,
       
  4362              start_of (layout_of aprog) as, n)
       
  4363             \<in> abc_dec_2_LE"
       
  4364   proof(insert dec_inv_2_steps[of "layout_of aprog" n e as am "(start_of (layout_of aprog) as + 1, l, r)" aprog na], 
       
  4365         case_tac "(t_steps (start_of (layout_of aprog) as + 1, l, r) (ci (layout_of aprog) (start_of (layout_of aprog) as) (Dec n e), start_of (layout_of aprog) as - Suc 0) na)", case_tac b, simp)
       
  4366     fix a b aa ba
       
  4367     assume "dec_inv_2 (layout_of aprog) n e (as, am) (a, aa, ba)" " a \<noteq> start_of (layout_of aprog) as + 2*n + 16" "abc_lm_v am n > 0" "abc_fetch as aprog = Dec n e "
       
  4368     thus "((t_step (a, aa, ba) (ci (layout_of aprog) (start_of (layout_of aprog) as) (Dec n e), start_of (layout_of aprog) as - Suc 0), start_of (layout_of aprog) as, n), (a, aa, ba),
       
  4369                     start_of (layout_of aprog) as, n)
       
  4370                    \<in> abc_dec_2_LE"
       
  4371       apply(case_tac "a = 0", auto split:if_splits simp add:t_step.simps dec_inv_2.simps, 
       
  4372                 tactic {* ALLGOALS (resolve_tac (thms "fetch_intro")) *})
       
  4373       apply(simp_all add:dec_fetch_simps new_tape.simps)
       
  4374       apply(auto simp add: abc_dec_2_LE_def  lex_square_def lex_triple_def lex_pair_def  
       
  4375                            split: if_splits)
       
  4376       
       
  4377       done
       
  4378   qed
       
  4379 qed
       
  4380 *)
       
  4381 
       
  4382 lemma [simp]: "inv_check_left_moving (as, abc_lm_s am n (abc_lm_v am n - Suc 0)) 
       
  4383   (start_of (layout_of aprog) as + 2 * n + 11, [], Oc # xs) ires = False"
       
  4384 apply(simp add: inv_check_left_moving.simps inv_check_left_moving_in_middle.simps)
       
  4385 done
       
  4386 
       
  4387 lemma dec_inv_stop2_pre: 
       
  4388   "\<lbrakk>abc_fetch as aprog = Some (Dec n e); abc_lm_v am n > 0\<rbrakk> \<Longrightarrow> 
       
  4389     \<forall>na. \<not> (\<lambda>(s, l, r) (ss, n', ires'). 
       
  4390                      s = start_of (layout_of aprog) as + 2 * n + 16)
       
  4391    (t_steps (Suc (start_of (layout_of aprog) as), l, r) 
       
  4392       (ci (layout_of aprog) (start_of (layout_of aprog) as) (Dec n e),
       
  4393             start_of (layout_of aprog) as - Suc 0) na)
       
  4394     (start_of (layout_of aprog) as, n, ires) \<and>
       
  4395  dec_inv_2 (layout_of aprog) n e (as, am)
       
  4396      (t_steps (Suc (start_of (layout_of aprog) as), l, r) 
       
  4397       (ci (layout_of aprog) (start_of (layout_of aprog) as) (Dec n e),
       
  4398           start_of (layout_of aprog) as - Suc 0) na) ires
       
  4399  \<longrightarrow>
       
  4400  dec_inv_2 (layout_of aprog) n e (as, am)
       
  4401      (t_steps (Suc (start_of (layout_of aprog) as), l, r) 
       
  4402       (ci (layout_of aprog) (start_of (layout_of aprog) as) (Dec n e),
       
  4403               start_of (layout_of aprog) as - Suc 0) (Suc na)) ires \<and>
       
  4404  ((t_steps (Suc (start_of (layout_of aprog) as), l, r) 
       
  4405       (ci (layout_of aprog) (start_of (layout_of aprog) as) (Dec n e),
       
  4406             start_of (layout_of aprog) as - Suc 0) (Suc na),  
       
  4407               start_of (layout_of aprog) as, n, ires),
       
  4408   t_steps (Suc (start_of (layout_of aprog) as), l, r) 
       
  4409       (ci (layout_of aprog) (start_of (layout_of aprog) as) (Dec n e),
       
  4410              start_of (layout_of aprog) as - Suc 0) na,
       
  4411                           start_of (layout_of aprog) as, n, ires)
       
  4412    \<in> abc_dec_2_LE"
       
  4413 apply(subgoal_tac "start_of (layout_of aprog) as > 0")
       
  4414 apply(rule allI, rule impI, simp add: t_steps_ind)
       
  4415 apply(case_tac "(t_steps (Suc (start_of (layout_of aprog) as), l, r)
       
  4416      (ci (layout_of aprog) (start_of (layout_of aprog) as) (Dec n e), 
       
  4417              start_of (layout_of aprog) as - Suc 0) na)", simp)
       
  4418 apply(auto split:if_splits simp add:t_step.simps dec_inv_2.simps, 
       
  4419            tactic {* ALLGOALS (resolve_tac [@{thm fetch_intro}]) *})
       
  4420 apply(simp_all add:dec_fetch_simps new_tape.simps dec_inv_2.simps)
       
  4421 apply(auto simp add: abc_dec_2_LE_def lex_square_def lex_triple_def 
       
  4422                      lex_pair_def split: if_splits)
       
  4423 apply(auto intro: dec_false_2_b dec_false_2)
       
  4424 apply(rule startof_not0)
       
  4425 done
       
  4426 
       
  4427 lemma dec_stop2: 
       
  4428  "\<lbrakk>ly = layout_of aprog; 
       
  4429    dec_inv_2 ly n e (as, am) (start_of ly as + 1, l, r) ires; 
       
  4430    abc_fetch as aprog = Some (Dec n e); 
       
  4431    abc_lm_v am n > 0\<rbrakk> \<Longrightarrow> 
       
  4432   (\<exists> stp. (\<lambda> (s', l', r'). s' = start_of ly (Suc as) \<and> 
       
  4433    dec_inv_2 ly n e (as, am) (s', l', r') ires)
       
  4434        (t_steps (start_of ly as+1, l, r) (ci ly (start_of ly as)
       
  4435                            (Dec n e), start_of ly as - Suc 0) stp))"
       
  4436 apply(insert halt_lemma2[of abc_dec_2_LE 
       
  4437       "\<lambda> ((s, l, r), ss, n', ires'). s = start_of ly (Suc as)"
       
  4438       "(\<lambda> stp. (t_steps (start_of ly as + 1, l, r) 
       
  4439        (ci ly (start_of ly as) (Dec n e), start_of ly as - Suc 0) stp,
       
  4440                  start_of ly as, n, ires))"
       
  4441       "(\<lambda> ((s, l, r), ss, n, ires'). dec_inv_2 ly n e (as, am) (s, l, r) ires')"])
       
  4442 apply(insert wf_dec_2_le, simp)
       
  4443 apply(insert dec_inv_stop2_pre[of as aprog n e am l r], 
       
  4444       simp add: t_steps.simps)
       
  4445 apply(erule_tac exE)
       
  4446 apply(rule_tac x = na in exI)
       
  4447 apply(case_tac "(t_steps (Suc (start_of (layout_of aprog) as), l, r) 
       
  4448 (ci (layout_of aprog) (start_of (layout_of aprog) as) (Dec n e), 
       
  4449             start_of (layout_of aprog) as - Suc 0) na)",
       
  4450       case_tac b, auto)
       
  4451 done
       
  4452 
       
  4453 lemma dec_inv_stop_cond1: 
       
  4454   "\<lbrakk>ly = layout_of aprog; 
       
  4455     dec_inv_1 ly n e (as, lm) (s, (l, r)) ires; s = start_of ly e;
       
  4456     abc_fetch as aprog = Some (Dec n e); abc_lm_v lm n = 0\<rbrakk> 
       
  4457    \<Longrightarrow> crsp_l ly (e, abc_lm_s lm n 0) (s, l, r) ires"
       
  4458 apply(simp add: dec_inv_1.simps split: if_splits)
       
  4459 apply(auto simp: crsp_l.simps inv_stop.simps )
       
  4460 done
       
  4461 
       
  4462 lemma dec_inv_stop_cond2: 
       
  4463    "\<lbrakk>ly = layout_of aprog; s = start_of ly (Suc as); 
       
  4464      dec_inv_2 ly n e (as, lm) (s, (l, r)) ires;
       
  4465      abc_fetch as aprog = Some (Dec n e); 
       
  4466      abc_lm_v lm n > 0\<rbrakk>
       
  4467    \<Longrightarrow> crsp_l ly (Suc as,
       
  4468                   abc_lm_s lm n (abc_lm_v lm n - Suc 0)) (s, l, r) ires"
       
  4469 apply(simp add: dec_inv_2.simps split: if_splits)
       
  4470 apply(auto simp: crsp_l.simps inv_stop.simps )
       
  4471 done
       
  4472 
       
  4473 lemma [simp]: "(case Bk\<^bsup>rn\<^esup> of [] \<Rightarrow> Bk |
       
  4474                  Bk # xs \<Rightarrow> Bk | Oc # xs \<Rightarrow> Oc) = Bk"
       
  4475 apply(case_tac rn, auto)
       
  4476 done
       
  4477 
       
  4478 lemma [simp]: "t_steps tc (p,off) (m + n) = 
       
  4479                    t_steps (t_steps tc (p, off) m) (p, off) n"
       
  4480 apply(induct m arbitrary: n)
       
  4481 apply(simp add: t_steps.simps)
       
  4482 proof -
       
  4483   fix m n
       
  4484   assume h1: "\<And>n. t_steps tc (p, off) (m + n) =
       
  4485                      t_steps (t_steps tc (p, off) m) (p, off) n"
       
  4486   hence h2: "t_steps tc (p, off) (Suc m + n) = 
       
  4487                      t_steps tc (p, off) (m + Suc n)"
       
  4488     by simp
       
  4489   from h1 and this show 
       
  4490     "t_steps tc (p, off) (Suc m + n) = 
       
  4491          t_steps (t_steps tc (p, off) (Suc m)) (p, off) n"
       
  4492   proof(simp only: h2, simp add: t_steps.simps)
       
  4493     have h3: "(t_step (t_steps tc (p, off) m) (p, off)) = 
       
  4494                       (t_steps (t_step tc (p, off)) (p, off) m)"
       
  4495       apply(simp add: t_steps.simps[THEN sym] t_steps_ind[THEN sym])
       
  4496       done
       
  4497     from h3 show 
       
  4498       "t_steps (t_step (t_steps tc (p, off) m) (p, off)) (p, off) n =          t_steps (t_steps (t_step tc (p, off)) (p, off) m) (p, off) n"
       
  4499       by simp
       
  4500   qed
       
  4501 qed
       
  4502 
       
  4503 lemma [simp]: " abc_fetch as aprog = Some (Dec n e) \<Longrightarrow> 
       
  4504           Suc (start_of (layout_of aprog) as) \<noteq> 
       
  4505                            start_of (layout_of aprog) e"
       
  4506 apply(case_tac "e = as", simp)
       
  4507 apply(case_tac "e < as")
       
  4508 apply(drule_tac a = e and b = as and ly = "layout_of aprog" 
       
  4509                                            in start_of_le, simp)
       
  4510 apply(drule_tac start_of_ge, auto)
       
  4511 done
       
  4512 
       
  4513 lemma [simp]: "inv_locate_b (as, []) (0, Oc # Bk # Bk # ires, Bk\<^bsup>rn - Suc 0\<^esup>) ires"
       
  4514 apply(auto simp: inv_locate_b.simps in_middle.simps)
       
  4515 apply(rule_tac x = "[]" in exI, rule_tac x = "Suc 0" in exI, 
       
  4516       rule_tac x = 0 in exI, simp)
       
  4517 apply(rule_tac x = "Suc 0" in exI, rule_tac x = 0 in exI, auto)
       
  4518 apply(case_tac rn, simp, case_tac nat, auto)
       
  4519 done
       
  4520 
       
  4521 lemma [simp]: 
       
  4522        "inv_locate_n_b (as, []) (0, Oc # Bk # Bk # ires, Bk\<^bsup>rn - Suc 0\<^esup>) ires"
       
  4523 apply(auto simp: inv_locate_n_b.simps in_middle.simps)
       
  4524 apply(case_tac rn, simp, case_tac nat, auto)
       
  4525 done 
       
  4526 
       
  4527 lemma [simp]:
       
  4528 "abc_fetch as aprog = Some (Dec n e) \<Longrightarrow>
       
  4529    dec_inv_1 (layout_of aprog) n e (as, []) 
       
  4530     (Suc (start_of (layout_of aprog) as), Oc # Bk # Bk # ires, Bk\<^bsup>rn - Suc 0\<^esup>) ires
       
  4531 \<and>
       
  4532    dec_inv_2 (layout_of aprog) n e (as, []) 
       
  4533     (Suc (start_of (layout_of aprog) as), Oc # Bk # Bk # ires, Bk\<^bsup>rn - Suc 0\<^esup>) ires"
       
  4534 apply(simp add: dec_inv_1.simps dec_inv_2.simps)
       
  4535 apply(case_tac n, auto)
       
  4536 done
       
  4537 
       
  4538 lemma [simp]: 
       
  4539  "\<lbrakk>am \<noteq> []; <am> = Oc # r'; 
       
  4540    abc_fetch as aprog = Some (Dec n e)\<rbrakk> 
       
  4541  \<Longrightarrow> inv_locate_b (as, am) (0, Oc # Bk # Bk # ires, r' @ Bk\<^bsup>rn\<^esup>) ires"
       
  4542 apply(auto simp: inv_locate_b.simps in_middle.simps)
       
  4543 apply(rule_tac x = "tl am" in exI, rule_tac x = 0 in exI,
       
  4544       rule_tac x = "hd am" in exI, simp)
       
  4545 apply(rule_tac x = "Suc 0" in exI)
       
  4546 apply(rule_tac x = "hd am" in exI, simp)
       
  4547 apply(case_tac am, simp, case_tac list, auto simp: tape_of_nl_abv tape_of_nat_list.simps)
       
  4548 apply(case_tac rn, auto)
       
  4549 done
       
  4550 
       
  4551 lemma [simp]: 
       
  4552   "\<lbrakk><am> = Oc # r'; abc_fetch as aprog = Some (Dec n e)\<rbrakk> \<Longrightarrow> 
       
  4553   inv_locate_n_b (as, am) (0, Oc # Bk # Bk # ires, r' @ Bk\<^bsup>rn\<^esup>) ires"
       
  4554 apply(auto simp: inv_locate_n_b.simps)
       
  4555 apply(rule_tac x = "tl am" in exI, rule_tac x = "hd am" in exI, auto)
       
  4556 apply(case_tac [!] am, auto simp: tape_of_nl_abv tape_of_nat_list.simps )
       
  4557 apply(case_tac [!]list, auto simp: tape_of_nl_abv tape_of_nat_list.simps)
       
  4558 apply(case_tac rn, simp, simp)
       
  4559 apply(erule_tac x = nat in allE, simp)
       
  4560 done
       
  4561 
       
  4562 lemma [simp]:
       
  4563    "\<lbrakk>am \<noteq> [];  
       
  4564      <am> = Oc # r'; 
       
  4565      abc_fetch as aprog = Some (Dec n e)\<rbrakk> \<Longrightarrow>
       
  4566     dec_inv_1 (layout_of aprog) n e (as, am) 
       
  4567       (Suc (start_of (layout_of aprog) as), 
       
  4568            Oc # Bk # Bk # ires, r' @ Bk\<^bsup>rn\<^esup>) ires \<and>
       
  4569     dec_inv_2 (layout_of aprog) n e (as, am) 
       
  4570       (Suc (start_of (layout_of aprog) as), 
       
  4571            Oc # Bk # Bk # ires, r' @ Bk\<^bsup>rn\<^esup>) ires"
       
  4572 apply(simp add: dec_inv_1.simps dec_inv_2.simps)
       
  4573 apply(case_tac n, auto)
       
  4574 done
       
  4575 
       
  4576 lemma [simp]: "am \<noteq> [] \<Longrightarrow>  \<exists>r'. <am::nat list> = Oc # r'"
       
  4577 apply(case_tac am, simp, case_tac list)
       
  4578 apply(auto simp: tape_of_nl_abv tape_of_nat_list.simps )
       
  4579 done
       
  4580 
       
  4581 lemma [simp]: "start_of (layout_of aprog) as > 0 \<Longrightarrow> 
       
  4582       (fetch (ci (layout_of aprog) 
       
  4583            (start_of (layout_of aprog) as) (Dec n e)) (Suc 0)  Bk)
       
  4584     = (W1, start_of (layout_of aprog) as)"
       
  4585 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  4586              nth_of.simps tshift.simps nth_append Suc_pre tdec_b_def)
       
  4587 thm findnth_nth
       
  4588 apply(insert findnth_nth[of 0 n 0], simp)
       
  4589 apply(simp add: findnth.simps)
       
  4590 done
       
  4591 
       
  4592 lemma [simp]:
       
  4593     "start_of (layout_of aprog) as > 0
       
  4594    \<Longrightarrow> (t_step (start_of (layout_of aprog) as, Bk # Bk # ires, Bk\<^bsup>rn\<^esup>)
       
  4595     (ci (layout_of aprog) (start_of (layout_of aprog) as) (Dec n e), 
       
  4596                              start_of (layout_of aprog) as - Suc 0))
       
  4597    = (start_of (layout_of aprog) as, Bk # Bk # ires, Oc # Bk\<^bsup>rn- Suc 0\<^esup>)"
       
  4598 apply(simp add: t_step.simps)
       
  4599 apply(case_tac "start_of (layout_of aprog) as",
       
  4600       auto simp: new_tape.simps)
       
  4601 apply(case_tac rn, auto)
       
  4602 done
       
  4603 
       
  4604 lemma [simp]: "start_of (layout_of aprog) as > 0 \<Longrightarrow> 
       
  4605  (fetch (ci (layout_of aprog) (start_of (layout_of aprog) as) 
       
  4606          (Dec n e)) (Suc 0)  Oc)
       
  4607   = (R, Suc (start_of (layout_of aprog) as))"
       
  4608 
       
  4609 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  4610                  nth_of.simps tshift.simps nth_append 
       
  4611                  Suc_pre tdec_b_def)
       
  4612 apply(insert findnth_nth[of 0 n "Suc 0"], simp)
       
  4613 apply(simp add: findnth.simps)
       
  4614 done
       
  4615 
       
  4616 lemma [simp]: "start_of (layout_of aprog) as > 0 \<Longrightarrow> 
       
  4617  (t_step (start_of (layout_of aprog) as, Bk # Bk # ires, Oc # Bk\<^bsup>rn - Suc 0\<^esup>)
       
  4618      (ci (layout_of aprog) (start_of (layout_of aprog) as) (Dec n e), 
       
  4619         start_of (layout_of aprog) as - Suc 0)) =
       
  4620   (Suc (start_of (layout_of aprog) as), Oc # Bk # Bk # ires, Bk\<^bsup>rn-Suc 0\<^esup>)"
       
  4621 apply(simp add: t_step.simps)
       
  4622 apply(case_tac "start_of (layout_of aprog) as", 
       
  4623       auto simp: new_tape.simps)
       
  4624 done
       
  4625 
       
  4626 lemma [simp]: "start_of (layout_of aprog) as > 0 \<Longrightarrow> 
       
  4627  t_step (start_of (layout_of aprog) as, Bk # Bk # ires, Oc # r' @ Bk\<^bsup>rn\<^esup>) 
       
  4628       (ci (layout_of aprog) (start_of (layout_of aprog) as) (Dec n e),
       
  4629                  start_of (layout_of aprog) as - Suc 0) =
       
  4630       (Suc (start_of (layout_of aprog) as), Oc # Bk # Bk # ires, r' @ Bk\<^bsup>rn\<^esup>)"
       
  4631 apply(simp add: t_step.simps)
       
  4632 apply(case_tac "start_of (layout_of aprog) as", 
       
  4633       auto simp: new_tape.simps)
       
  4634 done
       
  4635 
       
  4636 lemma crsp_next_state:
       
  4637   "\<lbrakk>crsp_l (layout_of aprog) (as, am) tc ires; 
       
  4638     abc_fetch as aprog = Some (Dec n e)\<rbrakk>
       
  4639   \<Longrightarrow> \<exists> stp' > 0. (\<lambda> (s, l, r). 
       
  4640            (s = Suc (start_of (layout_of aprog) as) 
       
  4641  \<and> (dec_inv_1 (layout_of aprog) n e (as, am) (s, l, r) ires) 
       
  4642  \<and> (dec_inv_2 (layout_of aprog) n e (as, am) (s, l, r)) ires)) 
       
  4643      (t_steps tc (ci (layout_of aprog) (start_of (layout_of aprog) as)
       
  4644              (Dec n e), start_of (layout_of aprog) as - Suc 0) stp')"
       
  4645 apply(subgoal_tac "start_of (layout_of aprog) as > 0")
       
  4646 apply(case_tac tc, case_tac b, auto simp: crsp_l.simps)
       
  4647 apply(case_tac "am = []", simp)
       
  4648 apply(rule_tac x = "Suc (Suc 0)" in exI, simp add: t_steps.simps)
       
  4649 proof-
       
  4650   fix  rn
       
  4651   assume h1: "am \<noteq> []" "abc_fetch as aprog = Some (Dec n e)" 
       
  4652              "start_of (layout_of aprog) as > 0"
       
  4653   hence h2: "\<exists> r'. <am> = Oc # r'"
       
  4654     by simp
       
  4655   from h1 and h2 show 
       
  4656    "\<exists>stp'>0. case t_steps (start_of (layout_of aprog) as, Bk # Bk # ires, <am> @ Bk\<^bsup>rn\<^esup>)
       
  4657     (ci (layout_of aprog) (start_of (layout_of aprog) as) (Dec n e),
       
  4658     start_of (layout_of aprog) as - Suc 0) stp' of
       
  4659     (s, ab) \<Rightarrow> s = Suc (start_of (layout_of aprog) as) \<and>
       
  4660     dec_inv_1 (layout_of aprog) n e (as, am) (s, ab) ires \<and> 
       
  4661     dec_inv_2 (layout_of aprog) n e (as, am) (s, ab) ires"
       
  4662   proof(erule_tac exE, simp, rule_tac x = "Suc 0" in exI, 
       
  4663         simp add: t_steps.simps)
       
  4664   qed
       
  4665 next
       
  4666   assume "abc_fetch as aprog = Some (Dec n e)"
       
  4667   thus "0 < start_of (layout_of aprog) as"
       
  4668    apply(insert startof_not0[of "layout_of aprog" as], simp)
       
  4669    done
       
  4670 qed
       
  4671 
       
  4672 lemma dec_crsp_ex1: 
       
  4673   "\<lbrakk>crsp_l (layout_of aprog) (as, am) tc ires;
       
  4674   abc_fetch as aprog = Some (Dec n e); 
       
  4675   abc_lm_v am n = 0\<rbrakk>
       
  4676   \<Longrightarrow> \<exists>stp > 0. crsp_l (layout_of aprog) (e, abc_lm_s am n 0) 
       
  4677     (t_steps tc (ci (layout_of aprog) (start_of (layout_of aprog) as)
       
  4678  (Dec n e), start_of (layout_of aprog) as - Suc 0) stp) ires"
       
  4679 proof -
       
  4680   assume h1: "crsp_l (layout_of aprog) (as, am) tc ires" 
       
  4681        "abc_fetch as aprog = Some (Dec n e)" "abc_lm_v am n = 0"
       
  4682   hence h2: "\<exists> stp' > 0. (\<lambda> (s, l, r). 
       
  4683     (s = Suc (start_of (layout_of aprog) as) \<and> 
       
  4684  (dec_inv_1 (layout_of aprog) n e (as, am) (s, l, r)) ires)) 
       
  4685    (t_steps tc (ci (layout_of aprog) (start_of (layout_of aprog) as) 
       
  4686       (Dec n e), start_of (layout_of aprog) as - Suc 0) stp')"
       
  4687     apply(insert crsp_next_state[of aprog as am tc ires n e], auto)
       
  4688     done
       
  4689   from h1 and h2 show 
       
  4690  "\<exists>stp > 0. crsp_l (layout_of aprog) (e, abc_lm_s am n 0) 
       
  4691            (t_steps tc (ci (layout_of aprog) (start_of 
       
  4692                 (layout_of aprog) as) (Dec n e), 
       
  4693                     start_of (layout_of aprog) as - Suc 0) stp) ires" 
       
  4694   proof(erule_tac exE, case_tac "(t_steps tc (ci (layout_of aprog)
       
  4695        (start_of (layout_of aprog) as) (Dec n e), start_of 
       
  4696           (layout_of aprog) as - Suc 0) stp')",  simp)
       
  4697     fix stp' a b c
       
  4698     assume h3: "stp' > 0 \<and> a = Suc (start_of (layout_of aprog) as) \<and> 
       
  4699                dec_inv_1 (layout_of aprog) n e (as, am) (a, b, c) ires" 
       
  4700              "abc_fetch as aprog = Some (Dec n e)" "abc_lm_v am n = 0"
       
  4701      "t_steps tc (ci (layout_of aprog) (start_of (layout_of aprog) as)
       
  4702           (Dec n e), start_of (layout_of aprog) as - Suc 0) stp' 
       
  4703         = (Suc (start_of (layout_of aprog) as), b, c)" 
       
  4704     thus "\<exists>stp > 0. crsp_l (layout_of aprog) (e, abc_lm_s am n 0) 
       
  4705      (t_steps tc (ci (layout_of aprog) (start_of (layout_of aprog) as)
       
  4706            (Dec n e), start_of (layout_of aprog) as - Suc 0) stp) ires"
       
  4707     proof(erule_tac conjE, simp)
       
  4708       assume "dec_inv_1 (layout_of aprog) n e (as, am) 
       
  4709                     (Suc (start_of (layout_of aprog) as), b, c) ires"     
       
  4710              "abc_fetch as aprog = Some (Dec n e)" 
       
  4711              "abc_lm_v am n = 0"
       
  4712              " t_steps tc (ci (layout_of aprog) 
       
  4713               (start_of (layout_of aprog) as) (Dec n e), 
       
  4714                start_of (layout_of aprog) as - Suc 0) stp' 
       
  4715              = (Suc (start_of (layout_of aprog) as), b, c)"
       
  4716       hence h4: "\<exists>stp. (\<lambda>(s', l', r'). s' = 
       
  4717                      start_of (layout_of aprog) e \<and> 
       
  4718                 dec_inv_1 (layout_of aprog) n e (as, am) (s', l', r') ires)
       
  4719                  (t_steps (start_of (layout_of aprog) as + 1, b, c) 
       
  4720                   (ci (layout_of aprog) 
       
  4721                       (start_of (layout_of aprog) as) (Dec n e), 
       
  4722                          start_of (layout_of aprog) as - Suc 0) stp)"
       
  4723 	apply(rule_tac dec_inv_stop1, auto)
       
  4724 	done
       
  4725       from  h3 and h4 show ?thesis
       
  4726 	apply(erule_tac exE)
       
  4727 	apply(rule_tac x = "stp' + stp" in exI, simp)
       
  4728 	apply(case_tac "(t_steps (Suc (start_of (layout_of aprog) as),
       
  4729                      b, c) (ci (layout_of aprog) 
       
  4730                      (start_of (layout_of aprog) as) (Dec n e), 
       
  4731                       start_of (layout_of aprog) as - Suc 0) stp)", 
       
  4732               simp)
       
  4733 	apply(rule_tac dec_inv_stop_cond1, auto)
       
  4734 	done
       
  4735     qed
       
  4736   qed
       
  4737 qed
       
  4738 	  
       
  4739 lemma dec_crsp_ex2:
       
  4740   "\<lbrakk>crsp_l (layout_of aprog) (as, am) tc ires; 
       
  4741     abc_fetch as aprog = Some (Dec n e);
       
  4742     0 < abc_lm_v am n\<rbrakk>
       
  4743  \<Longrightarrow> \<exists>stp > 0. crsp_l (layout_of aprog) 
       
  4744                (Suc as, abc_lm_s am n (abc_lm_v am n - Suc 0))
       
  4745    (t_steps tc (ci (layout_of aprog) (start_of (layout_of aprog) as) 
       
  4746               (Dec n e), start_of (layout_of aprog) as - Suc 0) stp) ires"
       
  4747 proof -
       
  4748   assume h1: 
       
  4749  "crsp_l (layout_of aprog) (as, am) tc ires" 
       
  4750  "abc_fetch as aprog = Some (Dec n e)"
       
  4751   "abc_lm_v am n > 0"
       
  4752   hence h2: 
       
  4753  "\<exists> stp' > 0. (\<lambda> (s, l, r). (s = Suc (start_of (layout_of aprog) as)
       
  4754  \<and> (dec_inv_2 (layout_of aprog) n e (as, am) (s, l, r)) ires)) 
       
  4755 (t_steps tc (ci (layout_of aprog) (start_of (layout_of aprog) as) 
       
  4756               (Dec n e), start_of (layout_of aprog) as - Suc 0) stp')"
       
  4757     apply(insert crsp_next_state[of aprog as am tc ires n e], auto)
       
  4758     done
       
  4759   from h1 and h2 show 
       
  4760  "\<exists>stp >0. crsp_l (layout_of aprog) 
       
  4761    (Suc as, abc_lm_s am n (abc_lm_v am n - Suc 0))
       
  4762    (t_steps tc (ci (layout_of aprog) (start_of (layout_of aprog) as) 
       
  4763                (Dec n e), start_of (layout_of aprog) as - Suc 0) stp) ires"
       
  4764   proof(erule_tac exE, 
       
  4765         case_tac 
       
  4766  "(t_steps tc (ci (layout_of aprog) (start_of (layout_of aprog) as) 
       
  4767       (Dec n e), start_of (layout_of aprog) as - Suc 0) stp')",  simp)
       
  4768     fix stp' a b c
       
  4769     assume h3: "0 < stp' \<and> a = Suc (start_of (layout_of aprog) as) \<and>
       
  4770                dec_inv_2 (layout_of aprog) n e (as, am) (a, b, c) ires" 
       
  4771                "abc_fetch as aprog = Some (Dec n e)" 
       
  4772                "abc_lm_v am n > 0"
       
  4773                "t_steps tc (ci (layout_of aprog) 
       
  4774                    (start_of (layout_of aprog) as) (Dec n e), 
       
  4775                      start_of (layout_of aprog) as - Suc 0) stp' 
       
  4776                   = (Suc (start_of (layout_of aprog) as), b, c)"
       
  4777     thus "?thesis"
       
  4778     proof(erule_tac conjE, simp)
       
  4779       assume 
       
  4780     "dec_inv_2 (layout_of aprog) n e (as, am) 
       
  4781       (Suc (start_of (layout_of aprog) as), b, c) ires" 
       
  4782     "abc_fetch as aprog = Some (Dec n e)" "abc_lm_v am n > 0"
       
  4783     "t_steps tc (ci (layout_of aprog) (start_of (layout_of aprog) as)
       
  4784          (Dec n e), start_of (layout_of aprog) as - Suc 0) stp'
       
  4785              = (Suc (start_of (layout_of aprog) as), b, c)"
       
  4786       hence h4: 
       
  4787    "\<exists>stp. (\<lambda>(s', l', r'). s' = start_of (layout_of aprog) (Suc as) \<and>
       
  4788            dec_inv_2 (layout_of aprog) n e (as, am) (s', l', r') ires)
       
  4789              (t_steps (start_of (layout_of aprog) as + 1, b, c) 
       
  4790               (ci (layout_of aprog) (start_of (layout_of aprog) as) 
       
  4791                (Dec n e), start_of (layout_of aprog) as - Suc 0) stp)"
       
  4792 	apply(rule_tac dec_stop2, auto)
       
  4793 	done
       
  4794       from  h3 and h4 show ?thesis
       
  4795 	apply(erule_tac exE)
       
  4796 	apply(rule_tac x = "stp' + stp" in exI, simp)
       
  4797 	apply(case_tac 
       
  4798          "(t_steps (Suc (start_of (layout_of aprog) as), b, c) 
       
  4799            (ci (layout_of aprog) (start_of (layout_of aprog) as)
       
  4800              (Dec n e), start_of (layout_of aprog) as - Suc 0) stp)"
       
  4801               ,simp)
       
  4802 	apply(rule_tac dec_inv_stop_cond2, auto)
       
  4803 	done
       
  4804     qed
       
  4805   qed
       
  4806 qed
       
  4807 
       
  4808 lemma dec_crsp_ex_pre:
       
  4809   "\<lbrakk>ly = layout_of aprog; crsp_l ly (as, am) tc ires; 
       
  4810      abc_fetch as aprog = Some (Dec n e)\<rbrakk>
       
  4811  \<Longrightarrow> \<exists>stp > 0. crsp_l ly (abc_step_l (as, am) (Some (Dec n e))) 
       
  4812       (t_steps tc (ci (layout_of aprog) (start_of ly as) (Dec n e),
       
  4813                                        start_of ly as - Suc 0) stp) ires"
       
  4814 apply(auto simp: abc_step_l.simps intro: dec_crsp_ex2 dec_crsp_ex1)
       
  4815 done
       
  4816 
       
  4817 lemma dec_crsp_ex:
       
  4818   assumes layout: -- {* There is an Abacus program @{text "aprog"} with layout @{text "ly"} *}
       
  4819   "ly = layout_of aprog"
       
  4820   and dec: -- {* There is an @{text "Dec n e"} instruction at postion @{text "as"} of @{text "aprog"} *}
       
  4821       "abc_fetch as aprog = Some (Dec n e)"
       
  4822   and correspond: 
       
  4823   -- {* Abacus configuration @{text "(as, am)"} is in correspondence with TM 
       
  4824          configuration @{text "tc"}
       
  4825       *}
       
  4826   "crsp_l ly (as, am) tc ires"
       
  4827 shows 
       
  4828    "\<exists>stp > 0. crsp_l ly (abc_step_l (as, am) (Some (Dec n e))) 
       
  4829       (t_steps tc (ci (layout_of aprog) (start_of ly as) (Dec n e),
       
  4830                                        start_of ly as - Suc 0) stp) ires"
       
  4831 proof -
       
  4832   from dec_crsp_ex_pre layout dec correspond  show ?thesis by blast
       
  4833 qed
       
  4834 
       
  4835 (*
       
  4836 subsection {* Compilation of @{text "Goto n"}*}
       
  4837 *)
       
  4838 
       
  4839 lemma goto_fetch: 
       
  4840      "fetch (ci (layout_of aprog) 
       
  4841          (start_of (layout_of aprog) as) (Goto n)) (Suc 0)  b
       
  4842      = (Nop, start_of (layout_of aprog) n)"
       
  4843 apply(auto simp: ci.simps fetch.simps nth_of.simps 
       
  4844            split: block.splits)
       
  4845 done
       
  4846 
       
  4847 text {*
       
  4848   Correctness of complied @{text "Goto n"}
       
  4849   *}
       
  4850 
       
  4851 lemma goto_crsp_ex_pre: 
       
  4852   "\<lbrakk>ly = layout_of aprog; 
       
  4853     crsp_l ly (as, am) tc ires;
       
  4854     abc_fetch as aprog = Some (Goto n)\<rbrakk>
       
  4855  \<Longrightarrow> \<exists>stp > 0. crsp_l ly (abc_step_l (as, am) (Some (Goto n))) 
       
  4856       (t_steps tc (ci (layout_of aprog) (start_of ly as) (Goto n), 
       
  4857                                         start_of ly as - Suc 0) stp) ires"
       
  4858 apply(rule_tac x = 1 in exI)
       
  4859 apply(simp add: abc_step_l.simps t_steps.simps t_step.simps)
       
  4860 apply(case_tac tc, simp)
       
  4861 apply(subgoal_tac "a = start_of (layout_of aprog) as", auto)
       
  4862 apply(subgoal_tac "start_of (layout_of aprog) as > 0", simp)
       
  4863 apply(auto simp: goto_fetch new_tape.simps crsp_l.simps)
       
  4864 apply(rule startof_not0)
       
  4865 done
       
  4866 
       
  4867 lemma goto_crsp_ex:
       
  4868   assumes layout: "ly = layout_of aprog"
       
  4869   and goto: "abc_fetch as aprog = Some (Goto n)"
       
  4870   and correspondence: "crsp_l ly (as, am) tc ires"
       
  4871   shows "\<exists>stp>0. crsp_l ly (abc_step_l (as, am) (Some (Goto n))) 
       
  4872               (t_steps tc (ci (layout_of aprog) (start_of ly as) (Goto n),
       
  4873                                            start_of ly as - Suc 0) stp) ires"
       
  4874 proof -
       
  4875   from goto_crsp_ex_pre and layout goto correspondence show "?thesis" by blast
       
  4876 qed
       
  4877 
       
  4878 subsection {*
       
  4879   The correctness of the compiler
       
  4880   *}
       
  4881 
       
  4882 declare abc_step_l.simps[simp del]
       
  4883 
       
  4884 lemma tm_crsp_ex: 
       
  4885          "\<lbrakk>ly = layout_of aprog;
       
  4886            crsp_l ly (as, am) tc ires; 
       
  4887            as < length aprog;
       
  4888            abc_fetch as aprog = Some ins\<rbrakk>
       
  4889       \<Longrightarrow> \<exists> n > 0. crsp_l ly (abc_step_l (as,am) (Some ins))
       
  4890                (t_steps tc (ci (layout_of aprog) (start_of ly as) 
       
  4891                   (ins), (start_of ly as) - (Suc 0)) n) ires"
       
  4892 apply(case_tac "ins", simp)
       
  4893 apply(auto intro: inc_crsp_ex_pre dec_crsp_ex goto_crsp_ex)
       
  4894 done
       
  4895 
       
  4896 lemma start_of_pre: 
       
  4897   "n < length aprog \<Longrightarrow> start_of (layout_of aprog) n
       
  4898                      = start_of (layout_of (butlast aprog)) n"
       
  4899 apply(induct n, simp add: start_of.simps, simp)
       
  4900 apply(simp add: layout_of.simps start_of.simps)
       
  4901 apply(subgoal_tac "n < length aprog - Suc 0", simp)
       
  4902 apply(subgoal_tac "(aprog ! n) = (butlast aprog ! n)", simp)
       
  4903 proof -
       
  4904   fix n
       
  4905   assume h1: "Suc n < length aprog"
       
  4906   thus "aprog ! n = butlast aprog ! n"
       
  4907     apply(case_tac "length aprog", simp, simp)
       
  4908     apply(insert nth_append[of "butlast aprog" "[last aprog]" n])
       
  4909     apply(subgoal_tac "(butlast aprog @ [last aprog]) = aprog")
       
  4910     apply(simp split: if_splits)
       
  4911     apply(rule append_butlast_last_id, case_tac aprog, simp, simp)
       
  4912     done
       
  4913 next
       
  4914   fix n
       
  4915   assume "Suc n < length aprog"
       
  4916   thus "n < length aprog - Suc 0"
       
  4917     apply(case_tac aprog, simp, simp)
       
  4918     done
       
  4919 qed
       
  4920     
       
  4921 lemma zip_eq: "xs = ys \<Longrightarrow> zip xs zs = zip ys zs"
       
  4922 by simp
       
  4923 
       
  4924 lemma tpairs_of_append_iff: "length aprog = Suc n \<Longrightarrow> 
       
  4925          tpairs_of aprog = tpairs_of (butlast aprog) @ 
       
  4926                      [(start_of (layout_of aprog) n, aprog ! n)]"
       
  4927 apply(simp add: tpairs_of.simps)
       
  4928 apply(insert zip_append[of "map (start_of (layout_of aprog)) [0..<n]"
       
  4929      "butlast aprog" "[start_of (layout_of aprog) n]" "[last aprog]"])
       
  4930 apply(simp del: zip_append)
       
  4931 apply(subgoal_tac "(butlast aprog @ [last aprog]) = aprog", auto)
       
  4932 apply(rule_tac zip_eq, auto)
       
  4933 apply(rule_tac start_of_pre, simp)
       
  4934 apply(insert last_conv_nth[of aprog], case_tac aprog, simp, simp)
       
  4935 apply(rule append_butlast_last_id, case_tac aprog, simp, simp)
       
  4936 done
       
  4937 
       
  4938 lemma [simp]: "list_all (\<lambda>(n, tm). abacus.t_ncorrect (ci layout n tm))
       
  4939          (zip (map (start_of layout) [0..<length aprog]) aprog)"
       
  4940 proof(induct "length aprog" arbitrary: aprog, simp)
       
  4941   fix x aprog
       
  4942   assume ind: "\<And>aprog. x = length aprog \<Longrightarrow> 
       
  4943         list_all (\<lambda>(n, tm). abacus.t_ncorrect (ci layout n tm))
       
  4944            (zip (map (start_of layout) [0..<length aprog]) aprog)"
       
  4945   and h: "Suc x = length (aprog::abc_inst list)"
       
  4946   have g1: "list_all (\<lambda>(n, tm). abacus.t_ncorrect (ci layout n tm)) 
       
  4947     (zip (map (start_of layout) [0..<length (butlast aprog)]) 
       
  4948                                                  (butlast aprog))"
       
  4949     using h
       
  4950     apply(rule_tac ind, auto)
       
  4951     done
       
  4952   have g2: "(map (start_of layout) [0..<length aprog]) = 
       
  4953                      map (start_of layout) ([0..<length aprog - 1] 
       
  4954          @ [length aprog - 1])"
       
  4955     using h
       
  4956     apply(case_tac aprog, simp, simp)
       
  4957     done
       
  4958   have "\<exists> xs a. aprog = xs @ [a]"
       
  4959     using h
       
  4960     apply(rule_tac x = "butlast aprog" in exI, 
       
  4961           rule_tac x = "last aprog" in exI)
       
  4962     apply(case_tac "aprog = []", simp, simp)
       
  4963     done
       
  4964   from this obtain xs where "\<exists> a. aprog = xs @ [a]" ..
       
  4965   from this obtain a where g3: "aprog = xs @ [a]" ..
       
  4966   from g1 and g2 and g3 show "list_all (\<lambda>(n, tm). 
       
  4967                               abacus.t_ncorrect (ci layout n tm)) 
       
  4968               (zip (map (start_of layout) [0..<length aprog]) aprog)"
       
  4969     apply(simp)
       
  4970     apply(auto simp: t_ncorrect.simps ci.simps  tshift.simps 
       
  4971           tinc_b_def tdec_b_def split: abc_inst.splits)
       
  4972     apply arith+
       
  4973     done
       
  4974 qed
       
  4975 
       
  4976 lemma [intro]: "abc2t_correct aprog"
       
  4977 apply(simp add: abc2t_correct.simps tpairs_of.simps 
       
  4978           split: abc_inst.splits)
       
  4979 done
       
  4980 
       
  4981 lemma as_out: "\<lbrakk>ly = layout_of aprog; tprog = tm_of aprog; 
       
  4982                 crsp_l ly (as, am) tc ires; length aprog \<le> as\<rbrakk> 
       
  4983             \<Longrightarrow> abc_step_l (as, am) (abc_fetch as aprog) = (as, am)"
       
  4984 apply(simp add: abc_fetch.simps abc_step_l.simps)
       
  4985 done
       
  4986 
       
  4987 lemma tm_merge_ex: 
       
  4988   "\<lbrakk>crsp_l (layout_of aprog) (as, am) tc ires; 
       
  4989     as < length aprog; 
       
  4990     abc_fetch as aprog = Some a; 
       
  4991     abc2t_correct aprog;
       
  4992     crsp_l (layout_of aprog) (abc_step_l (as, am) (Some a))
       
  4993      (t_steps tc (ci (layout_of aprog) (start_of (layout_of aprog) as)
       
  4994          a, start_of (layout_of aprog) as - Suc 0) n) ires; 
       
  4995     n > 0\<rbrakk>
       
  4996    \<Longrightarrow> \<exists>stp > 0. crsp_l (layout_of aprog) (abc_step_l (as, am) 
       
  4997                        (Some a)) (t_steps tc (tm_of aprog, 0) stp) ires"
       
  4998 apply(case_tac "(t_steps tc (ci (layout_of aprog) 
       
  4999            (start_of (layout_of aprog) as) a, 
       
  5000             start_of (layout_of aprog) as - Suc 0) n)",  simp)
       
  5001 apply(case_tac "(abc_step_l (as, am) (Some a))", simp)
       
  5002 proof -
       
  5003   fix aa b c aaa ba 
       
  5004   assume h: 
       
  5005   "crsp_l (layout_of aprog) (as, am) tc ires" 
       
  5006   "as < length aprog" 
       
  5007   "abc_fetch as aprog = Some a" 
       
  5008   "crsp_l (layout_of aprog) (aaa, ba) (aa, b, c) ires" 
       
  5009   "abc2t_correct aprog" 
       
  5010   "n>0"
       
  5011   "t_steps tc (ci (layout_of aprog) (start_of (layout_of aprog) as) a,
       
  5012       start_of (layout_of aprog) as - Suc 0) n = (aa, b, c)" 
       
  5013    "abc_step_l (as, am) (Some a) = (aaa, ba)"
       
  5014   hence "aa = start_of (layout_of aprog) aaa"
       
  5015     apply(simp add: crsp_l.simps)
       
  5016     done
       
  5017   from this and h show 
       
  5018   "\<exists>stp > 0. crsp_l (layout_of aprog) (aaa, ba) 
       
  5019                           (t_steps tc (tm_of aprog, 0) stp) ires"
       
  5020     apply(insert tms_out_ex[of "layout_of aprog" aprog 
       
  5021                 "tm_of aprog" as am tc ires a n aa b c aaa ba], auto)
       
  5022     done
       
  5023 qed
       
  5024  
       
  5025 lemma crsp_inside: 
       
  5026   "\<lbrakk>ly = layout_of aprog; 
       
  5027     tprog = tm_of aprog;
       
  5028     crsp_l ly (as, am) tc ires;
       
  5029     as < length aprog\<rbrakk> \<Longrightarrow> 
       
  5030     (\<exists> stp > 0. crsp_l ly (abc_step_l (as,am) (abc_fetch as aprog)) 
       
  5031                                          (t_steps tc (tprog, 0) stp) ires)"
       
  5032 apply(case_tac "abc_fetch as aprog", simp add: abc_fetch.simps)
       
  5033 proof -
       
  5034   fix a
       
  5035   assume "ly = layout_of aprog" 
       
  5036      "tprog = tm_of aprog" 
       
  5037      "crsp_l ly (as, am) tc ires" 
       
  5038      "as < length aprog" 
       
  5039      "abc_fetch as aprog = Some a"
       
  5040   thus "\<exists>stp > 0. crsp_l ly (abc_step_l (as, am) 
       
  5041                  (abc_fetch as aprog)) (t_steps tc (tprog, 0) stp) ires"
       
  5042     proof(insert tm_crsp_ex[of ly aprog as am tc ires a], 
       
  5043           auto intro: tm_merge_ex)
       
  5044   qed
       
  5045 qed
       
  5046 
       
  5047 lemma crsp_outside: 
       
  5048   "\<lbrakk>ly = layout_of aprog; tprog = tm_of aprog;
       
  5049     crsp_l ly (as, am) tc ires; as \<ge> length aprog\<rbrakk>
       
  5050     \<Longrightarrow> (\<exists> stp. crsp_l ly (abc_step_l (as,am) (abc_fetch as aprog)) 
       
  5051                                          (t_steps tc (tprog, 0) stp) ires)"
       
  5052 apply(subgoal_tac "abc_step_l (as, am) (abc_fetch as aprog)
       
  5053                 = (as, am)", simp)
       
  5054 apply(rule_tac x = 0 in exI, simp add: t_steps.simps)
       
  5055 apply(rule as_out, simp+)
       
  5056 done
       
  5057 
       
  5058 text {*
       
  5059   Single-step correntess of the compiler.
       
  5060 *}
       
  5061 lemma astep_crsp_pre: 
       
  5062       "\<lbrakk>ly = layout_of aprog; 
       
  5063         tprog = tm_of aprog;
       
  5064         crsp_l ly (as, am) tc ires\<rbrakk>
       
  5065        \<Longrightarrow> (\<exists> stp. crsp_l ly (abc_step_l (as,am) 
       
  5066                   (abc_fetch as aprog)) (t_steps tc (tprog, 0) stp) ires)"
       
  5067 apply(case_tac "as < length aprog")
       
  5068 apply(drule_tac crsp_inside, auto)
       
  5069 apply(rule_tac crsp_outside, simp+)
       
  5070 done
       
  5071 
       
  5072 text {*
       
  5073   Single-step correntess of the compiler.
       
  5074 *}
       
  5075 lemma astep_crsp_pre1: 
       
  5076       "\<lbrakk>ly = layout_of aprog;
       
  5077         tprog = tm_of aprog;
       
  5078         crsp_l ly (as, am) tc ires\<rbrakk>
       
  5079        \<Longrightarrow> (\<exists> stp. crsp_l ly (abc_step_l (as,am) 
       
  5080                   (abc_fetch as aprog)) (t_steps tc (tprog, 0) stp) ires)"
       
  5081 apply(case_tac "as < length aprog")
       
  5082 apply(drule_tac crsp_inside, auto)
       
  5083 apply(rule_tac crsp_outside, simp+)
       
  5084 done
       
  5085 
       
  5086 lemma astep_crsp:
       
  5087   assumes layout: 
       
  5088   -- {* There is a Abacus program @{text "aprog"} with layout @{text "ly"} *}
       
  5089   "ly = layout_of aprog"
       
  5090   and compiled: 
       
  5091   -- {* @{text "tprog"} is the TM compiled from @{text "aprog"} *}
       
  5092   "tprog = tm_of aprog"
       
  5093   and corresponds: 
       
  5094   -- {* Abacus configuration @{text "(as, am)"} is in correspondence with TM configuration
       
  5095    @{text "tc"} *}
       
  5096   "crsp_l ly (as, am) tc ires"
       
  5097   -- {* One step execution of @{text "aprog"} can be simulated by multi-step execution 
       
  5098   of @{text "tprog"} *}
       
  5099   shows "(\<exists> stp. crsp_l ly (abc_step_l (as,am) 
       
  5100                   (abc_fetch as aprog)) (t_steps tc (tprog, 0) stp) ires)"
       
  5101 proof -
       
  5102   from astep_crsp_pre1 [OF layout compiled corresponds] show ?thesis .
       
  5103 qed
       
  5104 
       
  5105 lemma steps_crsp_pre: 
       
  5106     "\<lbrakk>ly = layout_of aprog; tprog = tm_of aprog; 
       
  5107       crsp_l ly ac tc ires; ac' = abc_steps_l ac aprog n\<rbrakk> \<Longrightarrow> 
       
  5108         (\<exists> n'. crsp_l ly ac' (t_steps tc (tprog, 0) n') ires)"
       
  5109 apply(induct n arbitrary: ac' ac tc, simp add: abc_steps_l.simps)
       
  5110 apply(rule_tac x = 0 in exI)
       
  5111 apply(case_tac ac, simp add: abc_steps_l.simps t_steps.simps)
       
  5112 apply(case_tac ac, simp add: abc_steps_l.simps)
       
  5113 apply(subgoal_tac 
       
  5114    "(\<exists> stp. crsp_l ly (abc_step_l (a, b)
       
  5115             (abc_fetch a aprog)) (t_steps tc (tprog, 0) stp) ires)")
       
  5116 apply(erule exE)
       
  5117 apply(subgoal_tac 
       
  5118    "\<exists>n'. crsp_l (layout_of aprog) 
       
  5119     (abc_steps_l (abc_step_l (a, b) (abc_fetch a aprog)) aprog n)
       
  5120          (t_steps ((t_steps tc (tprog, 0) stp)) (tm_of aprog, 0) n') ires")
       
  5121 apply(erule exE)
       
  5122 apply(subgoal_tac 
       
  5123     "t_steps (t_steps tc (tprog, 0) stp) (tm_of aprog, 0) n' =
       
  5124      t_steps tc (tprog, 0) (stp + n')")
       
  5125 apply(rule_tac x = "stp + n'" in exI, simp)
       
  5126 apply(auto intro: astep_crsp simp: t_step_add)
       
  5127 done
       
  5128 
       
  5129 text {*
       
  5130   Multi-step correctess of the compiler.
       
  5131 *}
       
  5132 
       
  5133 lemma steps_crsp: 
       
  5134   assumes layout: 
       
  5135   -- {* There is an Abacus program @{text "aprog"} with layout @{text "ly"} *}
       
  5136     "ly = layout_of aprog"
       
  5137   and compiled: 
       
  5138   -- {* @{text "tprog"} is the TM compiled from @{text "aprog"} *}
       
  5139   "tprog = tm_of aprog"
       
  5140   and correspond: 
       
  5141   -- {* Abacus configuration @{text "ac"} is in correspondence with TM configuration @{text "tc"} *}
       
  5142       "crsp_l ly ac tc ires"
       
  5143   and execution: 
       
  5144   -- {* @{text "ac'"} is the configuration obtained from @{text "n"}-step execution 
       
  5145       of @{text "aprog"} starting from configuration @{text "ac"} *}
       
  5146   "ac' = abc_steps_l ac aprog n" 
       
  5147   -- {* There exists steps @{text "n'"} steps, after these steps of execution, 
       
  5148   the Turing configuration such obtained is in correspondence with @{text "ac'"} *}
       
  5149   shows "(\<exists> n'. crsp_l ly ac' (t_steps tc (tprog, 0) n') ires)"
       
  5150 proof -
       
  5151   from steps_crsp_pre [OF layout compiled correspond execution] show ?thesis .
       
  5152 qed
       
  5153 
       
  5154 subsection {* The Mop-up machine *}
       
  5155 
       
  5156 fun mop_bef :: "nat \<Rightarrow> tprog"
       
  5157   where
       
  5158   "mop_bef 0 = []" |
       
  5159   "mop_bef (Suc n) = mop_bef n @ 
       
  5160        [(R, 2*n + 3), (W0, 2*n + 2), (R, 2*n + 1), (W1, 2*n + 2)]"
       
  5161 
       
  5162 definition mp_up :: "tprog"
       
  5163   where
       
  5164   "mp_up \<equiv> [(R, 2), (R, 1), (L, 5), (W0, 3), (R, 4), (W0, 3),
       
  5165             (R, 2), (W0, 3), (L, 5), (L, 6), (R, 0), (L, 6)]"
       
  5166 
       
  5167 fun tMp :: "nat \<Rightarrow> nat \<Rightarrow> tprog"
       
  5168   where 
       
  5169   "tMp n off = tshift (mop_bef n @ tshift mp_up (2*n)) off"
       
  5170 
       
  5171 declare  mp_up_def[simp del]  tMp.simps[simp del] mop_bef.simps[simp del]
       
  5172 (**********Begin: equiv among aba and turing***********)
       
  5173 
       
  5174 lemma tm_append_step: 
       
  5175  "\<lbrakk>t_ncorrect tp1; t_step tc (tp1, 0) = (s, l, r); s \<noteq> 0\<rbrakk> 
       
  5176  \<Longrightarrow> t_step tc (tp1 @ tp2, 0) = (s, l, r)"
       
  5177 apply(simp add: t_step.simps)
       
  5178 apply(case_tac tc, simp)
       
  5179 apply(case_tac 
       
  5180        "(fetch tp1 a (case c of [] \<Rightarrow> Bk |
       
  5181                Bk # xs \<Rightarrow> Bk | Oc # xs \<Rightarrow> Oc))", simp)
       
  5182 apply(case_tac a, simp add: fetch.simps)
       
  5183 apply(simp add: fetch.simps)
       
  5184 apply(case_tac c, simp)
       
  5185 apply(case_tac [!] "ab::block")
       
  5186 apply(auto simp: nth_of.simps nth_append t_ncorrect.simps 
       
  5187            split: if_splits)
       
  5188 done
       
  5189 
       
  5190 lemma state0_ind: "t_steps (0, l, r) (tp, 0) stp = (0, l, r)"
       
  5191 apply(induct stp, simp add: t_steps.simps)
       
  5192 apply(simp add: t_steps.simps t_step.simps fetch.simps new_tape.simps)
       
  5193 done
       
  5194 
       
  5195 lemma tm_append_steps:  
       
  5196  "\<lbrakk>t_ncorrect tp1; t_steps tc (tp1, 0) stp = (s, l ,r); s \<noteq> 0\<rbrakk>
       
  5197   \<Longrightarrow> t_steps tc (tp1 @ tp2, 0) stp = (s, l, r)"
       
  5198 apply(induct stp arbitrary: tc s l r)
       
  5199 apply(case_tac tc,  simp)
       
  5200 apply(simp add: t_steps.simps)
       
  5201 proof -
       
  5202   fix stp tc s l r
       
  5203   assume h1: "\<And>tc s l r. \<lbrakk>t_ncorrect tp1; t_steps tc (tp1, 0) stp = 
       
  5204    (s, l, r); s \<noteq> 0\<rbrakk> \<Longrightarrow> t_steps tc (tp1 @ tp2, 0) stp = (s, l, r)"
       
  5205     and h2: "t_steps tc (tp1, 0) (Suc stp) = (s, l, r)" "s \<noteq> 0" 
       
  5206             "t_ncorrect tp1"
       
  5207   thus "t_steps tc (tp1 @ tp2, 0) (Suc stp) = (s, l, r)"
       
  5208     apply(simp add: t_steps.simps)
       
  5209     apply(case_tac "(t_step tc (tp1, 0))", simp)
       
  5210     proof-
       
  5211       fix a b c 
       
  5212       assume g1: "\<And>tc s l r. \<lbrakk>t_steps tc (tp1, 0) stp = (s, l, r); 
       
  5213                 0 < s\<rbrakk> \<Longrightarrow> t_steps tc (tp1 @ tp2, 0) stp = (s, l, r)"
       
  5214 	and g2: "t_step tc (tp1, 0) = (a, b, c)" 
       
  5215                 "t_steps (a, b, c) (tp1, 0) stp = (s, l, r)" 
       
  5216                 "0 < s" 
       
  5217                 "t_ncorrect tp1"
       
  5218       hence g3: "a > 0"
       
  5219 	apply(case_tac "a::nat", auto simp: t_steps.simps)
       
  5220 	apply(simp add: state0_ind)
       
  5221 	done
       
  5222       from g1 and g2 and this have g4: 
       
  5223                     "(t_step tc (tp1 @ tp2, 0)) = (a, b, c)"
       
  5224 	apply(rule_tac tm_append_step, simp, simp, simp)
       
  5225 	done
       
  5226       from g1 and g2 and g3 and g4 show 
       
  5227           "t_steps (t_step tc (tp1 @ tp2, 0)) (tp1 @ tp2, 0) stp
       
  5228                                                          = (s, l, r)"
       
  5229 	apply(simp)
       
  5230 	done
       
  5231     qed
       
  5232 qed
       
  5233 
       
  5234 lemma shift_fetch: 
       
  5235  "\<lbrakk>n < length tp; 
       
  5236   (tp:: (taction \<times> nat) list) ! n = (aa, ba);
       
  5237    ba \<noteq> 0\<rbrakk> 
       
  5238    \<Longrightarrow> (tshift tp (length tp div 2)) ! n = 
       
  5239                      (aa , ba + length tp div 2)"
       
  5240 apply(simp add: tshift.simps)
       
  5241 done
       
  5242 
       
  5243 lemma tshift_length_equal: "length (tshift tp q) = length tp"
       
  5244 apply(auto simp: tshift.simps)
       
  5245 done
       
  5246 
       
  5247 thm nth_of.simps
       
  5248 
       
  5249 lemma [simp]: "t_ncorrect tp \<Longrightarrow> 2 * (length tp div 2) = length tp"
       
  5250 apply(auto simp: t_ncorrect.simps)
       
  5251 done
       
  5252 
       
  5253 lemma  tm_append_step_equal': 
       
  5254    "\<lbrakk>t_ncorrect tp; t_ncorrect tp'; off = length tp div 2\<rbrakk> \<Longrightarrow> 
       
  5255     (\<lambda> (s, l, r). ((\<lambda> (s', l', r'). 
       
  5256       (s'\<noteq> 0 \<longrightarrow> (s = s' + off \<and> l = l' \<and> r = r'))) 
       
  5257          (t_step (a, b, c) (tp', 0))))
       
  5258                (t_step (a + off, b, c) (tp @ tshift tp' off, 0))"
       
  5259 apply(simp add: t_step.simps)
       
  5260 apply(case_tac a, simp add: fetch.simps)
       
  5261 apply(case_tac 
       
  5262 "(fetch tp' a (case c of [] \<Rightarrow> Bk | Bk # xs \<Rightarrow> Bk | Oc # xs \<Rightarrow> Oc))",
       
  5263  simp)
       
  5264 apply(case_tac 
       
  5265 "(fetch (tp @ tshift tp' (length tp div 2))
       
  5266         (Suc (nat + length tp div 2)) 
       
  5267            (case c of [] \<Rightarrow> Bk | Bk # xs \<Rightarrow> Bk | Oc # xs \<Rightarrow> Oc))", 
       
  5268  simp)
       
  5269 apply(case_tac "(new_tape aa (b, c))",
       
  5270       case_tac "(new_tape aaa (b, c))", simp, 
       
  5271       rule impI, simp add: fetch.simps split: block.splits option.splits)
       
  5272 apply (auto simp: nth_of.simps t_ncorrect.simps 
       
  5273                       nth_append tshift_length_equal tshift.simps split: if_splits)
       
  5274 done
       
  5275 
       
  5276 
       
  5277 lemma  tm_append_step_equal: 
       
  5278  "\<lbrakk>t_ncorrect tp; t_ncorrect tp'; off = length tp div 2; 
       
  5279    t_step (a, b, c) (tp', 0) = (aa, ab, bb);  aa \<noteq> 0\<rbrakk>
       
  5280  \<Longrightarrow> t_step (a + length tp div 2, b, c) 
       
  5281         (tp @ tshift tp' (length tp div 2), 0)
       
  5282                           = (aa + length tp div 2, ab, bb)"
       
  5283 apply(insert tm_append_step_equal'[of tp tp' off a b c], simp)
       
  5284 apply(case_tac "(t_step (a + length tp div 2, b, c) 
       
  5285                    (tp @ tshift tp' (length tp div 2), 0))", simp)
       
  5286 done
       
  5287 
       
  5288 lemma tm_append_steps_equal: 
       
  5289  "\<lbrakk>t_ncorrect tp; t_ncorrect tp'; off = length tp div 2\<rbrakk> \<Longrightarrow> 
       
  5290    (\<lambda> (s, l, r). ((\<lambda> (s', l', r'). ((s'\<noteq> 0 \<longrightarrow> s = s' + off \<and> l = l'
       
  5291                      \<and> r = r'))) (t_steps (a, b, c) (tp', 0) stp)))
       
  5292    (t_steps (a + off, b, c) (tp @ tshift tp' off, 0) stp)"
       
  5293 apply(induct stp arbitrary : a b c, simp add: t_steps.simps)
       
  5294 apply(simp add: t_steps.simps)
       
  5295 apply(case_tac "(t_step (a, b, c) (tp', 0))", simp)
       
  5296 apply(case_tac "aa = 0", simp add: state0_ind)
       
  5297 apply(subgoal_tac "(t_step (a + length tp div 2, b, c) 
       
  5298                       (tp @ tshift tp' (length tp div 2), 0)) 
       
  5299   = (aa + length tp div 2, ba, ca)", simp)
       
  5300 apply(rule tm_append_step_equal, auto)
       
  5301 done
       
  5302 
       
  5303 (*********Begin: mop_up***************)
       
  5304 type_synonym mopup_type = "t_conf \<Rightarrow> nat list \<Rightarrow> nat \<Rightarrow> block list \<Rightarrow> bool"
       
  5305 
       
  5306 fun mopup_stop :: "mopup_type"
       
  5307   where
       
  5308   "mopup_stop (s, l, r) lm n ires= 
       
  5309         (\<exists> ln rn. l = Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires \<and> r = <abc_lm_v lm n> @ Bk\<^bsup>rn\<^esup>)"
       
  5310 
       
  5311 fun mopup_bef_erase_a :: "mopup_type"
       
  5312   where
       
  5313   "mopup_bef_erase_a (s, l, r) lm n ires= 
       
  5314          (\<exists> ln m rn. l = Bk \<^bsup>ln\<^esup> @ Bk # Bk # ires \<and> 
       
  5315                   r = Oc\<^bsup>m \<^esup>@ Bk # <(drop ((s + 1) div 2) lm)> @ Bk\<^bsup>rn\<^esup>)"
       
  5316 
       
  5317 fun mopup_bef_erase_b :: "mopup_type"
       
  5318   where
       
  5319   "mopup_bef_erase_b (s, l, r) lm n ires = 
       
  5320       (\<exists> ln m rn. l = Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires \<and> r = Bk # Oc\<^bsup>m\<^esup> @ Bk # 
       
  5321                                       <(drop (s div 2) lm)> @ Bk\<^bsup>rn\<^esup>)"
       
  5322 
       
  5323 
       
  5324 fun mopup_jump_over1 :: "mopup_type"
       
  5325   where
       
  5326   "mopup_jump_over1 (s, l, r) lm n ires = 
       
  5327       (\<exists> ln m1 m2 rn. m1 + m2 = Suc (abc_lm_v lm n) \<and> 
       
  5328         l = Oc\<^bsup>m1\<^esup> @ Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires \<and> 
       
  5329      (r = Oc\<^bsup>m2\<^esup> @ Bk # <(drop (Suc n) lm)> @ Bk\<^bsup>rn \<^esup>\<or> 
       
  5330      (r = Oc\<^bsup>m2\<^esup> \<and> (drop (Suc n) lm) = [])))"
       
  5331 
       
  5332 fun mopup_aft_erase_a :: "mopup_type"
       
  5333   where
       
  5334   "mopup_aft_erase_a (s, l, r) lm n ires = 
       
  5335       (\<exists> lnl lnr rn (ml::nat list) m. 
       
  5336           m = Suc (abc_lm_v lm n) \<and> l = Bk\<^bsup>lnr \<^esup>@ Oc\<^bsup>m \<^esup>@ Bk\<^bsup>lnl\<^esup> @ Bk # Bk # ires \<and> 
       
  5337                                    (r = <ml> @ Bk\<^bsup>rn\<^esup>))"
       
  5338 
       
  5339 fun mopup_aft_erase_b :: "mopup_type"
       
  5340   where
       
  5341   "mopup_aft_erase_b (s, l, r) lm n ires= 
       
  5342    (\<exists> lnl lnr rn (ml::nat list) m. 
       
  5343       m = Suc (abc_lm_v lm n) \<and> 
       
  5344       l = Bk\<^bsup>lnr \<^esup>@ Oc\<^bsup>m \<^esup>@ Bk\<^bsup>lnl\<^esup> @ Bk # Bk # ires \<and> 
       
  5345      (r = Bk # <ml> @ Bk\<^bsup>rn \<^esup>\<or>
       
  5346       r = Bk # Bk # <ml> @ Bk\<^bsup>rn\<^esup>))"
       
  5347 
       
  5348 fun mopup_aft_erase_c :: "mopup_type"
       
  5349   where
       
  5350   "mopup_aft_erase_c (s, l, r) lm n ires = 
       
  5351  (\<exists> lnl lnr rn (ml::nat list) m. 
       
  5352      m = Suc (abc_lm_v lm n) \<and> 
       
  5353      l = Bk\<^bsup>lnr \<^esup>@ Oc\<^bsup>m \<^esup>@ Bk\<^bsup>lnl\<^esup> @ Bk # Bk # ires \<and> 
       
  5354     (r = <ml> @ Bk\<^bsup>rn \<^esup>\<or> r = Bk # <ml> @ Bk\<^bsup>rn\<^esup>))"
       
  5355 
       
  5356 fun mopup_left_moving :: "mopup_type"
       
  5357   where
       
  5358   "mopup_left_moving (s, l, r) lm n ires = 
       
  5359   (\<exists> lnl lnr rn m.
       
  5360      m = Suc (abc_lm_v lm n) \<and> 
       
  5361    ((l = Bk\<^bsup>lnr \<^esup>@ Oc\<^bsup>m \<^esup>@ Bk\<^bsup>lnl\<^esup> @ Bk # Bk # ires \<and> r = Bk\<^bsup>rn\<^esup>) \<or>
       
  5362     (l = Oc\<^bsup>m - 1\<^esup> @ Bk\<^bsup>lnl\<^esup> @ Bk # Bk # ires \<and> r = Oc # Bk\<^bsup>rn\<^esup>)))"
       
  5363 
       
  5364 fun mopup_jump_over2 :: "mopup_type"
       
  5365   where
       
  5366   "mopup_jump_over2 (s, l, r) lm n ires = 
       
  5367      (\<exists> ln rn m1 m2.
       
  5368           m1 + m2 = Suc (abc_lm_v lm n) 
       
  5369         \<and> r \<noteq> [] 
       
  5370         \<and> (hd r = Oc \<longrightarrow> (l = Oc\<^bsup>m1\<^esup> @ Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires \<and> r = Oc\<^bsup>m2\<^esup> @ Bk\<^bsup>rn\<^esup>)) 
       
  5371         \<and> (hd r = Bk \<longrightarrow> (l = Bk\<^bsup>ln\<^esup> @ Bk # ires \<and> r = Bk # Oc\<^bsup>m1 + m2\<^esup> @ Bk\<^bsup>rn\<^esup>)))"
       
  5372 
       
  5373 
       
  5374 fun mopup_inv :: "mopup_type"
       
  5375   where
       
  5376   "mopup_inv (s, l, r) lm n ires = 
       
  5377       (if s = 0 then mopup_stop (s, l, r) lm n ires
       
  5378        else if s \<le> 2*n then
       
  5379                if s mod 2 = 1 then mopup_bef_erase_a (s, l, r) lm n ires
       
  5380                    else mopup_bef_erase_b (s, l, r) lm n ires
       
  5381             else if s = 2*n + 1 then 
       
  5382                 mopup_jump_over1 (s, l, r) lm n ires
       
  5383             else if s = 2*n + 2 then mopup_aft_erase_a (s, l, r) lm n ires
       
  5384             else if s = 2*n + 3 then mopup_aft_erase_b (s, l, r) lm n ires
       
  5385             else if s = 2*n + 4 then mopup_aft_erase_c (s, l, r) lm n ires
       
  5386             else if s = 2*n + 5 then mopup_left_moving (s, l, r) lm n ires
       
  5387             else if s = 2*n + 6 then mopup_jump_over2 (s, l, r) lm n ires
       
  5388             else False)"
       
  5389 
       
  5390 declare 
       
  5391   mopup_jump_over2.simps[simp del] mopup_left_moving.simps[simp del]
       
  5392   mopup_aft_erase_c.simps[simp del] mopup_aft_erase_b.simps[simp del] 
       
  5393   mopup_aft_erase_a.simps[simp del] mopup_jump_over1.simps[simp del]
       
  5394   mopup_bef_erase_a.simps[simp del] mopup_bef_erase_b.simps[simp del]
       
  5395   mopup_stop.simps[simp del]
       
  5396 
       
  5397 lemma mopup_fetch_0[simp]: 
       
  5398      "(fetch (mop_bef n @ tshift mp_up (2 * n)) 0 b) = (Nop, 0)"
       
  5399 by(simp add: fetch.simps)
       
  5400 
       
  5401 lemma mop_bef_length[simp]: "length (mop_bef n) = 4 * n"
       
  5402 apply(induct n, simp add: mop_bef.simps, simp add: mop_bef.simps)
       
  5403 done
       
  5404 
       
  5405 thm findnth_nth
       
  5406 lemma mop_bef_nth: 
       
  5407   "\<lbrakk>q < n; x < 4\<rbrakk> \<Longrightarrow> mop_bef n ! (4 * q + x) = 
       
  5408                              mop_bef (Suc q) ! ((4 * q) + x)"
       
  5409 apply(induct n, simp)
       
  5410 apply(case_tac "q < n", simp add: mop_bef.simps, auto)
       
  5411 apply(simp add: nth_append)
       
  5412 apply(subgoal_tac "q = n", simp)
       
  5413 apply(arith)
       
  5414 done
       
  5415 
       
  5416 lemma fetch_bef_erase_a_o[simp]: 
       
  5417  "\<lbrakk>0 < s; s \<le> 2 * n; s mod 2 = Suc 0\<rbrakk>
       
  5418   \<Longrightarrow> (fetch (mop_bef n @ tshift mp_up (2 * n)) s Oc) = (W0, s + 1)"
       
  5419 apply(subgoal_tac "\<exists> q. s = 2*q + 1", auto)
       
  5420 apply(subgoal_tac "length (mop_bef n) = 4*n")
       
  5421 apply(auto simp: fetch.simps nth_of.simps nth_append)
       
  5422 apply(subgoal_tac "mop_bef n ! (4 * q + 1) = 
       
  5423                       mop_bef (Suc q) ! ((4 * q) + 1)", 
       
  5424       simp add: mop_bef.simps nth_append)
       
  5425 apply(rule mop_bef_nth, auto)
       
  5426 done
       
  5427 
       
  5428 lemma fetch_bef_erase_a_b[simp]:
       
  5429   "\<lbrakk>n < length lm; 0 < s; s \<le> 2 * n; s mod 2 = Suc 0\<rbrakk>
       
  5430    \<Longrightarrow>  (fetch (mop_bef n @ tshift mp_up (2 * n)) s Bk) = (R, s + 2)"
       
  5431 apply(subgoal_tac "\<exists> q. s = 2*q + 1", auto)
       
  5432 apply(subgoal_tac "length (mop_bef n) = 4*n")
       
  5433 apply(auto simp: fetch.simps nth_of.simps nth_append)
       
  5434 apply(subgoal_tac "mop_bef n ! (4 * q + 0) = 
       
  5435                        mop_bef (Suc q) ! ((4 * q + 0))", 
       
  5436       simp add: mop_bef.simps nth_append)
       
  5437 apply(rule mop_bef_nth, auto)
       
  5438 done
       
  5439 
       
  5440 lemma fetch_bef_erase_b_b: 
       
  5441   "\<lbrakk>n < length lm; 0 < s; s \<le> 2 * n; s mod 2 = 0\<rbrakk> \<Longrightarrow> 
       
  5442      (fetch (mop_bef n @ tshift mp_up (2 * n)) s Bk) = (R, s - 1)"
       
  5443 apply(subgoal_tac "\<exists> q. s = 2 * q", auto)
       
  5444 apply(case_tac qa, simp, simp)
       
  5445 apply(auto simp: fetch.simps nth_of.simps nth_append)
       
  5446 apply(subgoal_tac "mop_bef n ! (4 * nat + 2) = 
       
  5447                      mop_bef (Suc nat) ! ((4 * nat) + 2)", 
       
  5448       simp add: mop_bef.simps nth_append)
       
  5449 apply(rule mop_bef_nth, auto)
       
  5450 done
       
  5451 
       
  5452 lemma fetch_jump_over1_o: 
       
  5453  "fetch (mop_bef n @ tshift mp_up (2 * n)) (Suc (2 * n)) Oc
       
  5454   = (R, Suc (2 * n))"
       
  5455 apply(subgoal_tac "length (mop_bef n) = 4 * n")
       
  5456 apply(auto simp: fetch.simps nth_of.simps mp_up_def nth_append 
       
  5457                  tshift.simps)
       
  5458 done
       
  5459 
       
  5460 lemma fetch_jump_over1_b: 
       
  5461  "fetch (mop_bef n @ tshift mp_up (2 * n)) (Suc (2 * n)) Bk 
       
  5462  = (R, Suc (Suc (2 * n)))"
       
  5463 apply(subgoal_tac "length (mop_bef n) = 4 * n")
       
  5464 apply(auto simp: fetch.simps nth_of.simps mp_up_def 
       
  5465                  nth_append tshift.simps)
       
  5466 done
       
  5467 
       
  5468 lemma fetch_aft_erase_a_o: 
       
  5469  "fetch (mop_bef n @ tshift mp_up (2 * n)) (Suc (Suc (2 * n))) Oc 
       
  5470  = (W0, Suc (2 * n + 2))"
       
  5471 apply(subgoal_tac "length (mop_bef n) = 4 * n")
       
  5472 apply(auto simp: fetch.simps nth_of.simps mp_up_def 
       
  5473                  nth_append tshift.simps)
       
  5474 done
       
  5475 
       
  5476 lemma fetch_aft_erase_a_b: 
       
  5477  "fetch (mop_bef n @ tshift mp_up (2 * n)) (Suc (Suc (2 * n))) Bk
       
  5478   = (L, Suc (2 * n + 4))"
       
  5479 apply(subgoal_tac "length (mop_bef n) = 4 * n")
       
  5480 apply(auto simp: fetch.simps nth_of.simps mp_up_def 
       
  5481                  nth_append tshift.simps)
       
  5482 done
       
  5483 
       
  5484 lemma fetch_aft_erase_b_b: 
       
  5485  "fetch (mop_bef n @ tshift mp_up (2 * n)) (2*n + 3) Bk
       
  5486   = (R, Suc (2 * n + 3))"
       
  5487 apply(subgoal_tac "length (mop_bef n) = 4 * n")
       
  5488 apply(subgoal_tac "2*n + 3 = Suc (2*n + 2)", simp only: fetch.simps)
       
  5489 apply(auto simp: nth_of.simps mp_up_def nth_append tshift.simps)
       
  5490 done
       
  5491 
       
  5492 lemma fetch_aft_erase_c_o: 
       
  5493  "fetch (mop_bef n @ tshift mp_up (2 * n)) (2 * n + 4) Oc 
       
  5494  = (W0, Suc (2 * n + 2))"
       
  5495 apply(subgoal_tac "length (mop_bef n) = 4 * n")
       
  5496 apply(subgoal_tac "2*n + 4 = Suc (2*n + 3)", simp only: fetch.simps)
       
  5497 apply(auto simp: nth_of.simps mp_up_def nth_append tshift.simps)
       
  5498 done
       
  5499 
       
  5500 lemma fetch_aft_erase_c_b: 
       
  5501  "fetch (mop_bef n @ tshift mp_up (2 * n)) (2 * n + 4) Bk 
       
  5502  = (R, Suc (2 * n + 1))"
       
  5503 apply(subgoal_tac "length (mop_bef n) = 4 * n")
       
  5504 apply(subgoal_tac "2*n + 4 = Suc (2*n + 3)", simp only: fetch.simps)
       
  5505 apply(auto simp: nth_of.simps mp_up_def nth_append tshift.simps)
       
  5506 done
       
  5507 
       
  5508 lemma fetch_left_moving_o: 
       
  5509  "(fetch (mop_bef n @ tshift mp_up (2 * n)) (2 * n + 5) Oc) 
       
  5510  = (L, 2*n + 6)"
       
  5511 apply(subgoal_tac "length (mop_bef n) = 4 * n")
       
  5512 apply(subgoal_tac "2*n + 5 = Suc (2*n + 4)", simp only: fetch.simps)
       
  5513 apply(auto simp: nth_of.simps mp_up_def nth_append tshift.simps)
       
  5514 done
       
  5515 
       
  5516 lemma fetch_left_moving_b: 
       
  5517  "(fetch (mop_bef n @ tshift mp_up (2 * n)) (2 * n + 5) Bk)
       
  5518   = (L, 2*n + 5)"
       
  5519 apply(subgoal_tac "length (mop_bef n) = 4 * n")
       
  5520 apply(subgoal_tac "2*n + 5 = Suc (2*n + 4)", simp only: fetch.simps)
       
  5521 apply(auto simp: nth_of.simps mp_up_def nth_append tshift.simps)
       
  5522 done
       
  5523 
       
  5524 lemma fetch_jump_over2_b:
       
  5525   "(fetch (mop_bef n @ tshift mp_up (2 * n)) (2 * n + 6) Bk) 
       
  5526  = (R, 0)"
       
  5527 apply(subgoal_tac "length (mop_bef n) = 4 * n")
       
  5528 apply(subgoal_tac "2*n + 6 = Suc (2*n + 5)", simp only: fetch.simps)
       
  5529 apply(auto simp: nth_of.simps mp_up_def nth_append tshift.simps)
       
  5530 done
       
  5531 
       
  5532 lemma fetch_jump_over2_o: 
       
  5533 "(fetch (mop_bef n @ tshift mp_up (2 * n)) (2 * n + 6) Oc) 
       
  5534  = (L, 2*n + 6)"
       
  5535 apply(subgoal_tac "length (mop_bef n) = 4 * n")
       
  5536 apply(subgoal_tac "2*n + 6 = Suc (2*n + 5)", simp only: fetch.simps)
       
  5537 apply(auto simp: nth_of.simps mp_up_def nth_append tshift.simps)
       
  5538 done
       
  5539 
       
  5540 lemmas mopupfetchs = 
       
  5541 fetch_bef_erase_a_o fetch_bef_erase_a_b fetch_bef_erase_b_b 
       
  5542 fetch_jump_over1_o fetch_jump_over1_b fetch_aft_erase_a_o 
       
  5543 fetch_aft_erase_a_b fetch_aft_erase_b_b fetch_aft_erase_c_o 
       
  5544 fetch_aft_erase_c_b fetch_left_moving_o fetch_left_moving_b 
       
  5545 fetch_jump_over2_b fetch_jump_over2_o
       
  5546 
       
  5547 lemma [simp]: 
       
  5548 "\<lbrakk>n < length lm; 0 < s; s mod 2 = Suc 0; 
       
  5549   mopup_bef_erase_a (s, l, Oc # xs) lm n ires; 
       
  5550   Suc s \<le> 2 * n\<rbrakk> \<Longrightarrow> 
       
  5551   mopup_bef_erase_b (Suc s, l, Bk # xs) lm n ires"
       
  5552 apply(auto simp: mopup_bef_erase_a.simps mopup_bef_erase_b.simps )
       
  5553 apply(rule_tac x = "m - 1" in exI, rule_tac x = rn in exI)
       
  5554 apply(case_tac m, simp, simp)
       
  5555 done
       
  5556 
       
  5557 lemma mopup_false1:
       
  5558   "\<lbrakk>0 < s; s \<le> 2 * n; s mod 2 = Suc 0;  \<not> Suc s \<le> 2 * n\<rbrakk> 
       
  5559   \<Longrightarrow> RR"
       
  5560 apply(arith)
       
  5561 done
       
  5562 
       
  5563 lemma [simp]: 
       
  5564  "\<lbrakk>n < length lm; 0 < s; s \<le> 2 * n; s mod 2 = Suc 0; 
       
  5565    mopup_bef_erase_a (s, l, Oc # xs) lm n ires; r = Oc # xs\<rbrakk>
       
  5566  \<Longrightarrow> (Suc s \<le> 2 * n \<longrightarrow> mopup_bef_erase_b (Suc s, l, Bk # xs) lm n ires)  \<and>
       
  5567      (\<not> Suc s \<le> 2 * n \<longrightarrow> mopup_jump_over1 (Suc s, l, Bk # xs) lm n ires) "
       
  5568 apply(auto elim: mopup_false1)
       
  5569 done
       
  5570 
       
  5571 lemma drop_abc_lm_v_simp[simp]: 
       
  5572    "n < length lm \<Longrightarrow> drop n lm = abc_lm_v lm n # drop (Suc n) lm"
       
  5573 apply(auto simp: abc_lm_v.simps)
       
  5574 apply(drule drop_Suc_conv_tl, simp)
       
  5575 done
       
  5576 lemma [simp]: "(\<exists>rna. Bk\<^bsup>rn\<^esup> = Bk # Bk\<^bsup>rna\<^esup>) \<or> Bk\<^bsup>rn\<^esup> = []"
       
  5577 apply(case_tac rn, simp, auto)
       
  5578 done
       
  5579 
       
  5580 lemma [simp]: "\<exists>lna. Bk # Bk\<^bsup>ln\<^esup> = Bk\<^bsup>lna\<^esup>"
       
  5581 apply(rule_tac x = "Suc ln" in exI, auto)
       
  5582 done
       
  5583 
       
  5584 lemma mopup_bef_erase_a_2_jump_over[simp]: 
       
  5585  "\<lbrakk>n < length lm; 0 < s; s mod 2 = Suc 0; 
       
  5586    mopup_bef_erase_a (s, l, Bk # xs) lm n ires; Suc s = 2 * n\<rbrakk> 
       
  5587 \<Longrightarrow> mopup_jump_over1 (Suc (2 * n), Bk # l, xs) lm n ires"
       
  5588 apply(auto simp: mopup_bef_erase_a.simps mopup_jump_over1.simps)
       
  5589 apply(case_tac m, simp)
       
  5590 apply(rule_tac x = "Suc ln" in exI, rule_tac x = 0 in exI, 
       
  5591       simp add: tape_of_nl_abv)
       
  5592 apply(case_tac "drop (Suc n) lm", auto simp: tape_of_nat_list.simps )
       
  5593 done
       
  5594 
       
  5595 lemma Suc_Suc_div:  "\<lbrakk>0 < s; s mod 2 = Suc 0; Suc (Suc s) \<le> 2 * n\<rbrakk>
       
  5596            \<Longrightarrow> (Suc (Suc (s div 2))) \<le> n"
       
  5597 apply(arith)
       
  5598 done
       
  5599 
       
  5600 lemma mopup_bef_erase_a_2_a[simp]: 
       
  5601  "\<lbrakk>n < length lm; 0 < s; s mod 2 = Suc 0; 
       
  5602    mopup_bef_erase_a (s, l, Bk # xs) lm n ires; 
       
  5603    Suc (Suc s) \<le> 2 * n\<rbrakk> \<Longrightarrow> 
       
  5604    mopup_bef_erase_a (Suc (Suc s), Bk # l, xs) lm n ires"
       
  5605 apply(auto simp: mopup_bef_erase_a.simps )
       
  5606 apply(subgoal_tac "drop (Suc (Suc (s div 2))) lm \<noteq> []")
       
  5607 apply(case_tac m, simp)
       
  5608 apply(rule_tac x = "Suc (abc_lm_v lm (Suc (s div 2)))" in exI, 
       
  5609       rule_tac x = rn in exI, simp, simp)
       
  5610 apply(subgoal_tac "(Suc (Suc (s div 2))) \<le> n", simp, 
       
  5611       rule_tac Suc_Suc_div, auto)
       
  5612 done
       
  5613 
       
  5614 lemma mopup_false2: 
       
  5615  "\<lbrakk>n < length lm; 0 < s; s \<le> 2 * n; 
       
  5616    s mod 2 = Suc 0; Suc s \<noteq> 2 * n;
       
  5617    \<not> Suc (Suc s) \<le> 2 * n\<rbrakk> \<Longrightarrow> RR"
       
  5618 apply(arith)
       
  5619 done
       
  5620 
       
  5621 lemma [simp]:
       
  5622   "\<lbrakk>n < length lm; 0 < s; s \<le> 2 * n; 
       
  5623    s mod 2 = Suc 0; 
       
  5624    mopup_bef_erase_a (s, l, Bk # xs) lm n ires; 
       
  5625    r = Bk # xs\<rbrakk>
       
  5626  \<Longrightarrow> (Suc s = 2 * n \<longrightarrow> 
       
  5627              mopup_jump_over1 (Suc (2 * n), Bk # l, xs) lm n ires) \<and>
       
  5628      (Suc s \<noteq> 2 * n \<longrightarrow> 
       
  5629        (Suc (Suc s) \<le> 2 * n \<longrightarrow> 
       
  5630           mopup_bef_erase_a (Suc (Suc s), Bk # l, xs) lm n ires) \<and> 
       
  5631        (\<not> Suc (Suc s) \<le> 2 * n \<longrightarrow> 
       
  5632           mopup_aft_erase_a (Suc (Suc s), Bk # l, xs) lm n ires))"
       
  5633 apply(auto elim: mopup_false2)
       
  5634 done
       
  5635 
       
  5636 lemma [simp]: "mopup_bef_erase_a (s, l, []) lm n ires \<Longrightarrow> 
       
  5637                         mopup_bef_erase_a (s, l, [Bk]) lm n ires"
       
  5638 apply(auto simp: mopup_bef_erase_a.simps)
       
  5639 done
       
  5640 
       
  5641 lemma [simp]:
       
  5642    "\<lbrakk>n < length lm; 0 < s; s \<le> 2 * n; s mod 2 = Suc 0;
       
  5643      mopup_bef_erase_a (s, l, []) lm n ires; r = []\<rbrakk>
       
  5644     \<Longrightarrow> (Suc s = 2 * n \<longrightarrow> 
       
  5645               mopup_jump_over1 (Suc (2 * n), Bk # l, []) lm n ires) \<and>
       
  5646         (Suc s \<noteq> 2 * n \<longrightarrow> 
       
  5647              (Suc (Suc s) \<le> 2 * n \<longrightarrow> 
       
  5648                  mopup_bef_erase_a (Suc (Suc s), Bk # l, []) lm n ires) \<and>
       
  5649              (\<not> Suc (Suc s) \<le> 2 * n \<longrightarrow> 
       
  5650                  mopup_aft_erase_a (Suc (Suc s), Bk # l, []) lm n ires))"
       
  5651 apply(auto)
       
  5652 done
       
  5653 
       
  5654 lemma "mopup_bef_erase_b (s, l, Oc # xs) lm n ires \<Longrightarrow> l \<noteq> []"
       
  5655 apply(auto simp: mopup_bef_erase_b.simps)
       
  5656 done
       
  5657 
       
  5658 lemma [simp]: "mopup_bef_erase_b (s, l, Oc # xs) lm n ires = False"
       
  5659 apply(auto simp: mopup_bef_erase_b.simps )
       
  5660 done
       
  5661  
       
  5662 lemma [simp]: "\<lbrakk>0 < s; s \<le> 2 *n; s mod 2 \<noteq> Suc 0\<rbrakk> \<Longrightarrow> 
       
  5663                                       (s - Suc 0) mod 2 = Suc 0"
       
  5664 apply(arith)
       
  5665 done
       
  5666 
       
  5667 lemma [simp]: "\<lbrakk>0 < s; s \<le> 2 *n; s mod 2 \<noteq> Suc 0\<rbrakk> \<Longrightarrow>
       
  5668                                        s - Suc 0 \<le> 2 * n"
       
  5669 apply(simp)
       
  5670 done
       
  5671 
       
  5672 lemma [simp]: "\<lbrakk>0 < s; s \<le> 2 *n; s mod 2 \<noteq> Suc 0\<rbrakk> \<Longrightarrow> \<not> s \<le> Suc 0"
       
  5673 apply(arith)
       
  5674 done
       
  5675 
       
  5676 lemma [simp]: "\<lbrakk>n < length lm; 0 < s; s \<le> 2 * n; 
       
  5677                s mod 2 \<noteq> Suc 0; 
       
  5678                mopup_bef_erase_b (s, l, Bk # xs) lm n ires; r = Bk # xs\<rbrakk> 
       
  5679            \<Longrightarrow> mopup_bef_erase_a (s - Suc 0, Bk # l, xs) lm n ires"
       
  5680 apply(auto simp: mopup_bef_erase_b.simps mopup_bef_erase_a.simps)
       
  5681 done
       
  5682 
       
  5683 lemma [simp]: "\<lbrakk>mopup_bef_erase_b (s, l, []) lm n ires\<rbrakk> \<Longrightarrow> 
       
  5684                    mopup_bef_erase_a (s - Suc 0, Bk # l, []) lm n ires"
       
  5685 apply(auto simp: mopup_bef_erase_b.simps mopup_bef_erase_a.simps)
       
  5686 done
       
  5687 
       
  5688 lemma [simp]: 
       
  5689    "\<lbrakk>n < length lm;
       
  5690     mopup_jump_over1 (Suc (2 * n), l, Oc # xs) lm n ires;
       
  5691     r = Oc # xs\<rbrakk>
       
  5692   \<Longrightarrow> mopup_jump_over1 (Suc (2 * n), Oc # l, xs) lm n ires"
       
  5693 apply(auto simp: mopup_jump_over1.simps)
       
  5694 apply(rule_tac x = ln in exI, rule_tac x = "Suc m1" in exI,
       
  5695        rule_tac x = "m2 - 1" in exI)
       
  5696 apply(case_tac "m2", simp, simp, rule_tac x = rn in exI, simp)
       
  5697 apply(rule_tac x = ln in exI, rule_tac x = "Suc m1" in exI, 
       
  5698       rule_tac x = "m2 - 1" in exI)
       
  5699 apply(case_tac m2, simp, simp)
       
  5700 done
       
  5701 
       
  5702 lemma mopup_jump_over1_2_aft_erase_a[simp]:  
       
  5703  "\<lbrakk>n < length lm; mopup_jump_over1 (Suc (2 * n), l, Bk # xs) lm n ires\<rbrakk>
       
  5704   \<Longrightarrow> mopup_aft_erase_a (Suc (Suc (2 * n)), Bk # l, xs) lm n ires"
       
  5705 apply(simp only: mopup_jump_over1.simps mopup_aft_erase_a.simps)
       
  5706 apply(erule_tac exE)+
       
  5707 apply(rule_tac x = ln in exI, rule_tac x = "Suc 0" in exI)
       
  5708 apply(case_tac m2, simp)
       
  5709 apply(rule_tac x = rn in exI, rule_tac x = "drop (Suc n) lm" in exI, 
       
  5710       simp)
       
  5711 apply(simp)
       
  5712 done
       
  5713 
       
  5714 lemma [simp]: 
       
  5715  "\<lbrakk>n < length lm; mopup_jump_over1 (Suc (2 * n), l, []) lm n ires\<rbrakk> \<Longrightarrow> 
       
  5716     mopup_aft_erase_a (Suc (Suc (2 * n)), Bk # l, []) lm n ires"
       
  5717 apply(rule mopup_jump_over1_2_aft_erase_a, simp)
       
  5718 apply(auto simp: mopup_jump_over1.simps)
       
  5719 apply(rule_tac x = ln in exI, rule_tac x = m1 in exI, 
       
  5720       rule_tac x = m2 in exI, simp add: )
       
  5721 apply(rule_tac x = 0 in exI, auto)
       
  5722 done
       
  5723 
       
  5724 lemma [simp]: 
       
  5725  "\<lbrakk>n < length lm; 
       
  5726    mopup_aft_erase_a (Suc (Suc (2 * n)), l, Oc # xs) lm n ires\<rbrakk> 
       
  5727  \<Longrightarrow> mopup_aft_erase_b (Suc (Suc (Suc (2 * n))), l, Bk # xs) lm n ires"
       
  5728 apply(auto simp: mopup_aft_erase_a.simps mopup_aft_erase_b.simps )
       
  5729 apply(case_tac ml, simp, case_tac rn, simp, simp)
       
  5730 apply(case_tac list, auto simp: tape_of_nl_abv 
       
  5731                                 tape_of_nat_list.simps )
       
  5732 apply(case_tac a, simp, rule_tac x = rn in exI, 
       
  5733       rule_tac x = "[]" in exI,
       
  5734        simp add: tape_of_nat_list.simps, simp)
       
  5735 apply(rule_tac x = rn in exI, rule_tac x = "[nat]" in exI, 
       
  5736       simp add: tape_of_nat_list.simps )
       
  5737 apply(case_tac a, simp, rule_tac x = rn in exI, 
       
  5738        rule_tac x = "aa # lista" in exI, simp, simp)
       
  5739 apply(rule_tac x = rn in exI, rule_tac x = "nat # aa # lista" in exI, 
       
  5740        simp add: tape_of_nat_list.simps )
       
  5741 done
       
  5742 
       
  5743 lemma [simp]:
       
  5744   "mopup_aft_erase_a (Suc (Suc (2 * n)), l, Bk # xs) lm n ires \<Longrightarrow> l \<noteq> []"
       
  5745 apply(auto simp: mopup_aft_erase_a.simps)
       
  5746 done
       
  5747 
       
  5748 lemma [simp]:
       
  5749   "\<lbrakk>n < length lm;
       
  5750     mopup_aft_erase_a (Suc (Suc (2 * n)), l, Bk # xs) lm n ires\<rbrakk>
       
  5751   \<Longrightarrow> mopup_left_moving (5 + 2 * n, tl l, hd l # Bk # xs) lm n ires"
       
  5752 apply(simp only: mopup_aft_erase_a.simps mopup_left_moving.simps)
       
  5753 apply(erule exE)+
       
  5754 apply(case_tac lnr, simp)
       
  5755 apply(rule_tac x = lnl in exI, simp, rule_tac x = rn in exI, simp)
       
  5756 apply(subgoal_tac "ml = []", simp)
       
  5757 apply(rule_tac xs = xs and rn = rn in BkCons_nil, simp, auto)
       
  5758 apply(subgoal_tac "ml = []", auto)
       
  5759 apply(rule_tac xs = xs and rn = rn in BkCons_nil, simp)
       
  5760 done
       
  5761 
       
  5762 lemma [simp]:
       
  5763   "mopup_aft_erase_a (Suc (Suc (2 * n)), l, []) lm n ires \<Longrightarrow> l \<noteq> []"
       
  5764 apply(simp only: mopup_aft_erase_a.simps)
       
  5765 apply(erule exE)+
       
  5766 apply(auto)
       
  5767 done
       
  5768 
       
  5769 lemma [simp]:
       
  5770   "\<lbrakk>n < length lm; mopup_aft_erase_a (Suc (Suc (2 * n)), l, []) lm n ires\<rbrakk>
       
  5771   \<Longrightarrow> mopup_left_moving (5 + 2 * n, tl l, [hd l]) lm n ires"
       
  5772 apply(simp only: mopup_aft_erase_a.simps mopup_left_moving.simps)
       
  5773 apply(erule exE)+
       
  5774 apply(subgoal_tac "ml = [] \<and> rn = 0", erule conjE, erule conjE, simp)
       
  5775 apply(case_tac lnr, simp, rule_tac x = lnl in exI, simp, 
       
  5776       rule_tac x = 0 in exI, simp)
       
  5777 apply(rule_tac x = lnl in exI, rule_tac x = nat in exI, 
       
  5778       rule_tac x = "Suc 0" in exI, simp)
       
  5779 apply(case_tac ml, simp, case_tac rn, simp, simp)
       
  5780 apply(case_tac list, auto simp: tape_of_nl_abv tape_of_nat_list.simps)
       
  5781 done
       
  5782 
       
  5783 lemma [simp]: "mopup_aft_erase_b (2 * n + 3, l, Oc # xs) lm n ires = False"
       
  5784 apply(auto simp: mopup_aft_erase_b.simps )
       
  5785 done
       
  5786 
       
  5787 lemma [simp]: 
       
  5788  "\<lbrakk>n < length lm; 
       
  5789    mopup_aft_erase_c (2 * n + 4, l, Oc # xs) lm n ires\<rbrakk>
       
  5790   \<Longrightarrow> mopup_aft_erase_b (Suc (Suc (Suc (2 * n))), l, Bk # xs) lm n ires"
       
  5791 apply(auto simp: mopup_aft_erase_c.simps mopup_aft_erase_b.simps )
       
  5792 apply(case_tac ml, simp, case_tac rn, simp, simp, simp)
       
  5793 apply(case_tac list, auto simp: tape_of_nl_abv 
       
  5794                         tape_of_nat_list.simps tape_of_nat_abv )
       
  5795 apply(case_tac a, rule_tac x = rn in exI, 
       
  5796       rule_tac x = "[]" in exI, simp add: tape_of_nat_list.simps)
       
  5797 apply(rule_tac x = rn in exI, rule_tac x = "[nat]" in exI, 
       
  5798       simp add: tape_of_nat_list.simps )
       
  5799 apply(case_tac a, simp, rule_tac x = rn in exI, 
       
  5800       rule_tac x = "aa # lista" in exI, simp)
       
  5801 apply(rule_tac x = rn in exI, rule_tac x = "nat # aa # lista" in exI, 
       
  5802       simp add: tape_of_nat_list.simps )
       
  5803 done
       
  5804 
       
  5805 lemma mopup_aft_erase_c_aft_erase_a[simp]: 
       
  5806  "\<lbrakk>n < length lm; mopup_aft_erase_c (2 * n + 4, l, Bk # xs) lm n ires\<rbrakk> 
       
  5807  \<Longrightarrow> mopup_aft_erase_a (Suc (Suc (2 * n)), Bk # l, xs) lm n ires"
       
  5808 apply(simp only: mopup_aft_erase_c.simps mopup_aft_erase_a.simps )
       
  5809 apply(erule_tac exE)+
       
  5810 apply(erule conjE, erule conjE, erule disjE)
       
  5811 apply(subgoal_tac "ml = []", simp, case_tac rn, 
       
  5812       simp, simp, rule conjI)
       
  5813 apply(rule_tac x = lnl in exI, rule_tac x = "Suc lnr" in exI, simp)
       
  5814 apply(rule_tac x = nat in exI, rule_tac x = "[]" in exI, simp)
       
  5815 apply(rule_tac xs = xs and rn = rn in BkCons_nil, simp, simp, 
       
  5816       rule conjI)
       
  5817 apply(rule_tac x = lnl in exI, rule_tac x = "Suc lnr" in exI, simp)
       
  5818 apply(rule_tac x = rn in exI, rule_tac x = "ml" in exI, simp)
       
  5819 done
       
  5820 
       
  5821 lemma [simp]: 
       
  5822  "\<lbrakk>n < length lm; mopup_aft_erase_c (2 * n + 4, l, []) lm n ires\<rbrakk> 
       
  5823  \<Longrightarrow> mopup_aft_erase_a (Suc (Suc (2 * n)), Bk # l, []) lm n ires"
       
  5824 apply(rule mopup_aft_erase_c_aft_erase_a, simp)
       
  5825 apply(simp only: mopup_aft_erase_c.simps)
       
  5826 apply(erule exE)+
       
  5827 apply(rule_tac x = lnl in exI, rule_tac x = lnr in exI, simp add: )
       
  5828 apply(rule_tac x = 0 in exI, rule_tac x = "[]" in exI, simp)
       
  5829 done
       
  5830 
       
  5831 lemma mopup_aft_erase_b_2_aft_erase_c[simp]:
       
  5832   "\<lbrakk>n < length lm; mopup_aft_erase_b (2 * n + 3, l, Bk # xs) lm n ires\<rbrakk>  
       
  5833  \<Longrightarrow> mopup_aft_erase_c (4 + 2 * n, Bk # l, xs) lm n ires"
       
  5834 apply(auto simp: mopup_aft_erase_b.simps mopup_aft_erase_c.simps)
       
  5835 apply(rule_tac x = "lnl" in exI, rule_tac x = "Suc lnr" in exI, simp)
       
  5836 apply(rule_tac x = "lnl" in exI, rule_tac x = "Suc lnr" in exI, simp)
       
  5837 done
       
  5838 
       
  5839 lemma [simp]: 
       
  5840  "\<lbrakk>n < length lm; mopup_aft_erase_b (2 * n + 3, l, []) lm n ires\<rbrakk> 
       
  5841  \<Longrightarrow> mopup_aft_erase_c (4 + 2 * n, Bk # l, []) lm n ires"
       
  5842 apply(rule_tac mopup_aft_erase_b_2_aft_erase_c, simp)
       
  5843 apply(simp add: mopup_aft_erase_b.simps)
       
  5844 done
       
  5845 
       
  5846 lemma [simp]: 
       
  5847     "mopup_left_moving (2 * n + 5, l, Oc # xs) lm n ires \<Longrightarrow> l \<noteq> []"
       
  5848 apply(auto simp: mopup_left_moving.simps)
       
  5849 done
       
  5850 
       
  5851 lemma [simp]:  
       
  5852  "\<lbrakk>n < length lm; mopup_left_moving (2 * n + 5, l, Oc # xs) lm n ires\<rbrakk>
       
  5853   \<Longrightarrow> mopup_jump_over2 (2 * n + 6, tl l, hd l # Oc # xs) lm n ires"
       
  5854 apply(simp only: mopup_left_moving.simps mopup_jump_over2.simps)
       
  5855 apply(erule_tac exE)+
       
  5856 apply(erule conjE, erule disjE, erule conjE)
       
  5857 apply(case_tac rn, simp, simp add: )
       
  5858 apply(case_tac "hd l", simp add:  )
       
  5859 apply(case_tac "abc_lm_v lm n", simp)
       
  5860 apply(rule_tac x = "lnl" in exI, rule_tac x = rn in exI, 
       
  5861       rule_tac x = "Suc 0" in exI, rule_tac x = 0 in exI)
       
  5862 apply(case_tac lnl, simp, simp, simp add: exp_ind[THEN sym], simp)
       
  5863 apply(case_tac "abc_lm_v lm n", simp)
       
  5864 apply(case_tac lnl, simp, simp)
       
  5865 apply(rule_tac x = lnl in exI, rule_tac x = rn in exI)
       
  5866 apply(rule_tac x = nat in exI, rule_tac x = "Suc (Suc 0)" in exI, simp)
       
  5867 done
       
  5868 
       
  5869 lemma [simp]: "mopup_left_moving (2 * n + 5, l, xs) lm n ires \<Longrightarrow> l \<noteq> []"
       
  5870 apply(auto simp: mopup_left_moving.simps)
       
  5871 done
       
  5872 
       
  5873 lemma [simp]:
       
  5874   "\<lbrakk>n < length lm; mopup_left_moving (2 * n + 5, l, Bk # xs) lm n ires\<rbrakk> 
       
  5875  \<Longrightarrow> mopup_left_moving (2 * n + 5, tl l, hd l # Bk # xs) lm n ires"
       
  5876 apply(simp only: mopup_left_moving.simps)
       
  5877 apply(erule exE)+
       
  5878 apply(case_tac lnr, simp)
       
  5879 apply(rule_tac x = lnl in exI, rule_tac x = 0 in exI, 
       
  5880       rule_tac x = rn in exI, simp, simp)
       
  5881 apply(rule_tac x = lnl in exI, rule_tac x = nat in exI, simp)
       
  5882 done
       
  5883 
       
  5884 lemma [simp]: 
       
  5885 "\<lbrakk>n < length lm; mopup_left_moving (2 * n + 5, l, []) lm n ires\<rbrakk>
       
  5886     \<Longrightarrow> mopup_left_moving (2 * n + 5, tl l, [hd l]) lm n ires"
       
  5887 apply(simp only: mopup_left_moving.simps)
       
  5888 apply(erule exE)+
       
  5889 apply(case_tac lnr, simp)
       
  5890 apply(rule_tac x = lnl in exI, rule_tac x = 0 in exI, 
       
  5891       rule_tac x = 0 in exI, simp, auto)
       
  5892 done
       
  5893 
       
  5894 lemma [simp]: 
       
  5895  "mopup_jump_over2 (2 * n + 6, l, Oc # xs) lm n ires \<Longrightarrow> l \<noteq> []"
       
  5896 apply(auto simp: mopup_jump_over2.simps )
       
  5897 done
       
  5898 
       
  5899 lemma [intro]: "\<exists>lna. Bk # Bk\<^bsup>ln\<^esup> = Bk\<^bsup>lna\<^esup> @ [Bk]"
       
  5900 apply(simp only: exp_ind[THEN sym], auto)
       
  5901 done
       
  5902 
       
  5903 lemma [simp]: 
       
  5904 "\<lbrakk>n < length lm; mopup_jump_over2 (2 * n + 6, l, Oc # xs) lm n ires\<rbrakk>
       
  5905  \<Longrightarrow>  mopup_jump_over2 (2 * n + 6, tl l, hd l # Oc # xs) lm n ires"
       
  5906 apply(simp only: mopup_jump_over2.simps)
       
  5907 apply(erule_tac exE)+
       
  5908 apply(simp add:  , erule conjE, erule_tac conjE)
       
  5909 apply(case_tac m1, simp)
       
  5910 apply(rule_tac x = ln in exI, rule_tac x = rn in exI, 
       
  5911       rule_tac x = 0 in exI, simp)
       
  5912 apply(case_tac ln, simp, simp, simp only: exp_ind[THEN sym], simp)
       
  5913 apply(rule_tac x = ln in exI, rule_tac x = rn in exI, 
       
  5914       rule_tac x = nat in exI, rule_tac x = "Suc m2" in exI, simp)
       
  5915 done
       
  5916 
       
  5917 lemma [simp]: "\<exists>rna. Oc # Oc\<^bsup>a\<^esup> @ Bk\<^bsup>rn\<^esup> = <a> @ Bk\<^bsup>rna\<^esup>"
       
  5918 apply(case_tac a, auto simp: tape_of_nat_abv )
       
  5919 done
       
  5920 
       
  5921 lemma [simp]: 
       
  5922  "\<lbrakk>n < length lm; mopup_jump_over2 (2 * n + 6, l, Bk # xs) lm n ires\<rbrakk> 
       
  5923   \<Longrightarrow> mopup_stop (0, Bk # l, xs) lm n ires"
       
  5924 apply(auto simp: mopup_jump_over2.simps mopup_stop.simps)
       
  5925 done
       
  5926 
       
  5927 lemma [simp]: "mopup_jump_over2 (2 * n + 6, l, []) lm n ires = False"
       
  5928 apply(simp only: mopup_jump_over2.simps, simp)
       
  5929 done
       
  5930 
       
  5931 lemma mopup_inv_step:
       
  5932   "\<lbrakk>n < length lm; mopup_inv (s, l, r) lm n ires\<rbrakk>
       
  5933   \<Longrightarrow> mopup_inv (t_step (s, l, r) 
       
  5934        ((mop_bef n @ tshift mp_up (2 * n)), 0)) lm n ires"
       
  5935 apply(auto split:if_splits simp add:t_step.simps,
       
  5936       tactic {* ALLGOALS (resolve_tac [@{thm "fetch_intro"}]) *})
       
  5937 apply(simp_all add: mopupfetchs new_tape.simps)
       
  5938 done
       
  5939 
       
  5940 declare mopup_inv.simps[simp del]
       
  5941 
       
  5942 lemma mopup_inv_steps: 
       
  5943 "\<lbrakk>n < length lm; mopup_inv (s, l, r) lm n ires\<rbrakk> \<Longrightarrow> 
       
  5944      mopup_inv (t_steps (s, l, r) 
       
  5945                    ((mop_bef n @ tshift mp_up (2 * n)), 0) stp) lm n ires"
       
  5946 apply(induct stp, simp add: t_steps.simps)
       
  5947 apply(simp add: t_steps_ind)
       
  5948 apply(case_tac "(t_steps (s, l, r) 
       
  5949                 (mop_bef n @ tshift mp_up (2 * n), 0) stp)", simp)
       
  5950 apply(rule_tac mopup_inv_step, simp, simp)
       
  5951 done
       
  5952 
       
  5953 lemma [simp]: 
       
  5954  "\<lbrakk>n < length lm; Suc 0 \<le> n\<rbrakk> \<Longrightarrow> 
       
  5955             mopup_bef_erase_a (Suc 0, Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires, <lm> @ Bk\<^bsup>rn\<^esup>) lm n ires"
       
  5956 apply(auto simp: mopup_bef_erase_a.simps  abc_lm_v.simps)
       
  5957 apply(case_tac lm, simp, case_tac list, simp, simp)
       
  5958 apply(rule_tac x = "Suc a" in exI, rule_tac x = rn in exI, simp)
       
  5959 done
       
  5960   
       
  5961 lemma [simp]:
       
  5962   "lm \<noteq> [] \<Longrightarrow> mopup_jump_over1 (Suc 0, Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires, <lm> @ Bk\<^bsup>rn\<^esup>) lm 0  ires"
       
  5963 apply(auto simp: mopup_jump_over1.simps)
       
  5964 apply(rule_tac x = ln in exI, rule_tac x = 0 in exI, simp add: )
       
  5965 apply(case_tac lm, simp, simp add: abc_lm_v.simps)
       
  5966 apply(case_tac rn, simp)
       
  5967 apply(case_tac list, rule_tac disjI2, 
       
  5968       simp add: tape_of_nl_abv tape_of_nat_list.simps)
       
  5969 apply(rule_tac disjI1,
       
  5970       simp add: tape_of_nl_abv tape_of_nat_list.simps )
       
  5971 apply(rule_tac disjI1, case_tac list, 
       
  5972       simp add: tape_of_nl_abv tape_of_nat_list.simps, 
       
  5973       rule_tac x = nat in exI, simp)
       
  5974 apply(simp add: tape_of_nl_abv tape_of_nat_list.simps )
       
  5975 done
       
  5976 
       
  5977 lemma mopup_init: 
       
  5978  "\<lbrakk>n < length lm; crsp_l ly (as, lm) (ac, l, r) ires\<rbrakk> \<Longrightarrow> 
       
  5979                                mopup_inv (Suc 0, l, r) lm n ires"
       
  5980 apply(auto simp: crsp_l.simps mopup_inv.simps)
       
  5981 apply(case_tac n, simp, auto simp: mopup_bef_erase_a.simps )
       
  5982 apply(rule_tac x = "Suc (hd lm)" in exI, rule_tac x = rn in exI, simp)
       
  5983 apply(case_tac lm, simp, case_tac list, simp, case_tac lista, simp add: abc_lm_v.simps)
       
  5984 apply(simp add: tape_of_nl_abv tape_of_nat_list.simps abc_lm_v.simps)
       
  5985 apply(simp add: mopup_jump_over1.simps)
       
  5986 apply(rule_tac x = 0 in exI, rule_tac x = 0 in exI, auto)
       
  5987 apply(case_tac [!] n, simp_all)
       
  5988 apply(case_tac [!] lm, simp, case_tac list, simp)
       
  5989 apply(case_tac rn, simp add: tape_of_nl_abv tape_of_nat_list.simps abc_lm_v.simps)
       
  5990 apply(erule_tac x = nat in allE, simp add: tape_of_nl_abv tape_of_nat_list.simps abc_lm_v.simps)
       
  5991 apply(simp add: abc_lm_v.simps, auto)
       
  5992 apply(case_tac list, simp_all add: tape_of_nl_abv tape_of_nat_list.simps abc_lm_v.simps) 
       
  5993 apply(erule_tac x = rn in allE, simp_all)
       
  5994 done
       
  5995 
       
  5996 fun abc_mopup_stage1 :: "t_conf \<Rightarrow> nat \<Rightarrow> nat"
       
  5997   where
       
  5998   "abc_mopup_stage1 (s, l, r) n = 
       
  5999            (if s > 0 \<and> s \<le> 2*n then 6
       
  6000             else if s = 2*n + 1 then 4
       
  6001             else if s \<ge> 2*n + 2 \<and> s \<le> 2*n + 4 then 3
       
  6002             else if s = 2*n + 5 then 2
       
  6003             else if s = 2*n + 6 then 1
       
  6004             else 0)"
       
  6005 
       
  6006 fun abc_mopup_stage2 :: "t_conf \<Rightarrow> nat \<Rightarrow> nat"
       
  6007   where
       
  6008   "abc_mopup_stage2 (s, l, r) n = 
       
  6009            (if s > 0 \<and> s \<le> 2*n then length r
       
  6010             else if s = 2*n + 1 then length r
       
  6011             else if s = 2*n + 5 then length l
       
  6012             else if s = 2*n + 6 then length l
       
  6013             else if s \<ge> 2*n + 2 \<and> s \<le> 2*n + 4 then length r
       
  6014             else 0)"
       
  6015 
       
  6016 fun abc_mopup_stage3 :: "t_conf \<Rightarrow> nat \<Rightarrow> nat"
       
  6017   where
       
  6018   "abc_mopup_stage3 (s, l, r) n = 
       
  6019           (if s > 0 \<and> s \<le> 2*n then 
       
  6020               if hd r = Bk then 0
       
  6021               else 1
       
  6022            else if s = 2*n + 2 then 1 
       
  6023            else if s = 2*n + 3 then 0
       
  6024            else if s = 2*n + 4 then 2
       
  6025            else 0)"
       
  6026 
       
  6027 fun abc_mopup_measure :: "(t_conf \<times> nat) \<Rightarrow> (nat \<times> nat \<times> nat)"
       
  6028   where
       
  6029   "abc_mopup_measure (c, n) = 
       
  6030     (abc_mopup_stage1 c n, abc_mopup_stage2 c n, 
       
  6031                                        abc_mopup_stage3 c n)"
       
  6032 
       
  6033 definition abc_mopup_LE ::
       
  6034    "(((nat \<times> block list \<times> block list) \<times> nat) \<times> 
       
  6035     ((nat \<times> block list \<times> block list) \<times> nat)) set"
       
  6036   where
       
  6037   "abc_mopup_LE \<equiv> (inv_image lex_triple abc_mopup_measure)"
       
  6038 
       
  6039 lemma wf_abc_mopup_le[intro]: "wf abc_mopup_LE"
       
  6040 by(auto intro:wf_inv_image wf_lex_triple simp:abc_mopup_LE_def)
       
  6041 
       
  6042 lemma [simp]: "mopup_bef_erase_a (a, aa, []) lm n ires = False"
       
  6043 apply(auto simp: mopup_bef_erase_a.simps)
       
  6044 done
       
  6045 
       
  6046 lemma [simp]: "mopup_bef_erase_b (a, aa, []) lm n ires = False"
       
  6047 apply(auto simp: mopup_bef_erase_b.simps) 
       
  6048 done
       
  6049 
       
  6050 lemma [simp]: "mopup_aft_erase_b (2 * n + 3, aa, []) lm n ires = False"
       
  6051 apply(auto simp: mopup_aft_erase_b.simps)
       
  6052 done
       
  6053 
       
  6054 lemma mopup_halt_pre: 
       
  6055  "\<lbrakk>n < length lm; mopup_inv (Suc 0, l, r) lm n ires; wf abc_mopup_LE\<rbrakk>
       
  6056  \<Longrightarrow>  \<forall>na. \<not> (\<lambda>(s, l, r) n. s = 0) (t_steps (Suc 0, l, r)
       
  6057       (mop_bef n @ tshift mp_up (2 * n), 0) na) n \<longrightarrow>
       
  6058        ((t_steps (Suc 0, l, r) (mop_bef n @ tshift mp_up (2 * n), 0) 
       
  6059         (Suc na), n),
       
  6060        t_steps (Suc 0, l, r) (mop_bef n @ tshift mp_up (2 * n), 0)
       
  6061          na, n) \<in> abc_mopup_LE"
       
  6062 apply(rule allI, rule impI, simp add: t_steps_ind)
       
  6063 apply(subgoal_tac "mopup_inv (t_steps (Suc 0, l, r) 
       
  6064                      (mop_bef n @ tshift mp_up (2 * n), 0) na) lm n ires")
       
  6065 apply(case_tac "(t_steps (Suc 0, l, r) 
       
  6066                (mop_bef n @ tshift mp_up (2 * n), 0) na)",  simp)
       
  6067 proof -
       
  6068   fix na a b c
       
  6069   assume  "n < length lm" "mopup_inv (a, b, c) lm n ires" "0 < a"
       
  6070   thus "((t_step (a, b, c) (mop_bef n @ tshift mp_up (2 * n), 0), n),
       
  6071          (a, b, c), n) \<in> abc_mopup_LE"
       
  6072     apply(auto split:if_splits simp add:t_step.simps mopup_inv.simps,
       
  6073       tactic {* ALLGOALS (resolve_tac [@{thm "fetch_intro"}]) *})
       
  6074     apply(simp_all add: mopupfetchs new_tape.simps abc_mopup_LE_def 
       
  6075                    lex_triple_def lex_pair_def )
       
  6076     done
       
  6077 next
       
  6078   fix na
       
  6079   assume "n < length lm" "mopup_inv (Suc 0, l, r) lm n ires"
       
  6080   thus "mopup_inv (t_steps (Suc 0, l, r) 
       
  6081        (mop_bef n @ tshift mp_up (2 * n), 0) na) lm n ires"
       
  6082     apply(rule mopup_inv_steps)
       
  6083     done
       
  6084 qed
       
  6085 
       
  6086 lemma mopup_halt: "\<lbrakk>n < length lm; crsp_l ly (as, lm) (s, l, r) ires\<rbrakk> \<Longrightarrow> 
       
  6087   \<exists> stp. (\<lambda> (s, l, r). s = 0) (t_steps (Suc 0, l, r) 
       
  6088         ((mop_bef n @ tshift mp_up (2 * n)), 0) stp)"
       
  6089 apply(subgoal_tac "mopup_inv (Suc 0, l, r) lm n ires")
       
  6090 apply(insert wf_abc_mopup_le)
       
  6091 apply(insert halt_lemma[of abc_mopup_LE 
       
  6092     "\<lambda> ((s, l, r), n). s = 0" 
       
  6093     "\<lambda> stp. (t_steps (Suc 0, l, r) ((mop_bef n @ tshift mp_up (2 * n))
       
  6094            , 0) stp, n)"], auto)
       
  6095 apply(insert mopup_halt_pre[of n lm l r], simp, erule exE)
       
  6096 apply(rule_tac x = na in exI, case_tac "(t_steps (Suc 0, l, r) 
       
  6097           (mop_bef n @ tshift mp_up (2 * n), 0) na)", simp)
       
  6098 apply(rule_tac mopup_init, auto)
       
  6099 done
       
  6100 (***End: mopup stop****)
       
  6101 
       
  6102 lemma mopup_halt_conf_pre: 
       
  6103  "\<lbrakk>n < length lm; crsp_l ly (as, lm) (s, l, r) ires\<rbrakk> 
       
  6104   \<Longrightarrow> \<exists> na. (\<lambda> (s', l', r').  s' = 0 \<and> mopup_stop (s', l', r') lm n ires)
       
  6105       (t_steps (Suc 0, l, r) 
       
  6106             ((mop_bef n @ tshift mp_up (2 * n)), 0) na)"
       
  6107 apply(subgoal_tac "\<exists> stp. (\<lambda> (s, l, r). s = 0) 
       
  6108  (t_steps (Suc 0, l, r) ((mop_bef n @ tshift mp_up (2 * n)), 0) stp)",
       
  6109        erule exE)
       
  6110 apply(rule_tac x = stp in exI, 
       
  6111       case_tac "(t_steps (Suc 0, l, r) 
       
  6112           (mop_bef n @ tshift mp_up (2 * n), 0) stp)", simp)
       
  6113 apply(subgoal_tac " mopup_inv (Suc 0, l, r) lm n ires")
       
  6114 apply(subgoal_tac "mopup_inv (t_steps (Suc 0, l, r) 
       
  6115             (mop_bef n @ tshift mp_up (2 * n), 0) stp) lm n ires", simp)
       
  6116 apply(simp only: mopup_inv.simps)
       
  6117 apply(rule_tac mopup_inv_steps, simp, simp)
       
  6118 apply(rule_tac mopup_init, simp, simp)
       
  6119 apply(rule_tac mopup_halt, simp, simp)
       
  6120 done
       
  6121 
       
  6122 lemma  mopup_halt_conf:
       
  6123   assumes len: "n < length lm"
       
  6124   and correspond: "crsp_l ly (as, lm) (s, l, r) ires"
       
  6125   shows 
       
  6126   "\<exists> na. (\<lambda> (s', l', r'). ((\<exists>ln rn. s' = 0 \<and> l' = Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires
       
  6127                            \<and> r' = Oc\<^bsup>Suc (abc_lm_v lm n)\<^esup> @ Bk\<^bsup>rn\<^esup>)))
       
  6128              (t_steps (Suc 0, l, r) 
       
  6129                   ((mop_bef n @ tshift mp_up (2 * n)), 0) na)"
       
  6130 using len correspond mopup_halt_conf_pre[of n lm ly as s l r ires]
       
  6131 apply(simp add: mopup_stop.simps tape_of_nat_abv tape_of_nat_list.simps)
       
  6132 done
       
  6133 
       
  6134 subsection {* Final results about Abacus machine *}
       
  6135 
       
  6136 lemma mopup_halt_bef: "\<lbrakk>n < length lm; crsp_l ly (as, lm) (s, l, r) ires\<rbrakk> 
       
  6137     \<Longrightarrow> \<exists>stp. (\<lambda>(s, l, r). s \<noteq> 0 \<and> ((\<lambda> (s', l', r'). s' = 0)
       
  6138    (t_step (s, l, r) (mop_bef n @ tshift mp_up (2 * n), 0))))
       
  6139     (t_steps (Suc 0, l, r) (mop_bef n @ tshift mp_up (2 * n), 0) stp)"
       
  6140 apply(insert mopup_halt[of n lm ly as s l r ires], simp, erule_tac exE)
       
  6141 proof -
       
  6142   fix stp
       
  6143   assume "n < length lm" 
       
  6144          "crsp_l ly (as, lm) (s, l, r) ires" 
       
  6145          "(\<lambda>(s, l, r). s = 0) 
       
  6146             (t_steps (Suc 0, l, r) 
       
  6147               (mop_bef n @ tshift mp_up (2 * n), 0) stp)"
       
  6148   thus "\<exists>stp. (\<lambda>(s, ab). 0 < s \<and> (\<lambda>(s', l', r'). s' = 0) 
       
  6149    (t_step (s, ab) (mop_bef n @ tshift mp_up (2 * n), 0))) 
       
  6150     (t_steps (Suc 0, l, r) (mop_bef n @ tshift mp_up (2 * n), 0) stp)"
       
  6151   proof(induct stp, simp add: t_steps.simps, simp)
       
  6152     fix stpa
       
  6153     assume h1: 
       
  6154       "(\<lambda>(s, l, r). s = 0) (t_steps (Suc 0, l, r) 
       
  6155            (mop_bef n @ tshift mp_up (2 * n), 0) stpa) \<Longrightarrow>
       
  6156        \<exists>stp. (\<lambda>(s, ab). 0 < s \<and> (\<lambda>(s', l', r'). s' = 0) 
       
  6157          (t_step (s, ab) (mop_bef n @ tshift mp_up (2 * n), 0))) 
       
  6158             (t_steps (Suc 0, l, r) 
       
  6159               (mop_bef n @ tshift mp_up (2 * n), 0) stp)"
       
  6160       and h2: 
       
  6161         "(\<lambda>(s, l, r). s = 0) (t_steps (Suc 0, l, r) 
       
  6162                     (mop_bef n @ tshift mp_up (2 * n), 0) (Suc stpa))"
       
  6163          "n < length lm" 
       
  6164          "crsp_l ly (as, lm) (s, l, r) ires"
       
  6165     thus "\<exists>stp. (\<lambda>(s, ab). 0 < s \<and> (\<lambda>(s', l', r'). s' = 0) 
       
  6166              (t_step (s, ab) (mop_bef n @ tshift mp_up (2 * n), 0))) (
       
  6167                 t_steps (Suc 0, l, r) 
       
  6168                   (mop_bef n @ tshift mp_up (2 * n), 0) stp)"
       
  6169       apply(case_tac "(\<lambda>(s, l, r). s = 0) (t_steps (Suc 0, l, r) 
       
  6170                      (mop_bef n @ tshift mp_up (2 * n), 0) stpa)", 
       
  6171             simp)
       
  6172       apply(rule_tac x = "stpa" in exI)
       
  6173       apply(case_tac "(t_steps (Suc 0, l, r) 
       
  6174                          (mop_bef n @ tshift mp_up (2 * n), 0) stpa)",
       
  6175             simp add: t_steps_ind)
       
  6176       done
       
  6177   qed
       
  6178 qed
       
  6179 
       
  6180 lemma tshift_nth_state0: "\<lbrakk>n < length tp; tp ! n = (a, 0)\<rbrakk>
       
  6181     \<Longrightarrow> tshift tp off ! n = (a, 0)"
       
  6182 apply(induct n, case_tac tp, simp)
       
  6183 apply(auto simp: tshift.simps)
       
  6184 done
       
  6185 
       
  6186 lemma shift_length: "length (tshift tp n) = length tp"
       
  6187 apply(auto simp: tshift.simps)
       
  6188 done
       
  6189 
       
  6190 lemma even_Suc_le: "\<lbrakk>y mod 2 = 0; 2 * x < y\<rbrakk> \<Longrightarrow> Suc (2 * x) < y"
       
  6191 by arith
       
  6192 
       
  6193 lemma [simp]: "(4::nat) * n mod 2 = 0"
       
  6194 by arith
       
  6195 
       
  6196 lemma tm_append_fetch_equal: 
       
  6197   "\<lbrakk>t_ncorrect (tm_of aprog); s'> 0;
       
  6198     fetch (mop_bef n @ tshift mp_up (2 * n)) s' b = (a, 0)\<rbrakk>
       
  6199 \<Longrightarrow> fetch (tm_of aprog @ tshift (mop_bef n @ tshift mp_up (2 * n)) 
       
  6200     (length (tm_of aprog) div 2)) (s' + length (tm_of aprog) div 2) b 
       
  6201    = (a, 0)"
       
  6202 apply(case_tac s', simp)
       
  6203 apply(auto simp: fetch.simps nth_of.simps t_ncorrect.simps shift_length nth_append
       
  6204                  tshift.simps split: list.splits block.splits split: if_splits)
       
  6205 done
       
  6206 
       
  6207 lemma [simp]:
       
  6208   "\<lbrakk>t_ncorrect (tm_of aprog);
       
  6209     t_step (s', l', r') (mop_bef n @ tshift mp_up (2 * n), 0) = 
       
  6210                                                (0, l'', r''); s' > 0\<rbrakk>
       
  6211   \<Longrightarrow> t_step (s' + length (tm_of aprog) div 2, l', r') 
       
  6212         (tm_of aprog @ tshift (mop_bef n @ tshift mp_up (2 * n))
       
  6213            (length (tm_of aprog) div 2), 0) = (0, l'', r'')"
       
  6214 apply(simp add: t_step.simps)
       
  6215 apply(subgoal_tac 
       
  6216    "(fetch (mop_bef n @ tshift mp_up (2 * n)) s' 
       
  6217               (case r' of [] \<Rightarrow> Bk | Bk # xs \<Rightarrow> Bk | Oc # xs \<Rightarrow> Oc))
       
  6218   = (fetch (tm_of aprog @ tshift (mop_bef n @ tshift mp_up (2 * n)) 
       
  6219        (length (tm_of aprog) div 2)) (s' + length (tm_of aprog) div 2)
       
  6220     (case r' of [] \<Rightarrow> Bk | Bk # xs \<Rightarrow> Bk | Oc # xs \<Rightarrow> Oc))", simp)
       
  6221 apply(case_tac "(fetch (mop_bef n @ tshift mp_up (2 * n)) s' 
       
  6222        (case r' of [] \<Rightarrow> Bk | Bk # xs \<Rightarrow> Bk | Oc # xs \<Rightarrow> Oc))", simp)
       
  6223 apply(drule_tac tm_append_fetch_equal, auto)
       
  6224 done
       
  6225 
       
  6226 lemma [intro]: 
       
  6227   "start_of (layout_of aprog) (length aprog) - Suc 0 = 
       
  6228                                       length (tm_of aprog) div 2"
       
  6229 apply(subgoal_tac  "abc2t_correct aprog")
       
  6230 apply(insert pre_lheq[of "concat (take (length aprog) 
       
  6231        (tms_of aprog))" "length aprog" aprog], simp add: tm_of.simps)
       
  6232 by auto
       
  6233 
       
  6234 lemma tm_append_stop_step: 
       
  6235   "\<lbrakk>t_ncorrect (tm_of aprog); 
       
  6236     t_ncorrect (mop_bef n @ tshift mp_up (2 * n)); n < length lm; 
       
  6237    (t_steps (Suc 0, l, r) (mop_bef n @ tshift mp_up (2 * n), 0) stp) =
       
  6238                          (s', l', r');
       
  6239     s' \<noteq> 0;
       
  6240     t_step (s', l', r') (mop_bef n @ tshift mp_up (2 * n), 0) 
       
  6241                                                      = (0, l'', r'')\<rbrakk>
       
  6242      \<Longrightarrow>
       
  6243 (t_steps ((start_of (layout_of aprog) (length aprog), l, r)) 
       
  6244   (tm_of aprog @ tshift (mop_bef n @ tshift mp_up (2 * n))
       
  6245    (start_of (layout_of aprog) (length aprog) - Suc 0), 0) (Suc stp))
       
  6246   = (0, l'', r'')"
       
  6247 apply(insert tm_append_steps_equal[of "tm_of aprog" 
       
  6248       "(mop_bef n @ tshift mp_up (2 * n))"
       
  6249       "(start_of (layout_of aprog) (length aprog) - Suc 0)" 
       
  6250       "Suc 0" l r stp], simp)
       
  6251 apply(subgoal_tac "(start_of (layout_of aprog) (length aprog) - Suc 0)
       
  6252               = (length (tm_of aprog) div 2)", simp add: t_steps_ind)
       
  6253 apply(case_tac 
       
  6254  "(t_steps (start_of (layout_of aprog) (length aprog), l, r) 
       
  6255       (tm_of aprog @ tshift (mop_bef n @ tshift mp_up (2 * n))
       
  6256            (length (tm_of aprog) div 2), 0) stp)", simp)
       
  6257 apply(subgoal_tac "start_of (layout_of aprog) (length aprog) > 0", 
       
  6258       case_tac "start_of (layout_of aprog) (length aprog)", 
       
  6259       simp, simp)
       
  6260 apply(rule startof_not0, auto)
       
  6261 done
       
  6262 
       
  6263 lemma start_of_out_range: 
       
  6264 "as \<ge> length aprog \<Longrightarrow> 
       
  6265    start_of (layout_of aprog) as = 
       
  6266              start_of (layout_of aprog) (length aprog)"
       
  6267 apply(induct as, simp)
       
  6268 apply(case_tac "length aprog = Suc as", simp)
       
  6269 apply(simp add: start_of.simps)
       
  6270 done
       
  6271 
       
  6272 lemma [intro]: "t_ncorrect (tm_of aprog)"
       
  6273 apply(simp add: tm_of.simps)
       
  6274 apply(insert tms_mod2[of "length aprog" aprog], 
       
  6275                                 simp add: t_ncorrect.simps)
       
  6276 done
       
  6277 
       
  6278 lemma abacus_turing_eq_halt_case_pre: 
       
  6279    "\<lbrakk>ly = layout_of aprog; 
       
  6280      tprog = tm_of aprog; 
       
  6281      crsp_l ly ac tc ires;
       
  6282      n < length am;
       
  6283      abc_steps_l ac aprog stp = (as, am); 
       
  6284      mop_ss = start_of ly (length aprog);
       
  6285      as \<ge> length aprog\<rbrakk>
       
  6286      \<Longrightarrow> \<exists> stp. (\<lambda> (s, l, r). s = 0 \<and> mopup_inv (0, l, r) am n ires)
       
  6287                 (t_steps tc (tprog @ (tMp n (mop_ss - 1)), 0) stp)"
       
  6288 apply(insert steps_crsp[of ly aprog tprog ac tc ires "(as, am)" stp], auto)
       
  6289 apply(case_tac "(t_steps tc (tm_of aprog, 0) n')",  
       
  6290       simp add: tMp.simps)
       
  6291 apply(subgoal_tac "t_ncorrect (mop_bef n @ tshift mp_up (2 * n))")
       
  6292 proof -
       
  6293   fix n' a b c
       
  6294   assume h1: 
       
  6295     "crsp_l (layout_of aprog) ac tc ires" 
       
  6296     "abc_steps_l ac aprog stp = (as, am)" 
       
  6297     "length aprog \<le> as"
       
  6298     "crsp_l (layout_of aprog) (as, am) (a, b, c) ires"
       
  6299     "t_steps tc (tm_of aprog, 0) n' = (a, b, c)"
       
  6300     "n < length am"
       
  6301     "t_ncorrect (mop_bef n @ tshift mp_up (2 * n))"
       
  6302   hence h2:
       
  6303   "t_steps tc (tm_of aprog @ tshift (mop_bef n @ tshift mp_up (2 * n))
       
  6304     (start_of (layout_of aprog) (length aprog) - Suc 0), 0) n' 
       
  6305                                     = (a, b, c)" 
       
  6306     apply(rule_tac tm_append_steps, simp)
       
  6307     apply(simp add: crsp_l.simps, auto)
       
  6308     apply(simp add: crsp_l.simps)
       
  6309     apply(rule startof_not0)
       
  6310     done
       
  6311   from h1 have h3: 
       
  6312   "\<exists>stp. (\<lambda>(s, l, r). s \<noteq> 0 \<and> ((\<lambda> (s', l', r'). s' = 0) 
       
  6313            (t_step (s, l, r) (mop_bef n @ tshift mp_up (2 * n), 0))))
       
  6314          (t_steps (Suc 0, b, c) 
       
  6315                (mop_bef n @ tshift mp_up (2 * n), 0) stp)"
       
  6316     apply(rule_tac mopup_halt_bef, auto)
       
  6317     done
       
  6318   from h1 and h2 and h3 show 
       
  6319     "\<exists>stp. case t_steps tc (tm_of aprog @ abacus.tshift (mop_bef n @ abacus.tshift mp_up (2 * n))
       
  6320     (start_of (layout_of aprog) (length aprog) - Suc 0), 0) stp of (s, ab)
       
  6321     \<Rightarrow> s = 0 \<and> mopup_inv (0, ab) am n ires"
       
  6322   proof(erule_tac exE, 
       
  6323     case_tac "(t_steps (Suc 0, b, c) 
       
  6324               (mop_bef n @ tshift mp_up (2 * n), 0) stpa)", simp,
       
  6325     case_tac "(t_step (aa, ba, ca) 
       
  6326               (mop_bef n @ tshift mp_up (2 * n), 0))", simp)
       
  6327     fix stpa aa ba ca aaa baa caa
       
  6328     assume g1: "0 < aa \<and> aaa = 0" 
       
  6329       "t_steps (Suc 0, b, c) 
       
  6330       (mop_bef n @ tshift mp_up (2 * n), 0) stpa = (aa, ba,ca)" 
       
  6331       "t_step (aa, ba, ca) (mop_bef n @ tshift mp_up (2 * n), 0)
       
  6332       = (0, baa, caa)"
       
  6333     from h1 and this have g2: 
       
  6334       "t_steps (start_of (layout_of aprog) (length aprog), b, c) 
       
  6335          (tm_of aprog @ tshift (mop_bef n @ tshift mp_up (2 * n)) 
       
  6336            (start_of (layout_of aprog) (length aprog) - Suc 0), 0) 
       
  6337                 (Suc stpa) = (0, baa, caa)"
       
  6338       apply(rule_tac tm_append_stop_step, auto)
       
  6339       done
       
  6340     from h1 and h2 and g1 and this show "?thesis"
       
  6341       apply(rule_tac x = "n' + Suc stpa" in exI)
       
  6342       apply(simp add: t_steps_ind del: t_steps.simps)
       
  6343       apply(subgoal_tac "a = start_of (layout_of aprog) 
       
  6344                                           (length aprog)", simp)
       
  6345       apply(insert mopup_inv_steps[of n am "Suc 0" b c ires "Suc stpa"],
       
  6346             simp add: t_steps_ind)
       
  6347       apply(subgoal_tac "mopup_inv (Suc 0, b, c) am n ires", simp)
       
  6348       apply(rule_tac mopup_init, simp, simp)
       
  6349       apply(simp add: crsp_l.simps)
       
  6350       apply(erule_tac start_of_out_range)
       
  6351       done
       
  6352   qed
       
  6353 next
       
  6354   show " t_ncorrect (mop_bef n @ tshift mp_up (2 * n))"
       
  6355     apply(auto simp: t_ncorrect.simps tshift.simps mp_up_def)
       
  6356     done   
       
  6357 qed
       
  6358 
       
  6359 text {*
       
  6360   One of the main theorems about Abacus compilation.
       
  6361 *}
       
  6362 
       
  6363 lemma abacus_turing_eq_halt_case: 
       
  6364   assumes layout: 
       
  6365   -- {* There is an Abacus program @{text "aprog"} with layout @{text "ly"}: *}
       
  6366   "ly = layout_of aprog"
       
  6367   and complied: 
       
  6368   -- {* The TM compiled from @{text "aprog"} is @{text "tprog"}: *}
       
  6369   "tprog = tm_of aprog"
       
  6370   and correspond: 
       
  6371   -- {* TM configuration @{text "tc"} and Abacus configuration @{text "ac"}
       
  6372   are in correspondence: *}
       
  6373   "crsp_l ly ac tc ires"
       
  6374   and halt_state: 
       
  6375   -- {* @{text "as"} is a program label outside the range of @{text "aprog"}. So 
       
  6376   if Abacus is in such a state, it is in halt state: *}
       
  6377   "as \<ge> length aprog"
       
  6378   and abc_exec: 
       
  6379   -- {* Supposing after @{text "stp"} step of execution, Abacus program @{text "aprog"}
       
  6380   reaches such a halt state: *}
       
  6381   "abc_steps_l ac aprog stp = (as, am)"
       
  6382   and rs_len: 
       
  6383   -- {* @{text "n"} is a memory address in the range of Abacus memory @{text "am"}: *}
       
  6384   "n < length am"
       
  6385   and mopup_start:
       
  6386   -- {* The startling label for mopup mahines, according to the layout and Abacus program 
       
  6387    should be @{text "mop_ss"}: *}
       
  6388   "mop_ss = start_of ly (length aprog)"
       
  6389   shows 
       
  6390   -- {* 
       
  6391   After @{text "stp"} steps of execution of the TM composed of @{text "tprog"} and the mopup 
       
  6392   TM @{text "(tMp n (mop_ss - 1))"} will halt and gives rise to a configuration which 
       
  6393   only hold the content of memory cell @{text "n"}:
       
  6394   *}
       
  6395   "\<exists> stp. (\<lambda> (s, l, r). \<exists> ln rn. s = 0 \<and>  l = Bk\<^bsup>ln\<^esup> @ Bk # Bk # ires
       
  6396      \<and> r = Oc\<^bsup>Suc (abc_lm_v am n)\<^esup> @ Bk\<^bsup>rn\<^esup>)
       
  6397            (t_steps tc (tprog @ (tMp n (mop_ss - 1)), 0) stp)"
       
  6398 proof -
       
  6399   from layout complied correspond halt_state abc_exec rs_len mopup_start
       
  6400        and abacus_turing_eq_halt_case_pre [of ly aprog tprog ac tc ires n am stp as mop_ss]
       
  6401   show "?thesis" 
       
  6402     apply(simp add: mopup_inv.simps mopup_stop.simps tape_of_nat_abv)
       
  6403     done
       
  6404 qed
       
  6405 
       
  6406 lemma abc_unhalt_case_zero: 
       
  6407 "\<lbrakk>crsp_l (layout_of aprog) ac tc ires;
       
  6408   n < length am; 
       
  6409   \<forall>stp. (\<lambda>(as, am). as < length aprog) (abc_steps_l ac aprog stp)\<rbrakk>
       
  6410  \<Longrightarrow> \<exists>astp bstp. 0 \<le> bstp \<and> 
       
  6411           crsp_l (layout_of aprog) (abc_steps_l ac aprog astp) 
       
  6412                 (t_steps tc (tm_of aprog, 0) bstp) ires"
       
  6413 apply(rule_tac x = "Suc 0" in exI)
       
  6414 apply(case_tac " abc_steps_l ac aprog (Suc 0)", simp)
       
  6415 proof -
       
  6416   fix a b
       
  6417   assume "crsp_l (layout_of aprog) ac tc ires" 
       
  6418          "abc_steps_l ac aprog (Suc 0) = (a, b)"
       
  6419   thus "\<exists>bstp. crsp_l (layout_of aprog) (a, b) 
       
  6420                (t_steps tc (tm_of aprog, 0) bstp) ires"
       
  6421     apply(insert steps_crsp[of "layout_of aprog" aprog 
       
  6422                   "tm_of aprog" ac tc ires "(a, b)" "Suc 0"], auto)
       
  6423     done
       
  6424 qed
       
  6425 
       
  6426 declare abc_steps_l.simps[simp del]
       
  6427 
       
  6428 lemma abc_steps_ind: 
       
  6429  "let (as, am) = abc_steps_l ac aprog stp in 
       
  6430    abc_steps_l ac aprog (Suc stp) =
       
  6431               abc_step_l (as, am) (abc_fetch as aprog) "
       
  6432 proof(simp)
       
  6433   show "(\<lambda>(as, am). abc_steps_l ac aprog (Suc stp) = 
       
  6434         abc_step_l (as, am) (abc_fetch as aprog)) 
       
  6435               (abc_steps_l ac aprog stp)"
       
  6436   proof(induct stp arbitrary: ac)
       
  6437     fix ac
       
  6438     show "(\<lambda>(as, am). abc_steps_l ac aprog (Suc 0) = 
       
  6439             abc_step_l (as, am) (abc_fetch as aprog))  
       
  6440                     (abc_steps_l ac aprog 0)"
       
  6441       apply(case_tac "ac:: nat \<times> nat list", 
       
  6442             simp add: abc_steps_l.simps)
       
  6443       apply(case_tac "(abc_step_l (a, b) (abc_fetch a aprog))",
       
  6444             simp add: abc_steps_l.simps)
       
  6445       done
       
  6446   next
       
  6447     fix stp ac
       
  6448     assume h1:
       
  6449       "(\<And>ac. (\<lambda>(as, am). abc_steps_l ac aprog (Suc stp) =
       
  6450                             abc_step_l (as, am) (abc_fetch as aprog)) 
       
  6451              (abc_steps_l ac aprog stp))"
       
  6452     thus 
       
  6453       "(\<lambda>(as, am). abc_steps_l ac aprog (Suc (Suc stp)) =
       
  6454               abc_step_l (as, am) (abc_fetch as aprog)) 
       
  6455                              (abc_steps_l ac aprog (Suc stp))"
       
  6456       apply(case_tac "ac::nat \<times> nat list", simp)
       
  6457       apply(subgoal_tac 
       
  6458            "abc_steps_l (a, b) aprog (Suc (Suc stp)) =
       
  6459             abc_steps_l (abc_step_l (a, b) (abc_fetch a aprog)) 
       
  6460                                               aprog (Suc stp)", simp)
       
  6461       apply(case_tac "(abc_step_l (a, b) (abc_fetch a aprog))", simp)
       
  6462     proof -
       
  6463       fix a b aa ba
       
  6464       assume h2: "abc_step_l (a, b) (abc_fetch a aprog) = (aa, ba)"
       
  6465       from h1 and h2  show 
       
  6466       "(\<lambda>(as, am). abc_steps_l (aa, ba) aprog (Suc stp) = 
       
  6467           abc_step_l (as, am) (abc_fetch as aprog)) 
       
  6468                     (abc_steps_l (a, b) aprog (Suc stp))"
       
  6469 	apply(insert h1[of "(aa, ba)"])
       
  6470 	apply(simp add: abc_steps_l.simps)
       
  6471 	apply(insert h2, simp)
       
  6472 	done
       
  6473     next
       
  6474       fix a b
       
  6475       show 
       
  6476         "abc_steps_l (a, b) aprog (Suc (Suc stp)) = 
       
  6477          abc_steps_l (abc_step_l (a, b) (abc_fetch a aprog)) 
       
  6478                                                    aprog (Suc stp)"
       
  6479 	apply(simp only: abc_steps_l.simps)
       
  6480 	done
       
  6481     qed
       
  6482   qed
       
  6483 qed
       
  6484 
       
  6485 lemma abc_unhalt_case_induct: 
       
  6486   "\<lbrakk>crsp_l (layout_of aprog) ac tc ires;
       
  6487     n < length am; 
       
  6488     \<forall>stp. (\<lambda>(as, am). as < length aprog) (abc_steps_l ac aprog stp); 
       
  6489     stp \<le> bstp;
       
  6490     crsp_l (layout_of aprog) (abc_steps_l ac aprog astp) 
       
  6491                            (t_steps tc (tm_of aprog, 0) bstp) ires\<rbrakk>
       
  6492  \<Longrightarrow> \<exists>astp bstp. Suc stp \<le> bstp \<and> crsp_l (layout_of aprog) 
       
  6493        (abc_steps_l ac aprog astp) (t_steps tc (tm_of aprog, 0) bstp) ires"
       
  6494 apply(rule_tac x = "Suc astp" in exI)
       
  6495 apply(case_tac "abc_steps_l ac aprog astp")
       
  6496 proof -
       
  6497   fix a b
       
  6498   assume 
       
  6499     "\<forall>stp. (\<lambda>(as, am). as < length aprog)  
       
  6500                  (abc_steps_l ac aprog stp)" 
       
  6501     "stp \<le> bstp"
       
  6502     "crsp_l (layout_of aprog) (abc_steps_l ac aprog astp) 
       
  6503       (t_steps tc (tm_of aprog, 0) bstp) ires" 
       
  6504     "abc_steps_l ac aprog astp = (a, b)"
       
  6505   thus 
       
  6506  "\<exists>bstp\<ge>Suc stp. crsp_l (layout_of aprog)
       
  6507        (abc_steps_l ac aprog (Suc astp)) 
       
  6508    (t_steps tc (tm_of aprog, 0) bstp) ires"
       
  6509     apply(insert crsp_inside[of "layout_of aprog" aprog 
       
  6510       "tm_of aprog" a b "(t_steps tc (tm_of aprog, 0) bstp)" "ires"], auto)
       
  6511     apply(erule_tac x = astp in allE, auto)
       
  6512     apply(rule_tac x = "bstp + stpa" in exI, simp)
       
  6513     apply(insert abc_steps_ind[of ac aprog "astp"], simp)
       
  6514     done
       
  6515 qed   
       
  6516 
       
  6517 lemma abc_unhalt_case: 
       
  6518   "\<lbrakk>crsp_l (layout_of aprog) ac tc ires;  
       
  6519     \<forall>stp. (\<lambda>(as, am). as < length aprog) (abc_steps_l ac aprog stp)\<rbrakk>
       
  6520  \<Longrightarrow> (\<exists> astp bstp. bstp \<ge> stp \<and> 
       
  6521          crsp_l (layout_of aprog) (abc_steps_l ac aprog astp) 
       
  6522                                 (t_steps tc (tm_of aprog, 0) bstp) ires)"
       
  6523 apply(induct stp)
       
  6524 apply(rule_tac abc_unhalt_case_zero, auto)
       
  6525 apply(rule_tac abc_unhalt_case_induct, auto)
       
  6526 done
       
  6527   
       
  6528 lemma abacus_turing_eq_unhalt_case_pre: 
       
  6529   "\<lbrakk>ly = layout_of aprog; 
       
  6530     tprog = tm_of aprog;
       
  6531     crsp_l ly ac tc ires;
       
  6532     \<forall> stp. ((\<lambda> (as, am). as < length aprog)
       
  6533                        (abc_steps_l ac aprog stp));
       
  6534     mop_ss = start_of ly (length aprog)\<rbrakk>
       
  6535   \<Longrightarrow> (\<not> (\<exists> stp. (\<lambda> (s, l, r). s = 0)
       
  6536               (t_steps tc (tprog @ (tMp n (mop_ss - 1)), 0) stp)))"
       
  6537   apply(auto)
       
  6538 proof -
       
  6539   fix stp a b
       
  6540   assume h1: 
       
  6541     "crsp_l (layout_of aprog) ac tc ires" 
       
  6542     "\<forall>stp. (\<lambda>(as, am). as < length aprog) (abc_steps_l ac aprog stp)"
       
  6543     "t_steps tc (tm_of aprog @ tMp n (start_of (layout_of aprog) 
       
  6544     (length aprog) - Suc 0), 0) stp = (0, a, b)"
       
  6545   thus "False"
       
  6546   proof(insert abc_unhalt_case[of aprog ac tc ires stp], auto, 
       
  6547         case_tac "(abc_steps_l ac aprog astp)", 
       
  6548         case_tac "(t_steps tc (tm_of aprog, 0) bstp)", simp)
       
  6549     fix astp bstp aa ba aaa baa c
       
  6550     assume h2: 
       
  6551       "abc_steps_l ac aprog astp = (aa, ba)" "stp \<le> bstp"
       
  6552       "t_steps tc (tm_of aprog, 0) bstp = (aaa, baa, c)" 
       
  6553       "crsp_l (layout_of aprog) (aa, ba) (aaa, baa, c) ires"
       
  6554     hence h3: 
       
  6555       "t_steps tc (tm_of aprog @ tMp n 
       
  6556        (start_of (layout_of aprog) (length aprog) - Suc 0), 0) bstp 
       
  6557                     = (aaa, baa, c)"
       
  6558       apply(intro tm_append_steps, auto)
       
  6559       apply(simp add: crsp_l.simps, rule startof_not0)
       
  6560       done
       
  6561     from h2 have h4: "\<exists> diff. bstp = stp + diff"
       
  6562       apply(rule_tac x = "bstp - stp" in exI, simp)
       
  6563       done
       
  6564     from h4 and h3 and h2  and h1 show "?thesis"
       
  6565       apply(auto)
       
  6566       apply(simp add: state0_ind crsp_l.simps)
       
  6567       apply(subgoal_tac "start_of (layout_of aprog) aa > 0", simp)
       
  6568       apply(rule startof_not0)
       
  6569       done
       
  6570   qed
       
  6571 qed
       
  6572 
       
  6573 lemma abacus_turing_eq_unhalt_case:
       
  6574   assumes layout: 
       
  6575   -- {* There is an Abacus program @{text "aprog"} with layout @{text "ly"}: *}
       
  6576   "ly = layout_of aprog"
       
  6577   and compiled: 
       
  6578   -- {* The TM compiled from @{text "aprog"} is @{text "tprog"}: *}
       
  6579   "tprog = tm_of aprog"
       
  6580   and correspond: 
       
  6581   -- {* 
       
  6582   TM configuration @{text "tc"} and Abacus configuration @{text "ac"}
       
  6583   are in correspondence: 
       
  6584   *}
       
  6585   "crsp_l ly ac tc ires"
       
  6586   and abc_unhalt: 
       
  6587   -- {*
       
  6588   If, no matter how many steps the Abacus program @{text "aprog"} executes, it
       
  6589   may never reach a halt state. 
       
  6590   *}
       
  6591   "\<forall> stp. ((\<lambda> (as, am). as < length aprog)
       
  6592                        (abc_steps_l ac aprog stp))"
       
  6593   and mopup_start: "mop_ss = start_of ly (length aprog)"
       
  6594   shows
       
  6595   -- {*
       
  6596   The the TM composed of TM @{text "tprog"} and the moupup TM may never reach a halt state as well.
       
  6597   *}
       
  6598   "\<not> (\<exists> stp. (\<lambda> (s, l, r). s = 0)
       
  6599               (t_steps tc (tprog @ (tMp n (mop_ss - 1)), 0) stp))"
       
  6600   using layout compiled correspond abc_unhalt mopup_start
       
  6601   apply(rule_tac abacus_turing_eq_unhalt_case_pre, auto)
       
  6602   done
       
  6603 
       
  6604 
       
  6605 definition abc_list_crsp:: "nat list \<Rightarrow> nat list \<Rightarrow> bool"
       
  6606   where
       
  6607   "abc_list_crsp xs ys = (\<exists> n. xs = ys @ 0\<^bsup>n\<^esup> \<or> ys = xs @ 0\<^bsup>n\<^esup>)"
       
  6608 lemma [intro]: "abc_list_crsp (lm @ 0\<^bsup>m\<^esup>) lm"
       
  6609 apply(auto simp: abc_list_crsp_def)
       
  6610 done
       
  6611 
       
  6612 lemma abc_list_crsp_lm_v: 
       
  6613   "abc_list_crsp lma lmb \<Longrightarrow> abc_lm_v lma n = abc_lm_v lmb n"
       
  6614 apply(auto simp: abc_list_crsp_def abc_lm_v.simps 
       
  6615                  nth_append exponent_def)
       
  6616 done
       
  6617 
       
  6618 lemma  rep_app_cons_iff: 
       
  6619   "k < n \<Longrightarrow> replicate n a[k:=b] = 
       
  6620           replicate k a @ b # replicate (n - k - 1) a"
       
  6621 apply(induct n arbitrary: k, simp)
       
  6622 apply(simp split:nat.splits)
       
  6623 done
       
  6624 
       
  6625 lemma abc_list_crsp_lm_s: 
       
  6626   "abc_list_crsp lma lmb \<Longrightarrow> 
       
  6627       abc_list_crsp (abc_lm_s lma m n) (abc_lm_s lmb m n)"
       
  6628 apply(auto simp: abc_list_crsp_def abc_lm_v.simps abc_lm_s.simps)
       
  6629 apply(simp_all add: list_update_append, auto simp: exponent_def)
       
  6630 proof -
       
  6631   fix na
       
  6632   assume h: "m < length lmb + na" " \<not> m < length lmb"
       
  6633   hence "m - length lmb < na" by simp
       
  6634   hence "replicate na 0[(m- length lmb):= n] = 
       
  6635            replicate (m - length lmb) 0 @ n # 
       
  6636               replicate (na - (m - length lmb) - 1) 0"
       
  6637     apply(erule_tac rep_app_cons_iff)
       
  6638     done
       
  6639   thus "\<exists>nb. replicate na 0[m - length lmb := n] =
       
  6640                  replicate (m - length lmb) 0 @ n # replicate nb 0 \<or>
       
  6641                  replicate (m - length lmb) 0 @ [n] =
       
  6642                  replicate na 0[m - length lmb := n] @ replicate nb 0"
       
  6643     apply(auto)
       
  6644     done
       
  6645 next
       
  6646   fix na
       
  6647   assume h: "\<not> m < length lmb + na"
       
  6648   show 
       
  6649     "\<exists>nb. replicate na 0 @ replicate (m - (length lmb + na)) 0 @ [n] =
       
  6650            replicate (m - length lmb) 0 @ n # replicate nb 0 \<or>
       
  6651           replicate (m - length lmb) 0 @ [n] =
       
  6652             replicate na 0 @
       
  6653             replicate (m - (length lmb + na)) 0 @ n # replicate nb 0"
       
  6654     apply(rule_tac x = 0 in exI, simp, auto)
       
  6655     using h
       
  6656     apply(simp add: replicate_add[THEN sym])
       
  6657     done
       
  6658 next
       
  6659   fix na
       
  6660   assume h: "\<not> m < length lma" "m < length lma + na"
       
  6661   hence "m - length lma < na" by simp
       
  6662   hence 
       
  6663     "replicate na 0[(m- length lma):= n] = replicate (m - length lma) 
       
  6664                   0 @ n # replicate (na - (m - length lma) - 1) 0"
       
  6665     apply(erule_tac rep_app_cons_iff)
       
  6666     done
       
  6667   thus "\<exists>nb. replicate (m - length lma) 0 @ [n] =
       
  6668                  replicate na 0[m - length lma := n] @ replicate nb 0 
       
  6669            \<or> replicate na 0[m - length lma := n] =
       
  6670                  replicate (m - length lma) 0 @ n # replicate nb 0"
       
  6671     apply(auto)
       
  6672     done
       
  6673 next
       
  6674   fix na
       
  6675   assume "\<not> m < length lma + na"
       
  6676   thus " \<exists>nb. replicate (m - length lma) 0 @ [n] =
       
  6677             replicate na 0 @
       
  6678             replicate (m - (length lma + na)) 0 @ n # replicate nb 0 
       
  6679         \<or>   replicate na 0 @ 
       
  6680                replicate (m - (length lma + na)) 0 @ [n] =
       
  6681             replicate (m - length lma) 0 @ n # replicate nb 0"
       
  6682     apply(rule_tac x = 0 in exI, simp, auto)
       
  6683     apply(simp add: replicate_add[THEN sym])
       
  6684     done
       
  6685 qed
       
  6686 
       
  6687 lemma abc_list_crsp_step: 
       
  6688   "\<lbrakk>abc_list_crsp lma lmb; abc_step_l (aa, lma) i = (a, lma'); 
       
  6689     abc_step_l (aa, lmb) i = (a', lmb')\<rbrakk>
       
  6690     \<Longrightarrow> a' = a \<and> abc_list_crsp lma' lmb'"
       
  6691 apply(case_tac i, auto simp: abc_step_l.simps 
       
  6692        abc_list_crsp_lm_s abc_list_crsp_lm_v Let_def 
       
  6693                        split: abc_inst.splits if_splits)
       
  6694 done
       
  6695 
       
  6696 lemma abc_steps_red: 
       
  6697   "abc_steps_l ac aprog stp = (as, am) \<Longrightarrow>
       
  6698      abc_steps_l ac aprog (Suc stp) = 
       
  6699            abc_step_l (as, am) (abc_fetch as aprog)"
       
  6700 using abc_steps_ind[of ac aprog stp]
       
  6701 apply(simp)
       
  6702 done
       
  6703 
       
  6704 lemma abc_list_crsp_steps: 
       
  6705   "\<lbrakk>abc_steps_l (0, lm @ 0\<^bsup>m\<^esup>) aprog stp = (a, lm'); aprog \<noteq> []\<rbrakk> 
       
  6706       \<Longrightarrow> \<exists> lma. abc_steps_l (0, lm) aprog stp = (a, lma) \<and> 
       
  6707                                           abc_list_crsp lm' lma"
       
  6708 apply(induct stp arbitrary: a lm', simp add: abc_steps_l.simps, auto)
       
  6709 apply(case_tac "abc_steps_l (0, lm @ 0\<^bsup>m\<^esup>) aprog stp", 
       
  6710       simp add: abc_steps_ind)
       
  6711 proof -
       
  6712   fix stp a lm' aa b
       
  6713   assume ind:
       
  6714     "\<And>a lm'. aa = a \<and> b = lm' \<Longrightarrow> 
       
  6715      \<exists>lma. abc_steps_l (0, lm) aprog stp = (a, lma) \<and>
       
  6716                                           abc_list_crsp lm' lma"
       
  6717     and h: "abc_steps_l (0, lm @ 0\<^bsup>m\<^esup>) aprog (Suc stp) = (a, lm')" 
       
  6718            "abc_steps_l (0, lm @ 0\<^bsup>m\<^esup>) aprog stp = (aa, b)" 
       
  6719            "aprog \<noteq> []"
       
  6720   hence g1: "abc_steps_l (0, lm @ 0\<^bsup>m\<^esup>) aprog (Suc stp)
       
  6721           = abc_step_l (aa, b) (abc_fetch aa aprog)"
       
  6722     apply(rule_tac abc_steps_red, simp)
       
  6723     done
       
  6724   have "\<exists>lma. abc_steps_l (0, lm) aprog stp = (aa, lma) \<and> 
       
  6725               abc_list_crsp b lma"
       
  6726     apply(rule_tac ind, simp)
       
  6727     done
       
  6728   from this obtain lma where g2: 
       
  6729     "abc_steps_l (0, lm) aprog stp = (aa, lma) \<and> 
       
  6730      abc_list_crsp b lma"   ..
       
  6731   hence g3: "abc_steps_l (0, lm) aprog (Suc stp)
       
  6732           = abc_step_l (aa, lma) (abc_fetch aa aprog)"
       
  6733     apply(rule_tac abc_steps_red, simp)
       
  6734     done
       
  6735   show "\<exists>lma. abc_steps_l (0, lm) aprog (Suc stp) = (a, lma) \<and>  
       
  6736               abc_list_crsp lm' lma"
       
  6737     using g1 g2 g3 h
       
  6738     apply(auto)
       
  6739     apply(case_tac "abc_step_l (aa, b) (abc_fetch aa aprog)",
       
  6740           case_tac "abc_step_l (aa, lma) (abc_fetch aa aprog)", simp)
       
  6741     apply(rule_tac abc_list_crsp_step, auto)
       
  6742     done
       
  6743 qed
       
  6744 
       
  6745 lemma [simp]: "(case ca of [] \<Rightarrow> Bk | Bk # xs \<Rightarrow> Bk | Oc # xs \<Rightarrow> Oc) =
       
  6746                 (case ca of [] \<Rightarrow> Bk | x # xs \<Rightarrow> x)"
       
  6747 by(case_tac ca, simp_all, case_tac a, simp, simp)
       
  6748 
       
  6749 lemma steps_eq: "length t mod 2 = 0 \<Longrightarrow> 
       
  6750                     t_steps c (t, 0) stp = steps c t stp"
       
  6751 apply(induct stp)
       
  6752 apply(simp add: steps.simps t_steps.simps)
       
  6753 apply(simp add:tstep_red t_steps_ind)
       
  6754 apply(case_tac "steps c t stp", simp)
       
  6755 apply(auto simp: t_step.simps tstep.simps)
       
  6756 done
       
  6757 
       
  6758 lemma crsp_l_start: "crsp_l ly (0, lm) (Suc 0, Bk # Bk # ires, <lm> @ Bk\<^bsup>rn\<^esup>) ires"
       
  6759 apply(simp add: crsp_l.simps, auto simp: start_of.simps)
       
  6760 done
       
  6761 
       
  6762 lemma t_ncorrect_app: "\<lbrakk>t_ncorrect t1; t_ncorrect t2\<rbrakk> \<Longrightarrow> 
       
  6763                                           t_ncorrect (t1 @ t2)"
       
  6764 apply(simp add: t_ncorrect.simps, auto)
       
  6765 done
       
  6766 
       
  6767 lemma [simp]: 
       
  6768   "(length (tm_of aprog) + 
       
  6769     length (tMp n (start_of ly (length aprog) - Suc 0))) mod 2 = 0"
       
  6770 apply(subgoal_tac 
       
  6771  "t_ncorrect (tm_of aprog @ tMp n 
       
  6772              (start_of ly (length aprog) - Suc 0))")
       
  6773 apply(simp add: t_ncorrect.simps)
       
  6774 apply(rule_tac t_ncorrect_app, 
       
  6775       auto simp: tMp.simps t_ncorrect.simps tshift.simps mp_up_def)
       
  6776 apply(subgoal_tac
       
  6777        "t_ncorrect (tm_of aprog)", simp add: t_ncorrect.simps)
       
  6778 apply(auto)
       
  6779 done
       
  6780 
       
  6781 lemma [simp]: "takeWhile (\<lambda>a. a = Oc) 
       
  6782               (replicate rs Oc @ replicate rn Bk) = replicate rs Oc"
       
  6783 apply(induct rs, auto)
       
  6784 apply(induct rn, auto)
       
  6785 done
       
  6786 
       
  6787 lemma abacus_turing_eq_halt': 
       
  6788   "\<lbrakk>ly = layout_of aprog; 
       
  6789     tprog = tm_of aprog; 
       
  6790     n < length am;
       
  6791     abc_steps_l (0, lm) aprog stp = (as, am); 
       
  6792     mop_ss = start_of ly (length aprog);
       
  6793     as \<ge> length aprog\<rbrakk>
       
  6794     \<Longrightarrow> \<exists> stp m l. steps (Suc 0, Bk # Bk # ires, <lm> @ Bk\<^bsup>rn\<^esup>) 
       
  6795                 (tprog @ (tMp n (mop_ss - 1))) stp
       
  6796                   = (0, Bk\<^bsup>m\<^esup> @ Bk # Bk # ires, Oc\<^bsup>Suc (abc_lm_v am n)\<^esup> @ Bk\<^bsup>l\<^esup>)"
       
  6797 apply(drule_tac tc = "(Suc 0, Bk # Bk # ires, <lm> @ Bk\<^bsup>rn\<^esup>)" in 
       
  6798                abacus_turing_eq_halt_case, auto intro: crsp_l_start)
       
  6799 apply(subgoal_tac 
       
  6800          "length (tm_of aprog @ tMp n 
       
  6801                   (start_of ly (length aprog) - Suc 0)) mod 2 = 0")
       
  6802 apply(simp add: steps_eq)
       
  6803 apply(rule_tac x = stpa in exI, 
       
  6804        simp add:  exponent_def, auto)
       
  6805 done
       
  6806 
       
  6807 
       
  6808 lemma list_length: "xs = ys \<Longrightarrow> length xs = length ys"
       
  6809 by simp
       
  6810 lemma [elim]: "tinres (Bk\<^bsup>m\<^esup>) b \<Longrightarrow> \<exists>m. b = Bk\<^bsup>m\<^esup>"
       
  6811 apply(auto simp: tinres_def)
       
  6812 apply(rule_tac x = "m-n" in exI, 
       
  6813              auto simp: exponent_def replicate_add[THEN sym]) 
       
  6814 apply(case_tac "m < n", auto)
       
  6815 apply(drule_tac list_length, auto)
       
  6816 apply(subgoal_tac "\<exists> d. m = d + n", auto simp: replicate_add)
       
  6817 apply(rule_tac x = "m - n" in exI, simp)
       
  6818 done
       
  6819 lemma [intro]: "tinres [Bk] (Bk\<^bsup>k\<^esup>) "
       
  6820 apply(auto simp: tinres_def exponent_def)
       
  6821 apply(case_tac k, auto)
       
  6822 apply(rule_tac x = "Suc 0" in exI, simp)
       
  6823 done
       
  6824 
       
  6825 lemma abacus_turing_eq_halt_pre: 
       
  6826  "\<lbrakk>ly = layout_of aprog; 
       
  6827    tprog = tm_of aprog; 
       
  6828    n < length am;     
       
  6829    abc_steps_l (0, lm) aprog stp = (as, am);  
       
  6830    mop_ss = start_of ly (length aprog);
       
  6831    as \<ge> length aprog\<rbrakk>
       
  6832   \<Longrightarrow> \<exists> stp m l. steps  (Suc 0, Bk # Bk # ires, <lm> @ Bk\<^bsup>rn\<^esup>)
       
  6833                (tprog @ (tMp n (mop_ss - 1))) stp
       
  6834                  = (0, Bk\<^bsup>m\<^esup> @ Bk # Bk # ires, Oc\<^bsup>Suc (abc_lm_v am n)\<^esup> @ Bk\<^bsup>l\<^esup>)"
       
  6835 using abacus_turing_eq_halt'
       
  6836 apply(simp)
       
  6837 done
       
  6838 
       
  6839 
       
  6840 text {*
       
  6841   Main theorem for the case when the original Abacus program does halt.
       
  6842 *}
       
  6843 
       
  6844 lemma abacus_turing_eq_halt: 
       
  6845   assumes layout:
       
  6846   "ly = layout_of aprog"
       
  6847   -- {* There is an Abacus program @{text "aprog"} with layout @{text "ly"}: *}
       
  6848   and compiled: "tprog = tm_of aprog"
       
  6849   -- {* The TM compiled from @{text "aprog"} is @{text "tprog"}: *}
       
  6850   and halt_state: 
       
  6851    -- {* @{text "as"} is a program label outside the range of @{text "aprog"}. So 
       
  6852   if Abacus is in such a state, it is in halt state: *}
       
  6853   "as \<ge> length aprog"
       
  6854   and abc_exec: 
       
  6855   -- {* Supposing after @{text "stp"} step of execution, Abacus program @{text "aprog"}
       
  6856   reaches such a halt state: *}
       
  6857   "abc_steps_l (0, lm) aprog stp = (as, am)"
       
  6858   and rs_locate: 
       
  6859    -- {* @{text "n"} is a memory address in the range of Abacus memory @{text "am"}: *}
       
  6860   "n < length am"  
       
  6861   and mopup_start: 
       
  6862    -- {* The startling label for mopup mahines, according to the layout and Abacus program 
       
  6863    should be @{text "mop_ss"}: *}
       
  6864   "mop_ss = start_of ly (length aprog)"
       
  6865   shows 
       
  6866   -- {* 
       
  6867   After @{text "stp"} steps of execution of the TM composed of @{text "tprog"} and the mopup 
       
  6868   TM @{text "(tMp n (mop_ss - 1))"} will halt and gives rise to a configuration which 
       
  6869   only hold the content of memory cell @{text "n"}:
       
  6870   *}
       
  6871   "\<exists> stp m l. steps (Suc 0, Bk # Bk # ires, <lm> @ Bk\<^bsup>rn\<^esup>) (tprog @ (tMp n (mop_ss - 1))) stp
       
  6872                       = (0, Bk\<^bsup>m\<^esup> @ Bk # Bk # ires, Oc\<^bsup>Suc (abc_lm_v am n)\<^esup> @ Bk\<^bsup>l\<^esup>)"
       
  6873   using layout compiled halt_state abc_exec rs_locate mopup_start
       
  6874   by(rule_tac abacus_turing_eq_halt_pre, auto)
       
  6875 
       
  6876 lemma abacus_turing_eq_uhalt': 
       
  6877  "\<lbrakk>ly = layout_of aprog; 
       
  6878    tprog = tm_of aprog; 
       
  6879    \<forall> stp. ((\<lambda> (as, am). as < length aprog) 
       
  6880                    (abc_steps_l (0, lm) aprog stp));
       
  6881    mop_ss = start_of ly (length aprog)\<rbrakk>
       
  6882   \<Longrightarrow> (\<not> (\<exists> stp. isS0 (steps (Suc 0, [Bk, Bk], <lm>) 
       
  6883                       (tprog @ (tMp n (mop_ss - 1))) stp)))"
       
  6884 apply(drule_tac tc = "(Suc 0, [Bk, Bk], <lm>)" and n = n and ires = "[]" in 
       
  6885          abacus_turing_eq_unhalt_case, auto intro: crsp_l_start)
       
  6886 apply(simp add: crsp_l.simps start_of.simps)
       
  6887 apply(erule_tac x = stp in allE, erule_tac x = stp in allE)
       
  6888 apply(subgoal_tac 
       
  6889    "length (tm_of aprog @ tMp n 
       
  6890          (start_of ly (length aprog) - Suc 0)) mod 2 = 0")
       
  6891 apply(simp add: steps_eq, auto simp: isS0_def)
       
  6892 done
       
  6893 
       
  6894 text {*
       
  6895   Main theorem for the case when the original Abacus program does not halt.
       
  6896   *}
       
  6897 lemma abacus_turing_eq_uhalt:
       
  6898   assumes layout: 
       
  6899   -- {* There is an Abacus program @{text "aprog"} with layout @{text "ly"}: *}
       
  6900   "ly = layout_of aprog"
       
  6901   and compiled:
       
  6902    -- {* The TM compiled from @{text "aprog"} is @{text "tprog"}: *}
       
  6903   "tprog = tm_of aprog"
       
  6904   and abc_unhalt:
       
  6905   -- {*
       
  6906   If, no matter how many steps the Abacus program @{text "aprog"} executes, it
       
  6907   may never reach a halt state. 
       
  6908   *}
       
  6909   "\<forall> stp. ((\<lambda> (as, am). as < length aprog) 
       
  6910                       (abc_steps_l (0, lm) aprog stp))"
       
  6911   and mop_start: "mop_ss = start_of ly (length aprog)"
       
  6912   shows 
       
  6913    -- {*
       
  6914   The the TM composed of TM @{text "tprog"} and the moupup TM may never reach a halt state as well.
       
  6915   *}
       
  6916   "\<not> (\<exists> stp. isS0 (steps (Suc 0, [Bk, Bk], <lm>) 
       
  6917                     (tprog @ (tMp n (mop_ss - 1))) stp))"
       
  6918   using abacus_turing_eq_uhalt'
       
  6919         layout compiled abc_unhalt mop_start
       
  6920   by(auto)
       
  6921 
       
  6922 end
       
  6923