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