thys/Abacus.thy
changeset 163 67063c5365e1
parent 115 653426ed4b38
child 165 582916f289ea
equal deleted inserted replaced
162:a63c3f8d7234 163:67063c5365e1
       
     1 header {* 
       
     2  {\em abacus} a kind of register machine
       
     3 *}
       
     4 
       
     5 theory Abacus
       
     6 imports Uncomputable
       
     7 begin
       
     8 
       
     9 (*
       
    10 declare tm_comp.simps [simp add] 
       
    11 declare adjust.simps[simp add] 
       
    12 declare shift.simps[simp add]
       
    13 declare tm_wf.simps[simp add]
       
    14 declare step.simps[simp add]
       
    15 declare steps.simps[simp add]
       
    16 *)
       
    17 declare replicate_Suc[simp add]
       
    18 
       
    19 text {*
       
    20   {\em Abacus} instructions:
       
    21 *}
       
    22 
       
    23 datatype abc_inst =
       
    24   -- {* @{text "Inc n"} increments the memory cell (or register) with address @{text "n"} by one.
       
    25      *}
       
    26      Inc nat
       
    27   -- {*
       
    28      @{text "Dec n label"} decrements the memory cell with address @{text "n"} by one. 
       
    29       If cell @{text "n"} is already zero, no decrements happens and the executio jumps to
       
    30       the instruction labeled by @{text "label"}.
       
    31      *}
       
    32    | Dec nat nat
       
    33   -- {*
       
    34   @{text "Goto label"} unconditionally jumps to the instruction labeled by @{text "label"}.
       
    35   *}
       
    36    | Goto nat
       
    37   
       
    38 
       
    39 text {*
       
    40   Abacus programs are defined as lists of Abacus instructions.
       
    41 *}
       
    42 type_synonym abc_prog = "abc_inst list"
       
    43 
       
    44 section {*
       
    45   Sample Abacus programs
       
    46   *}
       
    47 
       
    48 text {*
       
    49   Abacus for addition and clearance.
       
    50 *}
       
    51 fun plus_clear :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> abc_prog"  
       
    52   where
       
    53   "plus_clear m n e = [Dec m e, Inc n, Goto 0]"
       
    54 
       
    55 text {*
       
    56   Abacus for clearing memory untis.
       
    57 *}
       
    58 fun clear :: "nat \<Rightarrow> nat \<Rightarrow> abc_prog"
       
    59   where
       
    60   "clear n e = [Dec n e, Goto 0]"
       
    61 
       
    62 fun plus:: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> abc_prog"
       
    63   where
       
    64   "plus m n p e = [Dec m 4, Inc n, Inc p,
       
    65                    Goto 0, Dec p e, Inc m, Goto 4]"
       
    66 
       
    67 fun mult :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> abc_prog"
       
    68   where
       
    69   "mult m1 m2 n p e = [Dec m1 e]@ plus m1 m2 p 1"
       
    70 
       
    71 fun expo :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> abc_prog"
       
    72   where
       
    73   "expo n m1 m2 p e = [Inc n, Dec m1 e] @ mult m2 n n p 2"
       
    74 
       
    75 
       
    76 text {*
       
    77   The state of Abacus machine.
       
    78   *}
       
    79 type_synonym abc_state = nat
       
    80 
       
    81 (* text {*
       
    82   The memory of Abacus machine is defined as a function from address to contents.
       
    83 *}
       
    84 type_synonym abc_mem = "nat \<Rightarrow> nat" *)
       
    85 
       
    86 text {*
       
    87   The memory of Abacus machine is defined as a list of contents, with 
       
    88   every units addressed by index into the list.
       
    89   *}
       
    90 type_synonym abc_lm = "nat list"
       
    91 
       
    92 text {*
       
    93   Fetching contents out of memory. Units not represented by list elements are considered
       
    94   as having content @{text "0"}.
       
    95 *}
       
    96 fun abc_lm_v :: "abc_lm \<Rightarrow> nat \<Rightarrow> nat"
       
    97   where 
       
    98     "abc_lm_v lm n = (if (n < length lm) then (lm!n) else 0)"         
       
    99 
       
   100 
       
   101 text {*
       
   102   Set the content of memory unit @{text "n"} to value @{text "v"}.
       
   103   @{text "am"} is the Abacus memory before setting.
       
   104   If address @{text "n"} is outside to scope of @{text "am"}, @{text "am"} 
       
   105   is extended so that @{text "n"} becomes in scope.
       
   106 *}
       
   107 
       
   108 fun abc_lm_s :: "abc_lm \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> abc_lm"
       
   109   where
       
   110     "abc_lm_s am n v = (if (n < length am) then (am[n:=v]) else 
       
   111                            am@ (replicate (n - length am) 0) @ [v])"
       
   112 
       
   113 
       
   114 text {*
       
   115   The configuration of Abaucs machines consists of its current state and its
       
   116   current memory:
       
   117 *}
       
   118 type_synonym abc_conf = "abc_state \<times> abc_lm"
       
   119 
       
   120 text {*
       
   121   Fetch instruction out of Abacus program:
       
   122 *}
       
   123 
       
   124 fun abc_fetch :: "nat \<Rightarrow> abc_prog \<Rightarrow> abc_inst option" 
       
   125   where
       
   126   "abc_fetch s p = (if (s < length p) then Some (p ! s)
       
   127                     else None)"
       
   128 
       
   129 text {*
       
   130   Single step execution of Abacus machine. If no instruction is feteched, 
       
   131   configuration does not change.
       
   132 *}
       
   133 fun abc_step_l :: "abc_conf \<Rightarrow> abc_inst option \<Rightarrow> abc_conf"
       
   134   where
       
   135   "abc_step_l (s, lm) a = (case a of 
       
   136                None \<Rightarrow> (s, lm) |
       
   137                Some (Inc n)  \<Rightarrow> (let nv = abc_lm_v lm n in
       
   138                        (s + 1, abc_lm_s lm n (nv + 1))) |
       
   139                Some (Dec n e) \<Rightarrow> (let nv = abc_lm_v lm n in
       
   140                        if (nv = 0) then (e, abc_lm_s lm n 0) 
       
   141                        else (s + 1,  abc_lm_s lm n (nv - 1))) |
       
   142                Some (Goto n) \<Rightarrow> (n, lm) 
       
   143                )"
       
   144 
       
   145 text {*
       
   146   Multi-step execution of Abacus machine.
       
   147 *}
       
   148 fun abc_steps_l :: "abc_conf \<Rightarrow> abc_prog \<Rightarrow> nat \<Rightarrow> abc_conf"
       
   149   where
       
   150   "abc_steps_l (s, lm) p 0 = (s, lm)" |
       
   151   "abc_steps_l (s, lm) p (Suc n) = 
       
   152       abc_steps_l (abc_step_l (s, lm) (abc_fetch s p)) p n"
       
   153 
       
   154 section {*
       
   155   Compiling Abacus machines into Truing machines
       
   156 *}
       
   157 
       
   158 subsection {*
       
   159   Compiling functions
       
   160 *}
       
   161 
       
   162 text {*
       
   163   @{text "findnth n"} returns the TM which locates the represention of
       
   164   memory cell @{text "n"} on the tape and changes representation of zero
       
   165   on the way.
       
   166 *}
       
   167 
       
   168 fun findnth :: "nat \<Rightarrow> instr list"
       
   169   where
       
   170   "findnth 0 = []" |
       
   171   "findnth (Suc n) = (findnth n @ [(W1, 2 * n + 1), 
       
   172            (R, 2 * n + 2), (R, 2 * n + 3), (R, 2 * n + 2)])"
       
   173 
       
   174 text {*
       
   175   @{text "tinc_b"} returns the TM which increments the representation 
       
   176   of the memory cell under rw-head by one and move the representation 
       
   177   of cells afterwards to the right accordingly.
       
   178   *}
       
   179 
       
   180 definition tinc_b :: "instr list"
       
   181   where
       
   182   "tinc_b \<equiv> [(W1, 1), (R, 2), (W1, 3), (R, 2), (W1, 3), (R, 4), 
       
   183              (L, 7), (W0, 5), (R, 6), (W0, 5), (W1, 3), (R, 6),
       
   184              (L, 8), (L, 7), (R, 9), (L, 7), (R, 10), (W0, 9)]" 
       
   185 
       
   186 text {*
       
   187   @{text "tinc ss n"} returns the TM which simulates the execution of 
       
   188   Abacus instruction @{text "Inc n"}, assuming that TM is located at
       
   189   location @{text "ss"} in the final TM complied from the whole
       
   190   Abacus program.
       
   191 *}
       
   192 
       
   193 fun tinc :: "nat \<Rightarrow> nat \<Rightarrow> instr list"
       
   194   where
       
   195   "tinc ss n = shift (findnth n @ shift tinc_b (2 * n)) (ss - 1)"
       
   196 
       
   197 text {*
       
   198   @{text "tinc_b"} returns the TM which decrements the representation 
       
   199   of the memory cell under rw-head by one and move the representation 
       
   200   of cells afterwards to the left accordingly.
       
   201   *}
       
   202 
       
   203 definition tdec_b :: "instr list"
       
   204   where
       
   205   "tdec_b \<equiv>  [(W1, 1), (R, 2), (L, 14), (R, 3), (L, 4), (R, 3),
       
   206               (R, 5), (W0, 4), (R, 6), (W0, 5), (L, 7), (L, 8),
       
   207               (L, 11), (W0, 7), (W1, 8), (R, 9), (L, 10), (R, 9),
       
   208               (R, 5), (W0, 10), (L, 12), (L, 11), (R, 13), (L, 11),
       
   209               (R, 17), (W0, 13), (L, 15), (L, 14), (R, 16), (L, 14),
       
   210               (R, 0), (W0, 16)]"
       
   211 
       
   212 text {*
       
   213   @{text "sete tp e"} attaches the termination edges (edges leading to state @{text "0"}) 
       
   214   of TM @{text "tp"} to the intruction labelled by @{text "e"}.
       
   215   *}
       
   216 
       
   217 fun sete :: "instr list \<Rightarrow> nat \<Rightarrow> instr list"
       
   218   where
       
   219   "sete tp e = map (\<lambda> (action, state). (action, if state = 0 then e else state)) tp"
       
   220 
       
   221 text {*
       
   222   @{text "tdec ss n label"} returns the TM which simulates the execution of 
       
   223   Abacus instruction @{text "Dec n label"}, assuming that TM is located at
       
   224   location @{text "ss"} in the final TM complied from the whole
       
   225   Abacus program.
       
   226 *}
       
   227 
       
   228 fun tdec :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> instr list"
       
   229   where
       
   230   "tdec ss n e = shift (findnth n) (ss - 1) @ sete (shift (shift tdec_b (2 * n)) (ss - 1)) e"
       
   231  
       
   232 text {*
       
   233   @{text "tgoto f(label)"} returns the TM simulating the execution of Abacus instruction
       
   234   @{text "Goto label"}, where @{text "f(label)"} is the corresponding location of
       
   235   @{text "label"} in the final TM compiled from the overall Abacus program.
       
   236 *}
       
   237 
       
   238 fun tgoto :: "nat \<Rightarrow> instr list"
       
   239   where
       
   240   "tgoto n = [(Nop, n), (Nop, n)]"
       
   241 
       
   242 text {*
       
   243   The layout of the final TM compiled from an Abacus program is represented
       
   244   as a list of natural numbers, where the list element at index @{text "n"} represents the 
       
   245   starting state of the TM simulating the execution of @{text "n"}-th instruction
       
   246   in the Abacus program.
       
   247 *}
       
   248 
       
   249 type_synonym layout = "nat list"
       
   250 
       
   251 text {*
       
   252   @{text "length_of i"} is the length of the 
       
   253   TM simulating the Abacus instruction @{text "i"}.
       
   254 *}
       
   255 fun length_of :: "abc_inst \<Rightarrow> nat"
       
   256   where
       
   257   "length_of i = (case i of 
       
   258                     Inc n   \<Rightarrow> 2 * n + 9 |
       
   259                     Dec n e \<Rightarrow> 2 * n + 16 |
       
   260                     Goto n  \<Rightarrow> 1)"
       
   261 
       
   262 text {*
       
   263   @{text "layout_of ap"} returns the layout of Abacus program @{text "ap"}.
       
   264 *}
       
   265 fun layout_of :: "abc_prog \<Rightarrow> layout"
       
   266   where "layout_of ap = map length_of ap"
       
   267 
       
   268 
       
   269 text {*
       
   270   @{text "start_of layout n"} looks out the starting state of @{text "n"}-th
       
   271   TM in the finall TM.
       
   272 *}
       
   273 thm listsum_def
       
   274 
       
   275 fun start_of :: "nat list \<Rightarrow> nat \<Rightarrow> nat"
       
   276   where
       
   277   "start_of ly x = (Suc (listsum (take x ly))) "
       
   278 
       
   279 text {*
       
   280   @{text "ci lo ss i"} complies Abacus instruction @{text "i"}
       
   281   assuming the TM of @{text "i"} starts from state @{text "ss"} 
       
   282   within the overal layout @{text "lo"}.
       
   283 *}
       
   284 
       
   285 fun ci :: "layout \<Rightarrow> nat \<Rightarrow> abc_inst \<Rightarrow> instr list"
       
   286   where
       
   287   "ci ly ss (Inc n) = tinc ss n"
       
   288 | "ci ly ss (Dec n e) = tdec ss n (start_of ly e)"
       
   289 | "ci ly ss (Goto n) = tgoto (start_of ly n)"
       
   290 
       
   291 text {*
       
   292   @{text "tpairs_of ap"} transfroms Abacus program @{text "ap"} pairing
       
   293   every instruction with its starting state.
       
   294 *}
       
   295 
       
   296 fun tpairs_of :: "abc_prog \<Rightarrow> (nat \<times> abc_inst) list"
       
   297   where "tpairs_of ap = (zip (map (start_of (layout_of ap)) 
       
   298                          [0..<(length ap)]) ap)"
       
   299 
       
   300 text {*
       
   301   @{text "tms_of ap"} returns the list of TMs, where every one of them simulates
       
   302   the corresponding Abacus intruction in @{text "ap"}.
       
   303 *}
       
   304 
       
   305 fun tms_of :: "abc_prog \<Rightarrow> (instr list) list"
       
   306   where "tms_of ap = map (\<lambda> (n, tm). ci (layout_of ap) n tm) 
       
   307                          (tpairs_of ap)"
       
   308 
       
   309 text {*
       
   310   @{text "tm_of ap"} returns the final TM machine compiled from Abacus program @{text "ap"}.
       
   311 *}
       
   312 fun tm_of :: "abc_prog \<Rightarrow> instr list"
       
   313   where "tm_of ap = concat (tms_of ap)"
       
   314 
       
   315 text {*
       
   316   The following two functions specify the well-formedness of complied TM.
       
   317 *}
       
   318 (*
       
   319 fun t_ncorrect :: "tprog \<Rightarrow> bool"
       
   320   where
       
   321   "t_ncorrect tp = (length tp mod 2 = 0)"
       
   322 
       
   323 fun abc2t_correct :: "abc_prog \<Rightarrow> bool"
       
   324   where 
       
   325   "abc2t_correct ap = list_all (\<lambda> (n, tm). 
       
   326              t_ncorrect (ci (layout_of ap) n tm)) (tpairs_of ap)"
       
   327 *)
       
   328 
       
   329 lemma length_findnth: 
       
   330   "length (findnth n) = 4 * n"
       
   331 apply(induct n, auto)
       
   332 done
       
   333 
       
   334 lemma ci_length : "length (ci ns n ai) div 2 = length_of ai"
       
   335 apply(auto simp: ci.simps tinc_b_def tdec_b_def length_findnth
       
   336                  split: abc_inst.splits)
       
   337 done
       
   338 
       
   339 subsection {*
       
   340   Representation of Abacus memory by TM tape
       
   341 *}
       
   342 
       
   343 text {*
       
   344   @{text "crsp acf tcf"} meams the abacus configuration @{text "acf"}
       
   345   is corretly represented by the TM configuration @{text "tcf"}.
       
   346 *}
       
   347 
       
   348 fun crsp :: "layout \<Rightarrow> abc_conf \<Rightarrow> config \<Rightarrow> cell list \<Rightarrow> bool"
       
   349   where 
       
   350   "crsp ly (as, lm) (s, l, r) inres = 
       
   351            (s = start_of ly as \<and> (\<exists> x. r = <lm> @ Bk\<up>x) \<and> 
       
   352             l = Bk # Bk # inres)"
       
   353 
       
   354 declare crsp.simps[simp del]
       
   355 
       
   356 subsection {*
       
   357   A more general definition of TM execution. 
       
   358 *}
       
   359 
       
   360 (*
       
   361 fun nnth_of :: "(taction \<times> nat) list \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> (taction \<times> nat)"
       
   362   where
       
   363   "nnth_of p s b = (if 2*s < length p 
       
   364                     then (p ! (2*s + b)) else (Nop, 0))"
       
   365 
       
   366 thm nth_of.simps
       
   367 
       
   368 fun nfetch :: "tprog \<Rightarrow> nat \<Rightarrow> block \<Rightarrow> taction \<times> nat"
       
   369   where
       
   370   "nfetch p 0 b = (Nop, 0)" |
       
   371   "nfetch p (Suc s) b = 
       
   372              (case b of 
       
   373                 Bk \<Rightarrow> nnth_of p s 0 |
       
   374                 Oc \<Rightarrow> nnth_of p s 1)"
       
   375 *)
       
   376 
       
   377                     
       
   378 text {*
       
   379   The type of invarints expressing correspondence between 
       
   380   Abacus configuration and TM configuration.
       
   381 *}
       
   382 
       
   383 type_synonym inc_inv_t = "abc_conf \<Rightarrow> config \<Rightarrow> cell list \<Rightarrow> bool"
       
   384 
       
   385 declare tms_of.simps[simp del] tm_of.simps[simp del]
       
   386         layout_of.simps[simp del] abc_fetch.simps [simp del]  
       
   387         tpairs_of.simps[simp del] start_of.simps[simp del]
       
   388         ci.simps [simp del] length_of.simps[simp del] 
       
   389         layout_of.simps[simp del]
       
   390 
       
   391 (*
       
   392 subsection {* The compilation of @{text "Inc n"} *}
       
   393 *)
       
   394 
       
   395 text {*
       
   396   The lemmas in this section lead to the correctness of 
       
   397   the compilation of @{text "Inc n"} instruction.
       
   398 *}
       
   399 
       
   400 declare abc_step_l.simps[simp del] abc_steps_l.simps[simp del]
       
   401 lemma [simp]: "start_of ly as > 0"
       
   402 apply(simp add: start_of.simps)
       
   403 done
       
   404 
       
   405 lemma abc_steps_l_0: "abc_steps_l ac ap 0 = ac"
       
   406 by(case_tac ac, simp add: abc_steps_l.simps)
       
   407 
       
   408 lemma abc_step_red: 
       
   409  "abc_steps_l (as, am) ap stp = (bs, bm) \<Longrightarrow> 
       
   410   abc_steps_l (as, am) ap (Suc stp) = abc_step_l (bs, bm) (abc_fetch bs ap) "
       
   411 proof(induct stp arbitrary: as am bs bm)
       
   412   case 0
       
   413   thus "?case"
       
   414     by(simp add: abc_steps_l.simps abc_steps_l_0)
       
   415 next
       
   416   case (Suc stp as am bs bm)
       
   417   have ind: "\<And>as am bs bm. abc_steps_l (as, am) ap stp = (bs, bm) \<Longrightarrow> 
       
   418     abc_steps_l (as, am) ap (Suc stp) = abc_step_l (bs, bm) (abc_fetch bs ap)"
       
   419     by fact
       
   420   have h:" abc_steps_l (as, am) ap (Suc stp) = (bs, bm)" by fact
       
   421   obtain as' am' where g: "abc_step_l (as, am) (abc_fetch as ap) = (as', am')"
       
   422     by(case_tac "abc_step_l (as, am) (abc_fetch as ap)", auto)
       
   423   then have "abc_steps_l (as', am') ap (Suc stp) = abc_step_l (bs, bm) (abc_fetch bs ap)"
       
   424     using h
       
   425     by(rule_tac ind, simp add: abc_steps_l.simps)
       
   426   thus "?case"
       
   427     using g
       
   428     by(simp add: abc_steps_l.simps)
       
   429 qed
       
   430 
       
   431 lemma tm_shift_fetch: 
       
   432   "\<lbrakk>fetch A s b = (ac, ns); ns \<noteq> 0 \<rbrakk>
       
   433   \<Longrightarrow> fetch (shift A off) s b = (ac, ns + off)"
       
   434 apply(case_tac b)
       
   435 apply(case_tac [!] s, auto simp: fetch.simps shift.simps)
       
   436 done
       
   437 
       
   438 lemma tm_shift_eq_step:
       
   439   assumes exec: "step (s, l, r) (A, 0) = (s', l', r')"
       
   440   and notfinal: "s' \<noteq> 0"
       
   441   shows "step (s + off, l, r) (shift A off, off) = (s' + off, l', r')"
       
   442 using assms
       
   443 apply(simp add: step.simps)
       
   444 apply(case_tac "fetch A s (read r)", auto)
       
   445 apply(drule_tac [!] off = off in tm_shift_fetch, simp_all)
       
   446 done
       
   447 
       
   448 declare step.simps[simp del] steps.simps[simp del] shift.simps[simp del]
       
   449 
       
   450 lemma tm_shift_eq_steps: 
       
   451   assumes exec: "steps (s, l, r) (A, 0) stp = (s', l', r')"
       
   452   and notfinal: "s' \<noteq> 0"
       
   453   shows "steps (s + off, l, r) (shift A off, off) stp = (s' + off, l', r')"
       
   454   using exec notfinal
       
   455 proof(induct stp arbitrary: s' l' r', simp add: steps.simps)
       
   456   fix stp s' l' r'
       
   457   assume ind: "\<And>s' l' r'. \<lbrakk>steps (s, l, r) (A, 0) stp = (s', l', r'); s' \<noteq> 0\<rbrakk> 
       
   458      \<Longrightarrow> steps (s + off, l, r) (shift A off, off) stp = (s' + off, l', r')"
       
   459   and h: " steps (s, l, r) (A, 0) (Suc stp) = (s', l', r')" "s' \<noteq> 0"
       
   460   obtain s1 l1 r1 where g: "steps (s, l, r) (A, 0) stp = (s1, l1, r1)" 
       
   461     apply(case_tac "steps (s, l, r) (A, 0) stp") by blast
       
   462   moreover then have "s1 \<noteq> 0"
       
   463     using h
       
   464     apply(simp add: step_red)
       
   465     apply(case_tac "0 < s1", auto)
       
   466     done
       
   467   ultimately have "steps (s + off, l, r) (shift A off, off) stp =
       
   468                    (s1 + off, l1, r1)"
       
   469     apply(rule_tac ind, simp_all)
       
   470     done
       
   471   thus "steps (s + off, l, r) (shift A off, off) (Suc stp) = (s' + off, l', r')"
       
   472     using h g assms
       
   473     apply(simp add: step_red)
       
   474     apply(rule_tac tm_shift_eq_step, auto)
       
   475     done
       
   476 qed
       
   477 
       
   478 lemma startof_not0[simp]: "0 < start_of ly as"
       
   479 apply(simp add: start_of.simps)
       
   480 done
       
   481 
       
   482 lemma startof_ge1[simp]: "Suc 0 \<le> start_of ly as"
       
   483 apply(simp add: start_of.simps)
       
   484 done
       
   485 
       
   486 lemma start_of_Suc1: "\<lbrakk>ly = layout_of ap; 
       
   487        abc_fetch as ap = Some (Inc n)\<rbrakk>
       
   488        \<Longrightarrow> start_of ly (Suc as) = start_of ly as + 2 * n + 9"
       
   489 apply(auto simp: start_of.simps layout_of.simps  
       
   490                  length_of.simps abc_fetch.simps 
       
   491                  take_Suc_conv_app_nth split: if_splits)
       
   492 done
       
   493 
       
   494 lemma start_of_Suc2:
       
   495   "\<lbrakk>ly = layout_of ap;
       
   496   abc_fetch as ap = Some (Dec n e)\<rbrakk> \<Longrightarrow> 
       
   497         start_of ly (Suc as) = 
       
   498             start_of ly as + 2 * n + 16"
       
   499 apply(auto simp: start_of.simps layout_of.simps  
       
   500                  length_of.simps abc_fetch.simps 
       
   501                  take_Suc_conv_app_nth split: if_splits)
       
   502 done
       
   503 
       
   504 lemma start_of_Suc3:
       
   505   "\<lbrakk>ly = layout_of ap;
       
   506   abc_fetch as ap = Some (Goto n)\<rbrakk> \<Longrightarrow> 
       
   507   start_of ly (Suc as) = start_of ly as + 1"
       
   508 apply(auto simp: start_of.simps layout_of.simps  
       
   509                  length_of.simps abc_fetch.simps 
       
   510                  take_Suc_conv_app_nth split: if_splits)
       
   511 done
       
   512 
       
   513 lemma length_ci_inc: 
       
   514   "length (ci ly ss (Inc n)) = 4*n + 18"
       
   515 apply(auto simp: ci.simps length_findnth tinc_b_def)
       
   516 done
       
   517 
       
   518 lemma length_ci_dec: 
       
   519   "length (ci ly ss (Dec n e)) = 4*n + 32"
       
   520 apply(auto simp: ci.simps length_findnth tdec_b_def)
       
   521 done
       
   522 
       
   523 lemma length_ci_goto: 
       
   524   "length (ci ly ss (Goto n )) = 2"
       
   525 apply(auto simp: ci.simps length_findnth tdec_b_def)
       
   526 done
       
   527 
       
   528 lemma take_Suc_last[elim]: "Suc as \<le> length xs \<Longrightarrow> 
       
   529             take (Suc as) xs = take as xs @ [xs ! as]"
       
   530 apply(induct xs arbitrary: as, simp, simp)
       
   531 apply(case_tac as, simp, simp)
       
   532 done
       
   533 
       
   534 lemma concat_suc: "Suc as \<le> length xs \<Longrightarrow> 
       
   535        concat (take (Suc as) xs) = concat (take as xs) @ xs! as"
       
   536 apply(subgoal_tac "take (Suc as) xs = take as xs @ [xs ! as]", simp)
       
   537 by auto
       
   538 
       
   539 lemma concat_take_suc_iff: "Suc n \<le> length tps \<Longrightarrow> 
       
   540        concat (take n tps) @ (tps ! n) = concat (take (Suc n) tps)"
       
   541 apply(drule_tac concat_suc, simp)
       
   542 done
       
   543 
       
   544 lemma concat_drop_suc_iff: 
       
   545    "Suc n < length tps \<Longrightarrow> concat (drop (Suc n) tps) = 
       
   546            tps ! Suc n @ concat (drop (Suc (Suc n)) tps)"
       
   547 apply(induct tps arbitrary: n, simp, simp)
       
   548 apply(case_tac tps, simp, simp)
       
   549 apply(case_tac n, simp, simp)
       
   550 done
       
   551 
       
   552 declare append_assoc[simp del]
       
   553 
       
   554 lemma  tm_append:
       
   555   "\<lbrakk>n < length tps; tp = tps ! n\<rbrakk> \<Longrightarrow> 
       
   556   \<exists> tp1 tp2. concat tps = tp1 @ tp @ tp2 \<and> tp1 = 
       
   557   concat (take n tps) \<and> tp2 = concat (drop (Suc n) tps)"
       
   558 apply(rule_tac x = "concat (take n tps)" in exI)
       
   559 apply(rule_tac x = "concat (drop (Suc n) tps)" in exI)
       
   560 apply(auto)
       
   561 apply(induct n, simp)
       
   562 apply(case_tac tps, simp, simp, simp)
       
   563 apply(subgoal_tac "concat (take n tps) @ (tps ! n) = 
       
   564                concat (take (Suc n) tps)")
       
   565 apply(simp only: append_assoc[THEN sym], simp only: append_assoc)
       
   566 apply(subgoal_tac " concat (drop (Suc n) tps) = tps ! Suc n @ 
       
   567                   concat (drop (Suc (Suc n)) tps)", simp)
       
   568 apply(rule_tac concat_drop_suc_iff, simp)
       
   569 apply(rule_tac concat_take_suc_iff, simp)
       
   570 done
       
   571 
       
   572 declare append_assoc[simp]
       
   573 
       
   574 lemma map_of:  "n < length xs \<Longrightarrow> (map f xs) ! n = f (xs ! n)"
       
   575 by(auto)
       
   576 
       
   577 lemma [simp]: "length (tms_of aprog) = length aprog"
       
   578 apply(auto simp: tms_of.simps tpairs_of.simps)
       
   579 done
       
   580 
       
   581 lemma ci_nth: 
       
   582   "\<lbrakk>ly = layout_of aprog; 
       
   583   abc_fetch as aprog = Some ins\<rbrakk>
       
   584   \<Longrightarrow> ci ly (start_of ly as) ins = tms_of aprog ! as"
       
   585 apply(simp add: tms_of.simps tpairs_of.simps 
       
   586       abc_fetch.simps  map_of del: map_append split: if_splits)
       
   587 done
       
   588 
       
   589 lemma t_split:"\<lbrakk>
       
   590         ly = layout_of aprog;
       
   591         abc_fetch as aprog = Some ins\<rbrakk>
       
   592       \<Longrightarrow> \<exists> tp1 tp2. concat (tms_of aprog) = 
       
   593             tp1 @ (ci ly (start_of ly as) ins) @ tp2
       
   594             \<and> tp1 = concat (take as (tms_of aprog)) \<and> 
       
   595               tp2 = concat (drop (Suc as) (tms_of aprog))"
       
   596 apply(insert tm_append[of "as" "tms_of aprog" 
       
   597                              "ci ly (start_of ly as) ins"], simp)
       
   598 apply(subgoal_tac "ci ly (start_of ly as) ins = (tms_of aprog) ! as")
       
   599 apply(subgoal_tac "length (tms_of aprog) = length aprog")
       
   600 apply(simp add: abc_fetch.simps split: if_splits, simp)
       
   601 apply(rule_tac ci_nth, auto)
       
   602 done
       
   603 
       
   604 lemma math_sub: "\<lbrakk>x >= Suc 0; x - 1 = z\<rbrakk> \<Longrightarrow> x + y - Suc 0 = z + y"
       
   605 by auto
       
   606 
       
   607 lemma start_more_one: "as \<noteq> 0 \<Longrightarrow> start_of ly as >= Suc 0"
       
   608 apply(induct as, simp add: start_of.simps)
       
   609 apply(case_tac as, auto simp: start_of.simps)
       
   610 done
       
   611 
       
   612 lemma div_apart: "\<lbrakk>x mod (2::nat) = 0; y mod 2 = 0\<rbrakk> 
       
   613           \<Longrightarrow> (x + y) div 2 = x div 2 + y div 2"
       
   614 apply(drule mod_eqD)+
       
   615 apply(auto)
       
   616 done
       
   617 
       
   618 lemma div_apart_iff: "\<lbrakk>x mod (2::nat) = 0; y mod 2 = 0\<rbrakk> \<Longrightarrow> 
       
   619            (x + y) mod 2 = 0"
       
   620 apply(auto)
       
   621 done
       
   622 
       
   623 lemma [simp]: "length (layout_of aprog) = length aprog"
       
   624 apply(auto simp: layout_of.simps)
       
   625 done
       
   626 
       
   627 lemma start_of_ind: "\<lbrakk>as < length aprog; ly = layout_of aprog\<rbrakk> \<Longrightarrow> 
       
   628        start_of ly (Suc as) = start_of ly as + 
       
   629                           length ((tms_of aprog) ! as) div 2"
       
   630 apply(simp only: start_of.simps, simp)
       
   631 apply(auto simp: start_of.simps tms_of.simps layout_of.simps 
       
   632                  tpairs_of.simps)
       
   633 apply(simp add: ci_length take_Suc take_Suc_conv_app_nth)
       
   634 done
       
   635 
       
   636 lemma concat_take_suc: "Suc n \<le> length xs \<Longrightarrow>
       
   637   concat (take (Suc n) xs) = concat (take n xs) @ (xs ! n)"
       
   638 apply(subgoal_tac "take (Suc n) xs =
       
   639                    take n xs @ [xs ! n]")
       
   640 apply(auto)
       
   641 done
       
   642 
       
   643 lemma [simp]: 
       
   644   "\<lbrakk>as < length aprog; (abc_fetch as aprog) = Some ins\<rbrakk>
       
   645   \<Longrightarrow> ci (layout_of aprog) 
       
   646   (start_of (layout_of aprog) as) (ins) \<in> set (tms_of aprog)"
       
   647 apply(insert ci_nth[of "layout_of aprog" aprog as], simp)
       
   648 done
       
   649 
       
   650 lemma [simp]: "length (tms_of ap) = length ap"
       
   651 by(auto simp: tms_of.simps tpairs_of.simps)
       
   652 
       
   653 lemma [intro]:  "n < length ap \<Longrightarrow> length (tms_of ap ! n) mod 2 = 0"
       
   654 apply(auto simp: tms_of.simps tpairs_of.simps)
       
   655 apply(case_tac "ap ! n", auto simp: ci.simps length_findnth tinc_b_def tdec_b_def)
       
   656 apply arith
       
   657 by arith
       
   658 
       
   659 lemma compile_mod2: "length (concat (take n (tms_of ap))) mod 2 = 0"
       
   660 apply(induct n, auto)
       
   661 apply(case_tac "n < length (tms_of ap)", simp add: take_Suc_conv_app_nth, auto)
       
   662 apply(subgoal_tac "length (tms_of ap ! n) mod 2 = 0")
       
   663 apply arith
       
   664 by auto
       
   665 
       
   666 lemma tpa_states:
       
   667   "\<lbrakk>tp = concat (take as (tms_of ap));
       
   668   as \<le> length ap\<rbrakk> \<Longrightarrow> 
       
   669   start_of (layout_of ap) as = Suc (length tp div 2)"
       
   670 proof(induct as arbitrary: tp)
       
   671   case 0
       
   672   thus "?case"
       
   673     by(simp add: start_of.simps)
       
   674 next
       
   675   case (Suc as tp)
       
   676   have ind: "\<And>tp. \<lbrakk>tp = concat (take as (tms_of ap)); as \<le> length ap\<rbrakk> \<Longrightarrow>
       
   677     start_of (layout_of ap) as = Suc (length tp div 2)" by fact
       
   678   have tp: "tp = concat (take (Suc as) (tms_of ap))" by fact
       
   679   have le: "Suc as \<le> length ap" by fact
       
   680   have a: "start_of (layout_of ap) as = Suc (length (concat (take as (tms_of ap))) div 2)"
       
   681     using le
       
   682     by(rule_tac ind, simp_all)
       
   683   from a tp le show "?case"
       
   684     apply(simp add: start_of.simps take_Suc_conv_app_nth)
       
   685     apply(subgoal_tac "length (concat (take as (tms_of ap))) mod 2= 0")
       
   686     apply(subgoal_tac " length (tms_of ap ! as) mod 2 = 0")
       
   687     apply(simp add: Abacus.div_apart) 
       
   688     apply(simp add: layout_of.simps ci_length  tms_of.simps tpairs_of.simps)
       
   689     apply(auto  intro: compile_mod2)
       
   690     done
       
   691 qed
       
   692 
       
   693 lemma append_append_fetch: 
       
   694     "\<lbrakk>length tp1 mod 2 = 0; length tp mod 2 = 0;
       
   695       length tp1 div 2 < a \<and> a \<le> length tp1 div 2 + length tp div 2\<rbrakk>
       
   696     \<Longrightarrow>fetch (tp1 @ tp @ tp2) a b = fetch tp (a - length tp1 div 2) b "
       
   697 apply(subgoal_tac "\<exists> x. a = length tp1 div 2 + x", erule exE, simp)
       
   698 apply(case_tac x, simp)
       
   699 apply(subgoal_tac "length tp1 div 2 + Suc nat = 
       
   700              Suc (length tp1 div 2 + nat)")
       
   701 apply(simp only: fetch.simps nth_of.simps, auto)
       
   702 apply(case_tac b, simp)
       
   703 apply(subgoal_tac "2 * (length tp1 div 2) = length tp1", simp)
       
   704 apply(subgoal_tac "2 * nat < length tp", simp add: nth_append, simp)
       
   705 apply(subgoal_tac "2 * (length tp1 div 2) = length tp1", simp)
       
   706 apply(subgoal_tac "2 * nat < length tp", simp add: nth_append, auto)
       
   707 apply(auto simp: nth_append)
       
   708 apply(rule_tac x = "a - length tp1 div 2" in exI, simp)
       
   709 done
       
   710 
       
   711 lemma step_eq_fetch':
       
   712   assumes layout: "ly = layout_of ap"
       
   713   and compile: "tp = tm_of ap"
       
   714   and fetch: "abc_fetch as ap = Some ins"
       
   715   and range1: "s \<ge> start_of ly as"
       
   716   and range2: "s < start_of ly (Suc as)"
       
   717   shows "fetch tp s b = fetch (ci ly (start_of ly as) ins)
       
   718        (Suc s - start_of ly as) b "
       
   719 proof -
       
   720   have "\<exists>tp1 tp2. concat (tms_of ap) = tp1 @ ci ly (start_of ly as) ins @ tp2 \<and>
       
   721     tp1 = concat (take as (tms_of ap)) \<and> tp2 = concat (drop (Suc as) (tms_of ap))"
       
   722     using assms
       
   723     by(rule_tac t_split, simp_all)
       
   724   then obtain tp1 tp2 where a: "concat (tms_of ap) = tp1 @ ci ly (start_of ly as) ins @ tp2 \<and>
       
   725     tp1 = concat (take as (tms_of ap)) \<and> tp2 = concat (drop (Suc as) (tms_of ap))" by blast
       
   726   then have b: "start_of (layout_of ap) as = Suc (length tp1 div 2)"
       
   727     using fetch
       
   728     apply(rule_tac tpa_states, simp, simp add: abc_fetch.simps split: if_splits)
       
   729     done
       
   730   have "fetch (tp1 @ (ci ly (start_of ly as) ins) @ tp2)  s b = 
       
   731         fetch (ci ly (start_of ly as) ins) (s - length tp1 div 2) b"
       
   732   proof(rule_tac append_append_fetch)
       
   733     show "length tp1 mod 2 = 0"
       
   734       using a
       
   735       by(auto, rule_tac compile_mod2)
       
   736   next
       
   737     show "length (ci ly (start_of ly as) ins) mod 2 = 0"
       
   738       apply(case_tac ins, auto simp: ci.simps length_findnth tinc_b_def tdec_b_def)
       
   739       by(arith, arith)
       
   740   next
       
   741     show "length tp1 div 2 < s \<and> s \<le> 
       
   742       length tp1 div 2 + length (ci ly (start_of ly as) ins) div 2"
       
   743     proof -
       
   744       have "length (ci ly (start_of ly as) ins) div 2 = length_of ins"
       
   745         using ci_length by simp
       
   746       moreover have "start_of ly (Suc as) = start_of ly as + length_of ins"
       
   747         using fetch layout
       
   748         apply(simp add: start_of.simps abc_fetch.simps List.take_Suc_conv_app_nth 
       
   749           split: if_splits)
       
   750         apply(simp add: layout_of.simps)
       
   751         done
       
   752       ultimately show "?thesis"
       
   753         using b layout range1 range2
       
   754         apply(simp)
       
   755         done
       
   756     qed
       
   757   qed
       
   758   thus "?thesis"
       
   759     using b layout a compile  
       
   760     apply(simp add: tm_of.simps)
       
   761     done
       
   762 qed
       
   763 
       
   764 lemma step_eq_fetch: 
       
   765   assumes layout: "ly = layout_of ap"
       
   766   and compile: "tp = tm_of ap"
       
   767   and abc_fetch: "abc_fetch as ap = Some ins" 
       
   768   and fetch: "fetch (ci ly (start_of ly as) ins)
       
   769        (Suc s - start_of ly as) b = (ac, ns)"
       
   770   and notfinal: "ns \<noteq> 0"
       
   771   shows "fetch tp s b = (ac, ns)"
       
   772 proof -
       
   773   have "s \<ge> start_of ly as"
       
   774   proof(cases "s \<ge> start_of ly as")
       
   775     case True thus "?thesis" by simp
       
   776   next
       
   777     case False 
       
   778     have "\<not> start_of ly as \<le> s" by fact
       
   779     then have "Suc s - start_of ly as = 0"
       
   780       by arith
       
   781     then have "fetch (ci ly (start_of ly as) ins)
       
   782        (Suc s - start_of ly as) b = (Nop, 0)"
       
   783       by(simp add: fetch.simps)
       
   784     with notfinal fetch show "?thesis"
       
   785       by(simp)
       
   786   qed
       
   787   moreover have "s < start_of ly (Suc as)"
       
   788   proof(cases "s < start_of ly (Suc as)")
       
   789     case True thus "?thesis" by simp
       
   790   next
       
   791     case False
       
   792     have h: "\<not> s < start_of ly (Suc as)"
       
   793       by fact
       
   794     then have "s > start_of ly as"
       
   795       using abc_fetch layout
       
   796       apply(simp add: start_of.simps abc_fetch.simps split: if_splits)
       
   797       apply(simp add: List.take_Suc_conv_app_nth, auto)
       
   798       apply(subgoal_tac "layout_of ap ! as > 0") 
       
   799       apply arith
       
   800       apply(simp add: layout_of.simps)
       
   801       apply(case_tac "ap!as", auto simp: length_of.simps)
       
   802       done
       
   803     from this and h have "fetch (ci ly (start_of ly as) ins) (Suc s - start_of ly as) b = (Nop, 0)"
       
   804       using abc_fetch layout
       
   805       apply(case_tac b, simp_all add: Suc_diff_le)
       
   806       apply(case_tac [!] ins, simp_all add: start_of_Suc2 start_of_Suc1 start_of_Suc3)
       
   807       apply(simp_all only: length_ci_inc length_ci_dec length_ci_goto, auto)
       
   808       using layout
       
   809       apply(subgoal_tac [!] "start_of ly (Suc as) = start_of ly as + 2*nat1 + 16", simp_all)
       
   810       apply(rule_tac [!] start_of_Suc2, auto)
       
   811       done
       
   812     from fetch and notfinal this show "?thesis"by simp
       
   813   qed
       
   814   ultimately show "?thesis"
       
   815     using assms
       
   816     apply(drule_tac b= b and ins = ins in step_eq_fetch', auto)
       
   817     done
       
   818 qed
       
   819 
       
   820 
       
   821 lemma step_eq_in:
       
   822   assumes layout: "ly = layout_of ap"
       
   823   and compile: "tp = tm_of ap"
       
   824   and fetch: "abc_fetch as ap = Some ins"    
       
   825   and exec: "step (s, l, r) (ci ly (start_of ly as) ins, start_of ly as - 1) 
       
   826   = (s', l', r')"
       
   827   and notfinal: "s' \<noteq> 0"
       
   828   shows "step (s, l, r) (tp, 0) = (s', l', r')"
       
   829   using assms
       
   830   apply(simp add: step.simps)
       
   831   apply(case_tac "fetch (ci (layout_of ap) (start_of (layout_of ap) as) ins)
       
   832     (Suc s - start_of (layout_of ap) as) (read r)", simp)
       
   833   using layout
       
   834   apply(drule_tac s = s and b = "read r" and ac = a in step_eq_fetch, auto)
       
   835   done
       
   836 
       
   837 lemma steps_eq_in:
       
   838   assumes layout: "ly = layout_of ap"
       
   839   and compile: "tp = tm_of ap"
       
   840   and crsp: "crsp ly (as, lm) (s, l, r) ires"
       
   841   and fetch: "abc_fetch as ap = Some ins"    
       
   842   and exec: "steps (s, l, r) (ci ly (start_of ly as) ins, start_of ly as - 1) stp 
       
   843   = (s', l', r')"
       
   844   and notfinal: "s' \<noteq> 0"
       
   845   shows "steps (s, l, r) (tp, 0) stp = (s', l', r')"
       
   846   using exec notfinal
       
   847 proof(induct stp arbitrary: s' l' r', simp add: steps.simps)
       
   848   fix stp s' l' r'
       
   849   assume ind: 
       
   850     "\<And>s' l' r'. \<lbrakk>steps (s, l, r) (ci ly (start_of ly as) ins, start_of ly as - 1) stp = (s', l', r'); s' \<noteq> 0\<rbrakk>
       
   851               \<Longrightarrow> steps (s, l, r) (tp, 0) stp = (s', l', r')"
       
   852   and h: "steps (s, l, r) (ci ly (start_of ly as) ins, start_of ly as - 1) (Suc stp) = (s', l', r')" "s' \<noteq> 0"
       
   853   obtain s1 l1 r1 where g: "steps (s, l, r) (ci ly (start_of ly as) ins, start_of ly as - 1) stp = 
       
   854                         (s1, l1, r1)"
       
   855     apply(case_tac "steps (s, l, r) (ci ly (start_of ly as) ins, start_of ly as - 1) stp") by blast
       
   856   moreover hence "s1 \<noteq> 0"
       
   857     using h
       
   858     apply(simp add: step_red)
       
   859     apply(case_tac "0 < s1", simp_all)
       
   860     done
       
   861   ultimately have "steps (s, l, r) (tp, 0) stp = (s1, l1, r1)"
       
   862     apply(rule_tac ind, auto)
       
   863     done
       
   864   thus "steps (s, l, r) (tp, 0) (Suc stp) = (s', l', r')"
       
   865     using h g assms
       
   866     apply(simp add: step_red)
       
   867     apply(rule_tac step_eq_in, auto)
       
   868     done
       
   869 qed
       
   870 
       
   871 lemma tm_append_fetch_first: 
       
   872   "\<lbrakk>fetch A s b = (ac, ns); ns \<noteq> 0\<rbrakk> \<Longrightarrow> 
       
   873     fetch (A @ B) s b = (ac, ns)"
       
   874 apply(case_tac b)
       
   875 apply(case_tac [!] s, auto simp: fetch.simps nth_append split: if_splits)
       
   876 done
       
   877 
       
   878 lemma tm_append_first_step_eq: 
       
   879   assumes "step (s, l, r) (A, off) = (s', l', r')"
       
   880   and "s' \<noteq> 0"
       
   881   shows "step (s, l, r) (A @ B, off) = (s', l', r')"
       
   882 using assms
       
   883 apply(simp add: step.simps)
       
   884 apply(case_tac "fetch A (s - off) (read r)")
       
   885 apply(frule_tac  B = B and b = "read r" in tm_append_fetch_first, auto)
       
   886 done
       
   887 
       
   888 lemma tm_append_first_steps_eq: 
       
   889   assumes "steps (s, l, r) (A, off) stp = (s', l', r')"
       
   890   and "s' \<noteq> 0"
       
   891   shows "steps (s, l, r) (A @ B, off) stp = (s', l', r')"
       
   892 using assms
       
   893 proof(induct stp arbitrary: s' l' r', simp add: steps.simps)
       
   894   fix stp s' l' r'
       
   895   assume ind: "\<And>s' l' r'. \<lbrakk>steps (s, l, r) (A, off) stp = (s', l', r'); s' \<noteq> 0\<rbrakk>
       
   896     \<Longrightarrow> steps (s, l, r) (A @ B, off) stp = (s', l', r')"
       
   897     and h: "steps (s, l, r) (A, off) (Suc stp) = (s', l', r')" "s' \<noteq> 0"
       
   898   obtain sa la ra where a: "steps (s, l, r) (A, off) stp = (sa, la, ra)"
       
   899     apply(case_tac "steps (s, l, r) (A, off) stp") by blast
       
   900   hence "steps (s, l, r) (A @ B, off) stp = (sa, la, ra) \<and> sa \<noteq> 0"
       
   901     using h ind[of sa la ra]
       
   902     apply(case_tac sa, simp_all)
       
   903     done
       
   904   thus "steps (s, l, r) (A @ B, off) (Suc stp) = (s', l', r')"
       
   905     using h a
       
   906     apply(simp add: step_red)
       
   907     apply(rule_tac tm_append_first_step_eq, simp_all)
       
   908     done
       
   909 qed
       
   910 
       
   911 lemma tm_append_second_fetch_eq:
       
   912   assumes
       
   913   even: "length A mod 2 = 0"
       
   914   and off: "off = length A div 2"
       
   915   and fetch: "fetch B s b = (ac, ns)"
       
   916   and notfinal: "ns \<noteq> 0"
       
   917   shows "fetch (A @ shift B off) (s + off) b = (ac, ns + off)"
       
   918 using assms
       
   919 apply(case_tac b)
       
   920 apply(case_tac [!] s, auto simp: fetch.simps nth_append shift.simps 
       
   921   split: if_splits)
       
   922 done
       
   923 
       
   924 
       
   925 lemma tm_append_second_step_eq: 
       
   926   assumes 
       
   927   exec: "step0 (s, l, r) B = (s', l', r')"
       
   928   and notfinal: "s' \<noteq> 0"
       
   929   and off: "off = length A div 2"
       
   930   and even: "length A mod 2 = 0"
       
   931   shows "step0 (s + off, l, r) (A @ shift B off) = (s' + off, l', r')"
       
   932 using assms
       
   933 apply(simp add: step.simps)
       
   934 apply(case_tac "fetch B s (read r)")
       
   935 apply(frule_tac tm_append_second_fetch_eq, simp_all, auto)
       
   936 done
       
   937 
       
   938 
       
   939 lemma tm_append_second_steps_eq: 
       
   940   assumes 
       
   941   exec: "steps (s, l, r) (B, 0) stp = (s', l', r')"
       
   942   and notfinal: "s' \<noteq> 0"
       
   943   and off: "off = length A div 2"
       
   944   and even: "length A mod 2 = 0"
       
   945   shows "steps (s + off, l, r) (A @ shift B off, 0) stp = (s' + off, l', r')"
       
   946 using exec notfinal
       
   947 proof(induct stp arbitrary: s' l' r')
       
   948   case 0
       
   949   thus "steps0 (s + off, l, r) (A @ shift B off) 0 = (s' + off, l', r')"
       
   950     by(simp add: steps.simps)
       
   951 next
       
   952   case (Suc stp s' l' r')
       
   953   have ind: "\<And>s' l' r'. \<lbrakk>steps0 (s, l, r) B stp = (s', l', r'); s' \<noteq> 0\<rbrakk> \<Longrightarrow> 
       
   954     steps0 (s + off, l, r) (A @ shift B off) stp = (s' + off, l', r')"
       
   955     by fact
       
   956   have h: "steps0 (s, l, r) B (Suc stp) = (s', l', r')" by fact
       
   957   have k: "s' \<noteq> 0" by fact
       
   958   obtain s'' l'' r'' where a: "steps0 (s, l, r) B stp = (s'', l'', r'')"
       
   959     by (metis prod_cases3)
       
   960   then have b: "s'' \<noteq> 0"
       
   961     using h k
       
   962     by(rule_tac notI, auto simp: step_red)
       
   963   from a b have c: "steps0 (s + off, l, r) (A @ shift B off) stp = (s'' + off, l'', r'')"
       
   964     by(erule_tac ind, simp)
       
   965   from c b h a k assms show "?case"
       
   966     thm tm_append_second_step_eq
       
   967     apply(simp add: step_red) by(rule tm_append_second_step_eq, simp_all)
       
   968 qed
       
   969 
       
   970 lemma tm_append_second_fetch0_eq:
       
   971   assumes
       
   972   even: "length A mod 2 = 0"
       
   973   and off: "off = length A div 2"
       
   974   and fetch: "fetch B s b = (ac, 0)"
       
   975   and notfinal: "s \<noteq> 0"
       
   976   shows "fetch (A @ shift B off) (s + off) b = (ac, 0)"
       
   977 using assms
       
   978 apply(case_tac b)
       
   979 apply(case_tac [!] s, auto simp: fetch.simps nth_append shift.simps 
       
   980   split: if_splits)
       
   981 done
       
   982 
       
   983 lemma tm_append_second_halt_eq:
       
   984   assumes 
       
   985   exec: "steps (Suc 0, l, r) (B, 0) stp = (0, l', r')"
       
   986   and wf_B: "tm_wf (B, 0)"
       
   987   and off: "off = length A div 2"
       
   988   and even: "length A mod 2 = 0"
       
   989   shows "steps (Suc off, l, r) (A @ shift B off, 0) stp = (0, l', r')"
       
   990 proof -
       
   991   thm before_final
       
   992   have "\<exists>n. \<not> is_final (steps0 (1, l, r) B n) \<and> steps0 (1, l, r) B (Suc n) = (0, l', r')"
       
   993     using exec by(rule_tac before_final, simp)
       
   994  then obtain n where a: 
       
   995    "\<not> is_final (steps0 (1, l, r) B n) \<and> steps0 (1, l, r) B (Suc n) = (0, l', r')" ..
       
   996  obtain s'' l'' r'' where b: "steps0 (1, l, r) B n = (s'', l'', r'') \<and> s'' >0"
       
   997    using a
       
   998    by(case_tac "steps0 (1, l, r) B n", auto)
       
   999  have c: "steps (Suc 0 + off, l, r) (A @ shift B off, 0) n = (s'' + off, l'', r'')"
       
  1000    using a b assms
       
  1001    by(rule_tac tm_append_second_steps_eq, simp_all)
       
  1002  obtain ac where d: "fetch B s'' (read r'') = (ac, 0)"
       
  1003    using  b a
       
  1004    by(case_tac "fetch B s'' (read r'')", auto simp: step_red step.simps)
       
  1005  then have "fetch (A @ shift B off) (s'' + off) (read r'') = (ac, 0)"
       
  1006    using assms b
       
  1007    by(rule_tac tm_append_second_fetch0_eq, simp_all)
       
  1008  then have e: "steps (Suc 0 + off, l, r) (A @ shift B off, 0) (Suc n) = (0, l', r')"
       
  1009    using a b assms c d
       
  1010    by(simp add: step_red step.simps)
       
  1011  from a have "n < stp"
       
  1012    using exec
       
  1013  proof(cases "n < stp")
       
  1014    case  True thus "?thesis" by simp
       
  1015  next
       
  1016    case False
       
  1017    have "\<not> n < stp" by fact
       
  1018    then obtain d where  "n = stp + d"
       
  1019      by (metis add.comm_neutral less_imp_add_positive nat_neq_iff)
       
  1020    thus "?thesis"
       
  1021      using a e exec
       
  1022      by(simp add: steps_add)
       
  1023  qed
       
  1024  then obtain d where "stp = Suc n + d"
       
  1025    by(metis add_Suc less_iff_Suc_add)
       
  1026  thus "?thesis"
       
  1027    using e
       
  1028    by(simp only: steps_add, simp)
       
  1029 qed
       
  1030 
       
  1031 lemma tm_append_steps: 
       
  1032   assumes 
       
  1033   aexec: "steps (s, l, r) (A, 0) stpa = (Suc (length A div 2), la, ra)"
       
  1034   and bexec: "steps (Suc 0, la, ra) (B, 0) stpb =  (sb, lb, rb)"
       
  1035   and notfinal: "sb \<noteq> 0"
       
  1036   and off: "off = length A div 2"
       
  1037   and even: "length A mod 2 = 0"
       
  1038   shows "steps (s, l, r) (A @ shift B off, 0) (stpa + stpb) = (sb + off, lb, rb)"
       
  1039 proof -
       
  1040   have "steps (s, l, r) (A@shift B off, 0) stpa = (Suc (length A div 2), la, ra)"
       
  1041     apply(rule_tac tm_append_first_steps_eq)
       
  1042     apply(auto simp: assms)
       
  1043     done
       
  1044   moreover have "steps (1 + off, la, ra) (A @ shift B off, 0) stpb = (sb + off, lb, rb)"
       
  1045     apply(rule_tac tm_append_second_steps_eq)
       
  1046     apply(auto simp: assms bexec)
       
  1047     done
       
  1048   ultimately show "steps (s, l, r) (A @ shift B off, 0) (stpa + stpb) = (sb + off, lb, rb)"
       
  1049     apply(simp add: steps_add off)
       
  1050     done
       
  1051 qed
       
  1052        
       
  1053 subsection {* Crsp of Inc*}
       
  1054 
       
  1055 fun at_begin_fst_bwtn :: "inc_inv_t"
       
  1056   where
       
  1057   "at_begin_fst_bwtn (as, lm) (s, l, r) ires = 
       
  1058       (\<exists> lm1 tn rn. lm1 = (lm @ 0\<up>tn) \<and> length lm1 = s \<and> 
       
  1059           (if lm1 = [] then l = Bk # Bk # ires
       
  1060            else l = [Bk]@<rev lm1>@Bk#Bk#ires) \<and> r = Bk\<up>rn)" 
       
  1061 
       
  1062 
       
  1063 fun at_begin_fst_awtn :: "inc_inv_t"
       
  1064   where
       
  1065   "at_begin_fst_awtn (as, lm) (s, l, r) ires = 
       
  1066       (\<exists> lm1 tn rn. lm1 = (lm @ 0\<up>tn) \<and> length lm1 = s \<and>
       
  1067          (if lm1 = []  then l = Bk # Bk # ires
       
  1068           else l = [Bk]@<rev lm1>@Bk#Bk#ires) \<and> r = [Oc]@Bk\<up>rn)"
       
  1069 
       
  1070 fun at_begin_norm :: "inc_inv_t"
       
  1071   where
       
  1072   "at_begin_norm (as, lm) (s, l, r) ires= 
       
  1073       (\<exists> lm1 lm2 rn. lm = lm1 @ lm2 \<and> length lm1 = s \<and> 
       
  1074         (if lm1 = [] then l = Bk # Bk # ires
       
  1075          else l = Bk # <rev lm1> @ Bk # Bk # ires ) \<and> r = <lm2>@Bk\<up>rn)"
       
  1076 
       
  1077 fun in_middle :: "inc_inv_t"
       
  1078   where
       
  1079   "in_middle (as, lm) (s, l, r) ires = 
       
  1080       (\<exists> lm1 lm2 tn m ml mr rn. lm @ 0\<up>tn = lm1 @ [m] @ lm2
       
  1081        \<and> length lm1 = s \<and> m + 1 = ml + mr \<and>  
       
  1082          ml \<noteq> 0 \<and> tn = s + 1 - length lm \<and> 
       
  1083        (if lm1 = [] then l = Oc\<up>ml @ Bk # Bk # ires 
       
  1084         else l = Oc\<up>ml@[Bk]@<rev lm1>@
       
  1085                  Bk # Bk # ires) \<and> (r = Oc\<up>mr @ [Bk] @ <lm2>@ Bk\<up>rn \<or> 
       
  1086       (lm2 = [] \<and> r = Oc\<up>mr))
       
  1087       )"
       
  1088 
       
  1089 fun inv_locate_a :: "inc_inv_t"
       
  1090   where "inv_locate_a (as, lm) (s, l, r) ires = 
       
  1091      (at_begin_norm (as, lm) (s, l, r) ires \<or>
       
  1092       at_begin_fst_bwtn (as, lm) (s, l, r) ires \<or>
       
  1093       at_begin_fst_awtn (as, lm) (s, l, r) ires
       
  1094       )"
       
  1095 
       
  1096 fun inv_locate_b :: "inc_inv_t"
       
  1097   where "inv_locate_b (as, lm) (s, l, r) ires = 
       
  1098         (in_middle (as, lm) (s, l, r)) ires "
       
  1099 
       
  1100 fun inv_after_write :: "inc_inv_t"
       
  1101   where "inv_after_write (as, lm) (s, l, r) ires = 
       
  1102            (\<exists> rn m lm1 lm2. lm = lm1 @ m # lm2 \<and>
       
  1103              (if lm1 = [] then l = Oc\<up>m @ Bk # Bk # ires
       
  1104               else Oc # l = Oc\<up>Suc m@ Bk # <rev lm1> @ 
       
  1105                       Bk # Bk # ires) \<and> r = [Oc] @ <lm2> @ Bk\<up>rn)"
       
  1106 
       
  1107 fun inv_after_move :: "inc_inv_t"
       
  1108   where "inv_after_move (as, lm) (s, l, r) ires = 
       
  1109       (\<exists> rn m lm1 lm2. lm = lm1 @ m # lm2 \<and>
       
  1110         (if lm1 = [] then l = Oc\<up>Suc m @ Bk # Bk # ires
       
  1111          else l = Oc\<up>Suc m@ Bk # <rev lm1> @ Bk # Bk # ires) \<and> 
       
  1112         r = <lm2> @ Bk\<up>rn)"
       
  1113 
       
  1114 fun inv_after_clear :: "inc_inv_t"
       
  1115   where "inv_after_clear (as, lm) (s, l, r) ires =
       
  1116        (\<exists> rn m lm1 lm2 r'. lm = lm1 @ m # lm2 \<and> 
       
  1117         (if lm1 = [] then l = Oc\<up>Suc m @ Bk # Bk # ires
       
  1118          else l = Oc\<up>Suc m @ Bk # <rev lm1> @ Bk # Bk # ires) \<and> 
       
  1119           r = Bk # r' \<and> Oc # r' = <lm2> @ Bk\<up>rn)"
       
  1120 
       
  1121 fun inv_on_right_moving :: "inc_inv_t"
       
  1122   where "inv_on_right_moving (as, lm) (s, l, r) ires = 
       
  1123        (\<exists> lm1 lm2 m ml mr rn. lm = lm1 @ [m] @ lm2 \<and> 
       
  1124             ml + mr = m \<and> 
       
  1125           (if lm1 = [] then l = Oc\<up>ml @ Bk # Bk # ires
       
  1126           else l = Oc\<up>ml  @ [Bk] @ <rev lm1> @ Bk # Bk # ires) \<and> 
       
  1127          ((r = Oc\<up>mr @ [Bk] @ <lm2> @ Bk\<up>rn) \<or> 
       
  1128           (r = Oc\<up>mr \<and> lm2 = [])))"
       
  1129 
       
  1130 fun inv_on_left_moving_norm :: "inc_inv_t"
       
  1131   where "inv_on_left_moving_norm (as, lm) (s, l, r) ires =
       
  1132       (\<exists> lm1 lm2 m ml mr rn. lm = lm1 @ [m] @ lm2 \<and>  
       
  1133              ml + mr = Suc m \<and> mr > 0 \<and> (if lm1 = [] then l = Oc\<up>ml @ Bk # Bk # ires
       
  1134                                          else l =  Oc\<up>ml @ Bk # <rev lm1> @ Bk # Bk # ires)
       
  1135         \<and> (r = Oc\<up>mr @ Bk # <lm2> @ Bk\<up>rn \<or> 
       
  1136            (lm2 = [] \<and> r = Oc\<up>mr)))"
       
  1137 
       
  1138 fun inv_on_left_moving_in_middle_B:: "inc_inv_t"
       
  1139   where "inv_on_left_moving_in_middle_B (as, lm) (s, l, r) ires =
       
  1140                 (\<exists> lm1 lm2 rn. lm = lm1 @ lm2 \<and>  
       
  1141                      (if lm1 = [] then l = Bk # ires
       
  1142                       else l = <rev lm1> @ Bk # Bk # ires) \<and> 
       
  1143                       r = Bk # <lm2> @ Bk\<up>rn)"
       
  1144 
       
  1145 fun inv_on_left_moving :: "inc_inv_t"
       
  1146   where "inv_on_left_moving (as, lm) (s, l, r) ires = 
       
  1147        (inv_on_left_moving_norm  (as, lm) (s, l, r) ires \<or>
       
  1148         inv_on_left_moving_in_middle_B (as, lm) (s, l, r) ires)"
       
  1149 
       
  1150 
       
  1151 fun inv_check_left_moving_on_leftmost :: "inc_inv_t"
       
  1152   where "inv_check_left_moving_on_leftmost (as, lm) (s, l, r) ires = 
       
  1153                 (\<exists> rn. l = ires \<and> r = [Bk, Bk] @ <lm> @  Bk\<up>rn)"
       
  1154 
       
  1155 fun inv_check_left_moving_in_middle :: "inc_inv_t"
       
  1156   where "inv_check_left_moving_in_middle (as, lm) (s, l, r) ires = 
       
  1157               (\<exists> lm1 lm2 r' rn. lm = lm1 @ lm2 \<and>
       
  1158                  (Oc # l = <rev lm1> @ Bk # Bk # ires) \<and> r = Oc # Bk # r' \<and> 
       
  1159                            r' = <lm2> @  Bk\<up>rn)"
       
  1160 
       
  1161 fun inv_check_left_moving :: "inc_inv_t"
       
  1162   where "inv_check_left_moving (as, lm) (s, l, r) ires = 
       
  1163              (inv_check_left_moving_on_leftmost (as, lm) (s, l, r) ires \<or>
       
  1164              inv_check_left_moving_in_middle (as, lm) (s, l, r) ires)"
       
  1165 
       
  1166 fun inv_after_left_moving :: "inc_inv_t"
       
  1167   where "inv_after_left_moving (as, lm) (s, l, r) ires= 
       
  1168               (\<exists> rn. l = Bk # ires \<and> r = Bk # <lm> @  Bk\<up>rn)"
       
  1169 
       
  1170 fun inv_stop :: "inc_inv_t"
       
  1171   where "inv_stop (as, lm) (s, l, r) ires= 
       
  1172               (\<exists> rn. l = Bk # Bk # ires \<and> r = <lm> @  Bk\<up>rn)"
       
  1173 
       
  1174 
       
  1175 lemma halt_lemma2': 
       
  1176   "\<lbrakk>wf LE;  \<forall> n. ((\<not> P (f n) \<and> Q (f n)) \<longrightarrow> 
       
  1177     (Q (f (Suc n)) \<and> (f (Suc n), (f n)) \<in> LE)); Q (f 0)\<rbrakk> 
       
  1178       \<Longrightarrow> \<exists> n. P (f n)"
       
  1179 apply(intro exCI, simp)
       
  1180 apply(subgoal_tac "\<forall> n. Q (f n)", simp)
       
  1181 apply(drule_tac f = f in wf_inv_image)
       
  1182 apply(simp add: inv_image_def)
       
  1183 apply(erule wf_induct, simp)
       
  1184 apply(erule_tac x = x in allE)
       
  1185 apply(erule_tac x = n in allE, erule_tac x = n in allE)
       
  1186 apply(erule_tac x = "Suc x" in allE, simp)
       
  1187 apply(rule_tac allI)
       
  1188 apply(induct_tac n, simp)
       
  1189 apply(erule_tac x = na in allE, simp)
       
  1190 done
       
  1191 
       
  1192 lemma halt_lemma2'': 
       
  1193   "\<lbrakk>P (f n); \<not> P (f (0::nat))\<rbrakk> \<Longrightarrow> 
       
  1194          \<exists> n. (P (f n) \<and> (\<forall> i < n. \<not> P (f i)))"
       
  1195 apply(induct n rule: nat_less_induct, auto)
       
  1196 done
       
  1197 
       
  1198 lemma halt_lemma2''':
       
  1199  "\<lbrakk>\<forall>n. \<not> P (f n) \<and> Q (f n) \<longrightarrow> Q (f (Suc n)) \<and> (f (Suc n), f n) \<in> LE;
       
  1200                  Q (f 0);  \<forall>i<na. \<not> P (f i)\<rbrakk> \<Longrightarrow> Q (f na)"
       
  1201 apply(induct na, simp, simp)
       
  1202 done
       
  1203 
       
  1204 lemma halt_lemma2: 
       
  1205   "\<lbrakk>wf LE;  
       
  1206     Q (f 0); \<not> P (f 0);
       
  1207     \<forall> n. ((\<not> P (f n) \<and> Q (f n)) \<longrightarrow> (Q (f (Suc n)) \<and> (f (Suc n), (f n)) \<in> LE))\<rbrakk> 
       
  1208   \<Longrightarrow> \<exists> n. P (f n) \<and> Q (f n)"
       
  1209 apply(insert halt_lemma2' [of LE P f Q], simp, erule_tac exE)
       
  1210 apply(subgoal_tac "\<exists> n. (P (f n) \<and> (\<forall> i < n. \<not> P (f i)))")
       
  1211 apply(erule_tac exE)+
       
  1212 apply(rule_tac x = na in exI, auto)
       
  1213 apply(rule halt_lemma2''', simp, simp, simp)
       
  1214 apply(erule_tac halt_lemma2'', simp)
       
  1215 done
       
  1216 
       
  1217 
       
  1218 fun findnth_inv :: "layout \<Rightarrow> nat \<Rightarrow> inc_inv_t"
       
  1219   where
       
  1220   "findnth_inv ly n (as, lm) (s, l, r) ires =
       
  1221               (if s = 0 then False
       
  1222                else if s \<le> Suc (2*n) then 
       
  1223                   if s mod 2 = 1 then inv_locate_a (as, lm) ((s - 1) div 2, l, r) ires
       
  1224                   else inv_locate_b (as, lm) ((s - 1) div 2, l, r) ires
       
  1225                else False)"
       
  1226 
       
  1227 
       
  1228 fun findnth_state :: "config \<Rightarrow> nat \<Rightarrow> nat"
       
  1229   where
       
  1230   "findnth_state (s, l, r) n = (Suc (2*n) - s)"
       
  1231   
       
  1232 fun findnth_step :: "config \<Rightarrow> nat \<Rightarrow> nat"
       
  1233   where
       
  1234   "findnth_step (s, l, r) n = 
       
  1235            (if s mod 2 = 1 then
       
  1236                    (if (r \<noteq> [] \<and> hd r = Oc) then 0
       
  1237                     else 1)
       
  1238             else length r)"
       
  1239 
       
  1240 fun findnth_measure :: "config \<times> nat \<Rightarrow> nat \<times> nat"
       
  1241   where
       
  1242   "findnth_measure (c, n) = 
       
  1243      (findnth_state c n, findnth_step c n)"
       
  1244 
       
  1245 definition lex_pair :: "((nat \<times> nat) \<times> nat \<times> nat) set"
       
  1246   where
       
  1247   "lex_pair \<equiv> less_than <*lex*> less_than"
       
  1248 
       
  1249 definition findnth_LE :: "((config \<times> nat) \<times> (config \<times> nat)) set"
       
  1250   where
       
  1251    "findnth_LE \<equiv> (inv_image lex_pair findnth_measure)"
       
  1252 
       
  1253 lemma wf_findnth_LE: "wf findnth_LE"
       
  1254 by(auto intro:wf_inv_image simp: findnth_LE_def lex_pair_def)
       
  1255 
       
  1256 declare findnth_inv.simps[simp del]
       
  1257 
       
  1258 lemma [simp]: 
       
  1259   "\<lbrakk>x < Suc (Suc (2 * n)); Suc x mod 2 = Suc 0; \<not> x < 2 * n\<rbrakk>
       
  1260  \<Longrightarrow> x = 2*n"
       
  1261 by arith
       
  1262 
       
  1263 lemma [simp]: 
       
  1264   "\<lbrakk>0 < a; a < Suc (2 * n); a mod 2 = Suc 0\<rbrakk> 
       
  1265       \<Longrightarrow> fetch (findnth n) a Bk = (W1, a)"
       
  1266 apply(case_tac a, simp_all)
       
  1267 apply(induct n, auto simp: findnth.simps length_findnth nth_append)
       
  1268 apply arith
       
  1269 done
       
  1270 
       
  1271 lemma [simp]: 
       
  1272   "\<lbrakk>0 < a; a < Suc (2 * n); a mod 2 = Suc 0\<rbrakk> 
       
  1273       \<Longrightarrow> fetch (findnth n) a Oc = (R, Suc a)"
       
  1274 apply(case_tac a, simp_all)
       
  1275 apply(induct n, auto simp: findnth.simps length_findnth nth_append)
       
  1276 apply(subgoal_tac "nat = 2 * n", simp)
       
  1277 by arith
       
  1278 
       
  1279 lemma [simp]: 
       
  1280   "\<lbrakk>0 < a; a < Suc (2*n); a mod 2 \<noteq> Suc 0\<rbrakk>
       
  1281      \<Longrightarrow> fetch (findnth n) a Oc = (R, a)"
       
  1282 apply(case_tac a, simp_all)
       
  1283 apply(induct n, auto simp: findnth.simps length_findnth nth_append)
       
  1284 apply(subgoal_tac "nat = Suc (2 * n)", simp)
       
  1285 apply arith
       
  1286 done
       
  1287 
       
  1288 lemma [simp]: 
       
  1289   "\<lbrakk>0 < a; a < Suc (2*n); a mod 2 \<noteq> Suc 0\<rbrakk>
       
  1290      \<Longrightarrow> fetch (findnth n) a Bk = (R, Suc a)"
       
  1291 apply(case_tac a, simp_all)
       
  1292 apply(induct n, auto simp: findnth.simps length_findnth nth_append)
       
  1293 apply(subgoal_tac "nat = Suc (2 * n)", simp)
       
  1294 by arith
       
  1295 
       
  1296 declare at_begin_norm.simps[simp del] at_begin_fst_bwtn.simps[simp del] 
       
  1297    at_begin_fst_awtn.simps[simp del] in_middle.simps[simp del] 
       
  1298    abc_lm_s.simps[simp del] abc_lm_v.simps[simp del]  
       
  1299    ci.simps[simp del] inv_after_move.simps[simp del] 
       
  1300    inv_on_left_moving_norm.simps[simp del] 
       
  1301    inv_on_left_moving_in_middle_B.simps[simp del]
       
  1302    inv_after_clear.simps[simp del] 
       
  1303    inv_after_write.simps[simp del] inv_on_left_moving.simps[simp del]
       
  1304    inv_on_right_moving.simps[simp del] 
       
  1305    inv_check_left_moving.simps[simp del] 
       
  1306    inv_check_left_moving_in_middle.simps[simp del]
       
  1307    inv_check_left_moving_on_leftmost.simps[simp del] 
       
  1308    inv_after_left_moving.simps[simp del]
       
  1309    inv_stop.simps[simp del] inv_locate_a.simps[simp del] 
       
  1310    inv_locate_b.simps[simp del]
       
  1311 
       
  1312 lemma [intro]: "\<exists>rn. [Bk] = Bk \<up> rn"
       
  1313 by (metis replicate_0 replicate_Suc)
       
  1314 
       
  1315 lemma [intro]:  "at_begin_norm (as, am) (q, aaa, []) ires
       
  1316              \<Longrightarrow> at_begin_norm (as, am) (q, aaa, [Bk]) ires"
       
  1317 apply(simp add: at_begin_norm.simps, erule_tac exE, erule_tac exE)
       
  1318 apply(rule_tac x = lm1 in exI, simp, auto)
       
  1319 done
       
  1320 
       
  1321 lemma [intro]: "at_begin_fst_bwtn (as, am) (q, aaa, []) ires 
       
  1322             \<Longrightarrow> at_begin_fst_bwtn (as, am) (q, aaa, [Bk]) ires"
       
  1323 apply(simp only: at_begin_fst_bwtn.simps, erule_tac exE, erule_tac exE, erule_tac exE)
       
  1324 apply(rule_tac x = "am @ 0\<up>tn" in exI, auto)
       
  1325 done
       
  1326 
       
  1327 lemma [intro]: "at_begin_fst_awtn (as, am) (q, aaa, []) ires
       
  1328            \<Longrightarrow> at_begin_fst_awtn (as, am) (q, aaa, [Bk]) ires"
       
  1329 apply(auto simp: at_begin_fst_awtn.simps)
       
  1330 done 
       
  1331 
       
  1332 lemma [intro]: "inv_locate_a (as, am) (q, aaa, []) ires
       
  1333             \<Longrightarrow> inv_locate_a (as, am) (q, aaa, [Bk]) ires"
       
  1334 apply(simp only: inv_locate_a.simps)
       
  1335 apply(erule disj_forward)
       
  1336 defer
       
  1337 apply(erule disj_forward, auto)
       
  1338 done
       
  1339 
       
  1340 lemma tape_of_nl_cons: "<m # lm> = (if lm = [] then Oc\<up>(Suc m)
       
  1341                     else Oc\<up>(Suc m) @ Bk # <lm>)"
       
  1342 apply(case_tac lm, simp_all add: tape_of_nl_abv  tape_of_nat_abv split: if_splits)
       
  1343 done
       
  1344 
       
  1345 
       
  1346 lemma locate_a_2_locate_a[simp]: "inv_locate_a (as, am) (q, aaa, Bk # xs) ires
       
  1347        \<Longrightarrow> inv_locate_a (as, am) (q, aaa, Oc # xs) ires"
       
  1348 apply(simp only: inv_locate_a.simps at_begin_norm.simps 
       
  1349                  at_begin_fst_bwtn.simps at_begin_fst_awtn.simps)
       
  1350 apply(erule_tac disjE, erule exE, erule exE, erule exE, 
       
  1351       rule disjI2, rule disjI2)
       
  1352 defer
       
  1353 apply(erule_tac disjE, erule exE, erule exE, 
       
  1354       erule exE, rule disjI2, rule disjI2)
       
  1355 prefer 2
       
  1356 apply(simp)
       
  1357 proof-
       
  1358   fix lm1 tn rn
       
  1359   assume k: "lm1 = am @ 0\<up>tn \<and> length lm1 = q \<and> (if lm1 = [] then aaa = Bk # Bk # 
       
  1360     ires else aaa = [Bk] @ <rev lm1> @ Bk # Bk # ires) \<and> Bk # xs = Bk\<up>rn"
       
  1361   thus "\<exists>lm1 tn rn. lm1 = am @ 0 \<up> tn \<and> length lm1 = q \<and> 
       
  1362     (if lm1 = [] then aaa = Bk # Bk # ires else aaa = [Bk] @ <rev lm1> @ Bk # Bk # ires) \<and> Oc # xs = [Oc] @ Bk \<up> rn"
       
  1363     (is "\<exists>lm1 tn rn. ?P lm1 tn rn")
       
  1364   proof -
       
  1365     from k have "?P lm1 tn (rn - 1)"
       
  1366       apply(auto simp: Oc_def)
       
  1367       by(case_tac [!] "rn::nat", auto)
       
  1368     thus ?thesis by blast
       
  1369   qed
       
  1370 next
       
  1371   fix lm1 lm2 rn
       
  1372   assume h1: "am = lm1 @ lm2 \<and> length lm1 = q \<and> (if lm1 = [] 
       
  1373     then aaa = Bk # Bk # ires else aaa = Bk # <rev lm1> @ Bk # Bk # ires) \<and>
       
  1374     Bk # xs = <lm2> @ Bk\<up>rn"
       
  1375   from h1 have h2: "lm2 = []"
       
  1376     apply(auto split: if_splits)
       
  1377     apply(case_tac [!] lm2, simp_all add: tape_of_nl_cons split: if_splits)
       
  1378     done
       
  1379   from h1 and h2 show "\<exists>lm1 tn rn. lm1 = am @ 0\<up>tn \<and> length lm1 = q \<and> 
       
  1380     (if lm1 = [] then aaa = Bk # Bk # ires else aaa = [Bk] @ <rev lm1> @ Bk # Bk # ires) \<and>
       
  1381     Oc # xs = [Oc] @ Bk\<up>rn" 
       
  1382     (is "\<exists>lm1 tn rn. ?P lm1 tn rn")
       
  1383   proof -
       
  1384     from h1 and h2  have "?P lm1 0 (rn - 1)"
       
  1385       apply(auto simp: Oc_def
       
  1386                       tape_of_nl_abv tape_of_nat_list.simps)
       
  1387       by(case_tac "rn::nat", simp, simp)
       
  1388     thus ?thesis by blast
       
  1389   qed
       
  1390 qed
       
  1391 
       
  1392 lemma [simp]: "inv_locate_a (as, am) (q, aaa, []) ires \<Longrightarrow> 
       
  1393                inv_locate_a (as, am) (q, aaa, [Oc]) ires"
       
  1394 apply(insert locate_a_2_locate_a [of as am q aaa "[]"])
       
  1395 apply(subgoal_tac "inv_locate_a (as, am) (q, aaa, [Bk]) ires", auto)
       
  1396 done
       
  1397 
       
  1398 (*inv: from locate_b to locate_b*)
       
  1399 lemma [simp]: "inv_locate_b (as, am) (q, aaa, Oc # xs) ires
       
  1400          \<Longrightarrow> inv_locate_b (as, am) (q, Oc # aaa, xs) ires"
       
  1401 apply(simp only: inv_locate_b.simps in_middle.simps)
       
  1402 apply(erule exE)+
       
  1403 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  1404       rule_tac x = tn in exI, rule_tac x = m in exI)
       
  1405 apply(rule_tac x = "Suc ml" in exI, rule_tac x = "mr - 1" in exI,
       
  1406       rule_tac x = rn in exI)
       
  1407 apply(case_tac mr, simp_all, auto)
       
  1408 done
       
  1409 
       
  1410 (*
       
  1411 lemma zero_and_nil[intro]: "(Bk # Bk\<^bsup>n\<^esup> = Oc\<^bsup>mr\<^esup> @ Bk # <lm::nat list> @ 
       
  1412                              Bk\<^bsup>rn \<^esup>) \<or> (lm2 = [] \<and> Bk # Bk\<^bsup>n\<^esup> = Oc\<^bsup>mr\<^esup>)
       
  1413        \<Longrightarrow> mr = 0 \<and> lm = []"
       
  1414 apply(rule context_conjI)
       
  1415 apply(case_tac mr, auto simp:exponent_def)
       
  1416 apply(insert BkCons_nil[of "replicate (n - 1) Bk" lm rn])
       
  1417 apply(case_tac n, auto simp: exponent_def Bk_def  tape_of_nl_nil_eq)
       
  1418 done
       
  1419 
       
  1420 lemma tape_of_nat_def: "<[m::nat]> =  Oc # Oc\<^bsup>m\<^esup>"
       
  1421 apply(simp add: tape_of_nl_abv tape_of_nat_list.simps)
       
  1422 done
       
  1423 *)
       
  1424 lemma [simp]:  "<[x::nat]> = Oc\<up>(Suc x)"
       
  1425 apply(simp add: tape_of_nat_abv tape_of_nl_abv)
       
  1426 done
       
  1427 
       
  1428 lemma [simp]: " <([]::nat list)> = []"
       
  1429 apply(simp add: tape_of_nl_abv)
       
  1430 done
       
  1431 
       
  1432 lemma [simp]: "\<lbrakk>inv_locate_b (as, am) (q, aaa, Bk # xs) ires; \<exists>n. xs = Bk\<up>n\<rbrakk>
       
  1433             \<Longrightarrow> inv_locate_a (as, am) (Suc q, Bk # aaa, xs) ires"
       
  1434 apply(simp add: inv_locate_b.simps inv_locate_a.simps)
       
  1435 apply(rule_tac disjI2, rule_tac disjI1)
       
  1436 apply(simp only: in_middle.simps at_begin_fst_bwtn.simps)
       
  1437 apply(erule_tac exE)+
       
  1438 apply(rule_tac x = "lm1 @ [m]" in exI, rule_tac x = tn in exI, simp split: if_splits)
       
  1439 apply(case_tac mr, simp_all)
       
  1440 apply(case_tac "length am", simp_all, case_tac tn, simp_all)
       
  1441 apply(case_tac lm2, simp_all add: tape_of_nl_cons split: if_splits)
       
  1442 apply(case_tac am, simp_all)
       
  1443 apply(case_tac n, simp_all)
       
  1444 apply(case_tac n, simp_all)
       
  1445 apply(case_tac mr, simp_all)
       
  1446 apply(case_tac lm2, simp_all add: tape_of_nl_cons split: if_splits, auto)
       
  1447 apply(case_tac [!] n, simp_all)
       
  1448 done
       
  1449 
       
  1450 lemma [simp]: "(Oc # r = Bk \<up> rn) = False"
       
  1451 apply(case_tac rn, simp_all)
       
  1452 done
       
  1453 
       
  1454 lemma [simp]: "(\<exists>rna. Bk \<up> rn = Bk # Bk \<up> rna) \<or> rn = 0"
       
  1455 apply(case_tac rn, auto)
       
  1456 done
       
  1457 
       
  1458 lemma [simp]: "(\<forall> x. a \<noteq> x) = False"
       
  1459 by auto
       
  1460 
       
  1461 lemma exp_ind: "a\<up>(Suc x) = a\<up>x @ [a]"
       
  1462 apply(induct x, auto)
       
  1463 done
       
  1464 
       
  1465 lemma [simp]: 
       
  1466       "inv_locate_a (as, lm) (q, l, Oc # r) ires
       
  1467        \<Longrightarrow> inv_locate_b (as, lm) (q, Oc # l, r) ires"
       
  1468 apply(simp only: inv_locate_a.simps inv_locate_b.simps in_middle.simps
       
  1469           at_begin_norm.simps at_begin_fst_bwtn.simps
       
  1470           at_begin_fst_awtn.simps)
       
  1471 apply(erule disjE, erule exE, erule exE, erule exE)
       
  1472 apply(rule_tac x = lm1 in exI, rule_tac x = "tl lm2" in exI, simp)
       
  1473 apply(rule_tac x = 0 in exI, rule_tac x = "hd lm2" in exI)
       
  1474 apply(case_tac lm2, auto simp: tape_of_nl_cons )
       
  1475 apply(rule_tac x = 1 in exI, rule_tac x = a in exI, auto)
       
  1476 apply(case_tac list, simp_all)
       
  1477 apply(case_tac rn, simp_all)
       
  1478 apply(rule_tac x = "lm @ replicate tn 0" in exI, 
       
  1479       rule_tac x = "[]" in exI, 
       
  1480       rule_tac x = "Suc tn" in exI, 
       
  1481       rule_tac x = 0 in exI, auto)
       
  1482 apply(simp only: replicate_Suc[THEN sym] exp_ind)
       
  1483 apply(rule_tac x = "Suc 0" in exI, auto)
       
  1484 done
       
  1485 
       
  1486 lemma length_equal: "xs = ys \<Longrightarrow> length xs = length ys"
       
  1487 by auto
       
  1488 
       
  1489 lemma [simp]: "\<lbrakk>inv_locate_b (as, am) (q, aaa, Bk # xs) ires; 
       
  1490                 \<not> (\<exists>n. xs = Bk\<up>n)\<rbrakk> 
       
  1491        \<Longrightarrow> inv_locate_a (as, am) (Suc q, Bk # aaa, xs) ires"
       
  1492 apply(simp add: inv_locate_b.simps inv_locate_a.simps)
       
  1493 apply(rule_tac disjI1)
       
  1494 apply(simp only: in_middle.simps at_begin_norm.simps)
       
  1495 apply(erule_tac exE)+
       
  1496 apply(rule_tac x = "lm1 @ [m]" in exI, rule_tac x = lm2 in exI, simp)
       
  1497 apply(subgoal_tac "tn = 0", simp , auto split: if_splits)
       
  1498 apply(case_tac [!] mr, simp_all, auto)
       
  1499 apply(simp add: tape_of_nl_cons)
       
  1500 apply(drule_tac length_equal, simp)
       
  1501 apply(case_tac "length am", simp_all, erule_tac x = rn in allE, simp)
       
  1502 apply(drule_tac length_equal, simp)
       
  1503 apply(case_tac "(Suc (length lm1) - length am)", simp_all)
       
  1504 apply(case_tac lm2, simp, simp)
       
  1505 done
       
  1506 
       
  1507 lemma locate_b_2_a[intro]: 
       
  1508        "inv_locate_b (as, am) (q, aaa, Bk # xs) ires
       
  1509     \<Longrightarrow> inv_locate_a (as, am) (Suc q, Bk # aaa, xs) ires"
       
  1510 apply(case_tac "\<exists> n. xs = Bk\<up>n", simp, simp)
       
  1511 done
       
  1512 
       
  1513 
       
  1514 lemma [simp]:  "inv_locate_b (as, am) (q, l, []) ires 
       
  1515            \<Longrightarrow>  inv_locate_b (as, am) (q, l, [Bk]) ires"
       
  1516 apply(simp only: inv_locate_b.simps in_middle.simps)
       
  1517 apply(erule exE)+
       
  1518 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  1519       rule_tac x = tn in exI, rule_tac x = m in exI, 
       
  1520       rule_tac x = ml in exI, rule_tac x = mr in exI)
       
  1521 apply(auto)
       
  1522 done
       
  1523 
       
  1524 (*inv: from locate_b to after_write*)
       
  1525 
       
  1526 lemma [simp]: "(a mod 2 \<noteq> Suc 0) = (a mod 2 = 0)  "
       
  1527 by arith
       
  1528 
       
  1529 lemma [simp]: "(a mod 2 \<noteq> 0) = (a mod 2 = Suc 0)  "
       
  1530 by arith
       
  1531 
       
  1532 lemma mod_ex1: "(a mod 2 = Suc 0) = (\<exists> q. a = Suc (2 * q))"
       
  1533 by arith
       
  1534 
       
  1535 lemma mod_ex2: "(a mod (2::nat) = 0) = (\<exists> q. a = 2 * q)"
       
  1536 by arith
       
  1537 
       
  1538 lemma [simp]: "(2*q - Suc 0) div 2 = (q - 1)"
       
  1539 by arith
       
  1540 
       
  1541 lemma [simp]: "(Suc (2*q)) div 2 = q"
       
  1542 by arith
       
  1543 
       
  1544 lemma mod_2: "x mod 2  = 0 \<or>  x mod 2 = Suc 0"
       
  1545 by arith
       
  1546 
       
  1547 lemma [simp]: "x mod 2 = 0 \<Longrightarrow> Suc x mod 2 = Suc 0"
       
  1548 by arith
       
  1549 
       
  1550 lemma [simp]: "x mod 2 = Suc 0 \<Longrightarrow> Suc x mod 2 = 0"
       
  1551 by arith
       
  1552 
       
  1553 lemma [simp]:  "inv_locate_b (as, am) (q, l, []) ires 
       
  1554            \<Longrightarrow>  inv_locate_b (as, am) (q, l, [Bk]) ires"
       
  1555 apply(simp only: inv_locate_b.simps in_middle.simps)
       
  1556 apply(erule exE)+
       
  1557 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  1558       rule_tac x = tn in exI, rule_tac x = m in exI, 
       
  1559       rule_tac x = ml in exI, rule_tac x = mr in exI)
       
  1560 apply(auto)
       
  1561 done
       
  1562 
       
  1563 lemma locate_b_2_locate_a[simp]: 
       
  1564     "\<lbrakk>q > 0;  inv_locate_b (as, am) (q - Suc 0, aaa, Bk # xs) ires\<rbrakk>
       
  1565    \<Longrightarrow>  inv_locate_a (as, am) (q, Bk # aaa, xs) ires"
       
  1566 apply(insert locate_b_2_a [of as am "q - 1" aaa xs ires], simp)
       
  1567 done
       
  1568 
       
  1569 
       
  1570 lemma [simp]:  "inv_locate_b (as, am) (q, l, []) ires 
       
  1571            \<Longrightarrow>  inv_locate_b (as, am) (q, l, [Bk]) ires"
       
  1572 apply(simp only: inv_locate_b.simps in_middle.simps)
       
  1573 apply(erule exE)+
       
  1574 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  1575       rule_tac x = tn in exI, rule_tac x = m in exI, 
       
  1576       rule_tac x = ml in exI, rule_tac x = mr in exI)
       
  1577 apply(auto)
       
  1578 done
       
  1579 
       
  1580 (*inv: from locate_b to after_write*)
       
  1581 
       
  1582 lemma [simp]:
       
  1583   "crsp (layout_of ap) (as, lm) (s, l, r) ires
       
  1584   \<Longrightarrow> findnth_inv (layout_of ap) n (as, lm) (Suc 0, l, r) ires"
       
  1585 apply(auto simp: crsp.simps findnth_inv.simps inv_locate_a.simps
       
  1586                at_begin_norm.simps at_begin_fst_awtn.simps at_begin_fst_bwtn.simps)
       
  1587 done
       
  1588 
       
  1589 lemma findnth_correct_pre: 
       
  1590   assumes layout: "ly = layout_of ap"
       
  1591   and crsp: "crsp ly (as, lm) (s, l, r) ires"
       
  1592   and not0: "n > 0"
       
  1593   and f: "f = (\<lambda> stp. (steps (Suc 0, l, r) (findnth n, 0) stp, n))"
       
  1594   and P: "P = (\<lambda> ((s, l, r), n). s = Suc (2 * n))"
       
  1595   and Q: "Q = (\<lambda> ((s, l, r), n). findnth_inv ly n (as, lm) (s, l, r) ires)"
       
  1596   shows "\<exists> stp. P (f stp) \<and> Q (f stp)"
       
  1597 thm halt_lemma2
       
  1598 proof(rule_tac LE = findnth_LE in halt_lemma2)
       
  1599   show "wf findnth_LE"  by(intro wf_findnth_LE)
       
  1600 next
       
  1601   show "Q (f 0)"
       
  1602     using crsp layout
       
  1603     apply(simp add: f P Q steps.simps)
       
  1604     done
       
  1605 next
       
  1606   show "\<not> P (f 0)"
       
  1607     using not0
       
  1608     apply(simp add: f P steps.simps)
       
  1609     done
       
  1610 next
       
  1611   show "\<forall>n. \<not> P (f n) \<and> Q (f n) \<longrightarrow> Q (f (Suc n)) \<and> (f (Suc n), f n) 
       
  1612         \<in> findnth_LE"
       
  1613   proof(rule_tac allI, rule_tac impI, simp add: f, 
       
  1614       case_tac "steps (Suc 0, l, r) (findnth n, 0) na", simp add: P)
       
  1615     fix na a b c
       
  1616     assume "a \<noteq> Suc (2 * n) \<and> Q ((a, b, c), n)"
       
  1617     thus  "Q (step (a, b, c) (findnth n, 0), n) \<and> 
       
  1618         ((step (a, b, c) (findnth n, 0), n), (a, b, c), n) \<in> findnth_LE"
       
  1619       apply(case_tac c, case_tac [2] aa)
       
  1620       apply(simp_all add: step.simps findnth_LE_def Q findnth_inv.simps mod_2  lex_pair_def split: if_splits)
       
  1621       apply(auto simp: mod_ex1 mod_ex2)
       
  1622       done
       
  1623   qed
       
  1624 qed
       
  1625             
       
  1626 lemma [intro]: "inv_locate_a (as, lm) (0, Bk # Bk # ires, <lm> @ Bk \<up> x) ires"
       
  1627 apply(auto simp: crsp.simps inv_locate_a.simps at_begin_norm.simps)
       
  1628 done
       
  1629 lemma [simp]: "crsp ly (as, lm) (s, l, r) ires \<Longrightarrow> inv_locate_a (as, lm) (0, l, r) ires"
       
  1630 apply(auto simp: crsp.simps inv_locate_a.simps at_begin_norm.simps)
       
  1631 done
       
  1632 
       
  1633 lemma findnth_correct: 
       
  1634   assumes layout: "ly = layout_of ap"
       
  1635   and crsp: "crsp ly (as, lm) (s, l, r) ires"
       
  1636   shows "\<exists> stp l' r'. steps (Suc 0, l, r) (findnth n, 0) stp = (Suc (2 * n), l', r')
       
  1637               \<and> inv_locate_a (as, lm) (n, l', r') ires"
       
  1638   using crsp
       
  1639   apply(case_tac "n = 0")
       
  1640   apply(rule_tac x = 0 in exI, auto simp: steps.simps)
       
  1641   using assms
       
  1642   apply(drule_tac findnth_correct_pre, auto)
       
  1643   apply(rule_tac x = stp in exI, simp add: findnth_inv.simps)
       
  1644   done
       
  1645 
       
  1646 
       
  1647 fun inc_inv :: "nat \<Rightarrow> inc_inv_t"
       
  1648   where
       
  1649   "inc_inv n (as, lm) (s, l, r) ires =
       
  1650               (let lm' = abc_lm_s lm n (Suc (abc_lm_v lm n)) in
       
  1651                 if s = 0 then False
       
  1652                 else if s = 1 then 
       
  1653                    inv_locate_a (as, lm) (n, l, r) ires
       
  1654                 else if s = 2 then 
       
  1655                    inv_locate_b (as, lm) (n, l, r) ires
       
  1656                 else if s = 3 then 
       
  1657                    inv_after_write (as, lm') (s, l, r) ires
       
  1658                 else if s = Suc 3 then 
       
  1659                    inv_after_move (as, lm') (s, l, r) ires
       
  1660                 else if s = Suc 4 then 
       
  1661                    inv_after_clear (as, lm') (s, l, r) ires
       
  1662                 else if s = Suc (Suc 4) then 
       
  1663                    inv_on_right_moving (as, lm') (s, l, r) ires
       
  1664                 else if s = Suc (Suc 5) then 
       
  1665                    inv_on_left_moving (as, lm') (s, l, r) ires
       
  1666                 else if s = Suc (Suc (Suc 5)) then 
       
  1667                    inv_check_left_moving (as, lm') (s, l, r) ires
       
  1668                 else if s = Suc (Suc (Suc (Suc 5))) then 
       
  1669                    inv_after_left_moving (as, lm') (s, l, r) ires
       
  1670                 else if s = Suc (Suc (Suc (Suc (Suc 5)))) then 
       
  1671                    inv_stop (as, lm') (s, l, r) ires
       
  1672                 else False)"
       
  1673 
       
  1674 
       
  1675 fun abc_inc_stage1 :: "config \<Rightarrow> nat"
       
  1676   where
       
  1677   "abc_inc_stage1 (s, l, r) = 
       
  1678             (if s = 0 then 0
       
  1679              else if s \<le> 2 then 5
       
  1680              else if s \<le> 6 then 4
       
  1681              else if s \<le> 8 then 3
       
  1682              else if s = 9 then 2
       
  1683              else 1)"
       
  1684 
       
  1685 fun abc_inc_stage2 :: "config \<Rightarrow> nat"
       
  1686   where
       
  1687   "abc_inc_stage2 (s, l, r) =
       
  1688                 (if s = 1 then 2
       
  1689                  else if s = 2 then 1
       
  1690                  else if s = 3 then length r
       
  1691                  else if s = 4 then length r
       
  1692                  else if s = 5 then length r
       
  1693                  else if s = 6 then 
       
  1694                                   if r \<noteq> [] then length r
       
  1695                                   else 1
       
  1696                  else if s = 7 then length l
       
  1697                  else if s = 8 then length l
       
  1698                  else 0)"
       
  1699 
       
  1700 fun abc_inc_stage3 :: "config \<Rightarrow>  nat"
       
  1701   where
       
  1702   "abc_inc_stage3 (s, l, r) = (
       
  1703               if s = 4 then 4
       
  1704               else if s = 5 then 3
       
  1705               else if s = 6 then 
       
  1706                    if r \<noteq> [] \<and> hd r = Oc then 2
       
  1707                    else 1
       
  1708               else if s = 3 then 0
       
  1709               else if s = 2 then length r
       
  1710               else if s = 1 then 
       
  1711                       if (r \<noteq> [] \<and> hd r = Oc) then 0
       
  1712                       else 1
       
  1713               else 10 - s)"
       
  1714 
       
  1715 
       
  1716 definition inc_measure :: "config \<Rightarrow> nat \<times> nat \<times> nat"
       
  1717   where
       
  1718   "inc_measure c = 
       
  1719     (abc_inc_stage1 c, abc_inc_stage2 c, abc_inc_stage3 c)"
       
  1720 
       
  1721 definition lex_triple :: 
       
  1722    "((nat \<times> (nat \<times> nat)) \<times> (nat \<times> (nat \<times> nat))) set"
       
  1723   where "lex_triple \<equiv> less_than <*lex*> lex_pair"
       
  1724 
       
  1725 definition inc_LE :: "(config \<times> config) set"
       
  1726   where
       
  1727   "inc_LE \<equiv> (inv_image lex_triple inc_measure)"
       
  1728 
       
  1729 declare inc_inv.simps[simp del]
       
  1730 
       
  1731 lemma wf_inc_le[intro]: "wf inc_LE"
       
  1732 by(auto intro:wf_inv_image simp: inc_LE_def lex_triple_def lex_pair_def)
       
  1733 
       
  1734 lemma numeral_5_eq_5: "5 = Suc (Suc (Suc (Suc (Suc 0))))"
       
  1735 by arith
       
  1736 
       
  1737 lemma numeral_6_eq_6: "6 = Suc (Suc (Suc (Suc (Suc 1))))"
       
  1738 by arith
       
  1739 
       
  1740 lemma numeral_7_eq_7: "7 = Suc (Suc (Suc (Suc (Suc 2))))"
       
  1741 by arith
       
  1742 
       
  1743 lemma numeral_8_eq_8: "8 = Suc (Suc (Suc (Suc (Suc 3))))"
       
  1744 by arith
       
  1745 
       
  1746 lemma numeral_9_eq_9: "9 = Suc (Suc (Suc (Suc (Suc (Suc 3)))))"
       
  1747 by arith
       
  1748 
       
  1749 lemma numeral_10_eq_10: "10 = Suc (Suc (Suc (Suc (Suc (Suc (Suc 3))))))"
       
  1750 by arith
       
  1751 
       
  1752 lemma inv_locate_b_2_after_write[simp]: 
       
  1753       "inv_locate_b (as, am) (n, aaa, Bk # xs) ires
       
  1754       \<Longrightarrow> inv_after_write (as, abc_lm_s am n (Suc (abc_lm_v am n)))
       
  1755           (s, aaa, Oc # xs) ires"
       
  1756 apply(auto simp: in_middle.simps inv_after_write.simps 
       
  1757                  abc_lm_v.simps abc_lm_s.simps  inv_locate_b.simps)
       
  1758 apply(case_tac [!] mr, auto split: if_splits)
       
  1759 apply(rule_tac x = rn in exI, rule_tac x = "Suc m" in exI,
       
  1760       rule_tac x = "lm1" in exI, simp)
       
  1761 apply(rule_tac x = "lm2" in exI, simp)
       
  1762 apply(simp only: Suc_diff_le exp_ind)
       
  1763 apply(subgoal_tac "lm2 = []", simp)
       
  1764 apply(drule_tac length_equal, simp)
       
  1765 done
       
  1766 
       
  1767 lemma [simp]: "inv_locate_b (as, am) (n, aaa, []) ires \<Longrightarrow> 
       
  1768      inv_after_write (as, abc_lm_s am n (Suc (abc_lm_v am n))) 
       
  1769                      (s, aaa, [Oc]) ires"
       
  1770 apply(insert inv_locate_b_2_after_write [of as am n aaa "[]"])
       
  1771 by(simp)
       
  1772 
       
  1773 
       
  1774 
       
  1775 (*inv: from after_write to after_move*)
       
  1776 lemma [simp]: "inv_after_write (as, lm) (x, l, Oc # r) ires
       
  1777                 \<Longrightarrow> inv_after_move (as, lm) (y, Oc # l, r) ires"
       
  1778 apply(auto simp:inv_after_move.simps inv_after_write.simps split: if_splits)
       
  1779 done
       
  1780 
       
  1781 lemma [simp]: "inv_after_write (as, abc_lm_s am n (Suc (abc_lm_v am n)
       
  1782                 )) (x, aaa, Bk # xs) ires = False"
       
  1783 apply(simp add: inv_after_write.simps )
       
  1784 done
       
  1785 
       
  1786 lemma [simp]: 
       
  1787  "inv_after_write (as, abc_lm_s am n (Suc (abc_lm_v am n))) 
       
  1788                         (x, aaa, []) ires = False"
       
  1789 apply(simp add: inv_after_write.simps )
       
  1790 done
       
  1791 
       
  1792 (*inv: from after_move to after_clear*)
       
  1793 lemma [simp]: "inv_after_move (as, lm) (s, l, Oc # r) ires
       
  1794                 \<Longrightarrow> inv_after_clear (as, lm) (s', l, Bk # r) ires"
       
  1795 apply(auto simp: inv_after_move.simps inv_after_clear.simps split: if_splits)
       
  1796 done
       
  1797 
       
  1798 (*inv: from after_move to on_leftmoving*)
       
  1799 lemma [intro]: "Bk \<up> rn = Bk # Bk \<up> (rn - Suc 0) \<or> rn = 0"
       
  1800 apply(case_tac rn, auto)
       
  1801 done
       
  1802 
       
  1803 lemma inv_after_move_2_inv_on_left_moving[simp]:  
       
  1804    "inv_after_move (as, lm) (s, l, Bk # r) ires
       
  1805    \<Longrightarrow> (l = [] \<longrightarrow> 
       
  1806          inv_on_left_moving (as, lm) (s', [], Bk # Bk # r) ires) \<and>
       
  1807       (l \<noteq> [] \<longrightarrow> 
       
  1808          inv_on_left_moving (as, lm) (s', tl l, hd l # Bk # r) ires)"
       
  1809 apply(simp only: inv_after_move.simps inv_on_left_moving.simps)
       
  1810 apply(subgoal_tac "l \<noteq> []", rule conjI, simp, rule impI, 
       
  1811                 rule disjI1, simp only: inv_on_left_moving_norm.simps)
       
  1812 apply(erule exE)+
       
  1813 apply(subgoal_tac "lm2 = []")
       
  1814 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI,  
       
  1815     rule_tac x = m in exI, rule_tac x = m in exI, 
       
  1816     rule_tac x = 1 in exI,  
       
  1817     rule_tac x = "rn - 1" in exI, auto)
       
  1818 apply(auto split: if_splits)
       
  1819 apply(case_tac [1-2] rn, simp_all)
       
  1820 apply(case_tac [!] lm2, simp_all add: tape_of_nl_cons split: if_splits)
       
  1821 done
       
  1822 
       
  1823 
       
  1824 lemma inv_after_move_2_inv_on_left_moving_B[simp]: 
       
  1825     "inv_after_move (as, lm) (s, l, []) ires
       
  1826       \<Longrightarrow> (l = [] \<longrightarrow> inv_on_left_moving (as, lm) (s', [], [Bk]) ires) \<and>
       
  1827           (l \<noteq> [] \<longrightarrow> inv_on_left_moving (as, lm) (s', tl l, [hd l]) ires)"
       
  1828 apply(simp only: inv_after_move.simps inv_on_left_moving.simps)
       
  1829 apply(subgoal_tac "l \<noteq> []", rule conjI, simp, rule impI, rule disjI1,
       
  1830         simp only: inv_on_left_moving_norm.simps)
       
  1831 apply(erule exE)+
       
  1832 apply(subgoal_tac "lm2 = []")
       
  1833 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI,  
       
  1834       rule_tac x = m in exI, rule_tac x = m in exI, 
       
  1835       rule_tac x = 1 in exI, rule_tac x = "rn - 1" in exI, simp, case_tac rn)
       
  1836 apply(auto split: if_splits)
       
  1837 apply(case_tac [!] lm2, auto simp: tape_of_nl_cons split: if_splits)
       
  1838 done
       
  1839 
       
  1840 (*inv: from after_clear to on_right_moving*)
       
  1841 lemma [simp]: "Oc # r = replicate rn Bk = False"
       
  1842 apply(case_tac rn, simp, simp)
       
  1843 done
       
  1844 
       
  1845 lemma inv_after_clear_2_inv_on_right_moving[simp]: 
       
  1846      "inv_after_clear (as, lm) (x, l, Bk # r) ires
       
  1847       \<Longrightarrow> inv_on_right_moving (as, lm) (y, Bk # l, r) ires"
       
  1848 apply(auto simp: inv_after_clear.simps inv_on_right_moving.simps )
       
  1849 apply(subgoal_tac "lm2 \<noteq> []")
       
  1850 apply(rule_tac x = "lm1 @ [m]" in exI, rule_tac x = "tl lm2" in exI, 
       
  1851       rule_tac x = "hd lm2" in exI, simp)
       
  1852 apply(rule_tac x = 0 in exI, rule_tac x = "hd lm2" in exI)
       
  1853 apply(simp, rule conjI)
       
  1854 apply(case_tac [!] "lm2::nat list", auto)
       
  1855 apply(case_tac rn, auto split: if_splits simp: tape_of_nl_cons)
       
  1856 apply(case_tac [!] rn, simp_all)
       
  1857 done
       
  1858 
       
  1859 lemma [simp]: "inv_after_clear (as, lm) (x, l, []) ires\<Longrightarrow> 
       
  1860                inv_after_clear (as, lm) (y, l, [Bk]) ires" 
       
  1861 by(auto simp: inv_after_clear.simps)
       
  1862 
       
  1863 lemma [simp]: "inv_after_clear (as, lm) (x, l, []) ires
       
  1864              \<Longrightarrow> inv_on_right_moving (as, lm) (y, Bk # l, []) ires"
       
  1865 by(insert 
       
  1866     inv_after_clear_2_inv_on_right_moving[of as lm n l "[]"], simp)
       
  1867 
       
  1868 (*inv: from on_right_moving to on_right_movign*)
       
  1869 lemma [simp]: "inv_on_right_moving (as, lm) (x, l, Oc # r) ires
       
  1870       \<Longrightarrow> inv_on_right_moving (as, lm) (y, Oc # l, r) ires"
       
  1871 apply(auto simp: inv_on_right_moving.simps)
       
  1872 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  1873            rule_tac x = "ml + mr" in exI, simp)
       
  1874 apply(rule_tac x = "Suc ml" in exI, 
       
  1875            rule_tac x = "mr - 1" in exI, simp)
       
  1876 apply(case_tac mr, auto)
       
  1877 apply(rule_tac x = lm1 in exI, rule_tac x = "[]" in exI, 
       
  1878       rule_tac x = "ml + mr" in exI, simp)
       
  1879 apply(rule_tac x = "Suc ml" in exI, 
       
  1880       rule_tac x = "mr - 1" in exI, simp)
       
  1881 apply(case_tac mr, auto split: if_splits)
       
  1882 done
       
  1883 
       
  1884 lemma inv_on_right_moving_2_inv_on_right_moving[simp]: 
       
  1885      "inv_on_right_moving (as, lm) (x, l, Bk # r) ires
       
  1886      \<Longrightarrow> inv_after_write (as, lm) (y, l, Oc # r) ires"
       
  1887 apply(auto simp: inv_on_right_moving.simps inv_after_write.simps )
       
  1888 apply(case_tac mr, auto simp: split: if_splits)
       
  1889 done
       
  1890       
       
  1891 lemma [simp]: "inv_on_right_moving (as, lm) (x, l, []) ires\<Longrightarrow> 
       
  1892              inv_on_right_moving (as, lm) (y, l, [Bk]) ires"
       
  1893 apply(auto simp: inv_on_right_moving.simps)
       
  1894 apply(rule_tac x = lm1 in exI, rule_tac x = "[]" in exI, simp)
       
  1895 done
       
  1896 
       
  1897 (*inv: from on_right_moving to after_write*)
       
  1898 lemma [simp]: "inv_on_right_moving (as, lm) (x, l, []) ires
       
  1899        \<Longrightarrow> inv_after_write (as, lm) (y, l, [Oc]) ires"
       
  1900 apply(rule_tac inv_on_right_moving_2_inv_on_right_moving, simp)
       
  1901 done
       
  1902 
       
  1903 (*inv: from on_left_moving to on_left_moving*)
       
  1904 lemma [simp]: "inv_on_left_moving_in_middle_B (as, lm) 
       
  1905                (s, l, Oc # r) ires = False"
       
  1906 apply(auto simp: inv_on_left_moving_in_middle_B.simps )
       
  1907 done
       
  1908 
       
  1909 lemma [simp]: "inv_on_left_moving_norm (as, lm) (s, l, Bk # r) ires 
       
  1910              = False"
       
  1911 apply(auto simp: inv_on_left_moving_norm.simps)
       
  1912 apply(case_tac [!] mr, auto simp: )
       
  1913 done
       
  1914 
       
  1915 lemma [simp]: 
       
  1916   "\<lbrakk>inv_on_left_moving_norm (as, lm) (s, l, Oc # r) ires;
       
  1917     hd l = Bk; l \<noteq> []\<rbrakk> \<Longrightarrow> 
       
  1918      inv_on_left_moving_in_middle_B (as, lm) (s, tl l, Bk # Oc # r) ires"
       
  1919 apply(case_tac l, simp, simp)
       
  1920 apply(simp only: inv_on_left_moving_norm.simps 
       
  1921                  inv_on_left_moving_in_middle_B.simps)
       
  1922 apply(erule_tac exE)+
       
  1923 apply(rule_tac x = lm1 in exI, rule_tac x = "m # lm2" in exI, auto)
       
  1924 apply(case_tac [!] ml, auto)
       
  1925 apply(auto simp: tape_of_nl_cons split: if_splits)
       
  1926 apply(rule_tac [!] x = "Suc rn" in exI, simp_all)
       
  1927 done
       
  1928 
       
  1929 lemma [simp]: "\<lbrakk>inv_on_left_moving_norm (as, lm) (s, l, Oc # r) ires; 
       
  1930                 hd l = Oc; l \<noteq> []\<rbrakk>
       
  1931             \<Longrightarrow> inv_on_left_moving_norm (as, lm) 
       
  1932                                         (s, tl l, Oc # Oc # r) ires"
       
  1933 apply(simp only: inv_on_left_moving_norm.simps)
       
  1934 apply(erule exE)+
       
  1935 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  1936       rule_tac x = m in exI, rule_tac x = "ml - 1" in exI,
       
  1937       rule_tac x = "Suc mr" in exI, rule_tac x = rn in exI, simp)
       
  1938 apply(case_tac ml, auto simp: split: if_splits)
       
  1939 done
       
  1940 
       
  1941 lemma [simp]: "inv_on_left_moving_norm (as, lm) (s, [], Oc # r) ires
       
  1942      \<Longrightarrow> inv_on_left_moving_in_middle_B (as, lm) (s, [], Bk # Oc # r) ires"
       
  1943 apply(auto simp: inv_on_left_moving_norm.simps 
       
  1944                  inv_on_left_moving_in_middle_B.simps split: if_splits)
       
  1945 done
       
  1946 
       
  1947 lemma [simp]:"inv_on_left_moving (as, lm) (s, l, Oc # r) ires
       
  1948     \<Longrightarrow> (l = [] \<longrightarrow> inv_on_left_moving (as, lm) (s, [], Bk # Oc # r) ires)
       
  1949  \<and>  (l \<noteq> [] \<longrightarrow> inv_on_left_moving (as, lm) (s, tl l, hd l # Oc # r) ires)"
       
  1950 apply(simp add: inv_on_left_moving.simps)
       
  1951 apply(case_tac "l \<noteq> []", rule conjI, simp, simp)
       
  1952 apply(case_tac "hd l", simp, simp, simp)
       
  1953 done
       
  1954 
       
  1955 (*inv: from on_left_moving to check_left_moving*)
       
  1956 lemma [simp]: "inv_on_left_moving_in_middle_B (as, lm) 
       
  1957                                       (s, Bk # list, Bk # r) ires
       
  1958           \<Longrightarrow> inv_check_left_moving_on_leftmost (as, lm) 
       
  1959                                       (s', list, Bk # Bk # r) ires"
       
  1960 apply(auto simp: inv_on_left_moving_in_middle_B.simps 
       
  1961                  inv_check_left_moving_on_leftmost.simps split: if_splits)
       
  1962 apply(case_tac [!] "rev lm1", simp_all)
       
  1963 apply(case_tac [!] lista, simp_all add: tape_of_nl_abv tape_of_nat_abv tape_of_nat_list.simps)
       
  1964 done
       
  1965 
       
  1966 lemma [simp]:
       
  1967     "inv_check_left_moving_in_middle (as, lm) (s, l, Bk # r) ires= False"
       
  1968 by(auto simp: inv_check_left_moving_in_middle.simps )
       
  1969 
       
  1970 lemma [simp]: 
       
  1971  "inv_on_left_moving_in_middle_B (as, lm) (s, [], Bk # r) ires\<Longrightarrow> 
       
  1972   inv_check_left_moving_on_leftmost (as, lm) (s', [], Bk # Bk # r) ires"
       
  1973 apply(auto simp: inv_on_left_moving_in_middle_B.simps 
       
  1974                  inv_check_left_moving_on_leftmost.simps split: if_splits)
       
  1975 done
       
  1976 
       
  1977 lemma [simp]: "inv_check_left_moving_on_leftmost (as, lm) 
       
  1978                                        (s, list, Oc # r) ires= False"
       
  1979 by(auto simp: inv_check_left_moving_on_leftmost.simps split: if_splits)
       
  1980 
       
  1981 lemma [simp]: "inv_on_left_moving_in_middle_B (as, lm) 
       
  1982                                          (s, Oc # list, Bk # r) ires
       
  1983  \<Longrightarrow> inv_check_left_moving_in_middle (as, lm) (s', list, Oc # Bk # r) ires"
       
  1984 apply(auto simp: inv_on_left_moving_in_middle_B.simps 
       
  1985                  inv_check_left_moving_in_middle.simps  split: if_splits)
       
  1986 done
       
  1987 
       
  1988 lemma inv_on_left_moving_2_check_left_moving[simp]:
       
  1989  "inv_on_left_moving (as, lm) (s, l, Bk # r) ires
       
  1990  \<Longrightarrow> (l = [] \<longrightarrow> inv_check_left_moving (as, lm) (s', [], Bk # Bk # r) ires)
       
  1991  \<and> (l \<noteq> [] \<longrightarrow> 
       
  1992       inv_check_left_moving (as, lm) (s', tl l, hd l # Bk # r) ires)"
       
  1993 apply(simp add: inv_on_left_moving.simps inv_check_left_moving.simps)
       
  1994 apply(case_tac l, simp, simp)
       
  1995 apply(case_tac a, simp, simp)
       
  1996 done
       
  1997 
       
  1998 lemma [simp]: "inv_on_left_moving_norm (as, lm) (s, l, []) ires = False"
       
  1999 apply(auto simp: inv_on_left_moving_norm.simps)
       
  2000 done
       
  2001 
       
  2002 lemma [simp]: "inv_on_left_moving (as, lm) (s, l, []) ires\<Longrightarrow> 
       
  2003      inv_on_left_moving (as, lm) (6 + 2 * n, l, [Bk]) ires"
       
  2004 apply(simp add: inv_on_left_moving.simps)
       
  2005 apply(auto simp: inv_on_left_moving_in_middle_B.simps)
       
  2006 done
       
  2007 
       
  2008 lemma [simp]: "inv_on_left_moving (as, lm) (s, l, []) ires = False"
       
  2009 apply(simp add: inv_on_left_moving.simps)
       
  2010 apply(simp add: inv_on_left_moving_in_middle_B.simps)
       
  2011 done
       
  2012 
       
  2013 lemma [simp]: "inv_on_left_moving (as, lm) (s, l, []) ires
       
  2014  \<Longrightarrow> (l = [] \<longrightarrow> inv_check_left_moving (as, lm) (s', [], [Bk]) ires) \<and>
       
  2015     (l \<noteq> [] \<longrightarrow> inv_check_left_moving (as, lm) (s', tl l, [hd l]) ires)"
       
  2016 by simp
       
  2017 
       
  2018 lemma [intro]: "\<exists>rna. Bk # Bk \<up> rn = Bk \<up> rna"
       
  2019 apply(rule_tac x = "Suc rn" in exI, simp)
       
  2020 done
       
  2021 
       
  2022 lemma 
       
  2023 inv_check_left_moving_in_middle_2_on_left_moving_in_middle_B[simp]:
       
  2024 "inv_check_left_moving_in_middle (as, lm) (s, Bk # list, Oc # r) ires
       
  2025   \<Longrightarrow> inv_on_left_moving_in_middle_B (as, lm) (s', list, Bk # Oc # r) ires"
       
  2026 apply(simp only: inv_check_left_moving_in_middle.simps 
       
  2027                  inv_on_left_moving_in_middle_B.simps)
       
  2028 apply(erule_tac exE)+
       
  2029 apply(rule_tac x = "rev (tl (rev lm1))" in exI, 
       
  2030       rule_tac x = "[hd (rev lm1)] @ lm2" in exI, auto)
       
  2031 apply(case_tac [!] "rev lm1",simp_all add: tape_of_nat_abv tape_of_nl_abv tape_of_nat_list.simps)
       
  2032 apply(case_tac [!] a, simp_all)
       
  2033 apply(case_tac [1] lm2, simp_all add: tape_of_nat_list.simps tape_of_nat_abv, auto)
       
  2034 apply(case_tac [3] lm2, simp_all add: tape_of_nat_list.simps tape_of_nat_abv, auto)
       
  2035 apply(case_tac [!] lista, simp_all add: tape_of_nat_abv tape_of_nat_list.simps)
       
  2036 done
       
  2037 
       
  2038 lemma [simp]: 
       
  2039  "inv_check_left_moving_in_middle (as, lm) (s, [], Oc # r) ires\<Longrightarrow>
       
  2040      inv_check_left_moving_in_middle (as, lm) (s', [Bk], Oc # r) ires"
       
  2041 apply(auto simp: inv_check_left_moving_in_middle.simps )
       
  2042 done
       
  2043 
       
  2044 lemma [simp]: 
       
  2045  "inv_check_left_moving_in_middle (as, lm) (s, [], Oc # r) ires
       
  2046    \<Longrightarrow> inv_on_left_moving_in_middle_B (as, lm) (s', [], Bk # Oc # r) ires"
       
  2047 apply(insert 
       
  2048 inv_check_left_moving_in_middle_2_on_left_moving_in_middle_B[of 
       
  2049                   as lm n "[]" r], simp)
       
  2050 done 
       
  2051 
       
  2052 lemma [simp]: "inv_check_left_moving_in_middle (as, lm) 
       
  2053                        (s, Oc # list, Oc # r) ires
       
  2054    \<Longrightarrow> inv_on_left_moving_norm (as, lm) (s', list, Oc # Oc # r) ires"
       
  2055 apply(auto simp: inv_check_left_moving_in_middle.simps 
       
  2056                  inv_on_left_moving_norm.simps)
       
  2057 apply(rule_tac x = "rev (tl (rev lm1))" in exI, 
       
  2058       rule_tac x = lm2 in exI, rule_tac x = "hd (rev lm1)" in exI)
       
  2059 apply(rule_tac conjI)
       
  2060 apply(case_tac "rev lm1", simp, simp)
       
  2061 apply(rule_tac x = "hd (rev lm1) - 1" in exI, auto)
       
  2062 apply(rule_tac [!] x = "Suc (Suc 0)" in exI, simp)
       
  2063 apply(case_tac [!] "rev lm1", simp_all)
       
  2064 apply(case_tac [!] a, simp_all add: tape_of_nl_cons split: if_splits)
       
  2065 done
       
  2066 
       
  2067 lemma [simp]: "inv_check_left_moving (as, lm) (s, l, Oc # r) ires
       
  2068 \<Longrightarrow> (l = [] \<longrightarrow> inv_on_left_moving (as, lm) (s', [], Bk # Oc # r) ires) \<and>
       
  2069    (l \<noteq> [] \<longrightarrow> inv_on_left_moving (as, lm) (s', tl l, hd l # Oc # r) ires)"
       
  2070 apply(case_tac l, 
       
  2071       auto simp: inv_check_left_moving.simps inv_on_left_moving.simps)
       
  2072 apply(case_tac a, simp, simp)
       
  2073 done
       
  2074 
       
  2075 (*inv: check_left_moving to after_left_moving*)
       
  2076 lemma [simp]: "inv_check_left_moving (as, lm) (s, l, Bk # r) ires
       
  2077                 \<Longrightarrow> inv_after_left_moving (as, lm) (s', Bk # l, r) ires"
       
  2078 apply(auto simp: inv_check_left_moving.simps 
       
  2079  inv_check_left_moving_on_leftmost.simps inv_after_left_moving.simps)
       
  2080 done
       
  2081 
       
  2082 
       
  2083 lemma [simp]:"inv_check_left_moving (as, lm) (s, l, []) ires
       
  2084       \<Longrightarrow> inv_after_left_moving (as, lm) (s', Bk # l, []) ires"
       
  2085 by(simp add: inv_check_left_moving.simps  
       
  2086 inv_check_left_moving_in_middle.simps 
       
  2087 inv_check_left_moving_on_leftmost.simps)
       
  2088 
       
  2089 (*inv: after_left_moving to inv_stop*)
       
  2090 lemma [simp]: "inv_after_left_moving (as, lm) (s, l, Bk # r) ires
       
  2091        \<Longrightarrow> inv_stop (as, lm) (s', Bk # l, r) ires"
       
  2092 apply(auto simp: inv_after_left_moving.simps inv_stop.simps)
       
  2093 done
       
  2094 
       
  2095 lemma [simp]: "inv_after_left_moving (as, lm) (s, l, []) ires
       
  2096              \<Longrightarrow> inv_stop (as, lm) (s', Bk # l, []) ires"
       
  2097 by(auto simp: inv_after_left_moving.simps)
       
  2098 
       
  2099 (*inv: stop to stop*)
       
  2100 lemma [simp]: "inv_stop (as, lm) (x, l, r) ires \<Longrightarrow> 
       
  2101                inv_stop (as, lm) (y, l, r) ires"
       
  2102 apply(simp add: inv_stop.simps)
       
  2103 done
       
  2104 
       
  2105 lemma [simp]: "inv_after_clear (as, lm) (s, aaa, Oc # xs) ires= False"
       
  2106 apply(auto simp: inv_after_clear.simps )
       
  2107 done
       
  2108 
       
  2109 lemma [simp]: 
       
  2110   "inv_after_left_moving (as, lm) (s, aaa, Oc # xs) ires = False"
       
  2111 by(auto simp: inv_after_left_moving.simps  )
       
  2112 
       
  2113 lemma [simp]: "inv_after_clear (as, abc_lm_s lm n (Suc (abc_lm_v lm n))) (s, b, []) ires = False"
       
  2114 apply(auto simp: inv_after_clear.simps)
       
  2115 done
       
  2116 
       
  2117 lemma [simp]: "inv_on_left_moving (as, abc_lm_s lm n (Suc (abc_lm_v lm n))) 
       
  2118            (s, b, Oc # list) ires \<Longrightarrow> b \<noteq> []"
       
  2119 apply(auto simp: inv_on_left_moving.simps inv_on_left_moving_norm.simps split: if_splits)
       
  2120 done
       
  2121 
       
  2122 lemma [simp]: "inv_check_left_moving (as, abc_lm_s lm n (Suc (abc_lm_v lm n))) (s, b, Oc # list) ires \<Longrightarrow> b \<noteq> []"
       
  2123 apply(auto simp: inv_check_left_moving.simps inv_check_left_moving_in_middle.simps split: if_splits)
       
  2124 done
       
  2125 
       
  2126 lemma tinc_correct_pre:
       
  2127   assumes layout: "ly = layout_of ap"
       
  2128   and inv_start: "inv_locate_a (as, lm) (n, l, r) ires"
       
  2129   and lm': "lm' = abc_lm_s lm n (Suc (abc_lm_v lm n))"
       
  2130   and f: "f = steps (Suc 0, l, r) (tinc_b, 0)"
       
  2131   and P: "P = (\<lambda> (s, l, r). s = 10)"
       
  2132   and Q: "Q = (\<lambda> (s, l, r). inc_inv n (as, lm) (s, l, r) ires)" 
       
  2133   shows "\<exists> stp. P (f stp) \<and> Q (f stp)"
       
  2134 proof(rule_tac LE = inc_LE in halt_lemma2)
       
  2135   show "wf inc_LE" by(auto)
       
  2136 next
       
  2137   show "Q (f 0)"
       
  2138     using inv_start
       
  2139     apply(simp add: f P Q steps.simps inc_inv.simps)
       
  2140     done
       
  2141 next
       
  2142   show "\<not> P (f 0)"
       
  2143     apply(simp add: f P steps.simps)
       
  2144     done
       
  2145 next
       
  2146   show "\<forall>n. \<not> P (f n) \<and> Q (f n) \<longrightarrow> Q (f (Suc n)) \<and> (f (Suc n), f n) 
       
  2147         \<in> inc_LE"
       
  2148   proof(rule_tac allI, rule_tac impI, simp add: f, 
       
  2149       case_tac "steps (Suc 0, l, r) (tinc_b, 0) n", simp add: P)
       
  2150     fix n a b c
       
  2151     assume "a \<noteq> 10 \<and> Q (a, b, c)"
       
  2152     thus  "Q (step (a, b, c) (tinc_b, 0)) \<and> (step (a, b, c) (tinc_b, 0), a, b, c) \<in> inc_LE"
       
  2153       apply(simp add:Q)
       
  2154       apply(simp add: inc_inv.simps)
       
  2155       apply(case_tac c, case_tac [2] aa)
       
  2156       apply(auto simp: Let_def step.simps tinc_b_def numeral_2_eq_2 numeral_3_eq_3  split: if_splits)
       
  2157       apply(simp_all add: inc_inv.simps inc_LE_def lex_triple_def lex_pair_def inc_measure_def numeral_5_eq_5
       
  2158                           numeral_6_eq_6 numeral_7_eq_7 numeral_8_eq_8 numeral_9_eq_9)         
       
  2159       done
       
  2160   qed
       
  2161 qed
       
  2162          
       
  2163 
       
  2164 lemma tinc_correct: 
       
  2165   assumes layout: "ly = layout_of ap"
       
  2166   and inv_start: "inv_locate_a (as, lm) (n, l, r) ires"
       
  2167   and lm': "lm' = abc_lm_s lm n (Suc (abc_lm_v lm n))"
       
  2168   shows "\<exists> stp l' r'. steps (Suc 0, l, r) (tinc_b, 0) stp = (10, l', r')
       
  2169               \<and> inv_stop (as, lm') (10, l', r') ires"
       
  2170   using assms
       
  2171   apply(drule_tac tinc_correct_pre, auto)
       
  2172   apply(rule_tac x = stp in exI, simp)
       
  2173   apply(simp add: inc_inv.simps)
       
  2174   done
       
  2175 
       
  2176 declare inv_locate_a.simps[simp del] abc_lm_s.simps[simp del]
       
  2177         abc_lm_v.simps[simp del]
       
  2178 
       
  2179 lemma [simp]: "(4::nat) * n mod 2 = 0"
       
  2180 apply(arith)
       
  2181 done
       
  2182 
       
  2183 lemma crsp_step_inc_pre:
       
  2184   assumes layout: "ly = layout_of ap"
       
  2185   and crsp: "crsp ly (as, lm) (s, l, r) ires"
       
  2186   and aexec: "abc_step_l (as, lm) (Some (Inc n)) = (asa, lma)"
       
  2187   shows "\<exists> stp k. steps (Suc 0, l, r) (findnth n @ shift tinc_b (2 * n), 0) stp 
       
  2188         = (2*n + 10, Bk # Bk # ires, <lma> @ Bk\<up>k) \<and> stp > 0"
       
  2189 proof -
       
  2190   thm tm_append_steps
       
  2191   have "\<exists> stp l' r'. steps (Suc 0, l, r) (findnth n, 0) stp = (Suc (2 * n), l', r')
       
  2192     \<and> inv_locate_a (as, lm) (n, l', r') ires"
       
  2193     using assms
       
  2194     apply(rule_tac findnth_correct, simp_all add: crsp layout)
       
  2195     done
       
  2196   from this obtain stp l' r' where a:
       
  2197     "steps (Suc 0, l, r) (findnth n, 0) stp = (Suc (2 * n), l', r')
       
  2198     \<and> inv_locate_a (as, lm) (n, l', r') ires" by blast
       
  2199   moreover have
       
  2200     "\<exists> stp la ra. steps (Suc 0, l', r') (tinc_b, 0) stp = (10, la, ra)
       
  2201                         \<and> inv_stop (as, lma) (10, la, ra) ires"
       
  2202     using assms a
       
  2203   proof(rule_tac lm' = lma and n = n and lm = lm and ly = ly and ap = ap in tinc_correct,
       
  2204       simp, simp)
       
  2205     show "lma = abc_lm_s lm n (Suc (abc_lm_v lm n))"
       
  2206       using aexec
       
  2207       apply(simp add: abc_step_l.simps)
       
  2208       done
       
  2209   qed
       
  2210   from this obtain stpa la ra where b:
       
  2211     "steps (Suc 0, l', r') (tinc_b, 0) stpa = (10, la, ra)
       
  2212     \<and> inv_stop (as, lma) (10, la, ra) ires" by blast
       
  2213   from a b show "\<exists>stp k. steps (Suc 0, l, r) (findnth n @ shift tinc_b (2 * n), 0) stp
       
  2214     = (2 * n + 10, Bk # Bk # ires, <lma> @ Bk \<up> k) \<and> stp > 0"
       
  2215     apply(rule_tac x = "stp + stpa" in exI)
       
  2216     using tm_append_steps[of "Suc 0" l r "findnth n" stp l' r' tinc_b stpa 10 la ra "length (findnth n) div 2"]
       
  2217     apply(simp add: length_findnth inv_stop.simps)
       
  2218     apply(case_tac stpa, simp_all add: steps.simps)
       
  2219     done
       
  2220 qed 
       
  2221      
       
  2222 lemma crsp_step_inc:
       
  2223   assumes layout: "ly = layout_of ap"
       
  2224   and crsp: "crsp ly (as, lm) (s, l, r) ires"
       
  2225   and fetch: "abc_fetch as ap = Some (Inc n)"
       
  2226   shows "\<exists>stp > 0. crsp ly (abc_step_l (as, lm) (Some (Inc n)))
       
  2227   (steps (s, l, r) (ci ly (start_of ly as) (Inc n), start_of ly as - Suc 0) stp) ires"
       
  2228 proof(case_tac "(abc_step_l (as, lm) (Some (Inc n)))")
       
  2229   fix a b
       
  2230   assume aexec: "abc_step_l (as, lm) (Some (Inc n)) = (a, b)"
       
  2231   then have "\<exists> stp k. steps (Suc 0, l, r) (findnth n @ shift tinc_b (2 * n), 0) stp 
       
  2232         = (2*n + 10, Bk # Bk # ires, <b> @ Bk\<up>k) \<and> stp > 0"
       
  2233     using assms
       
  2234     apply(rule_tac crsp_step_inc_pre, simp_all)
       
  2235     done
       
  2236   thus "?thesis"
       
  2237     using assms aexec
       
  2238     apply(erule_tac exE)
       
  2239     apply(erule_tac exE)
       
  2240     apply(erule_tac conjE)
       
  2241     apply(rule_tac x = stp in exI, simp add: ci.simps tm_shift_eq_steps)
       
  2242     apply(drule_tac off = "(start_of (layout_of ap) as - Suc 0)" in tm_shift_eq_steps)
       
  2243     apply(auto simp: crsp.simps abc_step_l.simps fetch start_of_Suc1)
       
  2244     done
       
  2245 qed
       
  2246     
       
  2247 subsection{* Crsp of Dec n e*}
       
  2248 declare sete.simps[simp del]
       
  2249 
       
  2250 type_synonym dec_inv_t = "(nat * nat list) \<Rightarrow> config \<Rightarrow> cell list \<Rightarrow>  bool"
       
  2251 
       
  2252 fun dec_first_on_right_moving :: "nat \<Rightarrow> dec_inv_t"
       
  2253   where
       
  2254   "dec_first_on_right_moving n (as, lm) (s, l, r) ires = 
       
  2255                (\<exists> lm1 lm2 m ml mr rn. lm = lm1 @ [m] @ lm2 \<and> 
       
  2256          ml + mr = Suc m \<and> length lm1 = n \<and> ml > 0 \<and> m > 0 \<and>
       
  2257              (if lm1 = [] then l = Oc\<up>ml @ Bk # Bk # ires
       
  2258                           else  l = Oc\<up>ml @ [Bk] @ <rev lm1> @ Bk # Bk # ires) \<and> 
       
  2259     ((r = Oc\<up>mr @ [Bk] @ <lm2> @ Bk\<up>rn) \<or> (r = Oc\<up>mr \<and> lm2 = [])))"
       
  2260 
       
  2261 fun dec_on_right_moving :: "dec_inv_t"
       
  2262   where
       
  2263   "dec_on_right_moving (as, lm) (s, l, r) ires =  
       
  2264    (\<exists> lm1 lm2 m ml mr rn. lm = lm1 @ [m] @ lm2 \<and> 
       
  2265                              ml + mr = Suc (Suc m) \<and>
       
  2266    (if lm1 = [] then l = Oc\<up>ml@ Bk # Bk # ires
       
  2267                 else  l = Oc\<up>ml @ [Bk] @ <rev lm1> @ Bk # Bk # ires) \<and> 
       
  2268    ((r = Oc\<up>mr @ [Bk] @ <lm2> @ Bk\<up>rn) \<or> (r = Oc\<up>mr \<and> lm2 = [])))"
       
  2269 
       
  2270 fun dec_after_clear :: "dec_inv_t"
       
  2271   where
       
  2272   "dec_after_clear (as, lm) (s, l, r) ires = 
       
  2273               (\<exists> lm1 lm2 m ml mr rn. lm = lm1 @ [m] @ lm2 \<and> 
       
  2274                 ml + mr = Suc m \<and> ml = Suc m \<and> r \<noteq> [] \<and> r \<noteq> [] \<and>
       
  2275                (if lm1 = [] then l = Oc\<up>ml@ Bk # Bk # ires
       
  2276                             else l = Oc\<up>ml @ [Bk] @ <rev lm1> @ Bk # Bk # ires) \<and> 
       
  2277                (tl r = Bk # <lm2> @ Bk\<up>rn \<or> tl r = [] \<and> lm2 = []))"
       
  2278 
       
  2279 fun dec_after_write :: "dec_inv_t"
       
  2280   where
       
  2281   "dec_after_write (as, lm) (s, l, r) ires = 
       
  2282          (\<exists> lm1 lm2 m ml mr rn. lm = lm1 @ [m] @ lm2 \<and> 
       
  2283        ml + mr = Suc m \<and> ml = Suc m \<and> lm2 \<noteq> [] \<and>
       
  2284        (if lm1 = [] then l = Bk # Oc\<up>ml @ Bk # Bk # ires
       
  2285                     else l = Bk # Oc\<up>ml @ [Bk] @ <rev lm1> @ Bk # Bk # ires) \<and> 
       
  2286        tl r = <lm2> @ Bk\<up>rn)"
       
  2287 
       
  2288 fun dec_right_move :: "dec_inv_t"
       
  2289   where
       
  2290   "dec_right_move (as, lm) (s, l, r) ires = 
       
  2291         (\<exists> lm1 lm2 m ml mr rn. lm = lm1 @ [m] @ lm2 
       
  2292             \<and> ml = Suc m \<and> mr = (0::nat) \<and> 
       
  2293               (if lm1 = [] then l = Bk # Oc\<up>ml @ Bk # Bk # ires
       
  2294                           else l = Bk # Oc\<up>ml @ [Bk] @ <rev lm1> @ Bk # Bk # ires) 
       
  2295            \<and> (r = Bk # <lm2> @ Bk\<up>rn \<or> r = [] \<and> lm2 = []))"
       
  2296 
       
  2297 fun dec_check_right_move :: "dec_inv_t"
       
  2298   where
       
  2299   "dec_check_right_move (as, lm) (s, l, r) ires = 
       
  2300         (\<exists> lm1 lm2 m ml mr rn. lm = lm1 @ [m] @ lm2 \<and> 
       
  2301            ml = Suc m \<and> mr = (0::nat) \<and> 
       
  2302            (if lm1 = [] then l = Bk # Bk # Oc\<up>ml @ Bk # Bk # ires
       
  2303                        else l = Bk # Bk # Oc\<up>ml @ [Bk] @ <rev lm1> @ Bk # Bk # ires) \<and> 
       
  2304            r = <lm2> @ Bk\<up>rn)"
       
  2305 
       
  2306 fun dec_left_move :: "dec_inv_t"
       
  2307   where
       
  2308   "dec_left_move (as, lm) (s, l, r) ires = 
       
  2309     (\<exists> lm1 m rn. (lm::nat list) = lm1 @ [m::nat] \<and>   
       
  2310     rn > 0 \<and> 
       
  2311    (if lm1 = [] then l = Bk # Oc\<up>Suc m @ Bk # Bk # ires
       
  2312     else l = Bk # Oc\<up>Suc m @ Bk # <rev lm1> @ Bk # Bk # ires) \<and> r = Bk\<up>rn)"
       
  2313 
       
  2314 declare
       
  2315   dec_on_right_moving.simps[simp del] dec_after_clear.simps[simp del] 
       
  2316   dec_after_write.simps[simp del] dec_left_move.simps[simp del] 
       
  2317   dec_check_right_move.simps[simp del] dec_right_move.simps[simp del] 
       
  2318   dec_first_on_right_moving.simps[simp del]
       
  2319 
       
  2320 fun inv_locate_n_b :: "inc_inv_t"
       
  2321   where
       
  2322   "inv_locate_n_b (as, lm) (s, l, r) ires= 
       
  2323     (\<exists> lm1 lm2 tn m ml mr rn. lm @ 0\<up>tn = lm1 @ [m] @ lm2 \<and> 
       
  2324      length lm1 = s \<and> m + 1 = ml + mr \<and> 
       
  2325      ml = 1 \<and> tn = s + 1 - length lm \<and>
       
  2326      (if lm1 = [] then l = Oc\<up>ml @ Bk # Bk # ires
       
  2327       else l = Oc\<up>ml @ Bk # <rev lm1> @ Bk # Bk # ires) \<and> 
       
  2328      (r = Oc\<up>mr @ [Bk] @ <lm2>@ Bk\<up>rn \<or> (lm2 = [] \<and> r = Oc\<up>mr))
       
  2329   )"
       
  2330 (*
       
  2331 fun dec_inv_1 :: "layout \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> dec_inv_t"
       
  2332   where
       
  2333   "dec_inv_1 ly n e (as, am) (s, l, r) ires = 
       
  2334            (let ss = start_of ly as in
       
  2335             let am' = abc_lm_s am n (abc_lm_v am n - Suc 0) in
       
  2336             let am'' = abc_lm_s am n (abc_lm_v am n) in
       
  2337               if s = start_of ly e then inv_stop (as, am'') (s, l, r) ires
       
  2338               else if s = ss then False
       
  2339               else if s = ss + 2 * n then 
       
  2340                   inv_locate_a (as, am) (n, l, r) ires
       
  2341                 \<or> inv_locate_a (as, am'') (n, l, r) ires
       
  2342               else if s = ss + 2 * n + 1 then 
       
  2343                   inv_locate_b (as, am) (n, l, r) ires
       
  2344               else if s = ss + 2 * n + 13 then 
       
  2345                   inv_on_left_moving (as, am'') (s, l, r) ires
       
  2346               else if s = ss + 2 * n + 14 then 
       
  2347                   inv_check_left_moving (as, am'') (s, l, r) ires
       
  2348               else if s = ss + 2 * n + 15 then 
       
  2349                   inv_after_left_moving (as, am'') (s, l, r) ires
       
  2350               else False)"
       
  2351 *)
       
  2352 
       
  2353 
       
  2354 fun dec_inv_1 :: "layout \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> dec_inv_t"
       
  2355   where
       
  2356   "dec_inv_1 ly n e (as, am) (s, l, r) ires = 
       
  2357            (let ss = start_of ly as in
       
  2358             let am' = abc_lm_s am n (abc_lm_v am n - Suc 0) in
       
  2359             let am'' = abc_lm_s am n (abc_lm_v am n) in
       
  2360               if s = start_of ly e then inv_stop (as, am'') (s, l, r) ires
       
  2361               else if s = ss then False
       
  2362               else if s = ss + 2 * n + 1 then 
       
  2363                   inv_locate_b (as, am) (n, l, r) ires
       
  2364               else if s = ss + 2 * n + 13 then 
       
  2365                   inv_on_left_moving (as, am'') (s, l, r) ires
       
  2366               else if s = ss + 2 * n + 14 then 
       
  2367                   inv_check_left_moving (as, am'') (s, l, r) ires
       
  2368               else if s = ss + 2 * n + 15 then 
       
  2369                   inv_after_left_moving (as, am'') (s, l, r) ires
       
  2370               else False)"
       
  2371 
       
  2372 declare fetch.simps[simp del]
       
  2373 lemma [simp]:
       
  2374   "fetch (ci ly (start_of ly as) (Dec n e)) (Suc (2 * n)) Bk = (W1,  start_of ly as + 2 *n)"
       
  2375 apply(auto simp: fetch.simps length_ci_dec)
       
  2376 apply(auto simp: ci.simps nth_append length_findnth sete.simps shift.simps tdec_b_def)
       
  2377 using startof_not0[of ly as] by simp
       
  2378 
       
  2379 lemma [simp]:
       
  2380   "fetch (ci ly (start_of ly as) (Dec n e)) (Suc (2 * n)) Oc = (R,  Suc (start_of ly as) + 2 *n)"
       
  2381 apply(auto simp: fetch.simps length_ci_dec)
       
  2382 apply(auto simp: ci.simps nth_append length_findnth sete.simps shift.simps tdec_b_def)
       
  2383 done
       
  2384 
       
  2385 lemma [simp]: 
       
  2386   "\<lbrakk>r = [] \<or> hd r = Bk; inv_locate_a (as, lm) (n, l, r) ires\<rbrakk>
       
  2387     \<Longrightarrow> \<exists>stp la ra.
       
  2388   steps (start_of ly as + 2 * n, l, r) (ci ly (start_of ly as) (Dec n e), 
       
  2389   start_of ly as - Suc 0) stp = (Suc (start_of ly as + 2 * n), la, ra) \<and>
       
  2390   inv_locate_b (as, lm) (n, la, ra) ires"
       
  2391 apply(rule_tac x = "Suc (Suc 0)" in exI)
       
  2392 apply(auto simp: steps.simps step.simps length_ci_dec)
       
  2393 apply(case_tac r, simp_all)
       
  2394 done
       
  2395 
       
  2396 lemma [simp]: 
       
  2397   "\<lbrakk>inv_locate_a (as, lm) (n, l, r) ires; r \<noteq> [] \<and> hd r \<noteq> Bk\<rbrakk>
       
  2398     \<Longrightarrow> \<exists>stp la ra.
       
  2399   steps (start_of ly as + 2 * n, l, r) (ci ly (start_of ly as) (Dec n e), 
       
  2400   start_of ly as - Suc 0) stp = (Suc (start_of ly as + 2 * n), la, ra) \<and>
       
  2401   inv_locate_b (as, lm) (n, la, ra) ires"
       
  2402 apply(rule_tac x = "(Suc 0)" in exI, case_tac "hd r", simp_all)
       
  2403 apply(auto simp: steps.simps step.simps length_ci_dec)
       
  2404 apply(case_tac r, simp_all)
       
  2405 done
       
  2406 
       
  2407 fun abc_dec_1_stage1:: "config \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
  2408   where
       
  2409   "abc_dec_1_stage1 (s, l, r) ss n = 
       
  2410        (if s > ss \<and> s \<le> ss + 2*n + 1 then 4
       
  2411         else if s = ss + 2 * n + 13 \<or> s = ss + 2*n + 14 then 3
       
  2412         else if s = ss + 2*n + 15 then 2
       
  2413         else 0)"
       
  2414 
       
  2415 fun abc_dec_1_stage2:: "config \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
  2416   where
       
  2417   "abc_dec_1_stage2 (s, l, r) ss n = 
       
  2418        (if s \<le> ss + 2 * n + 1 then (ss + 2 * n + 16 - s)
       
  2419         else if s = ss + 2*n + 13 then length l
       
  2420         else if s = ss + 2*n + 14 then length l
       
  2421         else 0)"
       
  2422 
       
  2423 fun abc_dec_1_stage3 :: "config \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
  2424   where
       
  2425   "abc_dec_1_stage3 (s, l, r) ss n  = 
       
  2426         (if s \<le> ss + 2*n + 1 then 
       
  2427              if (s - ss) mod 2 = 0 then 
       
  2428                          if r \<noteq> [] \<and> hd r = Oc then 0 else 1  
       
  2429                          else length r
       
  2430          else if s = ss + 2 * n + 13 then 
       
  2431              if r \<noteq> [] \<and> hd r = Oc then 2 
       
  2432              else 1
       
  2433          else if s = ss + 2 * n + 14 then 
       
  2434              if r \<noteq> [] \<and> hd r = Oc then 3 else 0 
       
  2435          else 0)"
       
  2436 
       
  2437 fun abc_dec_1_measure :: "(config \<times> nat \<times> nat) \<Rightarrow> (nat \<times> nat \<times> nat)"
       
  2438   where
       
  2439   "abc_dec_1_measure (c, ss, n) = (abc_dec_1_stage1 c ss n, 
       
  2440                    abc_dec_1_stage2 c ss n, abc_dec_1_stage3 c ss n)"
       
  2441 
       
  2442 definition abc_dec_1_LE ::
       
  2443   "((config \<times> nat \<times>
       
  2444   nat) \<times> (config \<times> nat \<times> nat)) set"
       
  2445   where "abc_dec_1_LE \<equiv> (inv_image lex_triple abc_dec_1_measure)"
       
  2446 
       
  2447 lemma wf_dec_le: "wf abc_dec_1_LE"
       
  2448 by(auto intro:wf_inv_image simp:abc_dec_1_LE_def lex_triple_def lex_pair_def)
       
  2449 
       
  2450 lemma startof_Suc2:
       
  2451   "abc_fetch as ap = Some (Dec n e) \<Longrightarrow> 
       
  2452         start_of (layout_of ap) (Suc as) = 
       
  2453             start_of (layout_of ap) as + 2 * n + 16"
       
  2454 apply(auto simp: start_of.simps layout_of.simps  
       
  2455                  length_of.simps abc_fetch.simps 
       
  2456                  take_Suc_conv_app_nth split: if_splits)
       
  2457 done
       
  2458 
       
  2459 lemma start_of_less_2: 
       
  2460   "start_of ly e \<le> start_of ly (Suc e)"
       
  2461 thm take_Suc
       
  2462 apply(case_tac "e < length ly")
       
  2463 apply(auto simp: start_of.simps take_Suc take_Suc_conv_app_nth)
       
  2464 done
       
  2465 
       
  2466 lemma start_of_less_1: "start_of ly e \<le> start_of ly (e + d)"
       
  2467 proof(induct d)
       
  2468   case 0 thus "?case" by simp
       
  2469 next
       
  2470   case (Suc d)
       
  2471   have "start_of ly e \<le> start_of ly (e + d)"  by fact
       
  2472   moreover have "start_of ly (e + d) \<le> start_of ly (Suc (e + d))"
       
  2473     by(rule_tac start_of_less_2)
       
  2474   ultimately show"?case"
       
  2475     by(simp)
       
  2476 qed
       
  2477 
       
  2478 lemma start_of_less: 
       
  2479   assumes "e < as"
       
  2480   shows "start_of ly e \<le> start_of ly as"
       
  2481 proof -
       
  2482   obtain d where " as = e + d"
       
  2483     using assms by (metis less_imp_add_positive)
       
  2484   thus "?thesis"
       
  2485     by(simp add: start_of_less_1)
       
  2486 qed
       
  2487 
       
  2488 lemma start_of_ge: 
       
  2489   assumes fetch: "abc_fetch as ap = Some (Dec n e)"
       
  2490   and layout: "ly = layout_of ap"
       
  2491   and great: "e > as"
       
  2492   shows "start_of ly e \<ge> start_of ly as + 2*n + 16"
       
  2493 proof(cases "e = Suc as")
       
  2494   case True
       
  2495   have "e = Suc as" by fact
       
  2496   moreover hence "start_of ly (Suc as) = start_of ly as + 2*n + 16"
       
  2497     using layout fetch
       
  2498     by(simp add: startof_Suc2)
       
  2499   ultimately show "?thesis" by (simp)
       
  2500 next
       
  2501   case False
       
  2502   have "e \<noteq> Suc as" by fact
       
  2503   then have "e > Suc as" using great by arith
       
  2504   then have "start_of ly (Suc as) \<le> start_of ly e"
       
  2505     by(simp add: start_of_less)
       
  2506   moreover have "start_of ly (Suc as) = start_of ly as + 2*n + 16"
       
  2507     using layout fetch
       
  2508     by(simp add: startof_Suc2)
       
  2509   ultimately show "?thesis"
       
  2510     by arith
       
  2511 qed
       
  2512     
       
  2513 lemma [elim]: "\<lbrakk>abc_fetch as ap = Some (Dec n e); as < e; 
       
  2514   Suc (start_of (layout_of ap) as + 2 * n) = start_of (layout_of ap) e\<rbrakk> \<Longrightarrow> RR"
       
  2515 apply(drule_tac start_of_ge, simp_all)
       
  2516 apply(auto)
       
  2517 done
       
  2518 
       
  2519 lemma [elim]: "\<lbrakk>abc_fetch as ap = Some (Dec n e); as > e;
       
  2520   Suc (start_of (layout_of ap) as + 2 * n) = start_of (layout_of ap) e\<rbrakk> \<Longrightarrow> RR"
       
  2521 apply(drule_tac ly = "layout_of ap" in start_of_less[of])
       
  2522 apply(arith)
       
  2523 done
       
  2524 
       
  2525 lemma [elim]: "\<lbrakk>abc_fetch as ap = Some (Dec n e);
       
  2526   Suc (start_of (layout_of ap) as + 2 * n) = start_of (layout_of ap) e\<rbrakk> \<Longrightarrow> RR"
       
  2527 apply(subgoal_tac "as = e \<or> as < e \<or> as > e", auto)
       
  2528 done
       
  2529 
       
  2530 lemma [simp]:"fetch (ci (ly) (start_of ly as) (Dec n e)) (Suc (2 * n))  Oc
       
  2531   = (R, start_of ly as + 2*n + 1)"
       
  2532 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2533                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2534 done
       
  2535 
       
  2536 lemma [simp]: "(start_of ly as = 0) = False"
       
  2537 apply(simp add: start_of.simps)
       
  2538 done
       
  2539 
       
  2540 lemma [simp]: "fetch (ci (ly) 
       
  2541   (start_of ly as) (Dec n e)) (Suc (2 * n))  Bk
       
  2542   = (W1, start_of ly as + 2*n)"
       
  2543 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2544                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2545 done
       
  2546 
       
  2547 lemma [simp]: 
       
  2548   "fetch (ci (ly) 
       
  2549                 (start_of ly as) (Dec n e)) (Suc (Suc (2 * n)))  Oc
       
  2550       = (R, start_of ly as + 2*n + 2)"
       
  2551 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2552                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2553 done
       
  2554 
       
  2555 
       
  2556 lemma [simp]: "fetch (ci (ly) 
       
  2557                   (start_of ly as) (Dec n e)) (Suc (Suc (2 * n))) Bk
       
  2558       = (L, start_of ly as + 2*n + 13)"
       
  2559 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2560                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2561 done
       
  2562 
       
  2563 
       
  2564 lemma [simp]: "fetch (ci (ly) 
       
  2565              (start_of ly as) (Dec n e)) (Suc (Suc (Suc (2 * n))))  Oc
       
  2566      = (R, start_of ly as + 2*n + 2)"
       
  2567 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2568                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2569 done
       
  2570 
       
  2571 
       
  2572 lemma [simp]: "fetch (ci (ly) (start_of ly as) (Dec n e)) 
       
  2573                              (Suc (Suc (Suc (2 * n))))  Bk
       
  2574      = (L, start_of ly as + 2*n + 3)"
       
  2575 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2576                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2577 done
       
  2578 
       
  2579 lemma [simp]:
       
  2580      "fetch (ci (ly) 
       
  2581                       (start_of ly as) (Dec n e)) (2 * n + 4) Oc
       
  2582     = (W0, start_of ly as + 2*n + 3)"
       
  2583 apply(subgoal_tac "2*n + 4 = Suc (2*n + 3)", simp only: fetch.simps)
       
  2584 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2585                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2586 done
       
  2587 
       
  2588 lemma [simp]: "fetch (ci (ly) 
       
  2589                    (start_of ly as) (Dec n e)) (2 * n + 4) Bk
       
  2590     = (R, start_of ly as + 2*n + 4)"
       
  2591 apply(subgoal_tac "2*n + 4 = Suc (2*n + 3)", simp only: fetch.simps)
       
  2592 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2593                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2594 done
       
  2595 
       
  2596 lemma [simp]:"fetch (ci (ly) 
       
  2597                           (start_of ly as) (Dec n e)) (2 * n + 5) Bk
       
  2598     = (R, start_of ly as + 2*n + 5)"
       
  2599 apply(subgoal_tac "2*n + 5 = Suc (2*n + 4)", simp only: fetch.simps)
       
  2600 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2601                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2602 done
       
  2603 
       
  2604 
       
  2605 lemma [simp]: 
       
  2606   "fetch (ci (ly)
       
  2607                 (start_of ly as) (Dec n e)) (2 * n + 6) Bk
       
  2608     = (L, start_of ly as + 2*n + 6)"
       
  2609 apply(subgoal_tac "2*n + 6 = Suc (2*n + 5)", simp only: fetch.simps)
       
  2610 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2611                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2612 done
       
  2613 
       
  2614 lemma [simp]: 
       
  2615   "fetch (ci (ly) (start_of ly as) 
       
  2616                       (Dec n e)) (2 * n + 6) Oc
       
  2617     = (L, start_of ly as + 2*n + 7)"
       
  2618 apply(subgoal_tac "2*n + 6 = Suc (2*n + 5)", simp only: fetch.simps)
       
  2619 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2620                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2621 done
       
  2622 
       
  2623 lemma [simp]:"fetch (ci (ly) 
       
  2624              (start_of ly as) (Dec n e)) (2 * n + 7) Bk
       
  2625     = (L, start_of ly as + 2*n + 10)"
       
  2626 apply(subgoal_tac "2*n + 7 = Suc (2*n + 6)", simp only: fetch.simps)
       
  2627 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2628                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2629 done
       
  2630 
       
  2631 lemma [simp]:
       
  2632   "fetch (ci (ly) 
       
  2633                    (start_of ly as) (Dec n e)) (2 * n + 8) Bk
       
  2634     = (W1, start_of ly as + 2*n + 7)"
       
  2635 apply(subgoal_tac "2*n + 8 = Suc (2*n + 7)", simp only: fetch.simps)
       
  2636 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2637                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2638 done
       
  2639 
       
  2640 
       
  2641 lemma [simp]: 
       
  2642   "fetch (ci (ly) 
       
  2643                    (start_of ly as) (Dec n e)) (2 * n + 8) Oc
       
  2644     = (R, start_of ly as + 2*n + 8)"
       
  2645 apply(subgoal_tac "2*n + 8 = Suc (2*n + 7)", simp only: fetch.simps)
       
  2646 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2647                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2648 done
       
  2649 
       
  2650 lemma [simp]: 
       
  2651   "fetch (ci (ly) 
       
  2652   (start_of ly as) (Dec n e)) (2 * n + 9) Bk
       
  2653   = (L, start_of ly as + 2*n + 9)"
       
  2654 apply(subgoal_tac "2*n + 9 = Suc (2*n + 8)", simp only: fetch.simps)
       
  2655 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2656                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2657 done
       
  2658 
       
  2659 lemma [simp]: 
       
  2660   "fetch (ci (ly) 
       
  2661   (start_of ly as) (Dec n e)) (2 * n + 9) Oc
       
  2662   = (R, start_of ly as + 2*n + 8)"
       
  2663 apply(subgoal_tac "2*n + 9 = Suc (2*n + 8)", simp only: fetch.simps)
       
  2664 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2665                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2666 done
       
  2667 
       
  2668 
       
  2669 lemma [simp]: 
       
  2670   "fetch (ci (ly) 
       
  2671   (start_of ly as) (Dec n e)) (2 * n + 10) Bk
       
  2672   = (R, start_of ly as + 2*n + 4)" 
       
  2673 apply(subgoal_tac "2*n + 10 = Suc (2*n + 9)", simp only: fetch.simps)
       
  2674 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2675                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2676 done
       
  2677 
       
  2678 lemma [simp]: "fetch (ci (ly) 
       
  2679              (start_of ly as) (Dec n e)) (2 * n + 10) Oc
       
  2680     = (W0, start_of ly as + 2*n + 9)"
       
  2681 apply(subgoal_tac "2*n + 10 = Suc (2*n + 9)", simp only: fetch.simps)
       
  2682 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2683                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2684 done
       
  2685 
       
  2686 
       
  2687 lemma [simp]: 
       
  2688   "fetch (ci (ly) 
       
  2689   (start_of ly as) (Dec n e)) (2 * n + 11) Oc
       
  2690   = (L, start_of ly as + 2*n + 10)"
       
  2691 apply(subgoal_tac "2*n + 11 = Suc (2*n + 10)", simp only: fetch.simps)
       
  2692 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2693                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2694 done
       
  2695 
       
  2696 
       
  2697 lemma [simp]: 
       
  2698   "fetch (ci (ly) 
       
  2699   (start_of ly as) (Dec n e)) (2 * n + 11) Bk
       
  2700   = (L, start_of ly as + 2*n + 11)"
       
  2701 apply(subgoal_tac "2*n + 11 = Suc (2*n + 10)", simp only: fetch.simps)
       
  2702 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2703                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2704 done
       
  2705 
       
  2706 lemma [simp]:
       
  2707   "fetch (ci (ly) 
       
  2708   (start_of ly as) (Dec n e)) (2 * n + 12) Oc
       
  2709   = (L, start_of ly as + 2*n + 10)"
       
  2710 apply(subgoal_tac "2*n + 12 = Suc (2*n + 11)", simp only: fetch.simps)
       
  2711 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2712                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2713 done
       
  2714 
       
  2715 
       
  2716 lemma [simp]: 
       
  2717   "fetch (ci (ly) 
       
  2718   (start_of ly as) (Dec n e)) (2 * n + 12) Bk
       
  2719   = (R, start_of ly as + 2*n + 12)"
       
  2720 apply(subgoal_tac "2*n + 12 = Suc (2*n + 11)", simp only: fetch.simps)
       
  2721 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2722                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2723 done
       
  2724 
       
  2725 lemma [simp]: 
       
  2726   "fetch (ci (ly) 
       
  2727   (start_of ly as) (Dec n e)) (2 * n + 13) Bk
       
  2728   = (R, start_of ly as + 2*n + 16)"
       
  2729 apply(subgoal_tac "2*n + 13 = Suc (2*n + 12)", simp only: fetch.simps)
       
  2730 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2731                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2732 done
       
  2733 
       
  2734 
       
  2735 lemma [simp]: 
       
  2736   "fetch (ci (ly) 
       
  2737   (start_of ly as) (Dec n e)) (14 + 2 * n) Oc
       
  2738   = (L, start_of ly as + 2*n + 13)"
       
  2739 apply(subgoal_tac "14 + 2*n = Suc (2*n + 13)", simp only: fetch.simps)
       
  2740 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2741                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2742 done
       
  2743 
       
  2744 lemma [simp]: 
       
  2745   "fetch (ci (ly) 
       
  2746   (start_of ly as) (Dec n e)) (14 + 2 * n) Bk
       
  2747   = (L, start_of ly as + 2*n + 14)"
       
  2748 apply(subgoal_tac "14 + 2*n = Suc (2*n + 13)", simp only: fetch.simps)
       
  2749 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2750                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2751 done
       
  2752 
       
  2753 lemma [simp]: 
       
  2754   "fetch (ci (ly) 
       
  2755   (start_of ly as) (Dec n e)) (15 + 2 * n)  Oc
       
  2756   = (L, start_of ly as + 2*n + 13)"
       
  2757 apply(subgoal_tac "15 + 2*n = Suc (2*n + 14)", simp only: fetch.simps)
       
  2758 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2759                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2760 done
       
  2761 
       
  2762 lemma [simp]: 
       
  2763   "fetch (ci (ly) 
       
  2764   (start_of ly as) (Dec n e)) (15 + 2 * n)  Bk
       
  2765  = (R, start_of ly as + 2*n + 15)"
       
  2766 apply(subgoal_tac "15 + 2*n = Suc (2*n + 14)", simp only: fetch.simps)
       
  2767 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2768                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2769 done
       
  2770 
       
  2771 lemma [simp]: 
       
  2772   "abc_fetch as aprog = Some (Dec n e) \<Longrightarrow> 
       
  2773      fetch (ci (ly) (start_of (ly) as) 
       
  2774               (Dec n e)) (16 + 2 * n)  Bk
       
  2775  = (R, start_of (ly) e)"
       
  2776 apply(subgoal_tac "16 + 2*n = Suc (2*n + 15)", simp only: fetch.simps)
       
  2777 apply(auto simp: ci.simps findnth.simps fetch.simps
       
  2778                   nth_of.simps shift.simps nth_append tdec_b_def length_findnth sete.simps)
       
  2779 done
       
  2780 
       
  2781 declare dec_inv_1.simps[simp del]
       
  2782 
       
  2783 
       
  2784 lemma [simp]: 
       
  2785  "\<lbrakk>abc_fetch as aprog = Some (Dec n e); ly = layout_of aprog\<rbrakk>
       
  2786    \<Longrightarrow> (start_of ly e \<noteq> Suc (start_of ly as + 2 * n) \<and>
       
  2787         start_of ly e \<noteq> Suc (Suc (start_of ly as + 2 * n)) \<and>  
       
  2788         start_of ly e \<noteq> start_of ly as + 2 * n + 3 \<and> 
       
  2789         start_of ly e \<noteq> start_of ly as + 2 * n + 4 \<and>
       
  2790         start_of ly e \<noteq> start_of ly as + 2 * n + 5 \<and> 
       
  2791         start_of ly e \<noteq> start_of ly as + 2 * n + 6 \<and> 
       
  2792         start_of ly e \<noteq> start_of ly as + 2 * n + 7 \<and>
       
  2793         start_of ly e \<noteq> start_of ly as + 2 * n + 8 \<and> 
       
  2794         start_of ly e \<noteq> start_of ly as + 2 * n + 9 \<and> 
       
  2795         start_of ly e \<noteq> start_of ly as + 2 * n + 10 \<and>
       
  2796         start_of ly e \<noteq> start_of ly as + 2 * n + 11 \<and> 
       
  2797         start_of ly e \<noteq> start_of ly as + 2 * n + 12 \<and> 
       
  2798         start_of ly e \<noteq> start_of ly as + 2 * n + 13 \<and>
       
  2799         start_of ly e \<noteq> start_of ly as + 2 * n + 14 \<and> 
       
  2800         start_of ly e \<noteq> start_of ly as + 2 * n + 15)"
       
  2801 using start_of_ge[of as aprog n e ly] start_of_less[of e as ly]
       
  2802 apply(case_tac "e < as", simp)
       
  2803 apply(case_tac "e = as", simp, simp)
       
  2804 done
       
  2805 
       
  2806 lemma [simp]: "\<lbrakk>abc_fetch as aprog = Some (Dec n e); ly = layout_of aprog\<rbrakk>
       
  2807       \<Longrightarrow> (Suc (start_of ly as + 2 * n) \<noteq> start_of ly e \<and>
       
  2808           Suc (Suc (start_of ly as + 2 * n)) \<noteq> start_of ly e \<and> 
       
  2809           start_of ly as + 2 * n + 3 \<noteq> start_of ly e \<and> 
       
  2810           start_of ly as + 2 * n + 4 \<noteq> start_of ly e \<and>
       
  2811           start_of ly as + 2 * n + 5 \<noteq>start_of ly e \<and> 
       
  2812           start_of ly as + 2 * n + 6 \<noteq> start_of ly e \<and>
       
  2813           start_of ly as + 2 * n + 7 \<noteq> start_of ly e \<and> 
       
  2814           start_of ly as + 2 * n + 8 \<noteq> start_of ly e \<and> 
       
  2815           start_of ly as + 2 * n + 9 \<noteq> start_of ly e \<and> 
       
  2816           start_of ly as + 2 * n + 10 \<noteq> start_of ly e \<and>
       
  2817           start_of ly as + 2 * n + 11 \<noteq> start_of ly e \<and> 
       
  2818           start_of ly as + 2 * n + 12 \<noteq> start_of ly e \<and> 
       
  2819           start_of ly as + 2 * n + 13 \<noteq> start_of ly e \<and> 
       
  2820           start_of ly as + 2 * n + 14 \<noteq> start_of ly e \<and> 
       
  2821           start_of ly as + 2 * n + 15 \<noteq> start_of ly e)"
       
  2822 using start_of_ge[of as aprog n e ly] start_of_less[of e as ly]
       
  2823 apply(case_tac "e < as", simp, simp)
       
  2824 apply(case_tac "e = as", simp, simp)
       
  2825 done
       
  2826 
       
  2827 lemma [simp]: "inv_locate_b (as, lm) (n, [], []) ires = False"
       
  2828 apply(auto simp: inv_locate_b.simps in_middle.simps split: if_splits)
       
  2829 done
       
  2830 
       
  2831 lemma [simp]: "inv_locate_b (as, lm) (n, [], Bk # list) ires = False"
       
  2832 apply(auto simp: inv_locate_b.simps in_middle.simps split: if_splits)
       
  2833 done
       
  2834 
       
  2835 (*
       
  2836 
       
  2837 lemma  inv_locate_b_2_on_left_moving_b[simp]: 
       
  2838    "inv_locate_b (as, am) (n, l, []) ires
       
  2839      \<Longrightarrow> inv_on_left_moving (as, 
       
  2840                   abc_lm_s am n (abc_lm_v am n)) (s, [], [Bk]) ires"
       
  2841 apply(auto simp: inv_locate_b.simps inv_on_left_moving.simps inv_on_left_moving_in_middle_B.simps
       
  2842                  in_middle.simps split: if_splits)
       
  2843 apply(drule_tac length_equal, simp)
       
  2844 
       
  2845 apply(insert inv_locate_b_2_on_left_moving[of as am n l "[]" ires s])
       
  2846 apply(simp only: inv_on_left_moving.simps, simp)
       
  2847 apply(subgoal_tac "\<not> inv_on_left_moving_in_middle_B 
       
  2848          (as, abc_lm_s am n (abc_lm_v am n)) (s, tl l, [hd l]) ires", simp)
       
  2849 *)
       
  2850 
       
  2851 (*
       
  2852 lemma [simp]:
       
  2853   "inv_locate_b (as, am) (n, l, []) ires; l \<noteq> []\<rbrakk>
       
  2854  \<Longrightarrow> inv_on_left_moving (as, abc_lm_s am n 
       
  2855                   (abc_lm_v am n)) (s, tl l, [hd l]) ires"
       
  2856 apply(auto simp: inv_locate_b.simps inv_on_left_moving.simps inv_on_left_moving_in_middle_B.simps
       
  2857                  in_middle.simps split: if_splits)
       
  2858 apply(drule_tac length_equal, simp)
       
  2859 
       
  2860 apply(insert inv_locate_b_2_on_left_moving[of as am n l "[]" ires s])
       
  2861 apply(simp only: inv_on_left_moving.simps, simp)
       
  2862 apply(subgoal_tac "\<not> inv_on_left_moving_in_middle_B 
       
  2863          (as, abc_lm_s am n (abc_lm_v am n)) (s, tl l, [hd l]) ires", simp)
       
  2864 
       
  2865 apply(insert inv_locate_b_2_on_left_moving[of as am n l "[]" ires s])
       
  2866 apply(simp only: inv_on_left_moving.simps, simp)
       
  2867 apply(subgoal_tac "\<not> inv_on_left_moving_in_middle_B 
       
  2868          (as, abc_lm_s am n (abc_lm_v am n)) (s, tl l, [hd l]) ires", simp)
       
  2869 apply(simp only: inv_on_left_moving_norm.simps)
       
  2870 apply(erule_tac exE)+
       
  2871 apply(erule_tac conjE)+
       
  2872 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  2873       rule_tac x = m in exI, rule_tac x = ml in exI, 
       
  2874       rule_tac x = mr in exI, simp)
       
  2875 apply(case_tac mr, simp, simp, case_tac nat, auto intro: nil_2_nil)
       
  2876 done
       
  2877 *)
       
  2878 
       
  2879 lemma [simp]: 
       
  2880  "\<lbrakk>dec_first_on_right_moving n (as, am) (s, aaa, Oc # xs) ires\<rbrakk>
       
  2881    \<Longrightarrow> dec_first_on_right_moving n (as, am) (s', Oc # aaa, xs) ires"
       
  2882 apply(simp only: dec_first_on_right_moving.simps)
       
  2883 apply(erule exE)+
       
  2884 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  2885       rule_tac x = m in exI, simp)
       
  2886 apply(rule_tac x = "Suc ml" in exI, 
       
  2887       rule_tac x = "mr - 1" in exI, auto)
       
  2888 apply(case_tac [!] mr, auto)
       
  2889 done
       
  2890 
       
  2891 lemma [simp]: 
       
  2892   "dec_first_on_right_moving n (as, am) (s, l, Bk # xs) ires \<Longrightarrow> l \<noteq> []"
       
  2893 apply(auto simp: dec_first_on_right_moving.simps split: if_splits)
       
  2894 done
       
  2895 
       
  2896 lemma [elim]: 
       
  2897   "\<lbrakk>\<not> length lm1 < length am; 
       
  2898     am @ replicate (length lm1 - length am) 0 @ [0::nat] = 
       
  2899                                                 lm1 @ m # lm2;
       
  2900     0 < m\<rbrakk>
       
  2901    \<Longrightarrow> RR"
       
  2902 apply(subgoal_tac "lm2 = []", simp)
       
  2903 apply(drule_tac length_equal, simp)
       
  2904 done
       
  2905 
       
  2906 lemma [simp]: 
       
  2907  "\<lbrakk>dec_first_on_right_moving n (as, 
       
  2908                    abc_lm_s am n (abc_lm_v am n)) (s, l, Bk # xs) ires\<rbrakk>
       
  2909 \<Longrightarrow> dec_after_clear (as, abc_lm_s am n 
       
  2910                  (abc_lm_v am n - Suc 0)) (s', tl l, hd l # Bk # xs) ires"
       
  2911 apply(simp only: dec_first_on_right_moving.simps 
       
  2912                  dec_after_clear.simps abc_lm_s.simps abc_lm_v.simps)
       
  2913 apply(erule_tac exE)+
       
  2914 apply(case_tac "n < length am")
       
  2915 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  2916       rule_tac x = "m - 1" in exI, auto simp: )
       
  2917 apply(case_tac [!] mr, auto)
       
  2918 done
       
  2919 
       
  2920 lemma [simp]: 
       
  2921  "\<lbrakk>dec_first_on_right_moving n (as, 
       
  2922                    abc_lm_s am n (abc_lm_v am n)) (s, l, []) ires\<rbrakk>
       
  2923 \<Longrightarrow> (l = [] \<longrightarrow> dec_after_clear (as, 
       
  2924              abc_lm_s am n (abc_lm_v am n - Suc 0)) (s', [], [Bk]) ires) \<and>
       
  2925     (l \<noteq> [] \<longrightarrow> dec_after_clear (as, abc_lm_s am n 
       
  2926                       (abc_lm_v am n - Suc 0)) (s', tl l, [hd l]) ires)"
       
  2927 apply(subgoal_tac "l \<noteq> []", 
       
  2928       simp only: dec_first_on_right_moving.simps 
       
  2929                  dec_after_clear.simps abc_lm_s.simps abc_lm_v.simps)
       
  2930 apply(erule_tac exE)+
       
  2931 apply(case_tac "n < length am", simp)
       
  2932 apply(rule_tac x = lm1 in exI, rule_tac x = "m - 1" in exI, auto)
       
  2933 apply(case_tac [1-2] m, auto)
       
  2934 apply(auto simp: dec_first_on_right_moving.simps split: if_splits)
       
  2935 done
       
  2936 
       
  2937 lemma [simp]: "\<lbrakk>dec_after_clear (as, am) (s, l, Oc # r) ires\<rbrakk>
       
  2938                 \<Longrightarrow> dec_after_clear (as, am) (s', l, Bk # r) ires"
       
  2939 apply(auto simp: dec_after_clear.simps)
       
  2940 done
       
  2941 
       
  2942 lemma [simp]: "\<lbrakk>dec_after_clear (as, am) (s, l, Bk # r) ires\<rbrakk>
       
  2943                 \<Longrightarrow> dec_right_move (as, am) (s', Bk # l, r) ires"
       
  2944 apply(auto simp: dec_after_clear.simps dec_right_move.simps split: if_splits)
       
  2945 done
       
  2946 
       
  2947 lemma [simp]: "\<lbrakk>dec_after_clear (as, am) (s, l, []) ires\<rbrakk>
       
  2948              \<Longrightarrow> dec_right_move (as, am) (s', Bk # l, []) ires"
       
  2949 apply(auto simp: dec_after_clear.simps dec_right_move.simps )
       
  2950 done
       
  2951 
       
  2952 lemma [simp]: "\<lbrakk>dec_after_clear (as, am) (s, l, []) ires\<rbrakk>
       
  2953              \<Longrightarrow> dec_right_move (as, am) (s', Bk # l, [Bk]) ires"
       
  2954 apply(auto simp: dec_after_clear.simps dec_right_move.simps split: if_splits)
       
  2955 done
       
  2956 
       
  2957 lemma [simp]:"dec_right_move (as, am) (s, l, Oc # r) ires = False"
       
  2958 apply(auto simp: dec_right_move.simps)
       
  2959 done
       
  2960               
       
  2961 lemma dec_right_move_2_check_right_move[simp]:
       
  2962      "\<lbrakk>dec_right_move (as, am) (s, l, Bk # r) ires\<rbrakk>
       
  2963       \<Longrightarrow> dec_check_right_move (as, am) (s', Bk # l, r) ires"
       
  2964 apply(auto simp: dec_right_move.simps dec_check_right_move.simps split: if_splits)
       
  2965 done
       
  2966 
       
  2967 lemma [simp]: "(<lm::nat list> = []) = (lm = [])"
       
  2968 apply(case_tac lm, simp_all add: tape_of_nl_cons)
       
  2969 done
       
  2970 
       
  2971 lemma [simp]: 
       
  2972  "dec_right_move (as, am) (s, l, []) ires= 
       
  2973   dec_right_move (as, am) (s, l, [Bk]) ires"
       
  2974 apply(simp add: dec_right_move.simps)
       
  2975 done
       
  2976 
       
  2977 lemma [simp]: "\<lbrakk>dec_right_move (as, am) (s, l, []) ires\<rbrakk>
       
  2978              \<Longrightarrow> dec_check_right_move (as, am) (s, Bk # l, []) ires"
       
  2979 apply(insert dec_right_move_2_check_right_move[of as am s l "[]" s'], 
       
  2980       simp)
       
  2981 done
       
  2982 
       
  2983 lemma [simp]: "dec_check_right_move (as, am) (s, l, r) ires\<Longrightarrow> l \<noteq> []"
       
  2984 apply(auto simp: dec_check_right_move.simps split: if_splits)
       
  2985 done
       
  2986  
       
  2987 lemma [simp]: "\<lbrakk>dec_check_right_move (as, am) (s, l, Oc # r) ires\<rbrakk>
       
  2988              \<Longrightarrow> dec_after_write (as, am) (s', tl l, hd l # Oc # r) ires"
       
  2989 apply(auto simp: dec_check_right_move.simps dec_after_write.simps)
       
  2990 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  2991       rule_tac x = m in exI, auto)
       
  2992 done
       
  2993 
       
  2994 
       
  2995 
       
  2996 lemma [simp]: "\<lbrakk>dec_check_right_move (as, am) (s, l, Bk # r) ires\<rbrakk>
       
  2997                 \<Longrightarrow> dec_left_move (as, am) (s', tl l, hd l # Bk # r) ires"
       
  2998 apply(auto simp: dec_check_right_move.simps 
       
  2999                  dec_left_move.simps inv_after_move.simps)
       
  3000 apply(rule_tac x = lm1 in exI, rule_tac x = m in exI, auto split: if_splits)
       
  3001 apply(case_tac [!] lm2, simp_all add: tape_of_nl_cons split: if_splits)
       
  3002 apply(rule_tac [!] x = "(Suc rn)" in exI, simp_all)
       
  3003 done
       
  3004 
       
  3005 lemma [simp]: "\<lbrakk>dec_check_right_move (as, am) (s, l, []) ires\<rbrakk>
       
  3006              \<Longrightarrow> dec_left_move (as, am) (s', tl l, [hd l]) ires"
       
  3007 apply(auto simp: dec_check_right_move.simps 
       
  3008                  dec_left_move.simps inv_after_move.simps)
       
  3009 apply(rule_tac x = lm1 in exI, rule_tac x = m in exI, auto)
       
  3010 done
       
  3011 
       
  3012 lemma [simp]: "dec_left_move (as, am) (s, aaa, Oc # xs) ires = False"
       
  3013 apply(auto simp: dec_left_move.simps inv_after_move.simps)
       
  3014 done
       
  3015 
       
  3016 lemma [simp]: "dec_left_move (as, am) (s, l, r) ires
       
  3017              \<Longrightarrow> l \<noteq> []"
       
  3018 apply(auto simp: dec_left_move.simps split: if_splits)
       
  3019 done
       
  3020 
       
  3021 lemma [simp]: "inv_on_left_moving_in_middle_B (as, [m])
       
  3022   (s', Oc # Oc\<up>m @ Bk # Bk # ires, Bk # Bk\<up>rn) ires"
       
  3023 apply(simp add: inv_on_left_moving_in_middle_B.simps)
       
  3024 apply(rule_tac x = "[m]" in exI, auto)
       
  3025 done
       
  3026 
       
  3027 lemma [simp]: "inv_on_left_moving_in_middle_B (as, [m])
       
  3028   (s', Oc # Oc\<up>m @ Bk # Bk # ires, [Bk]) ires"
       
  3029 apply(simp add: inv_on_left_moving_in_middle_B.simps)
       
  3030 done
       
  3031 
       
  3032 
       
  3033 lemma [simp]: "lm1 \<noteq> [] \<Longrightarrow> 
       
  3034   inv_on_left_moving_in_middle_B (as, lm1 @ [m]) (s', 
       
  3035   Oc # Oc\<up>m @ Bk # <rev lm1> @ Bk # Bk # ires, Bk # Bk\<up>rn) ires"
       
  3036 apply(simp only: inv_on_left_moving_in_middle_B.simps)
       
  3037 apply(rule_tac x = "lm1 @ [m ]" in exI, rule_tac x = "[]" in exI, simp)
       
  3038 apply(simp add: tape_of_nl_cons split: if_splits)
       
  3039 done
       
  3040 
       
  3041 lemma [simp]: "lm1 \<noteq> [] \<Longrightarrow> 
       
  3042   inv_on_left_moving_in_middle_B (as, lm1 @ [m]) (s', 
       
  3043   Oc # Oc\<up> m @ Bk # <rev lm1> @ Bk # Bk # ires, [Bk]) ires"
       
  3044 apply(simp only: inv_on_left_moving_in_middle_B.simps)
       
  3045 apply(rule_tac x = "lm1 @ [m ]" in exI, rule_tac x = "[]" in exI, simp)
       
  3046 apply(simp add: tape_of_nl_cons split: if_splits)
       
  3047 done
       
  3048 
       
  3049 lemma [simp]: "dec_left_move (as, am) (s, l, Bk # r) ires
       
  3050        \<Longrightarrow> inv_on_left_moving (as, am) (s', tl l, hd l # Bk # r) ires"
       
  3051 apply(auto simp: dec_left_move.simps inv_on_left_moving.simps split: if_splits)
       
  3052 done
       
  3053 
       
  3054 (*
       
  3055 lemma [simp]: "inv_on_left_moving_in_middle_B (as, lm1 @ [m]) 
       
  3056                         (s', Oc # Oc\<^bsup>m\<^esup> @ Bk # <rev lm1> @ Bk\<^bsup>ln\<^esup>, [Bk])  ires"
       
  3057 apply(auto simp: inv_on_left_moving_in_middle_B.simps)
       
  3058 apply(rule_tac x = "lm1 @ [m]" in exI, rule_tac x = "[]" in exI, auto)
       
  3059 done
       
  3060 *)
       
  3061 
       
  3062 lemma [simp]: "dec_left_move (as, am) (s, l, []) ires
       
  3063              \<Longrightarrow> inv_on_left_moving (as, am) (s', tl l, [hd l]) ires"
       
  3064 apply(auto simp: dec_left_move.simps inv_on_left_moving.simps split: if_splits)
       
  3065 done
       
  3066 
       
  3067 lemma [simp]: "dec_after_write (as, am) (s, l, Oc # r) ires
       
  3068        \<Longrightarrow> dec_on_right_moving (as, am) (s', Oc # l, r) ires"
       
  3069 apply(auto simp: dec_after_write.simps dec_on_right_moving.simps)
       
  3070 apply(rule_tac x = "lm1 @ [m]" in exI, rule_tac x = "tl lm2" in exI, 
       
  3071       rule_tac x = "hd lm2" in exI, simp)
       
  3072 apply(rule_tac x = "Suc 0" in exI,rule_tac x =  "Suc (hd lm2)" in exI)
       
  3073 apply(case_tac lm2, auto split: if_splits simp: tape_of_nl_cons)
       
  3074 done
       
  3075 
       
  3076 lemma [simp]: "dec_after_write (as, am) (s, l, Bk # r) ires
       
  3077        \<Longrightarrow> dec_after_write (as, am) (s', l, Oc # r) ires"
       
  3078 apply(auto simp: dec_after_write.simps)
       
  3079 done
       
  3080 
       
  3081 lemma [simp]: "dec_after_write (as, am) (s, aaa, []) ires
       
  3082              \<Longrightarrow> dec_after_write (as, am) (s', aaa, [Oc]) ires"
       
  3083 apply(auto simp: dec_after_write.simps)
       
  3084 done
       
  3085 
       
  3086 lemma [simp]: "dec_on_right_moving (as, am) (s, l, Oc # r) ires
       
  3087        \<Longrightarrow> dec_on_right_moving (as, am) (s', Oc # l, r) ires"
       
  3088 apply(simp only: dec_on_right_moving.simps)
       
  3089 apply(erule_tac exE)+
       
  3090 apply(erule conjE)+
       
  3091 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI,
       
  3092       rule_tac x = "m" in exI, rule_tac x = "Suc ml" in exI, 
       
  3093       rule_tac x = "mr - 1" in exI, simp)
       
  3094 apply(case_tac mr, auto)
       
  3095 done
       
  3096 
       
  3097 lemma [simp]: "dec_on_right_moving (as, am) (s, l, r) ires\<Longrightarrow>  l \<noteq> []"
       
  3098 apply(auto simp: dec_on_right_moving.simps split: if_splits)
       
  3099 done
       
  3100 
       
  3101 lemma [simp]: "dec_on_right_moving (as, am) (s, l, Bk # r) ires
       
  3102       \<Longrightarrow>  dec_after_clear (as, am) (s', tl l, hd l # Bk # r) ires"
       
  3103 apply(auto simp: dec_on_right_moving.simps dec_after_clear.simps)
       
  3104 apply(case_tac [!] mr, auto split: if_splits)
       
  3105 done
       
  3106 
       
  3107 lemma [simp]: "dec_on_right_moving (as, am) (s, l, []) ires
       
  3108              \<Longrightarrow> dec_after_clear (as, am) (s', tl l, [hd l]) ires"
       
  3109 apply(auto simp: dec_on_right_moving.simps dec_after_clear.simps)
       
  3110 apply(simp_all split: if_splits)
       
  3111 apply(rule_tac x = lm1 in exI, simp)
       
  3112 done
       
  3113 
       
  3114 lemma [simp]: 
       
  3115  "inv_stop (as, abc_lm_s am n (abc_lm_v am n)) (s, l, r) ires \<Longrightarrow> l \<noteq> []"
       
  3116 apply(auto simp: inv_stop.simps)
       
  3117 done
       
  3118 
       
  3119 lemma dec_false_1[simp]:
       
  3120  "\<lbrakk>abc_lm_v am n = 0; inv_locate_b (as, am) (n, aaa, Oc # xs) ires\<rbrakk>
       
  3121   \<Longrightarrow> False"
       
  3122 apply(auto simp: inv_locate_b.simps in_middle.simps)
       
  3123 apply(case_tac "length lm1 \<ge> length am", auto)
       
  3124 apply(subgoal_tac "lm2 = []", simp, subgoal_tac "m = 0", simp)
       
  3125 apply(case_tac mr, auto simp: )
       
  3126 apply(subgoal_tac "Suc (length lm1) - length am = 
       
  3127                    Suc (length lm1 - length am)", 
       
  3128       simp add: exp_ind del: replicate.simps, simp)
       
  3129 apply(drule_tac xs = "am @ replicate (Suc (length lm1) - length am) 0"
       
  3130                 and ys = "lm1 @ m # lm2" in length_equal, simp)
       
  3131 apply(case_tac mr, auto simp: abc_lm_v.simps)
       
  3132 apply(case_tac "mr = 0", simp_all split: if_splits)
       
  3133 apply(subgoal_tac "Suc (length lm1) - length am = 
       
  3134                        Suc (length lm1 - length am)", 
       
  3135       simp add: exp_ind del: replicate.simps, simp)
       
  3136 done
       
  3137 
       
  3138 lemma [simp]: 
       
  3139  "\<lbrakk>inv_locate_b (as, am) (n, aaa, Bk # xs) ires; 
       
  3140    abc_lm_v am n = 0\<rbrakk>
       
  3141    \<Longrightarrow> inv_on_left_moving (as, abc_lm_s am n 0) 
       
  3142                          (s, tl aaa, hd aaa # Bk # xs) ires"
       
  3143 apply(simp add: inv_on_left_moving.simps)
       
  3144 apply(simp only: inv_locate_b.simps in_middle.simps) 
       
  3145 apply(erule_tac exE)+
       
  3146 apply(simp add: inv_on_left_moving.simps)
       
  3147 apply(subgoal_tac "\<not> inv_on_left_moving_in_middle_B 
       
  3148          (as, abc_lm_s am n 0) (s, tl aaa, hd aaa # Bk # xs) ires", simp)
       
  3149 apply(simp only: inv_on_left_moving_norm.simps)
       
  3150 apply(erule_tac conjE)+
       
  3151 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  3152       rule_tac x =  m in exI, rule_tac x = m in exI, 
       
  3153       rule_tac x = "Suc 0" in exI, simp add: abc_lm_s.simps)
       
  3154 apply(case_tac mr, simp_all, auto simp: abc_lm_v.simps)
       
  3155 apply(simp only: exp_ind[THEN sym] replicate_Suc Nat.Suc_diff_le)
       
  3156 apply(auto simp: inv_on_left_moving_in_middle_B.simps split: if_splits)
       
  3157 done
       
  3158 
       
  3159 
       
  3160 lemma [simp]:
       
  3161  "\<lbrakk>abc_lm_v am n = 0; inv_locate_b (as, am) (n, aaa, []) ires\<rbrakk>
       
  3162    \<Longrightarrow> inv_on_left_moving (as, abc_lm_s am n 0) (s, tl aaa, [hd aaa]) ires"
       
  3163 apply(simp add: inv_on_left_moving.simps)
       
  3164 apply(simp only: inv_locate_b.simps in_middle.simps) 
       
  3165 apply(erule_tac exE)+
       
  3166 apply(simp add: inv_on_left_moving.simps)
       
  3167 apply(subgoal_tac "\<not> inv_on_left_moving_in_middle_B 
       
  3168          (as, abc_lm_s am n 0) (s, tl aaa, [hd aaa]) ires", simp)
       
  3169 apply(simp only: inv_on_left_moving_norm.simps)
       
  3170 apply(erule_tac conjE)+
       
  3171 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  3172       rule_tac x =  m in exI, rule_tac x = m in exI, 
       
  3173       rule_tac x = "Suc 0" in exI, simp add: abc_lm_s.simps)
       
  3174 apply(case_tac mr, simp_all, auto simp: abc_lm_v.simps)
       
  3175 apply(simp_all only: exp_ind Nat.Suc_diff_le del: replicate_Suc, simp_all)
       
  3176 apply(auto simp: inv_on_left_moving_in_middle_B.simps split: if_splits)
       
  3177 apply(case_tac [!] m, simp_all)
       
  3178 done
       
  3179 
       
  3180 lemma [simp]: "\<lbrakk>am ! n = (0::nat); n < length am\<rbrakk> \<Longrightarrow> am[n := 0] = am"
       
  3181 apply(simp add: list_update_same_conv)
       
  3182 done
       
  3183 
       
  3184 lemma  [intro]: "\<lbrakk>abc_lm_v (a # list) 0 = 0\<rbrakk> \<Longrightarrow> a = 0"
       
  3185 apply(simp add: abc_lm_v.simps split: if_splits)
       
  3186 done
       
  3187 
       
  3188 lemma [simp]: 
       
  3189  "inv_stop (as, abc_lm_s am n 0) 
       
  3190           (start_of (layout_of aprog) e, aaa, Oc # xs) ires
       
  3191   \<Longrightarrow> inv_locate_a (as, abc_lm_s am n 0) (0, aaa, Oc # xs) ires"
       
  3192 apply(simp add: inv_locate_a.simps)
       
  3193 apply(rule disjI1)
       
  3194 apply(auto simp: inv_stop.simps at_begin_norm.simps)
       
  3195 done
       
  3196 
       
  3197 lemma [simp]: 
       
  3198  "\<lbrakk>inv_stop (as, abc_lm_s am n 0) 
       
  3199           (start_of (layout_of aprog) e, aaa, Oc # xs) ires\<rbrakk>
       
  3200   \<Longrightarrow> inv_locate_b (as, am) (0, Oc # aaa, xs) ires \<or> 
       
  3201       inv_locate_b (as, abc_lm_s am n 0) (0, Oc # aaa, xs) ires"
       
  3202 apply(simp)
       
  3203 done
       
  3204 
       
  3205 lemma dec_false2: 
       
  3206  "inv_stop (as, abc_lm_s am n 0) 
       
  3207   (start_of (layout_of aprog) e, aaa, Bk # xs) ires = False"
       
  3208 apply(auto simp: inv_stop.simps abc_lm_s.simps)
       
  3209 apply(case_tac [!] am, auto)
       
  3210 apply(case_tac [!] n, auto simp: tape_of_nl_cons split: if_splits)
       
  3211 done
       
  3212 
       
  3213 lemma dec_false3:
       
  3214    "inv_stop (as, abc_lm_s am n 0) 
       
  3215               (start_of (layout_of aprog) e, aaa, []) ires = False"
       
  3216 apply(auto simp: inv_stop.simps abc_lm_s.simps)
       
  3217 done
       
  3218 
       
  3219 lemma [simp]:
       
  3220   "fetch (ci (layout_of aprog) 
       
  3221        (start_of (layout_of aprog) as) (Dec n e)) 0 b = (Nop, 0)"
       
  3222 by(simp add: fetch.simps)
       
  3223 
       
  3224 declare dec_inv_1.simps[simp del]
       
  3225 
       
  3226 declare inv_locate_n_b.simps [simp del]
       
  3227 
       
  3228 lemma [simp]:
       
  3229   "\<lbrakk>0 < abc_lm_v am n; 0 < n; 
       
  3230     at_begin_fst_bwtn (as, am) (n, aaa, Oc # xs) ires\<rbrakk>
       
  3231  \<Longrightarrow> inv_locate_n_b (as, am) (n, Oc # aaa, xs) ires"
       
  3232 apply(simp add: at_begin_fst_bwtn.simps inv_locate_n_b.simps )
       
  3233 done
       
  3234  
       
  3235 lemma Suc_minus:"length am + tn = n
       
  3236        \<Longrightarrow> Suc tn = Suc n - length am "
       
  3237 apply(arith)
       
  3238 done
       
  3239 
       
  3240 lemma [simp]: 
       
  3241  "\<lbrakk>0 < abc_lm_v am n; 0 < n; 
       
  3242    at_begin_fst_awtn (as, am) (n, aaa, Oc # xs) ires\<rbrakk>
       
  3243  \<Longrightarrow> inv_locate_n_b (as, am) (n, Oc # aaa, xs) ires"
       
  3244 apply(simp only: at_begin_fst_awtn.simps inv_locate_n_b.simps )
       
  3245 apply(erule exE)+
       
  3246 apply(erule conjE)+
       
  3247 apply(rule_tac x = lm1 in exI, rule_tac x = "[]" in exI, 
       
  3248       rule_tac x = "Suc tn" in exI, rule_tac x = 0 in exI)
       
  3249 apply(simp add: exp_ind del: replicate.simps)
       
  3250 apply(rule conjI)+
       
  3251 apply(auto)
       
  3252 done
       
  3253 
       
  3254 lemma [simp]:
       
  3255  "\<lbrakk>inv_locate_n_b (as, am) (n, aaa, Oc # xs) ires\<rbrakk>
       
  3256  \<Longrightarrow> dec_first_on_right_moving n (as, abc_lm_s am n (abc_lm_v am n))  
       
  3257                                       (s, Oc # aaa, xs) ires"
       
  3258 apply(auto simp: inv_locate_n_b.simps dec_first_on_right_moving.simps 
       
  3259                  abc_lm_s.simps abc_lm_v.simps)
       
  3260 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  3261       rule_tac x = m in exI, simp)
       
  3262 apply(rule_tac x = "Suc (Suc 0)" in exI, 
       
  3263       rule_tac x = "m - 1" in exI, simp)
       
  3264 apply(case_tac m, auto)
       
  3265 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  3266       rule_tac x = m in exI, 
       
  3267       simp add: Suc_diff_le exp_ind del: replicate.simps)
       
  3268 apply(rule_tac x = "Suc (Suc 0)" in exI, 
       
  3269       rule_tac x = "m - 1" in exI, simp)
       
  3270 apply(case_tac m, auto)
       
  3271 apply(rule_tac x = lm1 in exI, rule_tac x = "[]" in exI, 
       
  3272       rule_tac x = m in exI, simp)
       
  3273 apply(rule_tac x = "Suc (Suc 0)" in exI, 
       
  3274       rule_tac x = "m - 1" in exI, simp)
       
  3275 apply(case_tac m, auto)
       
  3276 apply(rule_tac x = lm1 in exI, rule_tac x = lm2 in exI, 
       
  3277       rule_tac x = m in exI, 
       
  3278       simp add: Suc_diff_le exp_ind del: replicate.simps, simp)
       
  3279 done
       
  3280 
       
  3281 lemma [simp]: "inv_on_left_moving (as, am) (s, [], r) ires 
       
  3282   = False"
       
  3283 apply(simp add: inv_on_left_moving.simps inv_on_left_moving_norm.simps
       
  3284                 inv_on_left_moving_in_middle_B.simps)
       
  3285 done
       
  3286 
       
  3287 lemma [simp]: 
       
  3288   "inv_check_left_moving (as, abc_lm_s am n 0)
       
  3289   (start_of (layout_of aprog) as + 2 * n + 14, [], Oc # xs) ires
       
  3290  = False"
       
  3291 apply(simp add: inv_check_left_moving.simps inv_check_left_moving_in_middle.simps)
       
  3292 done
       
  3293 
       
  3294 lemma [simp]: "inv_check_left_moving (as, abc_lm_s lm n (abc_lm_v lm n)) (s, [], Oc # list) ires = False"
       
  3295 apply(simp add: inv_check_left_moving.simps inv_check_left_moving_in_middle.simps)
       
  3296 done
       
  3297 
       
  3298 lemma [elim]: "\<lbrakk>abc_fetch as ap = Some (Dec n e);
       
  3299                 start_of (layout_of ap) as < start_of (layout_of ap) e; 
       
  3300                 start_of (layout_of ap) e \<le> Suc (start_of (layout_of ap) as + 2 * n)\<rbrakk>
       
  3301        \<Longrightarrow> RR"
       
  3302   using start_of_less[of e as "layout_of ap"] start_of_ge[of as ap n e "layout_of ap"]
       
  3303 apply(case_tac "as < e", simp)
       
  3304 apply(case_tac "as = e", simp, simp)
       
  3305 done
       
  3306 
       
  3307 lemma crsp_step_dec_b_e_pre':
       
  3308   assumes layout: "ly = layout_of ap"
       
  3309   and inv_start: "inv_locate_b (as, lm) (n, la, ra) ires"
       
  3310   and fetch: "abc_fetch as ap = Some (Dec n e)"
       
  3311   and dec_0: "abc_lm_v lm n = 0"
       
  3312   and f: "f = (\<lambda> stp. (steps (Suc (start_of ly as) + 2 * n, la, ra) (ci ly (start_of ly as) (Dec n e), 
       
  3313             start_of ly as - Suc 0) stp, start_of ly as, n))"
       
  3314   and P: "P = (\<lambda> ((s, l, r), ss, x). s = start_of ly e)"
       
  3315   and Q: "Q = (\<lambda> ((s, l, r), ss, x). dec_inv_1 ly x e (as, lm) (s, l, r) ires)"
       
  3316   shows "\<exists> stp. P (f stp) \<and> Q (f stp)"
       
  3317 proof(rule_tac LE = abc_dec_1_LE in halt_lemma2)
       
  3318   show "wf abc_dec_1_LE" by(intro wf_dec_le)
       
  3319 next
       
  3320   show "Q (f 0)"
       
  3321     using layout fetch
       
  3322     apply(simp add: f steps.simps Q dec_inv_1.simps)
       
  3323     apply(subgoal_tac "e > as \<or> e = as \<or> e < as")
       
  3324     apply(auto simp: Let_def start_of_ge start_of_less inv_start)
       
  3325     done
       
  3326 next
       
  3327   show "\<not> P (f 0)"
       
  3328     using layout fetch
       
  3329     apply(simp add: f steps.simps P)
       
  3330     done
       
  3331 next
       
  3332   show "\<forall>n. \<not> P (f n) \<and> Q (f n) \<longrightarrow> Q (f (Suc n)) \<and> (f (Suc n), f n) \<in> abc_dec_1_LE"
       
  3333     using fetch
       
  3334   proof(rule_tac allI, rule_tac impI)
       
  3335     fix na
       
  3336     assume "\<not> P (f na) \<and> Q (f na)"
       
  3337     thus "Q (f (Suc na)) \<and> (f (Suc na), f na) \<in> abc_dec_1_LE"
       
  3338       apply(simp add: f)
       
  3339       apply(case_tac "steps (Suc (start_of ly as + 2 * n), la, ra)
       
  3340         (ci ly (start_of ly as) (Dec n e), start_of ly as - Suc 0) na", simp)
       
  3341     proof -
       
  3342       fix a b c 
       
  3343       assume "\<not> P ((a, b, c), start_of ly as, n) \<and> Q ((a, b, c), start_of ly as, n)"
       
  3344       thus "Q (step (a, b, c) (ci ly (start_of ly as) (Dec n e), start_of ly as - Suc 0), start_of ly as, n) \<and>
       
  3345                ((step (a, b, c) (ci ly (start_of ly as) (Dec n e), start_of ly as - Suc 0), start_of ly as, n), 
       
  3346                    (a, b, c), start_of ly as, n) \<in> abc_dec_1_LE"
       
  3347         apply(simp add: Q)
       
  3348         apply(case_tac c, case_tac [2] aa)
       
  3349         apply(simp_all add: dec_inv_1.simps Let_def split: if_splits)
       
  3350         using fetch layout dec_0
       
  3351         apply(auto simp: step.simps P dec_inv_1.simps Let_def abc_dec_1_LE_def lex_triple_def lex_pair_def)
       
  3352         using dec_0
       
  3353         apply(drule_tac dec_false_1, simp_all)
       
  3354         done
       
  3355     qed
       
  3356   qed
       
  3357 qed
       
  3358 
       
  3359 lemma crsp_step_dec_b_e_pre:
       
  3360   assumes "ly = layout_of ap"
       
  3361   and inv_start: "inv_locate_b (as, lm) (n, la, ra) ires"
       
  3362   and dec_0: "abc_lm_v lm n  = 0"
       
  3363   and fetch: "abc_fetch as ap = Some (Dec n e)"
       
  3364   shows "\<exists>stp lb rb.
       
  3365        steps (Suc (start_of ly as) + 2 * n, la, ra) (ci ly (start_of ly as) (Dec n e), 
       
  3366        start_of ly as - Suc 0) stp = (start_of ly e, lb, rb) \<and>
       
  3367        dec_inv_1 ly n e (as, lm) (start_of ly e, lb, rb) ires"
       
  3368   using assms
       
  3369   apply(drule_tac crsp_step_dec_b_e_pre', auto)
       
  3370   apply(rule_tac x = stp in exI, simp)
       
  3371   done
       
  3372 
       
  3373 lemma [simp]:
       
  3374   "\<lbrakk>abc_lm_v lm n = 0;
       
  3375   inv_stop (as, abc_lm_s lm n (abc_lm_v lm n)) (start_of ly e, lb, rb) ires\<rbrakk>
       
  3376   \<Longrightarrow> crsp ly (abc_step_l (as, lm) (Some (Dec n e))) (start_of ly e, lb, rb) ires"
       
  3377 apply(auto simp: crsp.simps abc_step_l.simps inv_stop.simps)
       
  3378 done
       
  3379 
       
  3380 lemma crsp_step_dec_b_e:
       
  3381   assumes layout: "ly = layout_of ap"
       
  3382   and inv_start: "inv_locate_a (as, lm) (n, l, r) ires"
       
  3383   and dec_0: "abc_lm_v lm n = 0"
       
  3384   and fetch: "abc_fetch as ap = Some (Dec n e)"
       
  3385   shows "\<exists>stp > 0. crsp ly (abc_step_l (as, lm) (Some (Dec n e)))
       
  3386   (steps (start_of ly as + 2 * n, l, r) (ci ly (start_of ly as) (Dec n e), start_of ly as - Suc 0) stp) ires"
       
  3387 proof -
       
  3388   let ?P = "ci ly (start_of ly as) (Dec n e)"
       
  3389   let ?off = "start_of ly as - Suc 0"
       
  3390   have "\<exists> stp la ra. steps (start_of ly as + 2 * n, l, r) (?P, ?off) stp = (Suc (start_of ly as) + 2*n, la, ra)
       
  3391              \<and>  inv_locate_b (as, lm) (n, la, ra) ires"
       
  3392     using inv_start
       
  3393     apply(case_tac "r = [] \<or> hd r = Bk", simp_all)
       
  3394     done
       
  3395   from this obtain stpa la ra where a:
       
  3396     "steps (start_of ly as + 2 * n, l, r) (?P, ?off) stpa = (Suc (start_of ly as) + 2*n, la, ra)
       
  3397              \<and>  inv_locate_b (as, lm) (n, la, ra) ires" by blast
       
  3398   term dec_inv_1
       
  3399   have "\<exists> stp lb rb. steps (Suc (start_of ly as) + 2 * n, la, ra) (?P, ?off) stp = (start_of ly e, lb, rb)
       
  3400              \<and>  dec_inv_1 ly n e (as, lm) (start_of ly e, lb, rb) ires"
       
  3401     using assms a
       
  3402     apply(rule_tac crsp_step_dec_b_e_pre, auto)
       
  3403     done
       
  3404   from this obtain stpb lb rb where b:
       
  3405     "steps (Suc (start_of ly as) + 2 * n, la, ra) (?P, ?off) stpb = (start_of ly e, lb, rb)
       
  3406              \<and>  dec_inv_1 ly n e (as, lm) (start_of ly e, lb, rb) ires"  by blast
       
  3407   from a b show "\<exists>stp > 0. crsp ly (abc_step_l (as, lm) (Some (Dec n e))) 
       
  3408     (steps (start_of ly as + 2 * n, l, r) (?P, ?off) stp) ires"
       
  3409     apply(rule_tac x = "stpa + stpb" in exI)
       
  3410     apply(simp add: steps_add)
       
  3411     using dec_0
       
  3412     apply(simp add: dec_inv_1.simps)
       
  3413     apply(case_tac stpa, simp_all add: steps.simps)
       
  3414     done
       
  3415 qed    
       
  3416   
       
  3417 fun dec_inv_2 :: "layout \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> dec_inv_t"
       
  3418   where
       
  3419   "dec_inv_2 ly n e (as, am) (s, l, r) ires =
       
  3420            (let ss = start_of ly as in
       
  3421             let am' = abc_lm_s am n (abc_lm_v am n - Suc 0) in
       
  3422             let am'' = abc_lm_s am n (abc_lm_v am n) in
       
  3423               if s = 0 then False
       
  3424               else if s = ss + 2 * n then 
       
  3425                       inv_locate_a (as, am) (n, l, r) ires
       
  3426               else if s = ss + 2 * n + 1 then 
       
  3427                       inv_locate_n_b (as, am) (n, l, r) ires
       
  3428               else if s = ss + 2 * n + 2 then 
       
  3429                       dec_first_on_right_moving n (as, am'') (s, l, r) ires
       
  3430               else if s = ss + 2 * n + 3 then 
       
  3431                       dec_after_clear (as, am') (s, l, r) ires
       
  3432               else if s = ss + 2 * n + 4 then 
       
  3433                       dec_right_move (as, am') (s, l, r) ires
       
  3434               else if s = ss + 2 * n + 5 then 
       
  3435                       dec_check_right_move (as, am') (s, l, r) ires
       
  3436               else if s = ss + 2 * n + 6 then 
       
  3437                       dec_left_move (as, am') (s, l, r) ires
       
  3438               else if s = ss + 2 * n + 7 then 
       
  3439                       dec_after_write (as, am') (s, l, r) ires
       
  3440               else if s = ss + 2 * n + 8 then 
       
  3441                       dec_on_right_moving (as, am') (s, l, r) ires
       
  3442               else if s = ss + 2 * n + 9 then 
       
  3443                       dec_after_clear (as, am') (s, l, r) ires
       
  3444               else if s = ss + 2 * n + 10 then 
       
  3445                       inv_on_left_moving (as, am') (s, l, r) ires
       
  3446               else if s = ss + 2 * n + 11 then 
       
  3447                       inv_check_left_moving (as, am') (s, l, r) ires
       
  3448               else if s = ss + 2 * n + 12 then 
       
  3449                       inv_after_left_moving (as, am') (s, l, r) ires
       
  3450               else if s = ss + 2 * n + 16 then 
       
  3451                       inv_stop (as, am') (s, l, r) ires
       
  3452               else False)"
       
  3453 
       
  3454 declare dec_inv_2.simps[simp del]
       
  3455 fun abc_dec_2_stage1 :: "config \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
  3456   where
       
  3457   "abc_dec_2_stage1 (s, l, r) ss n = 
       
  3458               (if s \<le> ss + 2*n + 1 then 7
       
  3459                else if s = ss + 2*n + 2 then 6 
       
  3460                else if s = ss + 2*n + 3 then 5
       
  3461                else if s \<ge> ss + 2*n + 4 \<and> s \<le> ss + 2*n + 9 then 4
       
  3462                else if s = ss + 2*n + 6 then 3
       
  3463                else if s = ss + 2*n + 10 \<or> s = ss + 2*n + 11 then 2
       
  3464                else if s = ss + 2*n + 12 then 1
       
  3465                else 0)"
       
  3466 
       
  3467 fun abc_dec_2_stage2 :: "config \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
  3468   where
       
  3469   "abc_dec_2_stage2 (s, l, r) ss n = 
       
  3470        (if s \<le> ss + 2 * n + 1 then (ss + 2 * n + 16 - s)
       
  3471         else if s = ss + 2*n + 10 then length l
       
  3472         else if s = ss + 2*n + 11 then length l
       
  3473         else if s = ss + 2*n + 4 then length r - 1
       
  3474         else if s = ss + 2*n + 5 then length r 
       
  3475         else if s = ss + 2*n + 7 then length r - 1
       
  3476         else if s = ss + 2*n + 8 then  
       
  3477               length r + length (takeWhile (\<lambda> a. a = Oc) l) - 1
       
  3478         else if s = ss + 2*n + 9 then 
       
  3479               length r + length (takeWhile (\<lambda> a. a = Oc) l) - 1
       
  3480         else 0)"
       
  3481 
       
  3482 fun abc_dec_2_stage3 :: "config \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
  3483   where
       
  3484   "abc_dec_2_stage3 (s, l, r) ss n  =
       
  3485         (if s \<le> ss + 2*n + 1 then 
       
  3486             if (s - ss) mod 2 = 0 then if r \<noteq> [] \<and> 
       
  3487                                           hd r = Oc then 0 else 1  
       
  3488             else length r
       
  3489          else if s = ss + 2 * n + 10 then 
       
  3490              if  r \<noteq> [] \<and> hd r = Oc then 2
       
  3491              else 1
       
  3492          else if s = ss + 2 * n + 11 then 
       
  3493              if r \<noteq> [] \<and> hd r = Oc then 3 
       
  3494              else 0 
       
  3495          else (ss + 2 * n + 16 - s))"
       
  3496 
       
  3497 fun abc_dec_2_stage4 :: "config \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
  3498   where
       
  3499   "abc_dec_2_stage4 (s, l, r) ss n = 
       
  3500           (if s = ss + 2*n + 2 then length r
       
  3501            else if s = ss + 2*n + 8 then length r
       
  3502            else if s = ss + 2*n + 3 then 
       
  3503                if r \<noteq> [] \<and> hd r = Oc then 1
       
  3504                else 0
       
  3505            else if s = ss + 2*n + 7 then 
       
  3506                if r \<noteq> [] \<and> hd r = Oc then 0 
       
  3507                else 1
       
  3508            else if s = ss + 2*n + 9 then 
       
  3509                if r \<noteq> [] \<and> hd r = Oc then 1
       
  3510                else 0 
       
  3511            else 0)"
       
  3512 
       
  3513 fun abc_dec_2_measure :: "(config \<times> nat \<times> nat) \<Rightarrow> (nat \<times> nat \<times> nat \<times> nat)"
       
  3514   where
       
  3515   "abc_dec_2_measure (c, ss, n) = 
       
  3516   (abc_dec_2_stage1 c ss n, 
       
  3517   abc_dec_2_stage2 c ss n, abc_dec_2_stage3 c ss n,  abc_dec_2_stage4 c ss n)"
       
  3518 
       
  3519 definition lex_square:: 
       
  3520    "((nat \<times> nat \<times> nat \<times> nat) \<times> (nat \<times> nat \<times> nat \<times> nat)) set"
       
  3521   where "lex_square \<equiv> less_than <*lex*> lex_triple"
       
  3522 
       
  3523 definition abc_dec_2_LE ::
       
  3524   "((config \<times> nat \<times>
       
  3525   nat) \<times> (config \<times> nat \<times> nat)) set"
       
  3526   where "abc_dec_2_LE \<equiv> (inv_image lex_square abc_dec_2_measure)"
       
  3527 
       
  3528 lemma wf_dec2_le: "wf abc_dec_2_LE"
       
  3529 by(auto intro:wf_inv_image simp:abc_dec_2_LE_def lex_square_def lex_triple_def lex_pair_def)
       
  3530 
       
  3531 lemma fix_add: "fetch ap ((x::nat) + 2*n) b = fetch ap (2*n + x) b"
       
  3532 by (metis Suc_1 mult_2 nat_add_commute)
       
  3533 
       
  3534 lemma [elim]: 
       
  3535  "\<lbrakk>0 < abc_lm_v am n; inv_locate_n_b (as, am) (n, aaa, Bk # xs) ires\<rbrakk> 
       
  3536  \<Longrightarrow> RR"
       
  3537 apply(auto simp: inv_locate_n_b.simps abc_lm_v.simps split: if_splits)
       
  3538 apply(case_tac [!] m, auto)
       
  3539 done
       
  3540  
       
  3541 lemma [elim]:
       
  3542  "\<lbrakk>0 < abc_lm_v am n; inv_locate_n_b (as, am) 
       
  3543                                 (n, aaa, []) ires\<rbrakk> \<Longrightarrow> RR"
       
  3544 apply(auto simp: inv_locate_n_b.simps abc_lm_v.simps split: if_splits)
       
  3545 done
       
  3546 
       
  3547 lemma [simp]: "dec_after_write (as, am) (s, aa, r) ires
       
  3548            \<Longrightarrow> takeWhile (\<lambda>a. a = Oc) aa = []"
       
  3549 apply(simp only : dec_after_write.simps)
       
  3550 apply(erule exE)+
       
  3551 apply(erule_tac conjE)+
       
  3552 apply(case_tac aa, simp)
       
  3553 apply(case_tac a, simp only: takeWhile.simps , simp_all split: if_splits)
       
  3554 done
       
  3555 
       
  3556 lemma [simp]: 
       
  3557      "\<lbrakk>dec_on_right_moving (as, lm) (s, aa, []) ires; 
       
  3558        length (takeWhile (\<lambda>a. a = Oc) (tl aa)) 
       
  3559            \<noteq> length (takeWhile (\<lambda>a. a = Oc) aa) - Suc 0\<rbrakk>
       
  3560     \<Longrightarrow> length (takeWhile (\<lambda>a. a = Oc) (tl aa)) < 
       
  3561                        length (takeWhile (\<lambda>a. a = Oc) aa) - Suc 0"
       
  3562 apply(simp only: dec_on_right_moving.simps)
       
  3563 apply(erule_tac exE)+
       
  3564 apply(erule_tac conjE)+
       
  3565 apply(case_tac mr, auto split: if_splits)
       
  3566 done
       
  3567 
       
  3568 lemma [simp]: 
       
  3569   "dec_after_clear (as, abc_lm_s am n (abc_lm_v am n - Suc 0)) 
       
  3570              (start_of (layout_of aprog) as + 2 * n + 9, aa, Bk # xs) ires
       
  3571  \<Longrightarrow> length xs - Suc 0 < length xs + 
       
  3572                              length (takeWhile (\<lambda>a. a = Oc) aa)"
       
  3573 apply(simp only: dec_after_clear.simps)
       
  3574 apply(erule_tac exE)+
       
  3575 apply(erule conjE)+
       
  3576 apply(simp split: if_splits )
       
  3577 done
       
  3578 
       
  3579 lemma [simp]: 
       
  3580  "\<lbrakk>dec_after_clear (as, abc_lm_s am n (abc_lm_v am n - Suc 0))
       
  3581        (start_of (layout_of aprog) as + 2 * n + 9, aa, []) ires\<rbrakk>
       
  3582     \<Longrightarrow> Suc 0 < length (takeWhile (\<lambda>a. a = Oc) aa)"
       
  3583 apply(simp add: dec_after_clear.simps split: if_splits)
       
  3584 done
       
  3585 
       
  3586 lemma [elim]: 
       
  3587   "inv_check_left_moving (as, lm)
       
  3588   (s, [], Oc # xs) ires
       
  3589  \<Longrightarrow> RR"
       
  3590 apply(simp add: inv_check_left_moving.simps inv_check_left_moving_in_middle.simps)
       
  3591 done
       
  3592 
       
  3593 lemma [simp]:
       
  3594 "\<lbrakk>0 < abc_lm_v am n; 
       
  3595   at_begin_norm (as, am) (n, aaa, Oc # xs) ires\<rbrakk>
       
  3596   \<Longrightarrow> inv_locate_n_b (as, am) (n, Oc # aaa, xs) ires"
       
  3597 apply(simp only: at_begin_norm.simps inv_locate_n_b.simps)
       
  3598 apply(erule_tac exE)+
       
  3599 apply(rule_tac x = lm1 in exI, simp)
       
  3600 apply(case_tac "length lm2", simp)
       
  3601 apply(case_tac "lm2", simp, simp)
       
  3602 apply(case_tac "lm2", auto simp: tape_of_nl_cons split: if_splits)
       
  3603 done
       
  3604 
       
  3605 lemma [simp]: 
       
  3606  "\<lbrakk>0 < abc_lm_v am n; 
       
  3607    at_begin_fst_awtn (as, am) (n, aaa, Oc # xs) ires\<rbrakk>
       
  3608  \<Longrightarrow> inv_locate_n_b (as, am) (n, Oc # aaa, xs) ires"
       
  3609 apply(simp only: at_begin_fst_awtn.simps inv_locate_n_b.simps )
       
  3610 apply(erule exE)+
       
  3611 apply(erule conjE)+
       
  3612 apply(rule_tac x = lm1 in exI, rule_tac x = "[]" in exI, 
       
  3613       rule_tac x = "Suc tn" in exI, rule_tac x = 0 in exI)
       
  3614 apply(simp add: exp_ind del: replicate.simps)
       
  3615 apply(rule conjI)+
       
  3616 apply(auto)
       
  3617 done
       
  3618 
       
  3619 lemma [simp]: 
       
  3620  "\<lbrakk>0 < abc_lm_v am n; inv_locate_a (as, am) (n, aaa, Oc # xs) ires\<rbrakk>
       
  3621  \<Longrightarrow> inv_locate_n_b (as, am) (n, Oc#aaa, xs) ires"
       
  3622 apply(auto simp: inv_locate_a.simps at_begin_fst_bwtn.simps)
       
  3623 done
       
  3624 
       
  3625 lemma [simp]: 
       
  3626  "\<lbrakk>dec_on_right_moving (as, am) (s, aa, Bk # xs) ires; 
       
  3627    Suc (length (takeWhile (\<lambda>a. a = Oc) (tl aa)))
       
  3628    \<noteq> length (takeWhile (\<lambda>a. a = Oc) aa)\<rbrakk>
       
  3629   \<Longrightarrow> Suc (length (takeWhile (\<lambda>a. a = Oc) (tl aa))) 
       
  3630     < length (takeWhile (\<lambda>a. a = Oc) aa)"
       
  3631 apply(simp only: dec_on_right_moving.simps)
       
  3632 apply(erule exE)+
       
  3633 apply(erule conjE)+
       
  3634 apply(case_tac ml, auto split: if_splits )
       
  3635 done
       
  3636 
       
  3637 lemma crsp_step_dec_b_suc_pre:
       
  3638   assumes layout: "ly = layout_of ap"
       
  3639   and crsp: "crsp ly (as, lm) (s, l, r) ires"
       
  3640   and inv_start: "inv_locate_a (as, lm) (n, la, ra) ires"
       
  3641   and fetch: "abc_fetch as ap = Some (Dec n e)"
       
  3642   and dec_suc: "0 < abc_lm_v lm n"
       
  3643   and f: "f = (\<lambda> stp. (steps (start_of ly as + 2 * n, la, ra) (ci ly (start_of ly as) (Dec n e), 
       
  3644             start_of ly as - Suc 0) stp, start_of ly as, n))"
       
  3645   and P: "P = (\<lambda> ((s, l, r), ss, x). s = start_of ly as + 2*n + 16)"
       
  3646   and Q: "Q = (\<lambda> ((s, l, r), ss, x). dec_inv_2 ly x e (as, lm) (s, l, r) ires)"
       
  3647   shows "\<exists> stp. P (f stp) \<and> Q(f stp)"
       
  3648   proof(rule_tac LE = abc_dec_2_LE in halt_lemma2)
       
  3649   show "wf abc_dec_2_LE" by(intro wf_dec2_le)
       
  3650 next
       
  3651   show "Q (f 0)"
       
  3652     using layout fetch inv_start
       
  3653     apply(simp add: f steps.simps Q)
       
  3654     apply(simp only: dec_inv_2.simps)
       
  3655     apply(auto simp: Let_def start_of_ge start_of_less inv_start dec_inv_2.simps)
       
  3656     done
       
  3657 next
       
  3658   show "\<not> P (f 0)"
       
  3659     using layout fetch
       
  3660     apply(simp add: f steps.simps P)
       
  3661     done
       
  3662 next
       
  3663   show "\<forall>n. \<not> P (f n) \<and> Q (f n) \<longrightarrow> Q (f (Suc n)) \<and> (f (Suc n), f n) \<in> abc_dec_2_LE"
       
  3664     using fetch
       
  3665   proof(rule_tac allI, rule_tac impI)
       
  3666     fix na
       
  3667     assume "\<not> P (f na) \<and> Q (f na)"
       
  3668     thus "Q (f (Suc na)) \<and> (f (Suc na), f na) \<in> abc_dec_2_LE"
       
  3669       apply(simp add: f)
       
  3670       apply(case_tac "steps ((start_of ly as + 2 * n), la, ra)
       
  3671         (ci ly (start_of ly as) (Dec n e), start_of ly as - Suc 0) na", simp)
       
  3672     proof -
       
  3673       fix a b c 
       
  3674       assume "\<not> P ((a, b, c), start_of ly as, n) \<and> Q ((a, b, c), start_of ly as, n)"
       
  3675       thus "Q (step (a, b, c) (ci ly (start_of ly as) (Dec n e), start_of ly as - Suc 0), start_of ly as, n) \<and>
       
  3676                ((step (a, b, c) (ci ly (start_of ly as) (Dec n e), start_of ly as - Suc 0), start_of ly as, n), 
       
  3677                    (a, b, c), start_of ly as, n) \<in> abc_dec_2_LE"
       
  3678         apply(simp add: Q)
       
  3679         apply(erule_tac conjE)
       
  3680         apply(case_tac c, case_tac [2] aa)
       
  3681         apply(simp_all add: dec_inv_2.simps Let_def)
       
  3682         apply(simp_all split: if_splits)
       
  3683         using fetch layout dec_suc
       
  3684         apply(auto simp: step.simps P dec_inv_2.simps Let_def abc_dec_2_LE_def lex_triple_def lex_pair_def lex_square_def
       
  3685                          fix_add numeral_3_eq_3) 
       
  3686         done
       
  3687     qed
       
  3688   qed
       
  3689 qed
       
  3690 
       
  3691 lemma [simp]: 
       
  3692   "\<lbrakk>inv_stop (as, abc_lm_s lm n (abc_lm_v lm n - Suc 0)) 
       
  3693   (start_of (layout_of ap) as + 2 * n + 16, a, b) ires;
       
  3694    abc_lm_v lm n > 0;
       
  3695    abc_fetch as ap = Some (Dec n e)\<rbrakk>
       
  3696   \<Longrightarrow> crsp (layout_of ap) (abc_step_l (as, lm) (Some (Dec n e))) 
       
  3697   (start_of (layout_of ap) as + 2 * n + 16, a, b) ires"
       
  3698 apply(auto simp: inv_stop.simps crsp.simps  abc_step_l.simps startof_Suc2)
       
  3699 apply(drule_tac startof_Suc2, simp)
       
  3700 done
       
  3701   
       
  3702 lemma crsp_step_dec_b_suc:
       
  3703   assumes layout: "ly = layout_of ap"
       
  3704   and crsp: "crsp ly (as, lm) (s, l, r) ires"
       
  3705   and inv_start: "inv_locate_a (as, lm) (n, la, ra) ires"
       
  3706   and fetch: "abc_fetch as ap = Some (Dec n e)"
       
  3707   and dec_suc: "0 < abc_lm_v lm n"
       
  3708   shows "\<exists>stp > 0. crsp ly (abc_step_l (as, lm) (Some (Dec n e)))
       
  3709               (steps (start_of ly as + 2 * n, la, ra) (ci (layout_of ap) 
       
  3710                   (start_of ly as) (Dec n e), start_of ly as - Suc 0) stp) ires"
       
  3711   using assms
       
  3712   apply(drule_tac crsp_step_dec_b_suc_pre, auto)
       
  3713   apply(rule_tac x = stp in exI, simp)
       
  3714   apply(simp add: dec_inv_2.simps)
       
  3715   apply(case_tac stp, simp_all add: steps.simps)
       
  3716   done
       
  3717 
       
  3718 lemma crsp_step_dec_b:
       
  3719   assumes layout: "ly = layout_of ap"
       
  3720   and crsp: "crsp ly (as, lm) (s, l, r) ires"
       
  3721   and inv_start: "inv_locate_a (as, lm) (n, la, ra) ires"
       
  3722   and fetch: "abc_fetch as ap = Some (Dec n e)"
       
  3723   shows "\<exists>stp > 0. crsp ly (abc_step_l (as, lm) (Some (Dec n e)))
       
  3724   (steps (start_of ly as + 2 * n, la, ra) (ci ly (start_of ly as) (Dec n e), start_of ly as - Suc 0) stp) ires"
       
  3725 using assms
       
  3726 apply(case_tac "abc_lm_v lm n = 0")
       
  3727 apply(rule_tac crsp_step_dec_b_e, simp_all)
       
  3728 apply(rule_tac crsp_step_dec_b_suc, simp_all)
       
  3729 done
       
  3730 
       
  3731 lemma crsp_step_dec: 
       
  3732   assumes layout: "ly = layout_of ap"
       
  3733   and crsp: "crsp ly (as, lm) (s, l, r) ires"
       
  3734   and fetch: "abc_fetch as ap = Some (Dec n e)"
       
  3735   shows "\<exists>stp > 0. crsp ly (abc_step_l (as, lm) (Some (Dec n e)))
       
  3736   (steps (s, l, r) (ci ly (start_of ly as) (Dec n e), start_of ly as - Suc 0) stp) ires"
       
  3737 proof(simp add: ci.simps)
       
  3738   let ?off = "start_of ly as - Suc 0"
       
  3739   let ?A = "findnth n"
       
  3740   let ?B = "sete (shift (shift tdec_b (2 * n)) ?off) (start_of ly e)"
       
  3741   have "\<exists> stp la ra. steps (s, l, r) (shift ?A ?off @ ?B, ?off) stp = (start_of ly as + 2*n, la, ra)
       
  3742                     \<and> inv_locate_a (as, lm) (n, la, ra) ires"
       
  3743   proof -
       
  3744     have "\<exists>stp l' r'. steps (Suc 0, l, r) (?A, 0) stp = (Suc (2 * n), l', r') \<and> 
       
  3745                      inv_locate_a (as, lm) (n, l', r') ires"
       
  3746       using assms
       
  3747       apply(rule_tac findnth_correct, simp_all)
       
  3748       done
       
  3749     then obtain stp l' r' where a: 
       
  3750       "steps (Suc 0, l, r) (?A, 0) stp = (Suc (2 * n), l', r') \<and> 
       
  3751       inv_locate_a (as, lm) (n, l', r') ires" by blast
       
  3752     then have "steps (Suc 0 + ?off, l, r) (shift ?A ?off, ?off) stp = (Suc (2 * n) + ?off, l', r')"
       
  3753       apply(rule_tac tm_shift_eq_steps, simp_all)
       
  3754       done
       
  3755     moreover have "s = start_of ly as"
       
  3756       using crsp
       
  3757       apply(auto simp: crsp.simps)
       
  3758       done
       
  3759     ultimately show "\<exists> stp la ra. steps (s, l, r) (shift ?A ?off @ ?B, ?off) stp = (start_of ly as + 2*n, la, ra)
       
  3760                     \<and> inv_locate_a (as, lm) (n, la, ra) ires"
       
  3761       using a
       
  3762       apply(drule_tac B = ?B in tm_append_first_steps_eq, auto)
       
  3763       apply(rule_tac x = stp in exI, simp)
       
  3764       done
       
  3765   qed
       
  3766   from this obtain stpa la ra where a: 
       
  3767     "steps (s, l, r) (shift ?A ?off @ ?B, ?off) stpa = (start_of ly as + 2*n, la, ra)
       
  3768                     \<and> inv_locate_a (as, lm) (n, la, ra) ires" by blast
       
  3769   have "\<exists>stp. crsp ly (abc_step_l (as, lm) (Some (Dec n e)))
       
  3770            (steps (start_of ly as + 2*n, la, ra) (shift ?A ?off @ ?B, ?off) stp) ires \<and> stp > 0"
       
  3771     using assms a
       
  3772     apply(drule_tac crsp_step_dec_b, auto)
       
  3773     apply(rule_tac x = stp in exI, simp add: ci.simps)
       
  3774     done
       
  3775   then obtain stpb where b: 
       
  3776     "crsp ly (abc_step_l (as, lm) (Some (Dec n e)))
       
  3777     (steps (start_of ly as + 2*n, la, ra) (shift ?A ?off @ ?B, ?off) stpb) ires \<and> stpb > 0" ..
       
  3778   from a b show "\<exists> stp>0. crsp ly (abc_step_l (as, lm) (Some (Dec n e)))
       
  3779     (steps (s, l, r) (shift ?A ?off @ ?B, ?off) stp) ires"
       
  3780     apply(rule_tac x = "stpa + stpb" in exI)
       
  3781     apply(simp add: steps_add)
       
  3782     done
       
  3783 qed    
       
  3784   
       
  3785 subsection{*Crsp of Goto*}
       
  3786 
       
  3787 lemma crsp_step_goto:
       
  3788   assumes layout: "ly = layout_of ap"
       
  3789   and crsp: "crsp ly (as, lm) (s, l, r) ires"
       
  3790   shows "\<exists>stp>0. crsp ly (abc_step_l (as, lm) (Some (Goto n)))
       
  3791   (steps (s, l, r) (ci ly (start_of ly as) (Goto n), 
       
  3792             start_of ly as - Suc 0) stp) ires"
       
  3793 using crsp
       
  3794 apply(rule_tac x = "Suc 0" in exI)
       
  3795 apply(case_tac r, case_tac [2] a)
       
  3796 apply(simp_all add: ci.simps steps.simps step.simps crsp.simps fetch.simps
       
  3797   crsp.simps abc_step_l.simps)
       
  3798 done
       
  3799 
       
  3800 lemma crsp_step_in:
       
  3801   assumes layout: "ly = layout_of ap"
       
  3802   and compile: "tp = tm_of ap"
       
  3803   and crsp: "crsp ly (as, lm) (s, l, r) ires"
       
  3804   and fetch: "abc_fetch as ap = Some ins"
       
  3805   shows "\<exists> stp>0. crsp ly (abc_step_l (as, lm) (Some ins))
       
  3806                       (steps (s, l, r) (ci ly (start_of ly as) ins, start_of ly as - 1) stp) ires"
       
  3807   using assms
       
  3808   apply(case_tac ins, simp_all)
       
  3809   apply(rule crsp_step_inc, simp_all)
       
  3810   apply(rule crsp_step_dec, simp_all)
       
  3811   apply(rule_tac crsp_step_goto, simp_all)
       
  3812   done
       
  3813 
       
  3814 lemma crsp_step:
       
  3815   assumes layout: "ly = layout_of ap"
       
  3816   and compile: "tp = tm_of ap"
       
  3817   and crsp: "crsp ly (as, lm) (s, l, r) ires"
       
  3818   and fetch: "abc_fetch as ap = Some ins"
       
  3819   shows "\<exists> stp>0. crsp ly (abc_step_l (as, lm) (Some ins))
       
  3820                       (steps (s, l, r) (tp, 0) stp) ires"
       
  3821 proof -
       
  3822   have "\<exists> stp>0. crsp ly (abc_step_l (as, lm) (Some ins))
       
  3823                       (steps (s, l, r) (ci ly (start_of ly as) ins, start_of ly as - 1) stp) ires"
       
  3824     using assms
       
  3825     apply(rule_tac crsp_step_in, simp_all)
       
  3826     done
       
  3827   from this obtain stp where d: "stp > 0 \<and> crsp ly (abc_step_l (as, lm) (Some ins))
       
  3828                       (steps (s, l, r) (ci ly (start_of ly as) ins, start_of ly as - 1) stp) ires" ..
       
  3829   obtain s' l' r' where e:
       
  3830     "(steps (s, l, r) (ci ly (start_of ly as) ins, start_of ly as - 1) stp) = (s', l', r')"
       
  3831     apply(case_tac "(steps (s, l, r) (ci ly (start_of ly as) ins, start_of ly as - 1) stp)")
       
  3832     by blast
       
  3833   then have "steps (s, l, r) (tp, 0) stp = (s', l', r')"
       
  3834     using assms d
       
  3835     apply(rule_tac steps_eq_in)
       
  3836     apply(simp_all)
       
  3837     apply(case_tac "(abc_step_l (as, lm) (Some ins))", simp add: crsp.simps)
       
  3838     done    
       
  3839   thus " \<exists>stp>0. crsp ly (abc_step_l (as, lm) (Some ins)) (steps (s, l, r) (tp, 0) stp) ires"
       
  3840     using d e
       
  3841     apply(rule_tac x = stp in exI, simp)
       
  3842     done
       
  3843 qed
       
  3844 
       
  3845 lemma crsp_steps:
       
  3846   assumes layout: "ly = layout_of ap"
       
  3847   and compile: "tp = tm_of ap"
       
  3848   and crsp: "crsp ly (as, lm) (s, l, r) ires"
       
  3849   shows "\<exists> stp. crsp ly (abc_steps_l (as, lm) ap n)
       
  3850                       (steps (s, l, r) (tp, 0) stp) ires"
       
  3851 (*
       
  3852 proof(induct n)
       
  3853   case 0
       
  3854   have "crsp ly (abc_steps_l (as, lm) ap 0) (steps (s, l, r) (tp, 0) 0) ires"
       
  3855     using crsp by(simp add: steps.simps abc_steps_l.simps)
       
  3856   thus "?case"
       
  3857     by(rule_tac x = 0 in exI, simp)
       
  3858 next
       
  3859   case (Suc n)
       
  3860   obtain as' lm' where a: "abc_steps_l (as, lm) ap n = (as', lm')"
       
  3861     by(case_tac "abc_steps_l (as, lm) ap n", auto) 
       
  3862   have "\<exists>stp\<ge>n. crsp ly (abc_steps_l (as, lm) ap n) (steps (s, l, r) (tp, 0) stp) ires"
       
  3863     by fact
       
  3864   from this a obtain stpa where b:
       
  3865     "stpa\<ge>n \<and> crsp ly (as', lm') (steps (s, l, r) (tp, 0) stpa) ires" by auto
       
  3866   obtain s' l' r' where "steps (s, l, r) (tp, 0) stpa = (s', l', r')"
       
  3867     by(case_tac "steps (s, l, r) (tp, 0) stpa")
       
  3868   then have "stpa\<ge>n \<and> crsp ly (as', lm') (s', l', r') ires" using b by simp
       
  3869   from a and this show "?case"
       
  3870   proof(cases "abc_fetch as' ap")
       
  3871     case None
       
  3872     
       
  3873   
       
  3874 
       
  3875     have "crsp ly (abc_steps_l (as, lm) ap 0) (steps (s, l, r) (tp, 0) stp) ires"
       
  3876     apply(simp add: steps.simps abc_steps_l.simps)
       
  3877 *)
       
  3878   using crsp
       
  3879   apply(induct n)
       
  3880   apply(rule_tac x = 0 in exI) 
       
  3881   apply(simp add: steps.simps abc_steps_l.simps, simp)
       
  3882   apply(case_tac "(abc_steps_l (as, lm) ap n)", auto)
       
  3883   apply(frule_tac abc_step_red, simp)
       
  3884   apply(case_tac "abc_fetch a ap", simp add: abc_step_l.simps, auto)
       
  3885   apply(case_tac "steps (s, l, r) (tp, 0) stp", simp)
       
  3886   using assms
       
  3887   apply(drule_tac s = ab and l = ba and r = c in crsp_step, auto)
       
  3888   apply(rule_tac x = "stp + stpa" in exI, simp add: steps_add)
       
  3889   done
       
  3890 
       
  3891 lemma tp_correct': 
       
  3892   assumes layout: "ly = layout_of ap"
       
  3893   and compile: "tp = tm_of ap"
       
  3894   and crsp: "crsp ly (0, lm) (Suc 0, l, r) ires"
       
  3895   and abc_halt: "abc_steps_l (0, lm) ap stp = (length ap, am)"
       
  3896   shows "\<exists> stp k. steps (Suc 0, l, r) (tp, 0) stp = (start_of ly (length ap), Bk # Bk # ires, <am> @ Bk\<up>k)"
       
  3897   using assms
       
  3898   apply(drule_tac n = stp in crsp_steps, auto)
       
  3899   apply(rule_tac x = stpa in exI)
       
  3900   apply(case_tac "steps (Suc 0, l, r) (tm_of ap, 0) stpa", simp add: crsp.simps)
       
  3901   done
       
  3902 
       
  3903 text{*The tp @ [(Nop, 0), (Nop, 0)] is nomoral turing machines, so we can use Hoare_plus when composing with Mop machine*}
       
  3904 
       
  3905 thm layout_of.simps
       
  3906 lemma layout_id_cons: "layout_of (ap @ [p]) = layout_of ap @ [length_of p]"
       
  3907 apply(simp add: layout_of.simps)
       
  3908 done
       
  3909 
       
  3910 lemma [simp]: "length (layout_of xs) = length xs"
       
  3911 by(simp add: layout_of.simps)
       
  3912 
       
  3913 thm tms_of.simps
       
  3914 term ci
       
  3915 thm tms_of.simps
       
  3916 thm tpairs_of.simps
       
  3917 
       
  3918 lemma [simp]:  
       
  3919   "map (start_of (layout_of xs @ [length_of x])) [0..<length xs] =  (map (start_of (layout_of xs)) [0..<length xs])"
       
  3920 apply(auto)
       
  3921 apply(simp add: layout_of.simps start_of.simps)
       
  3922 done
       
  3923 
       
  3924 lemma tpairs_id_cons: 
       
  3925   "tpairs_of (xs @ [x]) = tpairs_of xs @ [(start_of (layout_of (xs @ [x])) (length xs), x)]"
       
  3926 apply(auto simp: tpairs_of.simps layout_id_cons )
       
  3927 done
       
  3928 
       
  3929 lemma map_length_ci:
       
  3930   "(map (length \<circ> (\<lambda>(xa, y). ci (layout_of xs @ [length_of x]) xa y)) (tpairs_of xs)) = 
       
  3931   (map (length \<circ> (\<lambda>(x, y). ci (layout_of xs) x y)) (tpairs_of xs)) "
       
  3932 apply(auto)
       
  3933 apply(case_tac b, auto simp: ci.simps sete.simps)
       
  3934 done
       
  3935 
       
  3936 lemma length_tp'[simp]: 
       
  3937   "\<lbrakk>ly = layout_of ap; tp = tm_of ap\<rbrakk> \<Longrightarrow>
       
  3938        length tp = 2 * listsum (take (length ap) (layout_of ap))"
       
  3939 proof(induct ap arbitrary: ly tp rule: rev_induct)
       
  3940   case Nil
       
  3941   thus "?case"
       
  3942     by(simp add: tms_of.simps tm_of.simps tpairs_of.simps)
       
  3943 next
       
  3944   fix x xs ly tp
       
  3945   assume ind: "\<And>ly tp. \<lbrakk>ly = layout_of xs; tp = tm_of xs\<rbrakk> \<Longrightarrow> 
       
  3946     length tp = 2 * listsum (take (length xs) (layout_of xs))"
       
  3947   and layout: "ly = layout_of (xs @ [x])"
       
  3948   and tp: "tp = tm_of (xs @ [x])"
       
  3949   obtain ly' where a: "ly' = layout_of xs"
       
  3950     by metis
       
  3951   obtain tp' where b: "tp' = tm_of xs"
       
  3952     by metis
       
  3953   have c: "length tp' = 2 * listsum (take (length xs) (layout_of xs))"
       
  3954     using a b
       
  3955     by(erule_tac ind, simp)
       
  3956   thus "length tp = 2 * 
       
  3957     listsum (take (length (xs @ [x])) (layout_of (xs @ [x])))"
       
  3958     using tp b
       
  3959     apply(auto simp: layout_id_cons tm_of.simps tms_of.simps length_concat tpairs_id_cons map_length_ci)
       
  3960     apply(case_tac x)
       
  3961     apply(auto simp: ci.simps tinc_b_def tdec_b_def length_findnth sete.simps length_of.simps
       
  3962                  split: abc_inst.splits)
       
  3963     done
       
  3964 qed
       
  3965 
       
  3966 lemma [simp]: 
       
  3967   "\<lbrakk>ly = layout_of ap; tp = tm_of ap\<rbrakk> \<Longrightarrow>
       
  3968         fetch (tp @ [(Nop, 0), (Nop, 0)]) (start_of ly (length ap)) b = 
       
  3969        (Nop, 0)"
       
  3970 apply(case_tac b)
       
  3971 apply(simp_all add: start_of.simps fetch.simps nth_append)
       
  3972 done
       
  3973 (*
       
  3974 lemma tp_correct: 
       
  3975   assumes layout: "ly = layout_of ap"
       
  3976   and compile: "tp = tm_of ap"
       
  3977   and crsp: "crsp ly (0, lm) (Suc 0, l, r) ires"
       
  3978   and abc_halt: "abc_steps_l (0, lm) ap stp = (length ap, am)"
       
  3979   shows "\<exists> stp k. steps (Suc 0, l, r) (tp @ [(Nop, 0), (Nop, 0)], 0) stp = (0, Bk # Bk # ires, <am> @ Bk\<up>k)"
       
  3980   using assms
       
  3981 proof -
       
  3982   have "\<exists> stp k. steps (Suc 0, l, r) (tp @ [(Nop, 0), (Nop, 0)], 0) stp =
       
  3983     (start_of ly (length ap), Bk # Bk # ires, <am> @ Bk\<up>k)"
       
  3984   proof -
       
  3985     have "\<exists> stp k. steps (Suc 0, l, r) (tp, 0) stp =
       
  3986     (start_of ly (length ap), Bk # Bk # ires, <am> @ Bk\<up>k)"
       
  3987       using assms
       
  3988       apply(rule_tac tp_correct', simp_all)
       
  3989       done
       
  3990     from this obtain stp k where "steps (Suc 0, l, r) (tp, 0) stp =
       
  3991     (start_of ly (length ap), Bk # Bk # ires, <am> @ Bk\<up>k)" by blast
       
  3992     thus "?thesis"
       
  3993       apply(rule_tac x = stp in exI, rule_tac x = k in exI)
       
  3994       apply(drule_tac tm_append_first_steps_eq, simp_all)
       
  3995       done
       
  3996   qed
       
  3997   from this obtain stp k where 
       
  3998     "steps (Suc 0, l, r) (tp @ [(Nop, 0), (Nop, 0)], 0) stp =
       
  3999     (start_of ly (length ap), Bk # Bk # ires, <am> @ Bk\<up>k)"
       
  4000     by blast
       
  4001   thus "\<exists>stp k. steps (Suc 0, l, r) (tp @ [(Nop, 0), (Nop, 0)], 0) stp 
       
  4002     = (0, Bk # Bk # ires, <am> @ Bk \<up> k)"
       
  4003     using assms
       
  4004     apply(rule_tac x = "stp + Suc 0" in exI)
       
  4005     apply(simp add: steps_add)
       
  4006     apply(auto simp: step.simps)
       
  4007     done
       
  4008 qed
       
  4009  *)   
       
  4010 (********for mopup***********)
       
  4011 fun mopup_a :: "nat \<Rightarrow> instr list"
       
  4012   where
       
  4013   "mopup_a 0 = []" |
       
  4014   "mopup_a (Suc n) = mopup_a n @ 
       
  4015        [(R, 2*n + 3), (W0, 2*n + 2), (R, 2*n + 1), (W1, 2*n + 2)]"
       
  4016 
       
  4017 definition mopup_b :: "instr list"
       
  4018   where
       
  4019   "mopup_b \<equiv> [(R, 2), (R, 1), (L, 5), (W0, 3), (R, 4), (W0, 3),
       
  4020             (R, 2), (W0, 3), (L, 5), (L, 6), (R, 0), (L, 6)]"
       
  4021 
       
  4022 fun mopup :: "nat \<Rightarrow> instr list"
       
  4023   where 
       
  4024   "mopup n = mopup_a n @ shift mopup_b (2*n)"
       
  4025 (****)
       
  4026 
       
  4027 type_synonym mopup_type = "config \<Rightarrow> nat list \<Rightarrow> nat \<Rightarrow> cell list \<Rightarrow> bool"
       
  4028 
       
  4029 fun mopup_stop :: "mopup_type"
       
  4030   where
       
  4031   "mopup_stop (s, l, r) lm n ires= 
       
  4032         (\<exists> ln rn. l = Bk\<up>ln @ Bk # Bk # ires \<and> r = <abc_lm_v lm n> @ Bk\<up>rn)"
       
  4033 
       
  4034 fun mopup_bef_erase_a :: "mopup_type"
       
  4035   where
       
  4036   "mopup_bef_erase_a (s, l, r) lm n ires= 
       
  4037          (\<exists> ln m rn. l = Bk\<up>ln @ Bk # Bk # ires \<and> 
       
  4038                   r = Oc\<up>m@ Bk # <(drop ((s + 1) div 2) lm)> @ Bk\<up>rn)"
       
  4039 
       
  4040 fun mopup_bef_erase_b :: "mopup_type"
       
  4041   where
       
  4042   "mopup_bef_erase_b (s, l, r) lm n ires = 
       
  4043       (\<exists> ln m rn. l = Bk\<up>ln @ Bk # Bk # ires \<and> r = Bk # Oc\<up>m @ Bk # 
       
  4044                                       <(drop (s div 2) lm)> @ Bk\<up>rn)"
       
  4045 
       
  4046 fun mopup_jump_over1 :: "mopup_type"
       
  4047   where
       
  4048   "mopup_jump_over1 (s, l, r) lm n ires = 
       
  4049       (\<exists> ln m1 m2 rn. m1 + m2 = Suc (abc_lm_v lm n) \<and> 
       
  4050         l = Oc\<up>m1 @ Bk\<up>ln @ Bk # Bk # ires \<and> 
       
  4051      (r = Oc\<up>m2 @ Bk # <(drop (Suc n) lm)> @ Bk\<up>rn \<or> 
       
  4052      (r = Oc\<up>m2 \<and> (drop (Suc n) lm) = [])))"
       
  4053 
       
  4054 fun mopup_aft_erase_a :: "mopup_type"
       
  4055   where
       
  4056   "mopup_aft_erase_a (s, l, r) lm n ires = 
       
  4057       (\<exists> lnl lnr rn (ml::nat list) m. 
       
  4058           m = Suc (abc_lm_v lm n) \<and> l = Bk\<up>lnr @ Oc\<up>m @ Bk\<up>lnl @ Bk # Bk # ires \<and> 
       
  4059                                    (r = <ml> @ Bk\<up>rn))"
       
  4060 
       
  4061 fun mopup_aft_erase_b :: "mopup_type"
       
  4062   where
       
  4063   "mopup_aft_erase_b (s, l, r) lm n ires= 
       
  4064    (\<exists> lnl lnr rn (ml::nat list) m. 
       
  4065       m = Suc (abc_lm_v lm n) \<and> 
       
  4066       l = Bk\<up>lnr @ Oc\<up>m @ Bk\<up>lnl @ Bk # Bk # ires \<and> 
       
  4067      (r = Bk # <ml> @ Bk\<up>rn \<or>
       
  4068       r = Bk # Bk # <ml> @ Bk\<up>rn))"
       
  4069 
       
  4070 fun mopup_aft_erase_c :: "mopup_type"
       
  4071   where
       
  4072   "mopup_aft_erase_c (s, l, r) lm n ires = 
       
  4073  (\<exists> lnl lnr rn (ml::nat list) m. 
       
  4074      m = Suc (abc_lm_v lm n) \<and> 
       
  4075      l = Bk\<up>lnr @ Oc\<up>m @ Bk\<up>lnl @ Bk # Bk # ires \<and> 
       
  4076     (r = <ml> @ Bk\<up>rn \<or> r = Bk # <ml> @ Bk\<up>rn))"
       
  4077 
       
  4078 fun mopup_left_moving :: "mopup_type"
       
  4079   where
       
  4080   "mopup_left_moving (s, l, r) lm n ires = 
       
  4081   (\<exists> lnl lnr rn m.
       
  4082      m = Suc (abc_lm_v lm n) \<and> 
       
  4083    ((l = Bk\<up>lnr @ Oc\<up>m @ Bk\<up>lnl @ Bk # Bk # ires \<and> r = Bk\<up>rn) \<or>
       
  4084     (l = Oc\<up>(m - 1) @ Bk\<up>lnl @ Bk # Bk # ires \<and> r = Oc # Bk\<up>rn)))"
       
  4085 
       
  4086 fun mopup_jump_over2 :: "mopup_type"
       
  4087   where
       
  4088   "mopup_jump_over2 (s, l, r) lm n ires = 
       
  4089      (\<exists> ln rn m1 m2.
       
  4090           m1 + m2 = Suc (abc_lm_v lm n) 
       
  4091         \<and> r \<noteq> [] 
       
  4092         \<and> (hd r = Oc \<longrightarrow> (l = Oc\<up>m1 @ Bk\<up>ln @ Bk # Bk # ires \<and> r = Oc\<up>m2 @ Bk\<up>rn)) 
       
  4093         \<and> (hd r = Bk \<longrightarrow> (l = Bk\<up>ln @ Bk # ires \<and> r = Bk # Oc\<up>(m1+m2)@ Bk\<up>rn)))"
       
  4094 
       
  4095 
       
  4096 fun mopup_inv :: "mopup_type"
       
  4097   where
       
  4098   "mopup_inv (s, l, r) lm n ires = 
       
  4099       (if s = 0 then mopup_stop (s, l, r) lm n ires
       
  4100        else if s \<le> 2*n then
       
  4101                if s mod 2 = 1 then mopup_bef_erase_a (s, l, r) lm n ires
       
  4102                    else mopup_bef_erase_b (s, l, r) lm n ires
       
  4103             else if s = 2*n + 1 then 
       
  4104                 mopup_jump_over1 (s, l, r) lm n ires
       
  4105             else if s = 2*n + 2 then mopup_aft_erase_a (s, l, r) lm n ires
       
  4106             else if s = 2*n + 3 then mopup_aft_erase_b (s, l, r) lm n ires
       
  4107             else if s = 2*n + 4 then mopup_aft_erase_c (s, l, r) lm n ires
       
  4108             else if s = 2*n + 5 then mopup_left_moving (s, l, r) lm n ires
       
  4109             else if s = 2*n + 6 then mopup_jump_over2 (s, l, r) lm n ires
       
  4110             else False)"
       
  4111 
       
  4112 lemma mopup_fetch_0[simp]: 
       
  4113      "(fetch (mopup_a n @ shift mopup_b (2 * n)) 0 b) = (Nop, 0)"
       
  4114 by(simp add: fetch.simps)
       
  4115 
       
  4116 lemma mop_bef_length[simp]: "length (mopup_a n) = 4 * n"
       
  4117 apply(induct n, simp_all add: mopup_a.simps)
       
  4118 done
       
  4119 
       
  4120 lemma mopup_a_nth: 
       
  4121   "\<lbrakk>q < n; x < 4\<rbrakk> \<Longrightarrow> mopup_a n ! (4 * q + x) = 
       
  4122                              mopup_a (Suc q) ! ((4 * q) + x)"
       
  4123 apply(induct n, simp)
       
  4124 apply(case_tac "q < n", simp add: mopup_a.simps, auto)
       
  4125 apply(simp add: nth_append)
       
  4126 apply(subgoal_tac "q = n", simp)
       
  4127 apply(arith)
       
  4128 done
       
  4129 
       
  4130 lemma fetch_bef_erase_a_o[simp]: 
       
  4131  "\<lbrakk>0 < s; s \<le> 2 * n; s mod 2 = Suc 0\<rbrakk>
       
  4132   \<Longrightarrow> (fetch (mopup_a n @ shift mopup_b (2 * n)) s Oc) = (W0, s + 1)"
       
  4133 apply(subgoal_tac "\<exists> q. s = 2*q + 1", auto)
       
  4134 apply(subgoal_tac "length (mopup_a n) = 4*n")
       
  4135 apply(auto simp: fetch.simps nth_of.simps nth_append)
       
  4136 apply(subgoal_tac "mopup_a n ! (4 * q + 1) = 
       
  4137                       mopup_a (Suc q) ! ((4 * q) + 1)", 
       
  4138       simp add: mopup_a.simps nth_append)
       
  4139 apply(rule mopup_a_nth, auto)
       
  4140 apply arith
       
  4141 done
       
  4142 
       
  4143 lemma fetch_bef_erase_a_b[simp]:
       
  4144   "\<lbrakk>0 < s; s \<le> 2 * n; s mod 2 = Suc 0\<rbrakk>
       
  4145    \<Longrightarrow>  (fetch (mopup_a n @ shift mopup_b (2 * n)) s Bk) = (R, s + 2)"
       
  4146 apply(subgoal_tac "\<exists> q. s = 2*q + 1", auto)
       
  4147 apply(subgoal_tac "length (mopup_a n) = 4*n")
       
  4148 apply(auto simp: fetch.simps nth_of.simps nth_append)
       
  4149 apply(subgoal_tac "mopup_a n ! (4 * q + 0) = 
       
  4150                        mopup_a (Suc q) ! ((4 * q + 0))", 
       
  4151       simp add: mopup_a.simps nth_append)
       
  4152 apply(rule mopup_a_nth, auto)
       
  4153 apply arith
       
  4154 done
       
  4155 
       
  4156 lemma fetch_bef_erase_b_b: 
       
  4157   "\<lbrakk>n < length lm; 0 < s; s \<le> 2 * n; s mod 2 = 0\<rbrakk> \<Longrightarrow> 
       
  4158      (fetch (mopup_a n @ shift mopup_b (2 * n)) s Bk) = (R, s - 1)"
       
  4159 apply(subgoal_tac "\<exists> q. s = 2 * q", auto)
       
  4160 apply(case_tac qa, simp, simp)
       
  4161 apply(auto simp: fetch.simps nth_of.simps nth_append)
       
  4162 apply(subgoal_tac "mopup_a n ! (4 * nat + 2) = 
       
  4163                      mopup_a (Suc nat) ! ((4 * nat) + 2)", 
       
  4164       simp add: mopup_a.simps nth_append)
       
  4165 apply(rule mopup_a_nth, auto)
       
  4166 done
       
  4167 
       
  4168 lemma fetch_jump_over1_o: 
       
  4169  "fetch (mopup_a n @ shift mopup_b (2 * n)) (Suc (2 * n)) Oc
       
  4170   = (R, Suc (2 * n))"
       
  4171 apply(subgoal_tac "length (mopup_a n) = 4 * n")
       
  4172 apply(auto simp: fetch.simps nth_of.simps mopup_b_def nth_append 
       
  4173                  shift.simps)
       
  4174 done
       
  4175 
       
  4176 lemma fetch_jump_over1_b: 
       
  4177  "fetch (mopup_a n @ shift mopup_b (2 * n)) (Suc (2 * n)) Bk 
       
  4178  = (R, Suc (Suc (2 * n)))"
       
  4179 apply(subgoal_tac "length (mopup_a n) = 4 * n")
       
  4180 apply(auto simp: fetch.simps nth_of.simps mopup_b_def 
       
  4181                  nth_append shift.simps)
       
  4182 done
       
  4183 
       
  4184 lemma fetch_aft_erase_a_o: 
       
  4185  "fetch (mopup_a n @ shift mopup_b (2 * n)) (Suc (Suc (2 * n))) Oc 
       
  4186  = (W0, Suc (2 * n + 2))"
       
  4187 apply(subgoal_tac "length (mopup_a n) = 4 * n")
       
  4188 apply(auto simp: fetch.simps nth_of.simps mopup_b_def 
       
  4189                  nth_append shift.simps)
       
  4190 done
       
  4191 
       
  4192 lemma fetch_aft_erase_a_b: 
       
  4193  "fetch (mopup_a n @ shift mopup_b (2 * n)) (Suc (Suc (2 * n))) Bk
       
  4194   = (L, Suc (2 * n + 4))"
       
  4195 apply(subgoal_tac "length (mopup_a n) = 4 * n")
       
  4196 apply(auto simp: fetch.simps nth_of.simps mopup_b_def 
       
  4197                  nth_append shift.simps)
       
  4198 done
       
  4199 
       
  4200 lemma fetch_aft_erase_b_b: 
       
  4201  "fetch (mopup_a n @ shift mopup_b (2 * n)) (2*n + 3) Bk
       
  4202   = (R, Suc (2 * n + 3))"
       
  4203 apply(subgoal_tac "length (mopup_a n) = 4 * n")
       
  4204 apply(subgoal_tac "2*n + 3 = Suc (2*n + 2)", simp only: fetch.simps)
       
  4205 apply(auto simp: nth_of.simps mopup_b_def nth_append shift.simps)
       
  4206 done
       
  4207 
       
  4208 lemma fetch_aft_erase_c_o: 
       
  4209  "fetch (mopup_a n @ shift mopup_b (2 * n)) (2 * n + 4) Oc 
       
  4210  = (W0, Suc (2 * n + 2))"
       
  4211 apply(subgoal_tac "length (mopup_a n) = 4 * n")
       
  4212 apply(subgoal_tac "2*n + 4 = Suc (2*n + 3)", simp only: fetch.simps)
       
  4213 apply(auto simp: nth_of.simps mopup_b_def nth_append shift.simps)
       
  4214 done
       
  4215 
       
  4216 lemma fetch_aft_erase_c_b: 
       
  4217  "fetch (mopup_a n @ shift mopup_b (2 * n)) (2 * n + 4) Bk 
       
  4218  = (R, Suc (2 * n + 1))"
       
  4219 apply(subgoal_tac "length (mopup_a n) = 4 * n")
       
  4220 apply(subgoal_tac "2*n + 4 = Suc (2*n + 3)", simp only: fetch.simps)
       
  4221 apply(auto simp: nth_of.simps mopup_b_def nth_append shift.simps)
       
  4222 done
       
  4223 
       
  4224 lemma fetch_left_moving_o: 
       
  4225  "(fetch (mopup_a n @ shift mopup_b (2 * n)) (2 * n + 5) Oc) 
       
  4226  = (L, 2*n + 6)"
       
  4227 apply(subgoal_tac "length (mopup_a n) = 4 * n")
       
  4228 apply(subgoal_tac "2*n + 5 = Suc (2*n + 4)", simp only: fetch.simps)
       
  4229 apply(auto simp: nth_of.simps mopup_b_def nth_append shift.simps)
       
  4230 done
       
  4231 
       
  4232 lemma fetch_left_moving_b: 
       
  4233  "(fetch (mopup_a n @ shift mopup_b (2 * n)) (2 * n + 5) Bk)
       
  4234   = (L, 2*n + 5)"
       
  4235 apply(subgoal_tac "length (mopup_a n) = 4 * n")
       
  4236 apply(subgoal_tac "2*n + 5 = Suc (2*n + 4)", simp only: fetch.simps)
       
  4237 apply(auto simp: nth_of.simps mopup_b_def nth_append shift.simps)
       
  4238 done
       
  4239 
       
  4240 lemma fetch_jump_over2_b:
       
  4241   "(fetch (mopup_a n @ shift mopup_b (2 * n)) (2 * n + 6) Bk) 
       
  4242  = (R, 0)"
       
  4243 apply(subgoal_tac "length (mopup_a n) = 4 * n")
       
  4244 apply(subgoal_tac "2*n + 6 = Suc (2*n + 5)", simp only: fetch.simps)
       
  4245 apply(auto simp: nth_of.simps mopup_b_def nth_append shift.simps)
       
  4246 done
       
  4247 
       
  4248 lemma fetch_jump_over2_o: 
       
  4249 "(fetch (mopup_a n @ shift mopup_b (2 * n)) (2 * n + 6) Oc) 
       
  4250  = (L, 2*n + 6)"
       
  4251 apply(subgoal_tac "length (mopup_a n) = 4 * n")
       
  4252 apply(subgoal_tac "2*n + 6 = Suc (2*n + 5)", simp only: fetch.simps)
       
  4253 apply(auto simp: nth_of.simps mopup_b_def nth_append shift.simps)
       
  4254 done
       
  4255 
       
  4256 lemmas mopupfetchs = 
       
  4257 fetch_bef_erase_a_o fetch_bef_erase_a_b fetch_bef_erase_b_b 
       
  4258 fetch_jump_over1_o fetch_jump_over1_b fetch_aft_erase_a_o 
       
  4259 fetch_aft_erase_a_b fetch_aft_erase_b_b fetch_aft_erase_c_o 
       
  4260 fetch_aft_erase_c_b fetch_left_moving_o fetch_left_moving_b 
       
  4261 fetch_jump_over2_b fetch_jump_over2_o
       
  4262 
       
  4263 declare 
       
  4264   mopup_jump_over2.simps[simp del] mopup_left_moving.simps[simp del]
       
  4265   mopup_aft_erase_c.simps[simp del] mopup_aft_erase_b.simps[simp del] 
       
  4266   mopup_aft_erase_a.simps[simp del] mopup_jump_over1.simps[simp del]
       
  4267   mopup_bef_erase_a.simps[simp del] mopup_bef_erase_b.simps[simp del]
       
  4268   mopup_stop.simps[simp del]
       
  4269 
       
  4270 lemma [simp]: 
       
  4271   "\<lbrakk>mopup_bef_erase_a (s, l, Oc # xs) lm n ires\<rbrakk> \<Longrightarrow> 
       
  4272   mopup_bef_erase_b (Suc s, l, Bk # xs) lm n ires"
       
  4273 apply(auto simp: mopup_bef_erase_a.simps mopup_bef_erase_b.simps )
       
  4274 apply(rule_tac x = "m - 1" in exI, rule_tac x = rn in exI)
       
  4275 apply(case_tac m, simp, simp)
       
  4276 done
       
  4277 
       
  4278 lemma mopup_false1:
       
  4279   "\<lbrakk>0 < s; s \<le> 2 * n; s mod 2 = Suc 0;  \<not> Suc s \<le> 2 * n\<rbrakk> 
       
  4280   \<Longrightarrow> RR"
       
  4281 apply(arith)
       
  4282 done
       
  4283 
       
  4284 lemma [simp]: 
       
  4285  "\<lbrakk>n < length lm; 0 < s; s \<le> 2 * n; s mod 2 = Suc 0; 
       
  4286    mopup_bef_erase_a (s, l, Oc # xs) lm n ires; r = Oc # xs\<rbrakk>
       
  4287  \<Longrightarrow> (Suc s \<le> 2 * n \<longrightarrow> mopup_bef_erase_b (Suc s, l, Bk # xs) lm n ires)  \<and>
       
  4288      (\<not> Suc s \<le> 2 * n \<longrightarrow> mopup_jump_over1 (Suc s, l, Bk # xs) lm n ires) "
       
  4289 apply(auto elim: mopup_false1)
       
  4290 done
       
  4291 
       
  4292 lemma drop_tape_of_cons: 
       
  4293   "\<lbrakk>Suc q < length lm; x = lm ! q\<rbrakk> \<Longrightarrow> <drop q lm> = Oc # Oc \<up> x @ Bk # <drop (Suc q) lm>"
       
  4294 by (metis Suc_lessD append_Cons list.simps(2) nth_drop' replicate_Suc tape_of_nl_cons)
       
  4295 
       
  4296 lemma erase2jumpover1:
       
  4297   "\<lbrakk>q < length list; 
       
  4298              \<forall>rn. <drop q list> \<noteq> Oc # Oc \<up> abc_lm_v (a # list) (Suc q) @ Bk # <drop (Suc q) list> @ Bk \<up> rn\<rbrakk>
       
  4299        \<Longrightarrow> <drop q list> = Oc # Oc \<up> abc_lm_v (a # list) (Suc q)"
       
  4300 apply(erule_tac x = 0 in allE, simp)
       
  4301 apply(case_tac "Suc q < length list")
       
  4302 apply(erule_tac notE)
       
  4303 apply(rule_tac drop_tape_of_cons, simp_all add: abc_lm_v.simps)
       
  4304 apply(subgoal_tac "length list = Suc q", auto)
       
  4305 apply(subgoal_tac "drop q list = [list ! q]")
       
  4306 apply(simp add: tape_of_nl_abv tape_of_nat_abv)
       
  4307 by (metis append_Nil2 append_eq_conv_conj drop_Suc_conv_tl lessI)
       
  4308 
       
  4309 lemma erase2jumpover2:
       
  4310   "\<lbrakk>q < length list; \<forall>rn. <drop q list> @ Bk # Bk \<up> n \<noteq>
       
  4311   Oc # Oc \<up> abc_lm_v (a # list) (Suc q) @ Bk # <drop (Suc q) list> @ Bk \<up> rn\<rbrakk>
       
  4312   \<Longrightarrow> RR"
       
  4313 apply(case_tac "Suc q < length list")
       
  4314 apply(erule_tac x = "Suc n" in allE, simp)
       
  4315 apply(erule_tac notE)
       
  4316 apply(rule_tac drop_tape_of_cons, simp_all add: abc_lm_v.simps)
       
  4317 apply(subgoal_tac "length list = Suc q", auto)
       
  4318 apply(erule_tac x = "n" in allE, simp add: tape_of_nl_abv)
       
  4319 by (metis append_Nil2 append_eq_conv_conj drop_Suc_conv_tl lessI replicate_Suc tape_of_nl_abv tape_of_nl_cons)
       
  4320 
       
  4321 lemma mopup_bef_erase_a_2_jump_over[simp]: 
       
  4322  "\<lbrakk>n < length lm; 0 < s; s mod 2 = Suc 0;  s \<le> 2 * n;
       
  4323    mopup_bef_erase_a (s, l, Bk # xs) lm n ires; \<not> (Suc (Suc s) \<le> 2 * n)\<rbrakk> 
       
  4324 \<Longrightarrow> mopup_jump_over1 (s', Bk # l, xs) lm n ires"
       
  4325 apply(auto simp: mopup_bef_erase_a.simps mopup_jump_over1.simps)
       
  4326 apply(case_tac m, auto simp: mod_ex1)
       
  4327 apply(subgoal_tac "n = Suc q", auto)
       
  4328 apply(rule_tac x = "Suc ln" in exI, rule_tac x = 0 in exI, auto)
       
  4329 apply(case_tac [!] lm, simp_all)
       
  4330 apply(case_tac [!] rn, auto elim: erase2jumpover1 erase2jumpover2)
       
  4331 apply(erule_tac x = 0 in allE, simp)
       
  4332 apply(rule_tac classical, simp)
       
  4333 apply(erule_tac notE)
       
  4334 apply(rule_tac drop_tape_of_cons, simp_all add: abc_lm_v.simps)
       
  4335 done
       
  4336 
       
  4337 lemma Suc_Suc_div:  "\<lbrakk>0 < s; s mod 2 = Suc 0; Suc (Suc s) \<le> 2 * n\<rbrakk>
       
  4338            \<Longrightarrow> (Suc (Suc (s div 2))) \<le> n"
       
  4339 apply(arith)
       
  4340 done
       
  4341 
       
  4342 lemma mopup_bef_erase_a_2_a[simp]: 
       
  4343  "\<lbrakk>n < length lm; 0 < s; s mod 2 = Suc 0; 
       
  4344    mopup_bef_erase_a (s, l, Bk # xs) lm n ires; 
       
  4345    Suc (Suc s) \<le> 2 * n\<rbrakk> \<Longrightarrow> 
       
  4346    mopup_bef_erase_a (Suc (Suc s), Bk # l, xs) lm n ires"
       
  4347 apply(auto simp: mopup_bef_erase_a.simps)
       
  4348 apply(subgoal_tac "drop (Suc (Suc (s div 2))) lm \<noteq> []")
       
  4349 apply(case_tac m, simp_all)
       
  4350 apply(rule_tac x = "Suc (abc_lm_v lm (Suc (s div 2)))" in exI, 
       
  4351       rule_tac x = rn in exI, auto simp: mod_ex1)
       
  4352 apply(rule_tac drop_tape_of_cons)
       
  4353 apply arith
       
  4354 apply(simp add: abc_lm_v.simps)
       
  4355 done
       
  4356 
       
  4357 lemma mopup_false2: 
       
  4358  "\<lbrakk>0 < s; s \<le> 2 * n; 
       
  4359    s mod 2 = Suc 0; Suc s \<noteq> 2 * n;
       
  4360    \<not> Suc (Suc s) \<le> 2 * n\<rbrakk> \<Longrightarrow> RR"
       
  4361 apply(arith)
       
  4362 done
       
  4363 
       
  4364 lemma [simp]: "mopup_bef_erase_a (s, l, []) lm n ires \<Longrightarrow> 
       
  4365                         mopup_bef_erase_a (s, l, [Bk]) lm n ires"
       
  4366 apply(auto simp: mopup_bef_erase_a.simps)
       
  4367 done
       
  4368 
       
  4369 lemma [simp]:
       
  4370    "\<lbrakk>n < length lm; 0 < s; s \<le> 2 * n; s mod 2 = Suc 0; \<not> Suc (Suc s) \<le> 2 *n;
       
  4371      mopup_bef_erase_a (s, l, []) lm n ires\<rbrakk>
       
  4372     \<Longrightarrow>  mopup_jump_over1 (s', Bk # l, []) lm n ires"
       
  4373 by auto
       
  4374 
       
  4375 lemma "mopup_bef_erase_b (s, l, Oc # xs) lm n ires \<Longrightarrow> l \<noteq> []"
       
  4376 apply(auto simp: mopup_bef_erase_b.simps)
       
  4377 done
       
  4378 
       
  4379 lemma [simp]: "mopup_bef_erase_b (s, l, Oc # xs) lm n ires = False"
       
  4380 apply(auto simp: mopup_bef_erase_b.simps )
       
  4381 done
       
  4382  
       
  4383 lemma [simp]: "\<lbrakk>0 < s; s \<le> 2 *n; s mod 2 \<noteq> Suc 0\<rbrakk> \<Longrightarrow> 
       
  4384                                       (s - Suc 0) mod 2 = Suc 0"
       
  4385 apply(arith)
       
  4386 done
       
  4387 
       
  4388 lemma [simp]: "\<lbrakk>0 < s; s \<le> 2 *n; s mod 2 \<noteq> Suc 0\<rbrakk> \<Longrightarrow>
       
  4389                                        s - Suc 0 \<le> 2 * n"
       
  4390 apply(simp)
       
  4391 done
       
  4392 
       
  4393 lemma [simp]: "\<lbrakk>0 < s; s \<le> 2 *n; s mod 2 \<noteq> Suc 0\<rbrakk> \<Longrightarrow> \<not> s \<le> Suc 0"
       
  4394 apply(arith)
       
  4395 done
       
  4396 
       
  4397 lemma [simp]: "\<lbrakk>n < length lm; 0 < s; s \<le> 2 * n; 
       
  4398                s mod 2 \<noteq> Suc 0; 
       
  4399                mopup_bef_erase_b (s, l, Bk # xs) lm n ires; r = Bk # xs\<rbrakk> 
       
  4400            \<Longrightarrow> mopup_bef_erase_a (s - Suc 0, Bk # l, xs) lm n ires"
       
  4401 apply(auto simp: mopup_bef_erase_b.simps mopup_bef_erase_a.simps)
       
  4402 done
       
  4403 
       
  4404 lemma [simp]: "\<lbrakk>mopup_bef_erase_b (s, l, []) lm n ires\<rbrakk> \<Longrightarrow> 
       
  4405                    mopup_bef_erase_a (s - Suc 0, Bk # l, []) lm n ires"
       
  4406 apply(auto simp: mopup_bef_erase_b.simps mopup_bef_erase_a.simps)
       
  4407 done
       
  4408 
       
  4409 lemma [simp]: 
       
  4410    "\<lbrakk>n < length lm;
       
  4411     mopup_jump_over1 (Suc (2 * n), l, Oc # xs) lm n ires;
       
  4412     r = Oc # xs\<rbrakk>
       
  4413   \<Longrightarrow> mopup_jump_over1 (Suc (2 * n), Oc # l, xs) lm n ires"
       
  4414 apply(auto simp: mopup_jump_over1.simps)
       
  4415 apply(rule_tac x = ln in exI, rule_tac x = "Suc m1" in exI,
       
  4416        rule_tac x = "m2 - 1" in exI, simp)
       
  4417 apply(case_tac "m2", simp, simp)
       
  4418 apply(rule_tac x = ln in exI, rule_tac x = "Suc m1" in exI, 
       
  4419       rule_tac x = "m2 - 1" in exI)
       
  4420 apply(case_tac m2, simp, simp)
       
  4421 done
       
  4422 
       
  4423 lemma mopup_jump_over1_2_aft_erase_a[simp]:  
       
  4424  "\<lbrakk>n < length lm; mopup_jump_over1 (Suc (2 * n), l, Bk # xs) lm n ires\<rbrakk>
       
  4425   \<Longrightarrow> mopup_aft_erase_a (Suc (Suc (2 * n)), Bk # l, xs) lm n ires"
       
  4426 apply(simp only: mopup_jump_over1.simps mopup_aft_erase_a.simps)
       
  4427 apply(erule_tac exE)+
       
  4428 apply(rule_tac x = ln in exI, rule_tac x = "Suc 0" in exI)
       
  4429 apply(case_tac m2, simp)
       
  4430 apply(rule_tac x = rn in exI, rule_tac x = "drop (Suc n) lm" in exI, 
       
  4431       simp)
       
  4432 apply(simp)
       
  4433 done
       
  4434 
       
  4435 lemma [simp]: 
       
  4436  "\<lbrakk>n < length lm; mopup_jump_over1 (Suc (2 * n), l, []) lm n ires\<rbrakk> \<Longrightarrow> 
       
  4437     mopup_aft_erase_a (Suc (Suc (2 * n)), Bk # l, []) lm n ires"
       
  4438 apply(rule mopup_jump_over1_2_aft_erase_a, simp)
       
  4439 apply(auto simp: mopup_jump_over1.simps)
       
  4440 apply(rule_tac x = ln in exI, rule_tac x = "Suc (abc_lm_v lm n)" in exI, 
       
  4441       rule_tac x = 0 in exI, simp add: )
       
  4442 done
       
  4443 
       
  4444 
       
  4445 lemma [simp]: 
       
  4446  "\<lbrakk>n < length lm; 
       
  4447    mopup_aft_erase_a (Suc (Suc (2 * n)), l, Oc # xs) lm n ires\<rbrakk> 
       
  4448  \<Longrightarrow> mopup_aft_erase_b (Suc (Suc (Suc (2 * n))), l, Bk # xs) lm n ires"
       
  4449 apply(auto simp: mopup_aft_erase_a.simps mopup_aft_erase_b.simps )
       
  4450 apply(case_tac ml)
       
  4451 apply(simp_all add: tape_of_nl_cons split: if_splits)
       
  4452 apply(case_tac a, simp_all)
       
  4453 apply(rule_tac x = rn in exI, rule_tac x = "[]" in exI, simp)
       
  4454 apply(rule_tac x = rn in exI, rule_tac x = "[nat]" in exI, simp)
       
  4455 apply(case_tac a, simp_all)
       
  4456 apply(rule_tac x = rn in exI, rule_tac x = "list" in exI, simp)
       
  4457 apply(rule_tac x = rn in exI)
       
  4458 apply(rule_tac x = "nat # list" in exI, simp add: tape_of_nl_cons)
       
  4459 done
       
  4460 
       
  4461 lemma [simp]:
       
  4462   "mopup_aft_erase_a (Suc (Suc (2 * n)), l, Bk # xs) lm n ires \<Longrightarrow> l \<noteq> []"
       
  4463 apply(auto simp: mopup_aft_erase_a.simps)
       
  4464 done
       
  4465 
       
  4466 lemma [simp]:
       
  4467   "\<lbrakk>n < length lm;
       
  4468     mopup_aft_erase_a (Suc (Suc (2 * n)), l, Bk # xs) lm n ires\<rbrakk>
       
  4469   \<Longrightarrow> mopup_left_moving (5 + 2 * n, tl l, hd l # Bk # xs) lm n ires"
       
  4470 apply(simp only: mopup_aft_erase_a.simps mopup_left_moving.simps)
       
  4471 apply(erule exE)+
       
  4472 apply(case_tac lnr, simp)
       
  4473 apply(case_tac ml, simp, simp add: tape_of_nl_cons split: if_splits)
       
  4474 apply(auto)
       
  4475 apply(case_tac ml, simp_all add: tape_of_nl_cons split: if_splits)
       
  4476 apply(rule_tac x = "Suc rn" in exI, simp)
       
  4477 done
       
  4478 
       
  4479 lemma [simp]:
       
  4480   "mopup_aft_erase_a (Suc (Suc (2 * n)), l, []) lm n ires \<Longrightarrow> l \<noteq> []"
       
  4481 apply(simp only: mopup_aft_erase_a.simps)
       
  4482 apply(erule exE)+
       
  4483 apply(auto)
       
  4484 done
       
  4485 
       
  4486 lemma [simp]:
       
  4487   "\<lbrakk>n < length lm; mopup_aft_erase_a (Suc (Suc (2 * n)), l, []) lm n ires\<rbrakk>
       
  4488   \<Longrightarrow> mopup_left_moving (5 + 2 * n, tl l, [hd l]) lm n ires"
       
  4489 apply(simp only: mopup_aft_erase_a.simps mopup_left_moving.simps)
       
  4490 apply(erule exE)+
       
  4491 apply(subgoal_tac "ml = [] \<and> rn = 0", erule conjE, erule conjE, simp)
       
  4492 apply(case_tac lnr, simp)
       
  4493 apply(rule_tac x = lnl in exI, simp)
       
  4494 apply(rule_tac x = 1 in exI, simp)
       
  4495 apply(case_tac ml, simp, simp)
       
  4496 done
       
  4497 
       
  4498 
       
  4499 lemma [simp]: "mopup_aft_erase_b (2 * n + 3, l, Oc # xs) lm n ires = False"
       
  4500 apply(auto simp: mopup_aft_erase_b.simps )
       
  4501 done
       
  4502 
       
  4503 lemma tape_of_ex1[intro]: 
       
  4504   "\<exists>rna ml. Oc \<up> a @ Bk \<up> rn = <ml::nat list> @ Bk \<up> rna \<or> Oc \<up> a @ Bk \<up> rn = Bk # <ml> @ Bk \<up> rna"
       
  4505 apply(case_tac a, simp_all)
       
  4506 apply(rule_tac x = rn in exI, rule_tac x = "[]" in exI, simp)
       
  4507 apply(rule_tac x = rn in exI, rule_tac x = "[nat]" in exI, simp)
       
  4508 done
       
  4509 
       
  4510 lemma [intro]: "\<exists>rna ml. Oc \<up> a @ Bk # <list::nat list> @ Bk \<up> rn = 
       
  4511   <ml> @ Bk \<up> rna \<or> Oc \<up> a @ Bk # <list> @ Bk \<up> rn = Bk # <ml::nat list> @ Bk \<up> rna"
       
  4512 apply(case_tac "list = []", simp add: replicate_Suc[THEN sym] del: replicate_Suc)
       
  4513 apply(rule_tac rn = "Suc rn" in tape_of_ex1)
       
  4514 apply(case_tac a, simp)
       
  4515 apply(rule_tac x = rn in exI, rule_tac x = list in exI, simp)
       
  4516 apply(rule_tac x = rn in exI, rule_tac x = "nat # list" in exI)
       
  4517 apply(simp add: tape_of_nl_cons)
       
  4518 done
       
  4519 
       
  4520 lemma [simp]: 
       
  4521  "\<lbrakk>n < length lm; 
       
  4522    mopup_aft_erase_c (2 * n + 4, l, Oc # xs) lm n ires\<rbrakk>
       
  4523   \<Longrightarrow> mopup_aft_erase_b (Suc (Suc (Suc (2 * n))), l, Bk # xs) lm n ires"
       
  4524 apply(auto simp: mopup_aft_erase_c.simps mopup_aft_erase_b.simps )
       
  4525 apply(case_tac ml, simp_all add: tape_of_nl_cons split: if_splits, auto)
       
  4526 done
       
  4527 
       
  4528 lemma mopup_aft_erase_c_aft_erase_a[simp]: 
       
  4529  "\<lbrakk>n < length lm; mopup_aft_erase_c (2 * n + 4, l, Bk # xs) lm n ires\<rbrakk> 
       
  4530  \<Longrightarrow> mopup_aft_erase_a (Suc (Suc (2 * n)), Bk # l, xs) lm n ires"
       
  4531 apply(simp only: mopup_aft_erase_c.simps mopup_aft_erase_a.simps )
       
  4532 apply(erule_tac exE)+
       
  4533 apply(erule conjE, erule conjE, erule disjE)
       
  4534 apply(subgoal_tac "ml = []", simp, case_tac rn, 
       
  4535       simp, simp, rule conjI)
       
  4536 apply(rule_tac x = lnl in exI, rule_tac x = "Suc lnr" in exI, simp)
       
  4537 apply(rule_tac x = nat in exI, rule_tac x = "[]" in exI, simp)
       
  4538 apply(case_tac ml, simp, simp add: tape_of_nl_cons split: if_splits)
       
  4539 apply(rule_tac x = lnl in exI, rule_tac x = "Suc lnr" in exI, simp)
       
  4540 apply(rule_tac x = rn in exI, rule_tac x = "ml" in exI, simp)
       
  4541 done
       
  4542 
       
  4543 lemma [simp]: 
       
  4544  "\<lbrakk>n < length lm; mopup_aft_erase_c (2 * n + 4, l, []) lm n ires\<rbrakk> 
       
  4545  \<Longrightarrow> mopup_aft_erase_a (Suc (Suc (2 * n)), Bk # l, []) lm n ires"
       
  4546 apply(rule mopup_aft_erase_c_aft_erase_a, simp)
       
  4547 apply(simp only: mopup_aft_erase_c.simps)
       
  4548 apply(erule exE)+
       
  4549 apply(rule_tac x = lnl in exI, rule_tac x = lnr in exI, simp add: )
       
  4550 apply(rule_tac x = 0 in exI, rule_tac x = "[]" in exI, simp)
       
  4551 done
       
  4552 
       
  4553 lemma mopup_aft_erase_b_2_aft_erase_c[simp]:
       
  4554   "\<lbrakk>n < length lm; mopup_aft_erase_b (2 * n + 3, l, Bk # xs) lm n ires\<rbrakk>  
       
  4555  \<Longrightarrow> mopup_aft_erase_c (4 + 2 * n, Bk # l, xs) lm n ires"
       
  4556 apply(auto simp: mopup_aft_erase_b.simps mopup_aft_erase_c.simps)
       
  4557 apply(rule_tac x = "lnl" in exI, rule_tac x = "Suc lnr" in exI, simp)
       
  4558 apply(rule_tac x = "lnl" in exI, rule_tac x = "Suc lnr" in exI, simp)
       
  4559 done
       
  4560 
       
  4561 lemma [simp]: 
       
  4562  "\<lbrakk>n < length lm; mopup_aft_erase_b (2 * n + 3, l, []) lm n ires\<rbrakk> 
       
  4563  \<Longrightarrow> mopup_aft_erase_c (4 + 2 * n, Bk # l, []) lm n ires"
       
  4564 apply(rule_tac mopup_aft_erase_b_2_aft_erase_c, simp)
       
  4565 apply(simp add: mopup_aft_erase_b.simps)
       
  4566 done
       
  4567 
       
  4568 lemma [simp]: 
       
  4569     "mopup_left_moving (2 * n + 5, l, Oc # xs) lm n ires \<Longrightarrow> l \<noteq> []"
       
  4570 apply(auto simp: mopup_left_moving.simps)
       
  4571 done
       
  4572 
       
  4573 lemma [simp]:  
       
  4574  "\<lbrakk>n < length lm; mopup_left_moving (2 * n + 5, l, Oc # xs) lm n ires\<rbrakk>
       
  4575   \<Longrightarrow> mopup_jump_over2 (2 * n + 6, tl l, hd l # Oc # xs) lm n ires"
       
  4576 apply(simp only: mopup_left_moving.simps mopup_jump_over2.simps)
       
  4577 apply(erule_tac exE)+
       
  4578 apply(erule conjE, erule disjE, erule conjE)
       
  4579 apply(case_tac rn, simp, simp add: )
       
  4580 apply(case_tac "hd l", simp add:  )
       
  4581 apply(case_tac "abc_lm_v lm n", simp)
       
  4582 apply(rule_tac x = "lnl" in exI, rule_tac x = rn in exI, 
       
  4583       rule_tac x = "Suc 0" in exI, rule_tac x = 0 in exI)
       
  4584 apply(case_tac lnl, simp, simp, simp add: exp_ind[THEN sym], simp)
       
  4585 apply(case_tac "abc_lm_v lm n", simp)
       
  4586 apply(case_tac lnl, simp, simp)
       
  4587 apply(rule_tac x = lnl in exI, rule_tac x = rn in exI)
       
  4588 apply(rule_tac x = nat in exI, rule_tac x = "Suc (Suc 0)" in exI, simp)
       
  4589 done
       
  4590 
       
  4591 lemma [simp]: "mopup_left_moving (2 * n + 5, l, xs) lm n ires \<Longrightarrow> l \<noteq> []"
       
  4592 apply(auto simp: mopup_left_moving.simps)
       
  4593 done
       
  4594 
       
  4595 lemma [simp]:
       
  4596   "\<lbrakk>n < length lm; mopup_left_moving (2 * n + 5, l, Bk # xs) lm n ires\<rbrakk> 
       
  4597  \<Longrightarrow> mopup_left_moving (2 * n + 5, tl l, hd l # Bk # xs) lm n ires"
       
  4598 apply(simp only: mopup_left_moving.simps)
       
  4599 apply(erule exE)+
       
  4600 apply(case_tac lnr, simp)
       
  4601 apply(rule_tac x = lnl in exI, rule_tac x = nat in exI, simp)
       
  4602 apply(rule_tac x = "Suc rn" in exI, simp)
       
  4603 done
       
  4604 
       
  4605 lemma [simp]: 
       
  4606 "\<lbrakk>n < length lm; mopup_left_moving (2 * n + 5, l, []) lm n ires\<rbrakk>
       
  4607     \<Longrightarrow> mopup_left_moving (2 * n + 5, tl l, [hd l]) lm n ires"
       
  4608 apply(simp only: mopup_left_moving.simps)
       
  4609 apply(erule exE)+
       
  4610 apply(case_tac lnr, auto)
       
  4611 done
       
  4612 
       
  4613 
       
  4614 lemma [simp]: 
       
  4615  "mopup_jump_over2 (2 * n + 6, l, Oc # xs) lm n ires \<Longrightarrow> l \<noteq> []"
       
  4616 apply(auto simp: mopup_jump_over2.simps )
       
  4617 done
       
  4618 
       
  4619 lemma [simp]: 
       
  4620 "\<lbrakk>n < length lm; mopup_jump_over2 (2 * n + 6, l, Oc # xs) lm n ires\<rbrakk>
       
  4621  \<Longrightarrow>  mopup_jump_over2 (2 * n + 6, tl l, hd l # Oc # xs) lm n ires"
       
  4622 apply(simp only: mopup_jump_over2.simps)
       
  4623 apply(erule_tac exE)+
       
  4624 apply(simp add:  , erule conjE, erule_tac conjE)
       
  4625 apply(case_tac m1, simp)
       
  4626 apply(rule_tac x = ln in exI, rule_tac x = rn in exI, 
       
  4627       rule_tac x = 0 in exI, simp)
       
  4628 apply(case_tac ln, simp, simp, simp only: exp_ind[THEN sym], simp)
       
  4629 apply(rule_tac x = ln in exI, rule_tac x = rn in exI, 
       
  4630       rule_tac x = nat in exI, rule_tac x = "Suc m2" in exI, simp)
       
  4631 done
       
  4632 
       
  4633 lemma [simp]: 
       
  4634  "\<lbrakk>n < length lm; mopup_jump_over2 (2 * n + 6, l, Bk # xs) lm n ires\<rbrakk> 
       
  4635   \<Longrightarrow> mopup_stop (0, Bk # l, xs) lm n ires"
       
  4636 apply(auto simp: mopup_jump_over2.simps mopup_stop.simps)
       
  4637 apply(simp_all add: tape_of_nat_abv exp_ind[THEN sym])
       
  4638 done
       
  4639 
       
  4640 lemma [simp]: "mopup_jump_over2 (2 * n + 6, l, []) lm n ires = False"
       
  4641 apply(simp only: mopup_jump_over2.simps, simp)
       
  4642 done
       
  4643 
       
  4644 lemma mopup_inv_step:
       
  4645   "\<lbrakk>n < length lm; mopup_inv (s, l, r) lm n ires\<rbrakk>
       
  4646   \<Longrightarrow> mopup_inv (step (s, l, r) (mopup_a n @ shift mopup_b (2 * n), 0)) lm n ires"
       
  4647 apply(case_tac r, case_tac [2] a)
       
  4648 apply(auto split:if_splits simp add:step.simps)
       
  4649 apply(simp_all add: mopupfetchs)
       
  4650 done
       
  4651 
       
  4652 declare mopup_inv.simps[simp del]
       
  4653 lemma mopup_inv_steps: 
       
  4654 "\<lbrakk>n < length lm; mopup_inv (s, l, r) lm n ires\<rbrakk> \<Longrightarrow> 
       
  4655      mopup_inv (steps (s, l, r) (mopup_a n @ shift mopup_b (2 * n), 0)  stp) lm n ires"
       
  4656 apply(induct_tac stp, simp add: steps.simps)
       
  4657 apply(simp add: step_red)
       
  4658 apply(case_tac "steps (s, l, r) 
       
  4659                 (mopup_a n @ shift mopup_b (2 * n), 0) na", simp)
       
  4660 apply(rule_tac mopup_inv_step, simp, simp)
       
  4661 done
       
  4662 
       
  4663 fun abc_mopup_stage1 :: "config \<Rightarrow> nat \<Rightarrow> nat"
       
  4664   where
       
  4665   "abc_mopup_stage1 (s, l, r) n = 
       
  4666            (if s > 0 \<and> s \<le> 2*n then 6
       
  4667             else if s = 2*n + 1 then 4
       
  4668             else if s \<ge> 2*n + 2 \<and> s \<le> 2*n + 4 then 3
       
  4669             else if s = 2*n + 5 then 2
       
  4670             else if s = 2*n + 6 then 1
       
  4671             else 0)"
       
  4672 
       
  4673 fun abc_mopup_stage2 :: "config \<Rightarrow> nat \<Rightarrow> nat"
       
  4674   where
       
  4675   "abc_mopup_stage2 (s, l, r) n = 
       
  4676            (if s > 0 \<and> s \<le> 2*n then length r
       
  4677             else if s = 2*n + 1 then length r
       
  4678             else if s = 2*n + 5 then length l
       
  4679             else if s = 2*n + 6 then length l
       
  4680             else if s \<ge> 2*n + 2 \<and> s \<le> 2*n + 4 then length r
       
  4681             else 0)"
       
  4682 
       
  4683 fun abc_mopup_stage3 :: "config \<Rightarrow> nat \<Rightarrow> nat"
       
  4684   where
       
  4685   "abc_mopup_stage3 (s, l, r) n = 
       
  4686           (if s > 0 \<and> s \<le> 2*n then 
       
  4687               if hd r = Bk then 0
       
  4688               else 1
       
  4689            else if s = 2*n + 2 then 1 
       
  4690            else if s = 2*n + 3 then 0
       
  4691            else if s = 2*n + 4 then 2
       
  4692            else 0)"
       
  4693 
       
  4694 fun abc_mopup_measure :: "(config \<times> nat) \<Rightarrow> (nat \<times> nat \<times> nat)"
       
  4695   where
       
  4696   "abc_mopup_measure (c, n) = 
       
  4697     (abc_mopup_stage1 c n, abc_mopup_stage2 c n, 
       
  4698                                        abc_mopup_stage3 c n)"
       
  4699 
       
  4700 definition abc_mopup_LE ::
       
  4701    "(((nat \<times> cell list \<times> cell list) \<times> nat) \<times> 
       
  4702     ((nat \<times> cell list \<times> cell list) \<times> nat)) set"
       
  4703   where
       
  4704   "abc_mopup_LE \<equiv> (inv_image lex_triple abc_mopup_measure)"
       
  4705 
       
  4706 lemma wf_abc_mopup_le[intro]: "wf abc_mopup_LE"
       
  4707 by(auto intro:wf_inv_image simp:abc_mopup_LE_def lex_triple_def lex_pair_def)
       
  4708 
       
  4709 lemma [simp]: "mopup_bef_erase_a (a, aa, []) lm n ires = False"
       
  4710 apply(auto simp: mopup_bef_erase_a.simps)
       
  4711 done
       
  4712 
       
  4713 lemma [simp]: "mopup_bef_erase_b (a, aa, []) lm n ires = False"
       
  4714 apply(auto simp: mopup_bef_erase_b.simps) 
       
  4715 done
       
  4716 
       
  4717 lemma [simp]: "mopup_aft_erase_b (2 * n + 3, aa, []) lm n ires = False"
       
  4718 apply(auto simp: mopup_aft_erase_b.simps)
       
  4719 done
       
  4720 
       
  4721 declare mopup_inv.simps[simp del]
       
  4722 term mopup_inv
       
  4723 
       
  4724 lemma [simp]: 
       
  4725   "\<lbrakk>0 < q; q \<le> n\<rbrakk> \<Longrightarrow> 
       
  4726      (fetch (mopup_a n @ shift mopup_b (2 * n)) (2*q) Bk) = (R, 2*q - 1)"
       
  4727 apply(case_tac q, simp, simp)
       
  4728 apply(auto simp: fetch.simps nth_of.simps nth_append)
       
  4729 apply(subgoal_tac "mopup_a n ! (4 * nat + 2) = 
       
  4730                      mopup_a (Suc nat) ! ((4 * nat) + 2)", 
       
  4731       simp add: mopup_a.simps nth_append)
       
  4732 apply(rule mopup_a_nth, auto)
       
  4733 done
       
  4734 
       
  4735 (* FIXME: is also in uncomputable *)
       
  4736 lemma halt_lemma: 
       
  4737   "\<lbrakk>wf LE; \<forall>n. (\<not> P (f n) \<longrightarrow> (f (Suc n), (f n)) \<in> LE)\<rbrakk> \<Longrightarrow> \<exists>n. P (f n)"
       
  4738 by (metis wf_iff_no_infinite_down_chain)
       
  4739 
       
  4740 
       
  4741 lemma mopup_halt:
       
  4742   assumes 
       
  4743   less: "n < length lm"
       
  4744   and inv: "mopup_inv (Suc 0, l, r) lm n ires"
       
  4745   and f: "f = (\<lambda> stp. (steps (Suc 0, l, r) (mopup_a n @ shift mopup_b (2 * n), 0) stp, n))"
       
  4746   and P: "P = (\<lambda> (c, n). is_final c)"
       
  4747   shows "\<exists> stp. P (f stp)"
       
  4748 proof(rule_tac LE = abc_mopup_LE in halt_lemma)
       
  4749   show "wf abc_mopup_LE" by(auto)
       
  4750 next
       
  4751   show "\<forall>n. \<not> P (f n) \<longrightarrow> (f (Suc n), f n) \<in> abc_mopup_LE"
       
  4752   proof(rule_tac allI, rule_tac impI)
       
  4753     fix na
       
  4754     assume h: "\<not> P (f na)"
       
  4755     show "(f (Suc na), f na) \<in> abc_mopup_LE"
       
  4756     proof(simp add: f)
       
  4757       obtain a b c where g:"steps (Suc 0, l, r) (mopup_a n @ shift mopup_b (2 * n), 0) na = (a, b, c)"
       
  4758         apply(case_tac "steps (Suc 0, l, r) (mopup_a n @ shift mopup_b (2 * n), 0) na", auto)
       
  4759         done
       
  4760       then have "mopup_inv (a, b, c) lm n ires"
       
  4761         thm mopup_inv_steps
       
  4762         using inv less mopup_inv_steps[of n lm "Suc 0" l r ires na]
       
  4763         apply(simp)
       
  4764         done
       
  4765       moreover have "a > 0"
       
  4766         using h g
       
  4767         apply(simp add: f P)
       
  4768         done
       
  4769       ultimately have "((step (a, b, c) (mopup_a n @ shift mopup_b (2 * n), 0), n), (a, b, c), n) \<in> abc_mopup_LE"
       
  4770         apply(case_tac c, case_tac [2] aa)
       
  4771         apply(auto split:if_splits simp add:step.simps mopup_inv.simps)
       
  4772         apply(simp_all add: mopupfetchs abc_mopup_LE_def lex_triple_def lex_pair_def )
       
  4773         done
       
  4774       thus "((step (steps (Suc 0, l, r) (mopup_a n @ shift mopup_b (2 * n), 0) na) 
       
  4775         (mopup_a n @ shift mopup_b (2 * n), 0), n),
       
  4776         steps (Suc 0, l, r) (mopup_a n @ shift mopup_b (2 * n), 0) na, n)
       
  4777         \<in> abc_mopup_LE"
       
  4778         using g by simp
       
  4779     qed
       
  4780   qed
       
  4781 qed     
       
  4782 
       
  4783 lemma mopup_inv_start: 
       
  4784   "n < length am \<Longrightarrow> mopup_inv (Suc 0, Bk # Bk # ires, <am> @ Bk \<up> k) am n ires"
       
  4785 apply(auto simp: mopup_inv.simps mopup_bef_erase_a.simps mopup_jump_over1.simps)
       
  4786 apply(case_tac [!] am, auto split: if_splits simp: tape_of_nl_cons)
       
  4787 apply(rule_tac x = "Suc a" in exI, rule_tac x = k in exI, simp)
       
  4788 apply(case_tac [!] n, simp_all add: abc_lm_v.simps)
       
  4789 apply(case_tac k, simp, simp_all)
       
  4790 done
       
  4791       
       
  4792 lemma mopup_correct:
       
  4793   assumes less: "n < length (am::nat list)"
       
  4794   and rs: "abc_lm_v am n = rs"
       
  4795   shows "\<exists> stp i j. (steps (Suc 0, Bk # Bk # ires, <am> @ Bk \<up> k) (mopup_a n @ shift mopup_b (2 * n), 0) stp)
       
  4796     = (0, Bk\<up>i @ Bk # Bk # ires, Oc # Oc\<up> rs @ Bk\<up>j)"
       
  4797 using less
       
  4798 proof -
       
  4799   have a: "mopup_inv (Suc 0, Bk # Bk # ires, <am> @ Bk \<up> k) am n ires"
       
  4800     using less
       
  4801     apply(simp add: mopup_inv_start)
       
  4802     done    
       
  4803   then have "\<exists> stp. is_final (steps (Suc 0, Bk # Bk # ires, <am> @ Bk \<up> k) (mopup_a n @ shift mopup_b (2 * n), 0) stp)"
       
  4804     using less mopup_halt[of n am  "Bk # Bk # ires" "<am> @ Bk \<up> k" ires
       
  4805       "(\<lambda>stp. (steps (Suc 0, Bk # Bk # ires, <am> @ Bk \<up> k) (mopup_a n @ shift mopup_b (2 * n), 0) stp, n))"
       
  4806       "(\<lambda>(c, n). is_final c)"]
       
  4807     apply(simp)
       
  4808     done
       
  4809   from this obtain stp where b:
       
  4810     "is_final (steps (Suc 0, Bk # Bk # ires, <am> @ Bk \<up> k) (mopup_a n @ shift mopup_b (2 * n), 0) stp)" ..
       
  4811   from a b have
       
  4812     "mopup_inv (steps (Suc 0, Bk # Bk # ires, <am> @ Bk \<up> k) (mopup_a n @ shift mopup_b (2 * n), 0) stp)
       
  4813     am n ires"
       
  4814     apply(rule_tac mopup_inv_steps, simp_all add: less)
       
  4815     done    
       
  4816   from b and this show "?thesis"
       
  4817     apply(rule_tac x = stp in exI, simp)
       
  4818     apply(case_tac "steps (Suc 0, Bk # Bk # ires, <am> @ Bk \<up> k) 
       
  4819       (mopup_a n @ shift mopup_b (2 * n), 0) stp")
       
  4820     apply(simp add: mopup_inv.simps mopup_stop.simps rs)
       
  4821     using rs
       
  4822     apply(simp add: tape_of_nat_abv)
       
  4823     done
       
  4824 qed
       
  4825 
       
  4826 (*we can use Hoare_plus here*)
       
  4827 
       
  4828 lemma wf_mopup[intro]: "tm_wf (mopup n, 0)"
       
  4829 apply(induct n, simp add: mopup.simps shift.simps mopup_b_def tm_wf.simps)
       
  4830 apply(auto simp: mopup.simps shift.simps mopup_b_def tm_wf.simps)
       
  4831 done
       
  4832 
       
  4833 lemma length_tp:
       
  4834   "\<lbrakk>ly = layout_of ap; tp = tm_of ap\<rbrakk> \<Longrightarrow> 
       
  4835   start_of ly (length ap) = Suc (length tp div 2)"
       
  4836 apply(frule_tac length_tp', simp_all)
       
  4837 apply(simp add: start_of.simps)
       
  4838 done
       
  4839 
       
  4840 lemma compile_correct_halt: 
       
  4841   assumes layout: "ly = layout_of ap"
       
  4842   and compile: "tp = tm_of ap"
       
  4843   and crsp: "crsp ly (0, lm) (Suc 0, l, r) ires"
       
  4844   and abc_halt: "abc_steps_l (0, lm) ap stp = (length ap, am)"
       
  4845   and rs_loc: "n < length am"
       
  4846   and rs: "abc_lm_v am n = rs"
       
  4847   and off: "off = length tp div 2"
       
  4848   shows "\<exists> stp i j. steps (Suc 0, l, r) (tp @ shift (mopup n) off, 0) stp = (0, Bk\<up>i @ Bk # Bk # ires, Oc\<up>Suc rs @ Bk\<up>j)"
       
  4849 proof -
       
  4850   have "\<exists> stp k. steps (Suc 0, l, r) (tp, 0) stp = (Suc off, Bk # Bk # ires, <am> @ Bk\<up>k)"
       
  4851     using assms tp_correct'[of ly ap tp lm l r ires stp am]
       
  4852     by(simp add: length_tp)
       
  4853   then obtain stp k where "steps (Suc 0, l, r) (tp, 0) stp = (Suc off, Bk # Bk # ires, <am> @ Bk\<up>k)"
       
  4854     by blast
       
  4855   then have a: "steps (Suc 0, l, r) (tp@shift (mopup n) off , 0) stp = (Suc off, Bk # Bk # ires, <am> @ Bk\<up>k)"
       
  4856     using assms
       
  4857     by(auto intro: tm_append_first_steps_eq)
       
  4858   have "\<exists> stp i j. (steps (Suc 0, Bk # Bk # ires, <am> @ Bk \<up> k) (mopup_a n @ shift mopup_b (2 * n), 0) stp)
       
  4859     = (0, Bk\<up>i @ Bk # Bk # ires, Oc # Oc\<up> rs @ Bk\<up>j)"
       
  4860     using assms
       
  4861     by(auto intro: mopup_correct)
       
  4862   then obtain stpb i j where 
       
  4863     "steps (Suc 0, Bk # Bk # ires, <am> @ Bk \<up> k) (mopup_a n @ shift mopup_b (2 * n), 0) stpb
       
  4864     = (0, Bk\<up>i @ Bk # Bk # ires, Oc # Oc\<up> rs @ Bk\<up>j)" by blast
       
  4865   then have b: "steps (Suc 0 + off, Bk # Bk # ires, <am> @ Bk \<up> k) (tp @ shift (mopup n) off, 0) stpb
       
  4866     = (0, Bk\<up>i @ Bk # Bk # ires, Oc # Oc\<up> rs @ Bk\<up>j)"
       
  4867     using assms wf_mopup
       
  4868    thm tm_append_second_halt_eq
       
  4869     apply(drule_tac tm_append_second_halt_eq, auto)
       
  4870     done
       
  4871   from a b show "?thesis"
       
  4872     by(rule_tac x = "stp + stpb" in exI, simp add: steps_add)
       
  4873 qed
       
  4874  
       
  4875 declare mopup.simps[simp del]
       
  4876 lemma abc_step_red2:
       
  4877   "abc_steps_l (s, lm) p (Suc n) = (let (as', am') = abc_steps_l (s, lm) p n in
       
  4878                                     abc_step_l (as', am') (abc_fetch as' p))"
       
  4879 apply(case_tac "abc_steps_l (s, lm) p n", simp)
       
  4880 apply(drule_tac abc_step_red, simp)
       
  4881 done
       
  4882 
       
  4883 lemma crsp_steps2:
       
  4884   assumes 
       
  4885   layout: "ly = layout_of ap"
       
  4886   and compile: "tp = tm_of ap"
       
  4887   and crsp: "crsp ly (0, lm) (Suc 0, l, r) ires"
       
  4888   and nothalt: "as < length ap"
       
  4889   and aexec: "abc_steps_l (0, lm) ap stp = (as, am)"
       
  4890   shows "\<exists>stpa\<ge>stp. crsp ly (as, am) (steps (Suc 0, l, r) (tp, 0) stpa) ires"
       
  4891 using nothalt aexec
       
  4892 proof(induct stp arbitrary: as am)
       
  4893   case 0
       
  4894   thus "?case"
       
  4895     using crsp
       
  4896     by(rule_tac x = 0 in exI, auto simp: abc_steps_l.simps steps.simps crsp)
       
  4897 next
       
  4898   case (Suc stp as am)
       
  4899   have ind: 
       
  4900     "\<And> as am.  \<lbrakk>as < length ap; abc_steps_l (0, lm) ap stp = (as, am)\<rbrakk> 
       
  4901     \<Longrightarrow> \<exists>stpa\<ge>stp. crsp ly (as, am) (steps (Suc 0, l, r) (tp, 0) stpa) ires" by fact
       
  4902   have a: "as < length ap" by fact
       
  4903   have b: "abc_steps_l (0, lm) ap (Suc stp) = (as, am)" by fact
       
  4904   obtain as' am' where c: "abc_steps_l (0, lm) ap stp = (as', am')" 
       
  4905     by(case_tac "abc_steps_l (0, lm) ap stp", auto)
       
  4906   then have d: "as' < length ap"
       
  4907     using a b
       
  4908     by(simp add: abc_step_red2, case_tac "as' < length ap", simp,
       
  4909       simp add: abc_fetch.simps abc_steps_l.simps abc_step_l.simps)
       
  4910   have "\<exists>stpa\<ge>stp. crsp ly (as', am') (steps (Suc 0, l, r) (tp, 0) stpa) ires"
       
  4911     using d c ind by simp
       
  4912   from this obtain stpa where e: 
       
  4913     "stpa \<ge> stp \<and>  crsp ly (as', am') (steps (Suc 0, l, r) (tp, 0) stpa) ires"
       
  4914     by blast
       
  4915   obtain s' l' r' where f: "steps (Suc 0, l, r) (tp, 0) stpa = (s', l', r')"
       
  4916     by(case_tac "steps (Suc 0, l, r) (tp, 0) stpa", auto)
       
  4917   obtain ins where g: "abc_fetch as' ap = Some ins" using d 
       
  4918     by(case_tac "abc_fetch as' ap",auto simp: abc_fetch.simps)
       
  4919   then have "\<exists>stp> (0::nat). crsp ly (abc_step_l (as', am') (Some ins)) 
       
  4920     (steps (s', l', r') (tp, 0) stp) ires "
       
  4921     using layout compile e f 
       
  4922     by(rule_tac crsp_step, simp_all)
       
  4923   then obtain stpb where "stpb > 0 \<and> crsp ly (abc_step_l (as', am') (Some ins)) 
       
  4924     (steps (s', l', r') (tp, 0) stpb) ires" ..
       
  4925   from this show "?case" using b e g f c
       
  4926     by(rule_tac x = "stpa + stpb" in exI, simp add: steps_add abc_step_red2)
       
  4927 qed
       
  4928     
       
  4929 lemma compile_correct_unhalt: 
       
  4930   assumes layout: "ly = layout_of ap"
       
  4931   and compile: "tp = tm_of ap"
       
  4932   and crsp: "crsp ly (0, lm) (Suc 0, l, r) ires"
       
  4933   and off: "off = length tp div 2"
       
  4934   and abc_unhalt: "\<forall> stp. (\<lambda> (as, am). as < length ap) (abc_steps_l (0, lm) ap stp)"
       
  4935   shows "\<forall> stp.\<not> is_final (steps (Suc 0, l, r) (tp @ shift (mopup n) off, 0) stp)"
       
  4936 using assms
       
  4937 proof(rule_tac allI, rule_tac notI)
       
  4938   fix stp
       
  4939   assume h: "is_final (steps (Suc 0, l, r) (tp @ shift (mopup n) off, 0) stp)"
       
  4940   obtain as am where a: "abc_steps_l (0, lm) ap stp = (as, am)"
       
  4941     by(case_tac "abc_steps_l (0, lm) ap stp", auto)
       
  4942   then have b: "as < length ap"
       
  4943     using abc_unhalt
       
  4944     by(erule_tac x = stp in allE, simp)
       
  4945   have "\<exists> stpa\<ge>stp. crsp ly (as, am) (steps (Suc 0, l, r) (tp, 0) stpa) ires "
       
  4946     using assms b a
       
  4947     apply(rule_tac crsp_steps2, simp_all)
       
  4948     done
       
  4949   then obtain stpa where
       
  4950     "stpa\<ge>stp \<and> crsp ly (as, am) (steps (Suc 0, l, r) (tp, 0) stpa) ires" ..
       
  4951   then obtain s' l' r' where b: "(steps (Suc 0, l, r) (tp, 0) stpa) = (s', l', r') \<and> 
       
  4952        stpa\<ge>stp \<and> crsp ly (as, am) (s', l', r') ires"
       
  4953     by(case_tac "steps (Suc 0, l, r) (tp, 0) stpa", auto)
       
  4954   hence c:
       
  4955     "(steps (Suc 0, l, r) (tp @ shift (mopup n) off, 0) stpa) = (s', l', r')"
       
  4956     by(rule_tac tm_append_first_steps_eq, simp_all add: crsp.simps)
       
  4957   from b have d: "s' > 0 \<and> stpa \<ge> stp"
       
  4958     by(simp add: crsp.simps)
       
  4959   then obtain diff where e: "stpa = stp + diff"   by (metis le_iff_add)
       
  4960   obtain s'' l'' r'' where f:
       
  4961     "steps (Suc 0, l, r) (tp @ shift (mopup n) off, 0) stp = (s'', l'', r'') \<and> is_final (s'', l'', r'')"
       
  4962     using h
       
  4963     by(case_tac "steps (Suc 0, l, r) (tp @ shift (mopup n) off, 0) stp", auto)
       
  4964 
       
  4965   then have "is_final (steps (s'', l'', r'') (tp @ shift (mopup n) off, 0) diff)"
       
  4966     by(auto intro: after_is_final)
       
  4967   then have "is_final (steps (Suc 0, l, r) (tp @ shift (mopup n) off, 0) stpa)"
       
  4968     using e
       
  4969     by(simp add: steps_add f)
       
  4970   from this and c d show "False" by simp
       
  4971 qed
       
  4972 
       
  4973 end
       
  4974