Journal/Paper.thy
changeset 282 02b6fab379ba
equal deleted inserted replaced
281:00ac265b251b 282:02b6fab379ba
       
     1 (*<*)
       
     2 theory Paper
       
     3 imports "../thys/UTM" "../thys/Abacus_Defs"
       
     4 begin
       
     5 
       
     6 (*
       
     7 value "map (steps (1,[],[Oc]) ([(L,0),(L,2),(R,2),(R,0)],0)) [0 ..< 4]"
       
     8 *)
       
     9 hide_const (open) s 
       
    10 
       
    11 
       
    12 
       
    13 hide_const (open) Divides.adjust
       
    14 
       
    15 abbreviation
       
    16   "update2 p a \<equiv> update a p"
       
    17 
       
    18 consts DUMMY::'a
       
    19 
       
    20 (* Theorems as inference rules from LaTeXsugar.thy *)
       
    21 notation (Rule output)
       
    22   "==>"  ("\<^raw:\mbox{}\inferrule{\mbox{>_\<^raw:}}>\<^raw:{\mbox{>_\<^raw:}}>")
       
    23 
       
    24 syntax (Rule output)
       
    25   "_bigimpl" :: "asms \<Rightarrow> prop \<Rightarrow> prop"
       
    26   ("\<^raw:\mbox{}\inferrule{>_\<^raw:}>\<^raw:{\mbox{>_\<^raw:}}>")
       
    27 
       
    28   "_asms" :: "prop \<Rightarrow> asms \<Rightarrow> asms" 
       
    29   ("\<^raw:\mbox{>_\<^raw:}\\>/ _")
       
    30 
       
    31   "_asm" :: "prop \<Rightarrow> asms" ("\<^raw:\mbox{>_\<^raw:}>")
       
    32 
       
    33 notation (Axiom output)
       
    34   "Trueprop"  ("\<^raw:\mbox{}\inferrule{\mbox{}}{\mbox{>_\<^raw:}}>")
       
    35 
       
    36 notation (IfThen output)
       
    37   "==>"  ("\<^raw:{\normalsize{}>If\<^raw:\,}> _/ \<^raw:{\normalsize \,>then\<^raw:\,}>/ _.")
       
    38 syntax (IfThen output)
       
    39   "_bigimpl" :: "asms \<Rightarrow> prop \<Rightarrow> prop"
       
    40   ("\<^raw:{\normalsize{}>If\<^raw:\,}> _ /\<^raw:{\normalsize \,>then\<^raw:\,}>/ _.")
       
    41   "_asms" :: "prop \<Rightarrow> asms \<Rightarrow> asms" ("\<^raw:\mbox{>_\<^raw:}> /\<^raw:{\normalsize \,>and\<^raw:\,}>/ _")
       
    42   "_asm" :: "prop \<Rightarrow> asms" ("\<^raw:\mbox{>_\<^raw:}>")
       
    43 
       
    44 notation (IfThenNoBox output)
       
    45   "==>"  ("\<^raw:{\normalsize{}>If\<^raw:\,}> _/ \<^raw:{\normalsize \,>then\<^raw:\,}>/ _.")
       
    46 syntax (IfThenNoBox output)
       
    47   "_bigimpl" :: "asms \<Rightarrow> prop \<Rightarrow> prop"
       
    48   ("\<^raw:{\normalsize{}>If\<^raw:\,}> _ /\<^raw:{\normalsize \,>then\<^raw:\,}>/ _.")
       
    49   "_asms" :: "prop \<Rightarrow> asms \<Rightarrow> asms" ("_ /\<^raw:{\normalsize \,>and\<^raw:\,}>/ _")
       
    50   "_asm" :: "prop \<Rightarrow> asms" ("_")
       
    51 
       
    52 
       
    53 context uncomputable
       
    54 begin
       
    55 
       
    56 notation (latex output)
       
    57   Cons ("_::_" [48,47] 48) and
       
    58   set ("") and
       
    59   W0 ("W\<^bsub>\<^raw:\hspace{-2pt}>Bk\<^esub>") and
       
    60   W1 ("W\<^bsub>\<^raw:\hspace{-2pt}>Oc\<^esub>") and
       
    61   update2 ("update") and
       
    62   tm_wf0 ("wf") and
       
    63   tcopy_begin ("cbegin") and
       
    64   tcopy_loop ("cloop") and
       
    65   tcopy_end ("cend") and
       
    66   step0 ("step") and
       
    67   tcontra ("contra") and
       
    68   code_tcontra ("code contra") and
       
    69   steps0 ("steps") and
       
    70   adjust0 ("adjust") and
       
    71   exponent ("_\<^bsup>_\<^esup>") and
       
    72   tcopy ("copy") and 
       
    73   tape_of ("\<langle>_\<rangle>") and 
       
    74   tm_comp ("_ ; _") and 
       
    75   DUMMY  ("\<^raw:\mbox{$\_\!\_\,$}>") and
       
    76   inv_begin0 ("I\<^isub>0") and
       
    77   inv_begin1 ("I\<^isub>1") and
       
    78   inv_begin2 ("I\<^isub>2") and
       
    79   inv_begin3 ("I\<^isub>3") and
       
    80   inv_begin4 ("I\<^isub>4") and 
       
    81   inv_begin ("I\<^bsub>cbegin\<^esub>") and
       
    82   inv_loop1 ("J\<^isub>1") and
       
    83   inv_loop0 ("J\<^isub>0") and
       
    84   inv_end1 ("K\<^isub>1") and
       
    85   inv_end0 ("K\<^isub>0") and
       
    86   measure_begin_step ("M\<^bsub>cbegin\<^esub>") and
       
    87   layout_of ("layout") and
       
    88   findnth ("find'_nth") and
       
    89   recf.id ("id\<^raw:\makebox[0mm]{\,\,\,\,>\<^isup>_\<^raw:}>\<^isub>_") and
       
    90   Pr ("Pr\<^isup>_") and
       
    91   Cn ("Cn\<^isup>_") and
       
    92   Mn ("Mn\<^isup>_") and
       
    93   rec_exec ("eval") and
       
    94   tm_of_rec ("translate") and
       
    95   listsum ("\<Sigma>")
       
    96 
       
    97  
       
    98 lemma inv_begin_print:
       
    99   shows "s = 0 \<Longrightarrow> inv_begin n (s, tp) = inv_begin0 n tp" and
       
   100         "s = 1 \<Longrightarrow> inv_begin n (s, tp) = inv_begin1 n tp" and 
       
   101         "s = 2 \<Longrightarrow> inv_begin n (s, tp) = inv_begin2 n tp" and 
       
   102         "s = 3 \<Longrightarrow> inv_begin n (s, tp) = inv_begin3 n tp" and 
       
   103         "s = 4 \<Longrightarrow> inv_begin n (s, tp) = inv_begin4 n tp" and
       
   104         "s \<notin> {0,1,2,3,4} \<Longrightarrow> inv_begin n (s, l, r) = False"
       
   105 apply(case_tac [!] tp)
       
   106 by (auto)
       
   107 
       
   108 
       
   109 lemma inv1: 
       
   110   shows "0 < (n::nat) \<Longrightarrow> Turing_Hoare.assert_imp (inv_begin0 n) (inv_loop1 n)"
       
   111 unfolding Turing_Hoare.assert_imp_def
       
   112 unfolding inv_loop1.simps inv_begin0.simps
       
   113 apply(auto)
       
   114 apply(rule_tac x="1" in exI)
       
   115 apply(auto simp add: replicate.simps)
       
   116 done
       
   117 
       
   118 lemma inv2: 
       
   119   shows "0 < n \<Longrightarrow> inv_loop0 n = inv_end1 n"
       
   120 apply(rule ext)
       
   121 apply(case_tac x)
       
   122 apply(simp add: inv_end1.simps)
       
   123 done
       
   124 
       
   125 
       
   126 lemma measure_begin_print:
       
   127   shows "s = 2 \<Longrightarrow> measure_begin_step (s, l, r) = length r" and
       
   128         "s = 3 \<Longrightarrow> measure_begin_step (s, l, r) = (if r = [] \<or> r = [Bk] then 1 else 0)" and
       
   129         "s = 4 \<Longrightarrow> measure_begin_step (s, l, r) = length l" and 
       
   130         "s \<notin> {2,3,4} \<Longrightarrow> measure_begin_step (s, l, r) = 0"
       
   131 by (simp_all)
       
   132 
       
   133 declare [[show_question_marks = false]]
       
   134 
       
   135 lemma nats2tape:
       
   136   shows "<([]::nat list)> = []"
       
   137   and "<[n]> = <n>"
       
   138   and "ns \<noteq> [] \<Longrightarrow> <n#ns> = <(n::nat, ns)>"
       
   139   and "<(n, m)> = <n> @ [Bk] @ <m>"
       
   140   and "<[n, m]> = <(n, m)>"
       
   141   and "<n> = Oc \<up> (n + 1)" 
       
   142 apply(auto simp add: tape_of_nat_pair tape_of_nl_abv tape_of_nat_abv tape_of_nat_list.simps)
       
   143 apply(case_tac ns)
       
   144 apply(auto simp add: tape_of_nat_pair tape_of_nat_abv)
       
   145 done 
       
   146 
       
   147 lemmas HR1 = 
       
   148   Hoare_plus_halt[where ?S.0="R\<iota>" and ?A="p\<^isub>1" and B="p\<^isub>2"]
       
   149 
       
   150 lemmas HR2 =
       
   151   Hoare_plus_unhalt[where ?A="p\<^isub>1" and B="p\<^isub>2"]
       
   152 
       
   153 lemma inv_begin01:
       
   154   assumes "n > 1"
       
   155   shows "inv_begin0 n (l, r) = (n > 1 \<and> (l, r) = (Oc \<up> (n - 2), [Oc, Oc, Bk, Oc]))"
       
   156 using assms by auto                          
       
   157 
       
   158 lemma inv_begin02:
       
   159   assumes "n = 1"
       
   160   shows "inv_begin0 n (l, r) = (n = 1 \<and> (l, r) = ([], [Bk, Oc, Bk, Oc]))"
       
   161 using assms by auto
       
   162 
       
   163 
       
   164 lemma layout:
       
   165   shows "layout_of [] = []"
       
   166   and   "layout_of ((Inc R\<iota>)#is) = (2 * R\<iota> + 9)#(layout_of is)"
       
   167   and   "layout_of ((Dec R\<iota> l)#is) = (2 * R\<iota> + 16)#(layout_of is)"
       
   168   and   "layout_of ((Goto l)#is) = 1#(layout_of is)"
       
   169 by(auto simp add: layout_of.simps length_of.simps)
       
   170 
       
   171 
       
   172 lemma adjust_simps:
       
   173   shows "adjust0 p = map (\<lambda>(a, s). (a, if s = 0 then (Suc (length p div 2)) else s)) p"
       
   174 by(simp add: adjust.simps)
       
   175 
       
   176 fun clear :: "nat \<Rightarrow> nat \<Rightarrow> abc_prog"
       
   177   where
       
   178   "clear n e = [Dec n e, Goto 0]"
       
   179 
       
   180 partial_function (tailrec)
       
   181   run
       
   182 where
       
   183   "run p cf = (if (is_final cf) then cf else run p (step0 cf p))"
       
   184 
       
   185 lemma numeral2:
       
   186   shows "11 = Suc 10"
       
   187   and   "12 = Suc 11"
       
   188   and   "13 = Suc 12"
       
   189   and   "14 = Suc 13"
       
   190   and   "15 = Suc 14"
       
   191 apply(arith)+
       
   192 done
       
   193 
       
   194 lemma tm_wf_simps:
       
   195   "tm_wf0 p = (2 <=length p \<and> is_even(length p) \<and> (\<forall>(a,s) \<in> set p. s <= (length p) div 2))"
       
   196 apply(simp add: tm_wf.simps)
       
   197 done
       
   198 
       
   199 (*>*)
       
   200 
       
   201 section {* Introduction *}
       
   202 
       
   203 
       
   204 
       
   205 text {*
       
   206 
       
   207 %\noindent
       
   208 %We formalised in earlier work the correctness proofs for two
       
   209 %algorithms in Isabelle/HOL---one about type-checking in
       
   210 %LF~\cite{UrbanCheneyBerghofer11} and another about deciding requests
       
   211 %in access control~\cite{WuZhangUrban12}.  The formalisations
       
   212 %uncovered a gap in the informal correctness proof of the former and
       
   213 %made us realise that important details were left out in the informal
       
   214 %model for the latter. However, in both cases we were unable to
       
   215 %formalise in Isabelle/HOL computability arguments about the
       
   216 %algorithms. 
       
   217 
       
   218 %Suppose you want to mechanise a proof for whether a predicate @{term P}, 
       
   219 %say, is decidable or not. Decidability of @{text P} usually
       
   220 %amounts to showing whether \mbox{@{term "P \<or> \<not>P"}} holds. But this
       
   221 %does \emph{not} work in 
       
   222 
       
   223 
       
   224 %Since Isabelle/HOL and other HOL theorem provers,
       
   225 %are based on classical logic where the law of excluded
       
   226 %middle ensures that \mbox{@{term "P \<or> \<not>P"}} is always provable no
       
   227 %matter whether @{text P} is constructed by computable means. We hit on
       
   228 %this limitation previously when we mechanised the correctness proofs
       
   229 %of two algorithms \cite{UrbanCheneyBerghofer11,WuZhangUrban12}, but
       
   230 %were unable to formalise arguments about decidability or undecidability.
       
   231 
       
   232 %The same problem would arise if we had formulated
       
   233 %the algorithms as recursive functions, because internally in
       
   234 %Isabelle/HOL, like in all HOL-based theorem provers, functions are
       
   235 %represented as inductively defined predicates too.
       
   236 
       
   237 \noindent
       
   238 We like to enable Isabelle/HOL users to reason about computability
       
   239 theory.  Reasoning about decidability of predicates, for example, is not as
       
   240 straightforward as one might think in Isabelle/HOL and other HOL
       
   241 theorem provers, since they are based on classical logic where the law
       
   242 of excluded middle ensures that \mbox{@{term "P \<or> \<not>P"}} is always
       
   243 provable no matter whether the predicate @{text P} is constructed by
       
   244 computable means.
       
   245 
       
   246 Norrish formalised computability
       
   247 theory in HOL4. He choose the $\lambda$-calculus as the starting point
       
   248 for his formalisation because of its ``simplicity'' \cite[Page
       
   249 297]{Norrish11}.  Part of his formalisation is a clever infrastructure
       
   250 for reducing $\lambda$-terms. He also established the computational
       
   251 equivalence between the $\lambda$-calculus and recursive functions.
       
   252 Nevertheless he concluded that it would be appealing to have
       
   253 formalisations for more operational models of computations, such as
       
   254 Turing machines or register machines.  One reason is that many proofs
       
   255 in the literature use them.  He noted however that \cite[Page
       
   256 310]{Norrish11}:
       
   257 
       
   258 \begin{quote}
       
   259 \it``If register machines are unappealing because of their 
       
   260 general fiddliness,\\ Turing machines are an even more 
       
   261 daunting prospect.''
       
   262 \end{quote}
       
   263 
       
   264 \noindent
       
   265 In this paper we take on this daunting prospect and provide a
       
   266 formalisation of Turing machines, as well as abacus machines (a kind
       
   267 of register machines) and recursive functions. To see the difficulties
       
   268 involved with this work, one has to understand that Turing machine
       
   269 programs (similarly abacus programs) can be completely
       
   270 \emph{unstructured}, behaving similar to Basic programs containing the
       
   271 infamous goto \cite{Dijkstra68}. This precludes in the general case a
       
   272 compositional Hoare-style reasoning about Turing programs.  We provide
       
   273 such Hoare-rules for when it \emph{is} possible to reason in a
       
   274 compositional manner (which is fortunately quite often), but also
       
   275 tackle the more complicated case when we translate abacus programs
       
   276 into Turing programs.  This reasoning about concrete Turing machine
       
   277 programs is usually left out in the informal literature,
       
   278 e.g.~\cite{Boolos87}.
       
   279 
       
   280 %To see the difficulties
       
   281 %involved with this work, one has to understand that interactive
       
   282 %theorem provers, like Isabelle/HOL, are at their best when the
       
   283 %data-structures at hand are ``structurally'' defined, like lists,
       
   284 %natural numbers, regular expressions, etc. Such data-structures come
       
   285 %with convenient reasoning infrastructures (for example induction
       
   286 %principles, recursion combinators and so on).  But this is \emph{not}
       
   287 %the case with Turing machines (and also not with register machines):
       
   288 %underlying their definitions are sets of states together with 
       
   289 %transition functions, all of which are not structurally defined.  This
       
   290 %means we have to implement our own reasoning infrastructure in order
       
   291 %to prove properties about them. This leads to annoyingly fiddly
       
   292 %formalisations.  We noticed first the difference between both,
       
   293 %structural and non-structural, ``worlds'' when formalising the
       
   294 %Myhill-Nerode theorem, where regular expressions fared much better
       
   295 %than automata \cite{WuZhangUrban11}.  However, with Turing machines
       
   296 %there seems to be no alternative if one wants to formalise the great
       
   297 %many proofs from the literature that use them.  We will analyse one
       
   298 %example---undecidability of Wang's tiling problem---in Section~\ref{Wang}. The
       
   299 %standard proof of this property uses the notion of universal
       
   300 %Turing machines.
       
   301 
       
   302 We are not the first who formalised Turing machines: we are aware of
       
   303 the work by Asperti and Ricciotti \cite{AspertiRicciotti12}. They
       
   304 describe a complete formalisation of Turing machines in the Matita
       
   305 theorem prover, including a universal Turing machine. However, they do
       
   306 \emph{not} formalise the undecidability of the halting problem since
       
   307 their main focus is complexity, rather than computability theory. They
       
   308 also report that the informal proofs from which they started are not
       
   309 ``sufficiently accurate to be directly usable as a guideline for
       
   310 formalization'' \cite[Page 2]{AspertiRicciotti12}. For our
       
   311 formalisation we follow mainly the proofs from the textbook by Boolos
       
   312 et al \cite{Boolos87} and found that the description there is quite
       
   313 detailed. Some details are left out however: for example, constructing
       
   314 the \emph{copy Turing machine} is left as an exercise to the
       
   315 reader---a corresponding correctness proof is not mentioned at all; also \cite{Boolos87}
       
   316 only shows how the universal Turing machine is constructed for Turing
       
   317 machines computing unary functions. We had to figure out a way to
       
   318 generalise this result to $n$-ary functions. Similarly, when compiling
       
   319 recursive functions to abacus machines, the textbook again only shows
       
   320 how it can be done for 2- and 3-ary functions, but in the
       
   321 formalisation we need arbitrary functions. But the general ideas for
       
   322 how to do this are clear enough in \cite{Boolos87}.
       
   323 %However, one
       
   324 %aspect that is completely left out from the informal description in
       
   325 %\cite{Boolos87}, and similar ones we are aware of, is arguments why certain Turing
       
   326 %machines are correct. We will introduce Hoare-style proof rules
       
   327 %which help us with such correctness arguments of Turing machines.
       
   328 
       
   329 The main difference between our formalisation and the one by Asperti
       
   330 and Ricciotti is that their universal Turing machine uses a different
       
   331 alphabet than the machines it simulates. They write \cite[Page
       
   332 23]{AspertiRicciotti12}:
       
   333 
       
   334 \begin{quote}\it
       
   335 ``In particular, the fact that the universal machine operates with a
       
   336 different alphabet with respect to the machines it simulates is
       
   337 annoying.'' 
       
   338 \end{quote}
       
   339 
       
   340 \noindent
       
   341 In this paper we follow the approach by Boolos et al \cite{Boolos87},
       
   342 which goes back to Post \cite{Post36}, where all Turing machines
       
   343 operate on tapes that contain only \emph{blank} or \emph{occupied} cells. 
       
   344 Traditionally the content of a cell can be any
       
   345 character from a finite alphabet. Although computationally equivalent,
       
   346 the more restrictive notion of Turing machines in \cite{Boolos87} makes
       
   347 the reasoning more uniform. In addition some proofs \emph{about} Turing
       
   348 machines are simpler.  The reason is that one often needs to encode
       
   349 Turing machines---consequently if the Turing machines are simpler, then the coding
       
   350 functions are simpler too. Unfortunately, the restrictiveness also makes
       
   351 it harder to design programs for these Turing machines. In order
       
   352 to construct a universal Turing machine we therefore do not follow 
       
   353 \cite{AspertiRicciotti12}, instead follow the proof in
       
   354 \cite{Boolos87} by translating abacus machines to Turing machines and in
       
   355 turn recursive functions to abacus machines. The universal Turing
       
   356 machine can then be constructed by translating from a (universal) recursive function. 
       
   357 The part of mechanising the translation of recursive function to register 
       
   358 machines has already been done by Zammit in HOL4 \cite{Zammit99}, 
       
   359 although his register machines use a slightly different instruction
       
   360 set than the one described in \cite{Boolos87}.
       
   361 
       
   362 \smallskip
       
   363 \noindent
       
   364 {\bf Contributions:} We formalised in Isabelle/HOL Turing machines
       
   365 following the description of Boolos et al \cite{Boolos87} where tapes
       
   366 only have blank or occupied cells. We mechanise the undecidability of
       
   367 the halting problem and prove the correctness of concrete Turing
       
   368 machines that are needed in this proof; such correctness proofs are
       
   369 left out in the informal literature.  For reasoning about Turing
       
   370 machine programs we derive Hoare-rules.  We also construct the
       
   371 universal Turing machine from \cite{Boolos87} by translating recursive
       
   372 functions to abacus machines and abacus machines to Turing
       
   373 machines. This works essentially like a small, verified compiler 
       
   374 from recursive functions to Turing machine programs.
       
   375 When formalising the universal Turing machine,
       
   376 we stumbled in \cite{Boolos87} upon an inconsistent use of the definition of
       
   377 what partial function a Turing machine calculates. 
       
   378 
       
   379 %Since we have set up in
       
   380 %Isabelle/HOL a very general computability model and undecidability
       
   381 %result, we are able to formalise other results: we describe a proof of
       
   382 %the computational equivalence of single-sided Turing machines, which
       
   383 %is not given in \cite{Boolos87}, but needed for example for
       
   384 %formalising the undecidability proof of Wang's tiling problem
       
   385 %\cite{Robinson71}.  %We are not aware of any other %formalisation of a
       
   386 %substantial undecidability problem.
       
   387 *}
       
   388 
       
   389 section {* Turing Machines *}
       
   390 
       
   391 text {* \noindent
       
   392   Turing machines can be thought of as having a \emph{head},
       
   393   ``gliding'' over a potentially infinite tape. Boolos et
       
   394   al~\cite{Boolos87} only consider tapes with cells being either blank
       
   395   or occupied, which we represent by a datatype having two
       
   396   constructors, namely @{text Bk} and @{text Oc}.  One way to
       
   397   represent such tapes is to use a pair of lists, written @{term "(l,
       
   398   r)"}, where @{term l} stands for the tape on the left-hand side of
       
   399   the head and @{term r} for the tape on the right-hand side.  We use
       
   400   the notation @{term "Bk \<up> n"} (similarly @{term "Oc \<up> n"}) for lists
       
   401   composed of @{term n} elements of @{term Bk}s.  We also have the
       
   402   convention that the head, abbreviated @{term hd}, of the right list
       
   403   is the cell on which the head of the Turing machine currently
       
   404   scans. This can be pictured as follows:
       
   405   %
       
   406   \begin{center}
       
   407   \begin{tikzpicture}[scale=0.9]
       
   408   \draw[very thick] (-3.0,0)   -- ( 3.0,0);
       
   409   \draw[very thick] (-3.0,0.5) -- ( 3.0,0.5);
       
   410   \draw[very thick] (-0.25,0)   -- (-0.25,0.5);
       
   411   \draw[very thick] ( 0.25,0)   -- ( 0.25,0.5);
       
   412   \draw[very thick] (-0.75,0)   -- (-0.75,0.5);
       
   413   \draw[very thick] ( 0.75,0)   -- ( 0.75,0.5);
       
   414   \draw[very thick] (-1.25,0)   -- (-1.25,0.5);
       
   415   \draw[very thick] ( 1.25,0)   -- ( 1.25,0.5);
       
   416   \draw[very thick] (-1.75,0)   -- (-1.75,0.5);
       
   417   \draw[very thick] ( 1.75,0)   -- ( 1.75,0.5);
       
   418   \draw[rounded corners=1mm] (-0.35,-0.1) rectangle (0.35,0.6);
       
   419   \draw[fill]     (1.35,0.1) rectangle (1.65,0.4);
       
   420   \draw[fill]     (0.85,0.1) rectangle (1.15,0.4);
       
   421   \draw[fill]     (-0.35,0.1) rectangle (-0.65,0.4);
       
   422   \draw[fill]     (-1.65,0.1) rectangle (-1.35,0.4);
       
   423   \draw (-0.25,0.8) -- (-0.25,-0.8);
       
   424   \draw[<->] (-1.25,-0.7) -- (0.75,-0.7);
       
   425   \node [anchor=base] at (-0.85,-0.5) {\small left list};
       
   426   \node [anchor=base] at (0.40,-0.5) {\small right list};
       
   427   \node [anchor=base] at (0.1,0.7) {\small head};
       
   428   \node [anchor=base] at (-2.2,0.2) {\ldots};
       
   429   \node [anchor=base] at ( 2.3,0.2) {\ldots};
       
   430   \end{tikzpicture}
       
   431   \end{center}
       
   432   
       
   433   \noindent
       
   434   Note that by using lists each side of the tape is only finite. The
       
   435   potential infinity is achieved by adding an appropriate blank or occupied cell 
       
   436   whenever the head goes over the ``edge'' of the tape. To 
       
   437   make this formal we define five possible \emph{actions} 
       
   438   the Turing machine can perform:
       
   439 
       
   440   \begin{center}
       
   441   \begin{tabular}[t]{@ {}rcl@ {\hspace{2mm}}l}
       
   442   @{text "a"} & $::=$  & @{term "W0"} & (write blank, @{term Bk})\\
       
   443   & $\mid$ & @{term "W1"} & (write occupied, @{term Oc})\\
       
   444   & $\mid$ & @{term L} & (move left)\\
       
   445   & $\mid$ & @{term R} & (move right)\\
       
   446   & $\mid$ & @{term Nop} & (do-nothing operation)\\
       
   447   \end{tabular}
       
   448   \end{center}
       
   449 
       
   450   \noindent
       
   451   We slightly deviate
       
   452   from the presentation in \cite{Boolos87} (and also \cite{AspertiRicciotti12}) 
       
   453   by using the @{term Nop} operation; however its use
       
   454   will become important when we formalise halting computations and also universal Turing 
       
   455   machines.  Given a tape and an action, we can define the
       
   456   following tape updating function:
       
   457 
       
   458   \begin{center}
       
   459   \begin{tabular}{l@ {\hspace{1mm}}c@ {\hspace{1mm}}l}
       
   460   @{thm (lhs) update.simps(1)} & @{text "\<equiv>"} & @{thm (rhs) update.simps(1)}\\
       
   461   @{thm (lhs) update.simps(2)} & @{text "\<equiv>"} & @{thm (rhs) update.simps(2)}\\
       
   462   @{thm (lhs) update.simps(3)} & @{text "\<equiv>"} & @{thm (rhs) update.simps(3)}\\
       
   463   @{thm (lhs) update.simps(4)} & @{text "\<equiv>"} & @{thm (rhs) update.simps(4)}\\
       
   464   @{thm (lhs) update.simps(5)} & @{text "\<equiv>"} & @{thm (rhs) update.simps(5)}\\
       
   465   \end{tabular}
       
   466   \end{center}
       
   467 
       
   468   \noindent
       
   469   The first two clauses replace the head of the right list
       
   470   with a new @{term Bk} or @{term Oc}, respectively. To see that
       
   471   these two clauses make sense in case where @{text r} is the empty
       
   472   list, one has to know that the tail function, @{term tl}, is defined
       
   473   such that @{term "tl [] == []"} holds. The third clause 
       
   474   implements the move of the head one step to the left: we need
       
   475   to test if the left-list @{term l} is empty; if yes, then we just prepend a 
       
   476   blank cell to the right list; otherwise we have to remove the
       
   477   head from the left-list and prepend it to the right list. Similarly
       
   478   in the fourth clause for a right move action. The @{term Nop} operation
       
   479   leaves the tape unchanged.
       
   480 
       
   481   %Note that our treatment of the tape is rather ``unsymmetric''---we
       
   482   %have the convention that the head of the right list is where the
       
   483   %head is currently positioned. Asperti and Ricciotti
       
   484   %\cite{AspertiRicciotti12} also considered such a representation, but
       
   485   %dismiss it as it complicates their definition for \emph{tape
       
   486   %equality}. The reason is that moving the head one step to
       
   487   %the left and then back to the right might change the tape (in case
       
   488   %of going over the ``edge''). Therefore they distinguish four types
       
   489   %of tapes: one where the tape is empty; another where the head
       
   490   %is on the left edge, respectively right edge, and in the middle
       
   491   %of the tape. The reading, writing and moving of the tape is then
       
   492   %defined in terms of these four cases.  In this way they can keep the
       
   493   %tape in a ``normalised'' form, and thus making a left-move followed
       
   494   %by a right-move being the identity on tapes. Since we are not using
       
   495   %the notion of tape equality, we can get away with the unsymmetric
       
   496   %definition above, and by using the @{term update} function
       
   497   %cover uniformly all cases including corner cases.
       
   498 
       
   499   Next we need to define the \emph{states} of a Turing machine.  
       
   500   %Given
       
   501   %how little is usually said about how to represent them in informal
       
   502   %presentations, it might be surprising that in a theorem prover we
       
   503   %have to select carefully a representation. If we use the naive
       
   504   %representation where a Turing machine consists of a finite set of
       
   505   %states, then we will have difficulties composing two Turing
       
   506   %machines: we would need to combine two finite sets of states,
       
   507   %possibly renaming states apart whenever both machines share
       
   508   %states.\footnote{The usual disjoint union operation in Isabelle/HOL
       
   509   %cannot be used as it does not preserve types.} This renaming can be
       
   510   %quite cumbersome to reason about. 
       
   511   We follow the choice made in \cite{AspertiRicciotti12} 
       
   512   by representing a state with a natural number and the states in a Turing
       
   513   machine program by the initial segment of natural numbers starting from @{text 0}.
       
   514   In doing so we can compose two Turing machine programs by
       
   515   shifting the states of one by an appropriate amount to a higher
       
   516   segment and adjusting some ``next states'' in the other. 
       
   517 
       
   518   An \emph{instruction} of a Turing machine is a pair consisting of 
       
   519   an action and a natural number (the next state). A \emph{program} @{term p} of a Turing
       
   520   machine is then a list of such pairs. Using as an example the following Turing machine
       
   521   program, which consists of four instructions
       
   522   %
       
   523   \begin{equation}
       
   524   \begin{tikzpicture}
       
   525   \node [anchor=base] at (0,0) {@{thm dither_def}};
       
   526   \node [anchor=west] at (-1.5,-0.64) 
       
   527   {$\underbrace{\hspace{21mm}}_{\text{\begin{tabular}{@ {}l@ {}}1st state\\[-2mm] 
       
   528   = starting state\end{tabular}}}$};
       
   529   
       
   530   \node [anchor=west] at ( 1.1,-0.42) {$\underbrace{\hspace{17mm}}_{\text{2nd state}}$};
       
   531   \node [anchor=west] at (-1.5,0.65) {$\overbrace{\hspace{10mm}}^{\text{@{term Bk}-case}}$};
       
   532   \node [anchor=west] at (-0.1,0.65) {$\overbrace{\hspace{6mm}}^{\text{@{term Oc}-case}}$};
       
   533   \end{tikzpicture}
       
   534   \label{dither}
       
   535   \end{equation}
       
   536   %
       
   537   \noindent
       
   538   the reader can see we have organised our Turing machine programs so
       
   539   that segments of two pairs belong to a state. The first component of such a
       
   540   segment determines what action should be taken and which next state
       
   541   should be transitioned to in case the head reads a @{term Bk};
       
   542   similarly the second component determines what should be done in
       
   543   case of reading @{term Oc}. We have the convention that the first
       
   544   state is always the \emph{starting state} of the Turing machine.
       
   545   The @{text 0}-state is special in that it will be used as the
       
   546   ``halting state''.  There are no instructions for the @{text
       
   547   0}-state, but it will always perform a @{term Nop}-operation and
       
   548   remain in the @{text 0}-state.  
       
   549   We have chosen a very concrete
       
   550   representation for Turing machine programs, because when constructing a universal
       
   551   Turing machine, we need to define a coding function for programs.
       
   552   %This can be directly done for our programs-as-lists, but is
       
   553   %slightly more difficult for the functions used by Asperti and Ricciotti.
       
   554 
       
   555   Given a program @{term p}, a state
       
   556   and the cell being scanned by the head, we need to fetch
       
   557   the corresponding instruction from the program. For this we define 
       
   558   the function @{term fetch}
       
   559  
       
   560   \begin{equation}\label{fetch}
       
   561   \mbox{\begin{tabular}{l@ {\hspace{1mm}}c@ {\hspace{1mm}}l}
       
   562   \multicolumn{3}{l}{@{thm fetch.simps(1)[where b=DUMMY]}}\\
       
   563   @{thm (lhs) fetch.simps(2)} & @{text "\<equiv>"} & @{text "case nth_of p (2 * s) of"}\\
       
   564   \multicolumn{3}{@ {\hspace{4cm}}l}{@{text "None \<Rightarrow> (Nop, 0) | Some i \<Rightarrow> i"}}\\
       
   565   @{thm (lhs) fetch.simps(3)} & @{text "\<equiv>"} & @{text "case nth_of p (2 * s + 1) of"}\\
       
   566   \multicolumn{3}{@ {\hspace{4cm}}l}{@{text "None \<Rightarrow> (Nop, 0) | Some i \<Rightarrow> i"}}
       
   567   \end{tabular}}
       
   568   \end{equation}
       
   569 
       
   570   \noindent
       
   571   In this definition the function @{term nth_of} returns the @{text n}th element
       
   572   from a list, provided it exists (@{term Some}-case), or if it does not, it
       
   573   returns the default action @{term Nop} and the default state @{text 0} 
       
   574   (@{term None}-case). We often have to restrict Turing machine programs 
       
   575   to be well-formed: a program @{term p} is \emph{well-formed} if it 
       
   576   satisfies the following three properties:
       
   577 
       
   578   \begin{center}
       
   579   @{thm tm_wf_simps[where p="p", THEN eq_reflection]}
       
   580   \end{center}
       
   581 
       
   582   \noindent
       
   583   The first states that @{text p} must have at least an instruction for the starting 
       
   584   state; the second that @{text p} has a @{term Bk} and @{term Oc} instruction for every 
       
   585   state, and the third that every next-state is one of the states mentioned in
       
   586   the program or being the @{text 0}-state.
       
   587 
       
   588  
       
   589   A \emph{configuration} @{term c} of a Turing machine is a state
       
   590   together with a tape. This is written as @{text "(s, (l, r))"}.  We
       
   591   say a configuration \emph{is final} if @{term "s = (0::nat)"} and we
       
   592   say a predicate @{text P} \emph{holds for} a configuration if @{text
       
   593   "P"} holds for the tape @{text "(l, r)"}.  If we have a configuration and a program, we can
       
   594   calculate what the next configuration is by fetching the appropriate
       
   595   action and next state from the program, and by updating the state
       
   596   and tape accordingly.  This single step of execution is defined as
       
   597   the function @{term step}
       
   598 
       
   599   \begin{center}
       
   600   \begin{tabular}{l@ {\hspace{1mm}}c@ {\hspace{1mm}}l}
       
   601   @{text "step (s, (l, r)) p"} & @{text "\<equiv>"} & @{text "let (a, s') = fetch p s (read r)"}\\
       
   602   & & @{text "in (s', update (l, r) a)"}
       
   603   \end{tabular}
       
   604   \end{center}
       
   605 
       
   606   \noindent
       
   607   where @{term "read r"} returns the head of the list @{text r}, or if
       
   608   @{text r} is empty it returns @{term Bk}.  
       
   609   We lift this definition to an evaluation function that performs 
       
   610   exactly @{text n} steps:
       
   611 
       
   612   \begin{center}
       
   613   \begin{tabular}{l@ {\hspace{1mm}}c@ {\hspace{1mm}}l}
       
   614   @{thm (lhs) steps.simps(1)} & @{text "\<equiv>"} & @{thm (rhs) steps.simps(1)}\\
       
   615   @{thm (lhs) steps.simps(2)} & @{text "\<equiv>"} & @{thm (rhs) steps.simps(2)}\\
       
   616   \end{tabular}
       
   617   \end{center}
       
   618 
       
   619   \noindent Recall our definition of @{term fetch} (shown in
       
   620   \eqref{fetch}) with the default value for the @{text 0}-state. In
       
   621   case a Turing program takes according to the usual textbook
       
   622   definition, say \cite{Boolos87}, less than @{text n} steps before it
       
   623   halts, then in our setting the @{term steps}-evaluation does not
       
   624   actually halt, but rather transitions to the @{text 0}-state (the
       
   625   final state) and remains there performing @{text Nop}-actions until
       
   626   @{text n} is reached. 
       
   627 
       
   628 
       
   629   We often need to restrict tapes to be in standard form, which means 
       
   630   the left list of the tape is either empty or only contains @{text "Bk"}s, and 
       
   631   the right list contains some ``clusters'' of @{text "Oc"}s separated by single 
       
   632   blanks. To make this formal we define the following overloaded function
       
   633   encoding natural numbers into lists of @{term "Oc"}s and @{term Bk}s.
       
   634   % 
       
   635   \begin{equation}
       
   636   \mbox{\begin{tabular}[t]{@ {}l@ {\hspace{1mm}}c@ {\hspace{1mm}}l@ {}}
       
   637   @{thm (lhs) nats2tape(6)} & @{text "\<equiv>"} & @{thm (rhs) nats2tape(6)}\\
       
   638   @{thm (lhs) nats2tape(4)} & @{text "\<equiv>"} & @{thm (rhs) nats2tape(4)}\\
       
   639   \end{tabular}\hspace{6mm}
       
   640   \begin{tabular}[t]{@ {}l@ {\hspace{1mm}}c@ {\hspace{1mm}}l@ {}}
       
   641   @{thm (lhs) nats2tape(1)} & @{text "\<equiv>"} & @{thm (rhs) nats2tape(1)}\\
       
   642   @{thm (lhs) nats2tape(2)} & @{text "\<equiv>"} & @{thm (rhs) nats2tape(2)}\\
       
   643   @{thm (lhs) nats2tape(3)} & @{text "\<equiv>"} & @{thm (rhs) nats2tape(3)}
       
   644   \end{tabular}}\label{standard}
       
   645   \end{equation}
       
   646   %
       
   647   \noindent
       
   648   A \emph{standard tape} is then of the form @{text "(Bk\<^isup>k,\<langle>[n\<^isub>1,...,n\<^isub>m]\<rangle> @ Bk\<^isup>l)"} for some @{text k}, 
       
   649   @{text l} 
       
   650   and @{text "n\<^bsub>1...m\<^esub>"}. Note that the head in a standard tape ``points'' to the 
       
   651   leftmost @{term "Oc"} on the tape. Note also that the natural number @{text 0} 
       
   652   is represented by a single filled cell on a standard tape, @{text 1} by two filled cells and so on.
       
   653 
       
   654 
       
   655  We need to be able to sequentially compose Turing machine programs. Given our
       
   656   concrete representation, this is relatively straightforward, if
       
   657   slightly fiddly. We use the following two auxiliary functions:
       
   658 
       
   659   \begin{center}
       
   660   \begin{tabular}{@ {}l@ {\hspace{1mm}}c@ {\hspace{1mm}}l@ {}}
       
   661   @{thm (lhs) shift.simps} @{text "\<equiv>"} @{thm (rhs) shift.simps}\\
       
   662   @{thm (lhs) adjust_simps} @{text "\<equiv>"} @{thm (rhs) adjust_simps}\\
       
   663   \end{tabular}
       
   664   \end{center}
       
   665 
       
   666   \noindent
       
   667   The first adds @{text n} to all states, except the @{text 0}-state,
       
   668   thus moving all ``regular'' states to the segment starting at @{text
       
   669   n}; the second adds @{term "Suc(length p div 2)"} to the @{text
       
   670   0}-state, thus redirecting all references to the ``halting state''
       
   671   to the first state after the program @{text p}.  With these two
       
   672   functions in place, we can define the \emph{sequential composition}
       
   673   of two Turing machine programs @{text "p\<^isub>1"} and @{text "p\<^isub>2"} as
       
   674 
       
   675   \begin{center}
       
   676   @{thm tm_comp.simps[where ?p1.0="p\<^isub>1" and ?p2.0="p\<^isub>2", THEN eq_reflection]}
       
   677   \end{center}
       
   678 
       
   679   \noindent
       
   680   %This means @{text "p\<^isub>1"} is executed first. Whenever it originally
       
   681   %transitioned to the @{text 0}-state, it will in the composed program transition to the starting
       
   682   %state of @{text "p\<^isub>2"} instead. All the states of @{text "p\<^isub>2"}
       
   683   %have been shifted in order to make sure that the states of the composed 
       
   684   %program @{text "p\<^isub>1 \<oplus> p\<^isub>2"} still only ``occupy'' 
       
   685   %an initial segment of the natural numbers.
       
   686   
       
   687   \begin{figure}[t]
       
   688   \begin{center}
       
   689   \begin{tabular}{@ {}c@ {\hspace{3mm}}c@ {\hspace{3mm}}c}
       
   690   \begin{tabular}[t]{@ {}l@ {}}
       
   691   @{thm (lhs) tcopy_begin_def} @{text "\<equiv>"}\\
       
   692   \hspace{2mm}@{text "["}@{text "(W\<^bsub>Bk\<^esub>, 0), (R, 2), (R, 3),"}\\
       
   693   \hspace{2mm}\phantom{@{text "["}}@{text "(R, 2), (W\<^bsub>Oc\<^esub>, 3), (L, 4),"}\\
       
   694   \hspace{2mm}\phantom{@{text "["}}@{text "(L, 4), (L, 0)"}@{text "]"} 
       
   695   \end{tabular}
       
   696   &
       
   697   \begin{tabular}[t]{@ {}l@ {}}
       
   698   @{thm (lhs) tcopy_loop_def} @{text "\<equiv>"}\\
       
   699   \hspace{2mm}@{text "["}@{text "(R, 0), (R, 2), (R, 3),"}\\
       
   700   \hspace{2mm}\phantom{@{text "["}}@{text "(W\<^bsub>Bk\<^esub>, 2), (R, 3), (R, 4),"}\\
       
   701   \hspace{2mm}\phantom{@{text "["}}@{text "(W\<^bsub>Oc\<^esub>, 5), (R, 4), (L, 6),"}\\
       
   702   \hspace{2mm}\phantom{@{text "["}}@{text "(L, 5), (L, 6), (L, 1)"}@{text "]"} 
       
   703   \end{tabular}
       
   704   &
       
   705   \begin{tabular}[t]{@ {}l@ {}}
       
   706   @{thm (lhs) tcopy_end_def} @{text "\<equiv>"}\\
       
   707   \hspace{2mm}@{text "["}@{text "(L, 0), (R, 2), (W\<^bsub>Oc\<^esub>, 3),"}\\
       
   708   \hspace{2mm}\phantom{@{text "["}}@{text "(L, 4), (R, 2), (R, 2),"}\\
       
   709   \hspace{2mm}\phantom{@{text "["}}@{text "(L, 5), (W\<^bsub>Bk\<^esub>, 4), (R, 0),"}\\
       
   710   \hspace{2mm}\phantom{@{text "["}}@{text "(L, 5)"}@{text "]"} 
       
   711   \end{tabular}
       
   712   \end{tabular}\\[2mm]
       
   713 
       
   714   \begin{tikzpicture}[scale=0.7]
       
   715   \node [anchor=base] at (2.2,0.1) {\small$\Rightarrow$};
       
   716   \node [anchor=base] at (5.6,0.1) {\small$\Rightarrow$};
       
   717   \node [anchor=base] at (10.5,0.1) {\small$\Rightarrow$};
       
   718   \node [anchor=base] at (2.2,-0.6) {\small$\overbrace{@{term "tcopy_begin"}}^{}$};
       
   719   \node [anchor=base] at (5.6,-0.6) {\small$\overbrace{@{term "tcopy_loop"}}^{}$};
       
   720   \node [anchor=base] at (10.5,-0.6) {\small$\overbrace{@{term "tcopy_end"}}^{}$};
       
   721 
       
   722 
       
   723   \begin{scope}[shift={(0.5,0)}]
       
   724   \draw[very thick] (-0.25,0)   -- ( 1.25,0);
       
   725   \draw[very thick] (-0.25,0.5) -- ( 1.25,0.5);
       
   726   \draw[very thick] (-0.25,0)   -- (-0.25,0.5);
       
   727   \draw[very thick] ( 0.25,0)   -- ( 0.25,0.5);
       
   728   \draw[very thick] ( 0.75,0)   -- ( 0.75,0.5);
       
   729   \draw[very thick] ( 1.25,0)   -- ( 1.25,0.5);
       
   730   \draw[rounded corners=1mm] (-0.35,-0.1) rectangle (0.35,0.6);
       
   731   \draw[fill]     (-0.15,0.1) rectangle (0.15,0.4);
       
   732   \draw[fill]     ( 0.35,0.1) rectangle (0.65,0.4);
       
   733   \draw[fill]     ( 0.85,0.1) rectangle (1.15,0.4);
       
   734   \end{scope}
       
   735 
       
   736   \begin{scope}[shift={(2.9,0)}]
       
   737   \draw[very thick] (-0.25,0)   -- ( 2.25,0);
       
   738   \draw[very thick] (-0.25,0.5) -- ( 2.25,0.5);
       
   739   \draw[very thick] (-0.25,0)   -- (-0.25,0.5);
       
   740   \draw[very thick] ( 0.25,0)   -- ( 0.25,0.5);
       
   741   \draw[very thick] ( 0.75,0)   -- ( 0.75,0.5);
       
   742   \draw[very thick] ( 1.25,0)   -- ( 1.25,0.5);
       
   743   \draw[very thick] ( 1.75,0)   -- ( 1.75,0.5);
       
   744   \draw[very thick] ( 2.25,0)   -- ( 2.25,0.5);
       
   745   \draw[rounded corners=1mm] (0.15,-0.1) rectangle (0.85,0.6);
       
   746   \draw[fill]     (-0.15,0.1) rectangle (0.15,0.4);
       
   747   \draw[fill]     ( 0.35,0.1) rectangle (0.65,0.4);
       
   748   \draw[fill]     ( 0.85,0.1) rectangle (1.15,0.4);
       
   749   \draw[fill]     ( 1.85,0.1) rectangle (2.15,0.4);
       
   750   \end{scope}
       
   751 
       
   752   \begin{scope}[shift={(6.8,0)}]
       
   753   \draw[very thick] (-0.75,0)   -- ( 3.25,0);
       
   754   \draw[very thick] (-0.75,0.5) -- ( 3.25,0.5);
       
   755   \draw[very thick] (-0.75,0)   -- (-0.75,0.5);
       
   756   \draw[very thick] (-0.25,0)   -- (-0.25,0.5);
       
   757   \draw[very thick] ( 0.25,0)   -- ( 0.25,0.5);
       
   758   \draw[very thick] ( 0.75,0)   -- ( 0.75,0.5);
       
   759   \draw[very thick] ( 1.25,0)   -- ( 1.25,0.5);
       
   760   \draw[very thick] ( 1.75,0)   -- ( 1.75,0.5);
       
   761   \draw[very thick] ( 2.25,0)   -- ( 2.25,0.5);
       
   762   \draw[very thick] ( 2.75,0)   -- ( 2.75,0.5);
       
   763   \draw[very thick] ( 3.25,0)   -- ( 3.25,0.5);
       
   764   \draw[rounded corners=1mm] (-0.35,-0.1) rectangle (0.35,0.6);
       
   765   \draw[fill]     (-0.15,0.1) rectangle (0.15,0.4);
       
   766   \draw[fill]     ( 2.35,0.1) rectangle (2.65,0.4);
       
   767   \draw[fill]     ( 2.85,0.1) rectangle (3.15,0.4);
       
   768   \draw[fill]     ( 1.85,0.1) rectangle (2.15,0.4);
       
   769   \end{scope}
       
   770 
       
   771   \begin{scope}[shift={(11.7,0)}]
       
   772   \draw[very thick] (-0.75,0)   -- ( 3.25,0);
       
   773   \draw[very thick] (-0.75,0.5) -- ( 3.25,0.5);
       
   774   \draw[very thick] (-0.75,0)   -- (-0.75,0.5);
       
   775   \draw[very thick] (-0.25,0)   -- (-0.25,0.5);
       
   776   \draw[very thick] ( 0.25,0)   -- ( 0.25,0.5);
       
   777   \draw[very thick] ( 0.75,0)   -- ( 0.75,0.5);
       
   778   \draw[very thick] ( 1.25,0)   -- ( 1.25,0.5);
       
   779   \draw[very thick] ( 1.75,0)   -- ( 1.75,0.5);
       
   780   \draw[very thick] ( 2.25,0)   -- ( 2.25,0.5);
       
   781   \draw[very thick] ( 2.75,0)   -- ( 2.75,0.5);
       
   782   \draw[very thick] ( 3.25,0)   -- ( 3.25,0.5);
       
   783   \draw[rounded corners=1mm] (-0.35,-0.1) rectangle (0.35,0.6);
       
   784   \draw[fill]     (-0.15,0.1) rectangle (0.15,0.4);
       
   785   \draw[fill]     ( 2.35,0.1) rectangle (2.65,0.4);
       
   786   \draw[fill]     ( 2.85,0.1) rectangle (3.15,0.4);
       
   787   \draw[fill]     ( 1.85,0.1) rectangle (2.15,0.4);
       
   788   \draw[fill]     ( 0.35,0.1) rectangle (0.65,0.4);
       
   789   \draw[fill]     ( 0.85,0.1) rectangle (1.15,0.4);
       
   790   \end{scope}
       
   791   \end{tikzpicture}\\[-8mm]\mbox{} 
       
   792   \end{center}
       
   793   \caption{The three components of the \emph{copy Turing machine} (above). If started 
       
   794   (below) with the tape @{term "([], <(2::nat)>)"} the first machine appends @{term "[Bk, Oc]"} at 
       
   795   the end of the right tape; the second then ``moves'' all @{term Oc}s except the 
       
   796   first from the beginning of the tape to the end; the third ``refills'' the original 
       
   797   block of @{term "Oc"}s. The resulting tape is @{term "([Bk], <(2::nat, 2::nat)>)"}.}
       
   798   \label{copy}
       
   799   \end{figure}
       
   800 
       
   801 
       
   802 
       
   803 
       
   804   Before we can prove the undecidability of the halting problem for
       
   805   our Turing machines working on standard tapes, we have to analyse
       
   806   two concrete Turing machine programs and establish that they are
       
   807   correct---that means they are ``doing what they are supposed to be
       
   808   doing''.  Such correctness proofs are usually left out in the
       
   809   informal literature, for example \cite{Boolos87}.  The first program
       
   810   we need to prove correct is the @{term dither} program shown in
       
   811   \eqref{dither} and the second program is @{term "tcopy"} defined as
       
   812 
       
   813   \begin{equation}
       
   814   \mbox{\begin{tabular}{@ {}l@ {\hspace{1mm}}c@ {\hspace{1mm}}l@ {}}
       
   815   @{thm (lhs) tcopy_def} & @{text "\<equiv>"} & @{thm (rhs) tcopy_def}
       
   816   \end{tabular}}\label{tcopy}
       
   817   \end{equation}
       
   818 
       
   819   \noindent
       
   820   whose three components are given in Figure~\ref{copy}. For our
       
   821   correctness proofs, we introduce the notion of total correctness
       
   822   defined in terms of \emph{Hoare-triples}, written @{term "{P} (p::tprog0)
       
   823   {Q}"}.  They implement the idea that a program @{term
       
   824   p} started in state @{term "1::nat"} with a tape satisfying @{term
       
   825   P} will after some @{text n} steps halt (have transitioned into the
       
   826   halting state) with a tape satisfying @{term Q}. This idea is very
       
   827   similar to the notion of \emph{realisability} in \cite{AspertiRicciotti12}. We
       
   828   also have \emph{Hoare-pairs} of the form @{term "{P} (p::tprog0) \<up>"}
       
   829   implementing the case that a program @{term p} started with a tape
       
   830   satisfying @{term P} will loop (never transition into the halting
       
   831   state). Both notion are formally defined as
       
   832 
       
   833   \begin{center}
       
   834   \begin{tabular}{@ {}c@ {\hspace{4mm}}c@ {}}
       
   835   \begin{tabular}[t]{@ {}l@ {}}
       
   836   \colorbox{mygrey}{@{thm (lhs) Hoare_halt_def}} @{text "\<equiv>"}\\[1mm]
       
   837   \hspace{5mm}@{text "\<forall>"}@{term "tp"}.\\
       
   838   \hspace{7mm}if @{term "P tp"} holds then\\
       
   839   \hspace{7mm}@{text "\<exists>"}@{term n}. such that\\
       
   840   \hspace{7mm}@{text "is_final (steps (1, tp) p n)"} \hspace{1mm}@{text "\<and>"}\\
       
   841   \hspace{7mm}@{text "Q holds_for (steps (1, tp) p n)"}
       
   842   \end{tabular} &
       
   843   \begin{tabular}[t]{@ {}l@ {}}
       
   844   \colorbox{mygrey}{@{thm (lhs) Hoare_unhalt_def}} @{text "\<equiv>"}\\[1mm]
       
   845   \hspace{5mm}@{text "\<forall>"}@{term "tp"}.\\ 
       
   846   \hspace{7mm}if @{term "P tp"} holds then\\
       
   847   \hspace{7mm}@{text "\<forall>"}@{term n}. @{text "\<not> is_final (steps (1, tp) p n)"}
       
   848   \end{tabular}
       
   849   \end{tabular}
       
   850   \end{center}
       
   851   
       
   852   \noindent
       
   853   For our Hoare-triples we can easily prove the following Hoare-consequence rule
       
   854 
       
   855   \begin{equation}
       
   856   @{thm[mode=Rule] Hoare_consequence}
       
   857   \end{equation}
       
   858 
       
   859   \noindent
       
   860   where
       
   861   @{term "Turing_Hoare.assert_imp P' P"} stands for the fact that for all tapes @{term "tp"},
       
   862   @{term "P' tp"} implies @{term "P tp"} (similarly for @{text "Q"} and @{text "Q'"}).
       
   863 
       
   864   Like Asperti and Ricciotti with their notion of realisability, we
       
   865   have set up our Hoare-rules so that we can deal explicitly
       
   866   with total correctness and non-termination, rather than have
       
   867   notions for partial correctness and termination. Although the latter
       
   868   would allow us to reason more uniformly (only using Hoare-triples),
       
   869   we prefer our definitions because we can derive below some simple
       
   870   Hoare-rules for sequentially composed Turing programs.  In this way
       
   871   we can reason about the correctness of @{term "tcopy_begin"}, for
       
   872   example, completely separately from @{term "tcopy_loop"} and @{term
       
   873   "tcopy_end"}.
       
   874 
       
   875   It is relatively straightforward to prove that the Turing program 
       
   876   @{term "dither"} shown in \eqref{dither} is correct. This program
       
   877   should be the ``identity'' when started with a standard tape representing 
       
   878   @{text "1"} but loops when started with the @{text 0}-representation instead, as pictured 
       
   879   below.
       
   880 
       
   881 
       
   882   \begin{center}
       
   883   \begin{tabular}{l@ {\hspace{3mm}}lcl}
       
   884   & \multicolumn{1}{c}{start tape}\\[1mm]
       
   885   \raisebox{2mm}{halting case:} &
       
   886   \begin{tikzpicture}[scale=0.8]
       
   887   \draw[very thick] (-2,0)   -- ( 0.75,0);
       
   888   \draw[very thick] (-2,0.5) -- ( 0.75,0.5);
       
   889   \draw[very thick] (-0.25,0)   -- (-0.25,0.5);
       
   890   \draw[very thick] ( 0.25,0)   -- ( 0.25,0.5);
       
   891   \draw[very thick] (-0.75,0)   -- (-0.75,0.5);
       
   892   \draw[very thick] ( 0.75,0)   -- ( 0.75,0.5);
       
   893   \draw[very thick] (-1.25,0)   -- (-1.25,0.5);
       
   894   \draw[rounded corners=1mm] (-0.35,-0.1) rectangle (0.35,0.6);
       
   895   \draw[fill]     (-0.15,0.1) rectangle (0.15,0.4);
       
   896   \draw[fill]     ( 0.35,0.1) rectangle (0.65,0.4);
       
   897   \node [anchor=base] at (-1.7,0.2) {\ldots};
       
   898   \end{tikzpicture} 
       
   899   & \raisebox{2mm}{$\;\;\large\Rightarrow\;\;$} &
       
   900   \begin{tikzpicture}[scale=0.8]
       
   901   \draw[very thick] (-2,0)   -- ( 0.75,0);
       
   902   \draw[very thick] (-2,0.5) -- ( 0.75,0.5);
       
   903   \draw[very thick] (-0.25,0)   -- (-0.25,0.5);
       
   904   \draw[very thick] ( 0.25,0)   -- ( 0.25,0.5);
       
   905   \draw[very thick] (-0.75,0)   -- (-0.75,0.5);
       
   906   \draw[very thick] ( 0.75,0)   -- ( 0.75,0.5);
       
   907   \draw[very thick] (-1.25,0)   -- (-1.25,0.5);
       
   908   \draw[rounded corners=1mm] (-0.35,-0.1) rectangle (0.35,0.6);
       
   909   \draw[fill]     (-0.15,0.1) rectangle (0.15,0.4);
       
   910   \draw[fill]     ( 0.35,0.1) rectangle (0.65,0.4);
       
   911   \node [anchor=base] at (-1.7,0.2) {\ldots};
       
   912   \end{tikzpicture}\\
       
   913 
       
   914   \raisebox{2mm}{non-halting case:} &
       
   915   \begin{tikzpicture}[scale=0.8]
       
   916   \draw[very thick] (-2,0)   -- ( 0.25,0);
       
   917   \draw[very thick] (-2,0.5) -- ( 0.25,0.5);
       
   918   \draw[very thick] (-0.25,0)   -- (-0.25,0.5);
       
   919   \draw[very thick] ( 0.25,0)   -- ( 0.25,0.5);
       
   920   \draw[very thick] (-0.75,0)   -- (-0.75,0.5);
       
   921   \draw[very thick] (-1.25,0)   -- (-1.25,0.5);
       
   922   \draw[rounded corners=1mm] (-0.35,-0.1) rectangle (0.35,0.6);
       
   923   \draw[fill]     (-0.15,0.1) rectangle (0.15,0.4);
       
   924   \node [anchor=base] at (-1.7,0.2) {\ldots};
       
   925   \end{tikzpicture} 
       
   926   & \raisebox{2mm}{$\;\;\large\Rightarrow\;\;$} &
       
   927   \raisebox{2mm}{loops}
       
   928   \end{tabular}
       
   929   \end{center}
       
   930 
       
   931   \noindent
       
   932   We can prove the following two Hoare-statements:
       
   933  
       
   934   \begin{center}
       
   935   \begin{tabular}{l}
       
   936   @{thm dither_halts}\\
       
   937   @{thm dither_loops}
       
   938   \end{tabular}
       
   939   \end{center}
       
   940 
       
   941   \noindent
       
   942   The first is by a simple calculation. The second is by an induction on the
       
   943   number of steps we can perform starting from the input tape.
       
   944 
       
   945   The program @{term tcopy} defined in \eqref{tcopy} has 15 states;
       
   946   its purpose is to produce the standard tape @{term "(Bks, <(n,
       
   947   n::nat)>)"} when started with @{term "(Bks, <(n::nat)>)"}, that is
       
   948   making a copy of a value @{term n} on the tape.  Reasoning about this program
       
   949   is substantially harder than about @{term dither}. To ease the
       
   950   burden, we derive the following two Hoare-rules for sequentially
       
   951   composed programs.
       
   952 
       
   953   \begin{center}
       
   954   \begin{tabular}{@ {\hspace{-10mm}}c@ {\hspace{14mm}}c@ {}}
       
   955   $\inferrule*[Right=@{thm (prem 3) HR1}]
       
   956   {@{thm (prem 1) HR1} \\ @{thm (prem 2) HR1}}
       
   957   {@{thm (concl) HR1}}
       
   958   $ &
       
   959   $
       
   960   \inferrule*[Right=@{thm (prem 3) HR2}]
       
   961   {@{thm (prem 1) HR2} \\ @{thm (prem 2) HR2}}
       
   962   {@{thm (concl) HR2}}
       
   963   $
       
   964   \end{tabular}
       
   965   \end{center}
       
   966 
       
   967   \noindent
       
   968   The first corresponds to the usual Hoare-rule for composition of two
       
   969   terminating programs. The second rule gives the conditions for when
       
   970   the first program terminates generating a tape for which the second
       
   971   program loops.  The side-conditions about @{thm (prem 3) HR2} are
       
   972   needed in order to ensure that the redirection of the halting and
       
   973   initial state in @{term "p\<^isub>1"} and @{term "p\<^isub>2"}, respectively, match
       
   974   up correctly.  These Hoare-rules allow us to prove the correctness
       
   975   of @{term tcopy} by considering the correctness of the components
       
   976   @{term "tcopy_begin"}, @{term "tcopy_loop"} and @{term "tcopy_end"}
       
   977   in isolation. This simplifies the reasoning considerably, for
       
   978   example when designing decreasing measures for proving the termination
       
   979   of the programs.  We will show the details for the program @{term
       
   980   "tcopy_begin"}. For the two other programs we refer the reader to
       
   981   our formalisation.
       
   982 
       
   983   Given the invariants @{term "inv_begin0"},\ldots,
       
   984   @{term "inv_begin4"} shown in Figure~\ref{invbegin}, which
       
   985   correspond to each state of @{term tcopy_begin}, we define the
       
   986   following invariant for the whole @{term tcopy_begin} program:
       
   987 
       
   988   \begin{figure}[t]
       
   989   \begin{center}
       
   990   \begin{tabular}{@ {}lcl@ {\hspace{-0.5cm}}l@ {}}
       
   991   \hline
       
   992   @{thm (lhs) inv_begin1.simps} & @{text "\<equiv>"} & @{thm (rhs) inv_begin1.simps} & (starting state)\\
       
   993   @{thm (lhs) inv_begin2.simps} & @{text "\<equiv>"} & @{thm (rhs) inv_begin2.simps}\\
       
   994   @{thm (lhs) inv_begin3.simps} & @{text "\<equiv>"} & @{thm (rhs) inv_begin3.simps}\\
       
   995   @{thm (lhs) inv_begin4.simps} & @{text "\<equiv>"} & @{thm (rhs) inv_begin4.simps}\\
       
   996   @{thm (lhs) inv_begin0.simps} & @{text "\<equiv>"} & @{thm (rhs) inv_begin01} @{text "\<or>"}& (halting state)\\
       
   997                                 &             & @{thm (rhs) inv_begin02}\smallskip \\
       
   998    \hline
       
   999   @{thm (lhs) inv_loop1.simps} & @{text "\<equiv>"} & @{thm (rhs) inv_loop1_loop.simps} @{text "\<or>"}\\
       
  1000                                &             & @{thm (rhs) inv_loop1_exit.simps} & (starting state)\\
       
  1001   @{thm (lhs) inv_loop0.simps} & @{text "\<equiv>"} & @{thm (rhs) inv_loop0.simps}& (halting state)\smallskip\\
       
  1002    \hline
       
  1003   @{thm (lhs) inv_end1.simps} & @{text "\<equiv>"} & @{thm (rhs) inv_end1.simps} & (starting state)\\
       
  1004   @{thm (lhs) inv_end0.simps} & @{text "\<equiv>"} & @{thm (rhs) inv_end0.simps} & (halting state)\smallskip\\
       
  1005   \hline
       
  1006   \end{tabular}
       
  1007   \end{center}
       
  1008   \caption{The invariants @{term inv_begin0},\ldots,@{term inv_begin4} are for the states of 
       
  1009   @{term tcopy_begin}. Below, the invariants only for the starting and halting states of
       
  1010   @{term tcopy_loop} and @{term tcopy_end} are shown. In each invariant, the parameter 
       
  1011   @{term n} stands for the number
       
  1012   of @{term Oc}s with which the Turing machine is started.}\label{invbegin}
       
  1013   \end{figure}
       
  1014 
       
  1015   \begin{center}
       
  1016   \begin{tabular}{rcl}
       
  1017   @{thm (lhs) inv_begin.simps} & @{text "\<equiv>"} & 
       
  1018   @{text "if"} @{thm (prem 1) inv_begin_print(1)} @{text then} @{thm (rhs) inv_begin_print(1)}\\
       
  1019   & & @{text else} @{text "if"} @{thm (prem 1) inv_begin_print(2)} @{text then} @{thm (rhs) inv_begin_print(2)} \\
       
  1020  & & @{text else} @{text "if"} @{thm (prem 1) inv_begin_print(3)} @{text then} @{thm (rhs) inv_begin_print(3)}\\
       
  1021   & & @{text else} @{text "if"} @{thm (prem 1) inv_begin_print(4)} @{text then} @{thm (rhs) inv_begin_print(4)}\\
       
  1022    & & @{text else} @{text "if"} @{thm (prem 1) inv_begin_print(5)} @{text then} @{thm (rhs) inv_begin_print(5)}\\
       
  1023   & & @{text else} @{thm (rhs) inv_begin_print(6)}
       
  1024   \end{tabular}
       
  1025   \end{center}
       
  1026 
       
  1027   \noindent
       
  1028   This invariant depends on @{term n} representing the number of
       
  1029   @{term Oc}s on the tape. It is not hard (26
       
  1030   lines of automated proof script) to show that for @{term "n >
       
  1031   (0::nat)"} this invariant is preserved under the computation rules
       
  1032   @{term step} and @{term steps}. This gives us partial correctness
       
  1033   for @{term "tcopy_begin"}. 
       
  1034 
       
  1035   We next need to show that @{term "tcopy_begin"} terminates. For this
       
  1036   we introduce lexicographically ordered pairs @{term "(n, m)"}
       
  1037   derived from configurations @{text "(s, (l, r))"} whereby @{text n} is
       
  1038   the state @{text s}, but ordered according to how @{term tcopy_begin} executes
       
  1039   them, that is @{text "1 > 2 > 3 > 4 > 0"}; in order to have
       
  1040   a strictly decreasing measure, @{term m} takes the data on the tape into
       
  1041   account and is calculated according to the following measure function:
       
  1042 
       
  1043   \begin{center}
       
  1044   \begin{tabular}{rcl}
       
  1045   @{term measure_begin_step}@{text "(s, (l, r))"} & @{text "\<equiv>"} & 
       
  1046   @{text "if"} @{thm (prem 1) measure_begin_print(1)} @{text then} @{thm (rhs) measure_begin_print(1)}\\
       
  1047   & & @{text else} @{text "if"} @{thm (prem 1) measure_begin_print(2)} @{text then} 
       
  1048   @{text "("}@{thm (rhs) measure_begin_print(2)}@{text ")"} \\
       
  1049  & & @{text else} @{text "if"} @{thm (prem 1) measure_begin_print(3)} @{text then} @{thm (rhs) measure_begin_print(3)}\\
       
  1050   & & @{text else} @{thm (rhs) measure_begin_print(4)}\\
       
  1051   \end{tabular}
       
  1052   \end{center}
       
  1053   
       
  1054   \noindent
       
  1055   With this in place, we can show that for every starting tape of the
       
  1056   form @{term "([], Oc \<up> n)"} with @{term "n > (0::nat)"}, the Turing
       
  1057   machine @{term "tcopy_begin"} will eventually halt (the measure
       
  1058   decreases in each step). Taking this and the partial correctness
       
  1059   proof together, we obtain the Hoare-triple shown on the left for @{term tcopy_begin}:
       
  1060    
       
  1061 
       
  1062   \begin{center}
       
  1063   @{thm (concl) begin_correct}\hspace{6mm}
       
  1064   @{thm (concl) loop_correct}\hspace{6mm}
       
  1065   @{thm (concl) end_correct}
       
  1066   \end{center}
       
  1067 
       
  1068   \noindent 
       
  1069   where we assume @{text "0 < n"} (similar reasoning is needed for
       
  1070   the Hoare-triples for @{term tcopy_loop} and @{term tcopy_end}). Since the invariant of
       
  1071   the halting state of @{term tcopy_begin} implies the invariant of
       
  1072   the starting state of @{term tcopy_loop}, that is @{term "Turing_Hoare.assert_imp (inv_begin0 n)
       
  1073   (inv_loop1 n)"} holds, and also @{term "inv_loop0 n = inv_end1
       
  1074   n"}, we can derive the following Hoare-triple for the correctness 
       
  1075   of @{term tcopy}:
       
  1076 
       
  1077   \begin{center}
       
  1078   @{thm tcopy_correct}
       
  1079   \end{center}
       
  1080 
       
  1081   \noindent
       
  1082   That means if we start with a tape of the form @{term "([], <n::nat>)"} then 
       
  1083   @{term tcopy} will halt with the tape \mbox{@{term "([Bk], <(n::nat, n::nat)>)"}}, as desired.
       
  1084 
       
  1085   Finally, we are in the position to prove the undecidability of the halting problem.
       
  1086   A program @{term p} started with a standard tape containing the (encoded) numbers
       
  1087   @{term ns} will \emph{halt} with a standard tape containing a single (encoded) 
       
  1088   number is defined as
       
  1089 
       
  1090   \begin{center}
       
  1091   @{thm halts_def}
       
  1092   \end{center}
       
  1093 
       
  1094   \noindent
       
  1095   This roughly means we considering only Turing machine programs
       
  1096   representing functions that take some numbers as input and produce a
       
  1097   single number as output. For undecidability, the property we are
       
  1098   proving is that there is no Turing machine that can decide in
       
  1099   general whether a Turing machine program halts (answer either @{text
       
  1100   0} for halting or @{text 1} for looping). Given our correctness
       
  1101   proofs for @{term dither} and @{term tcopy} shown above, this
       
  1102   non-existence is now relatively straightforward to establish. We first
       
  1103   assume there is a coding function, written @{term "code M"}, which
       
  1104   represents a Turing machine @{term "M"} as a natural number.  No
       
  1105   further assumptions are made about this coding function. Suppose a
       
  1106   Turing machine @{term H} exists such that if started with the
       
  1107   standard tape @{term "([Bk], <(code M, ns)>)"} returns @{text 0},
       
  1108   respectively @{text 1}, depending on whether @{text M} halts or not when
       
  1109   started with the input tape containing @{term "<ns>"}.  This
       
  1110   assumption is formalised as follows---for all @{term M} and all lists of
       
  1111   natural numbers @{term ns}:
       
  1112 
       
  1113   \begin{center}
       
  1114   \begin{tabular}{r}
       
  1115   @{thm (prem 2) uncomputable.h_case} implies
       
  1116   @{thm (concl) uncomputable.h_case}\\
       
  1117   
       
  1118   @{thm (prem 2) uncomputable.nh_case} implies
       
  1119   @{thm (concl) uncomputable.nh_case}
       
  1120   \end{tabular}
       
  1121   \end{center}
       
  1122 
       
  1123   \noindent
       
  1124   The contradiction can be derived using the following Turing machine
       
  1125 
       
  1126   \begin{center}
       
  1127   @{thm tcontra_def}
       
  1128   \end{center}
       
  1129 
       
  1130   \noindent
       
  1131   Suppose @{thm (prem 1) "tcontra_halt"} holds. Given the invariants @{text "P\<^isub>1"}\ldots@{text "P\<^isub>3"} 
       
  1132   shown on the 
       
  1133   left, we can derive the following Hoare-pair for @{term tcontra} on the right.
       
  1134 
       
  1135   \begin{center}\small
       
  1136   \begin{tabular}{@ {}c@ {\hspace{-10mm}}c@ {}}
       
  1137   \begin{tabular}[t]{@ {}l@ {}}
       
  1138   @{term "P\<^isub>1 \<equiv> \<lambda>tp. tp = ([]::cell list, <code_tcontra>)"}\\
       
  1139   @{term "P\<^isub>2 \<equiv> \<lambda>tp. tp = ([Bk], <(code_tcontra, code_tcontra)>)"}\\
       
  1140   @{term "P\<^isub>3 \<equiv> \<lambda>tp. \<exists>k. tp = (Bk \<up> k, <0::nat>)"}
       
  1141   \end{tabular}
       
  1142   &
       
  1143   \begin{tabular}[b]{@ {}l@ {}}
       
  1144   \raisebox{-20mm}{$\inferrule*{
       
  1145     \inferrule*{@{term "{P\<^isub>1} tcopy {P\<^isub>2}"} \\ @{term "{P\<^isub>2} H {P\<^isub>3}"}}
       
  1146     {@{term "{P\<^isub>1} (tcopy |+| H) {P\<^isub>3}"}}
       
  1147     \\ @{term "{P\<^isub>3} dither \<up>"}
       
  1148    }
       
  1149    {@{term "{P\<^isub>1} tcontra \<up>"}}
       
  1150   $}
       
  1151   \end{tabular}
       
  1152   \end{tabular}
       
  1153   \end{center}
       
  1154 
       
  1155   \noindent
       
  1156   This Hoare-pair contradicts our assumption that @{term tcontra} started
       
  1157   with @{term "<(code tcontra)>"} halts.
       
  1158 
       
  1159   Suppose @{thm (prem 1) "tcontra_unhalt"} holds. Again, given the invariants 
       
  1160   @{text "Q\<^isub>1"}\ldots@{text "Q\<^isub>3"}
       
  1161   shown on the 
       
  1162   left, we can derive the Hoare-triple for @{term tcontra} on the right.
       
  1163 
       
  1164   \begin{center}\small
       
  1165   \begin{tabular}{@ {}c@ {\hspace{-18mm}}c@ {}}
       
  1166   \begin{tabular}[t]{@ {}l@ {}}
       
  1167   @{term "Q\<^isub>1 \<equiv> \<lambda>tp. tp = ([]::cell list, <code_tcontra>)"}\\
       
  1168   @{term "Q\<^isub>2 \<equiv> \<lambda>tp. tp = ([Bk], <(code_tcontra, code_tcontra)>)"}\\
       
  1169   @{term "Q\<^isub>3 \<equiv> \<lambda>tp. \<exists>k. tp = (Bk \<up> k, <1::nat>)"}
       
  1170   \end{tabular}
       
  1171   &
       
  1172   \begin{tabular}[t]{@ {}l@ {}}
       
  1173   \raisebox{-20mm}{$\inferrule*{
       
  1174     \inferrule*{@{term "{Q\<^isub>1} tcopy {Q\<^isub>2}"} \\ @{term "{Q\<^isub>2} H {Q\<^isub>3}"}}
       
  1175     {@{term "{Q\<^isub>1} (tcopy |+| H) {Q\<^isub>3}"}}
       
  1176     \\ @{term "{Q\<^isub>3} dither {Q\<^isub>3}"}
       
  1177    }
       
  1178    {@{term "{Q\<^isub>1} tcontra {Q\<^isub>3}"}}
       
  1179   $}
       
  1180   \end{tabular}
       
  1181   \end{tabular}
       
  1182   \end{center}
       
  1183 
       
  1184   \noindent
       
  1185   This time the Hoare-triple states that @{term tcontra} terminates 
       
  1186   with the ``output'' @{term "<(1::nat)>"}. In both cases we come
       
  1187   to a contradiction, which means we have to abandon our assumption 
       
  1188   that there exists a Turing machine @{term H} which can in general decide 
       
  1189   whether Turing machines terminate.
       
  1190 *}
       
  1191 
       
  1192 
       
  1193 section {* Abacus Machines *}
       
  1194 
       
  1195 text {*
       
  1196   \noindent
       
  1197   Boolos et al \cite{Boolos87} use abacus machines as a stepping stone
       
  1198   for making it less laborious to write Turing machine
       
  1199   programs. Abacus machines operate over a set of registers @{text "R\<^isub>0"},
       
  1200   @{text "R\<^isub>1"}, \ldots{}, @{text "R\<^isub>n"} each being able to hold an arbitrary large natural
       
  1201   number.  We use natural numbers to refer to registers; we also use a natural number
       
  1202   to represent a program counter and to represent jumping ``addresses'', for which we 
       
  1203   use the letter @{text l}. An abacus 
       
  1204   program is a list of \emph{instructions} defined by the datatype:
       
  1205 
       
  1206   \begin{center}
       
  1207   \begin{tabular}{rcl@ {\hspace{10mm}}l}
       
  1208   @{text "i"} & $::=$  & @{term "Inc R\<iota>"} & increment register @{text "R"} by one\\
       
  1209   & $\mid$ & @{term "Dec R\<iota> l"} & if content of @{text R} is non-zero, then decrement it by one\\
       
  1210   & & & otherwise jump to instruction @{text l}\\
       
  1211   & $\mid$ & @{term "Goto l"} & jump to instruction @{text l}
       
  1212   \end{tabular}
       
  1213   \end{center}
       
  1214 
       
  1215   \noindent
       
  1216   For example the program clearing the register @{text R} (that is setting
       
  1217   it to @{term "(0::nat)"}) can be defined as follows:
       
  1218 
       
  1219   \begin{center}
       
  1220   @{thm clear.simps[where n="R\<iota>" and e="l", THEN eq_reflection]}
       
  1221   \end{center}
       
  1222 
       
  1223   \noindent
       
  1224   Running such a program means we start with the first instruction
       
  1225   then execute one instructions after the other, unless there is a jump.  For
       
  1226   example the second instruction @{term "Goto 0"} above means
       
  1227   we jump back to the first instruction thereby closing the loop.  Like with our
       
  1228   Turing machines, we fetch instructions from an abacus program such
       
  1229   that a jump out of ``range'' behaves like a @{term "Nop"}-action. In
       
  1230   this way it is again easy to define a function @{term steps} that
       
  1231   executes @{term n} instructions of an abacus program. A \emph{configuration}
       
  1232   of an abacus machine is the current program counter together with a snapshot of 
       
  1233   all registers.
       
  1234   By convention
       
  1235   the value calculated by an abacus program is stored in the
       
  1236   last register (the one with the highest index in the program).
       
  1237   
       
  1238   The main point of abacus programs is to be able to translate them to 
       
  1239   Turing machine programs. Registers and their content are represented by
       
  1240   standard tapes (see definition shown in \eqref{standard}). Because of the jumps in abacus programs, it
       
  1241   is impossible to build Turing machine programs out of components 
       
  1242   using our @{text ";"}-operation shown in the previous section.
       
  1243   To overcome this difficulty, we calculate a \emph{layout} of an
       
  1244   abacus program as follows
       
  1245 
       
  1246   \begin{center}
       
  1247   \begin{tabular}[t]{@ {}l@ {\hspace{1mm}}c@ {\hspace{1mm}}l@ {}}
       
  1248   @{thm (lhs) layout(1)} & @{text "\<equiv>"} & @{thm (rhs) layout(1)}\\
       
  1249   @{thm (lhs) layout(2)} & @{text "\<equiv>"} & @{thm (rhs) layout(2)}\\
       
  1250   @{thm (lhs) layout(3)} & @{text "\<equiv>"} & @{thm (rhs) layout(3)}\\
       
  1251   @{thm (lhs) layout(4)} & @{text "\<equiv>"} & @{thm (rhs) layout(4)}\\
       
  1252   \end{tabular}
       
  1253   \end{center}
       
  1254 
       
  1255   \noindent
       
  1256   This gives us a list of natural numbers specifying how many states
       
  1257   are needed to translate each abacus instruction. This information
       
  1258   is needed in order to calculate the state where the Turing machine program
       
  1259   of an abacus instruction starts. This can be defined as
       
  1260 
       
  1261   \begin{center}
       
  1262   @{thm address.simps[where x="n"]}
       
  1263   \end{center}
       
  1264 
       
  1265   \noindent
       
  1266   where @{text p} is an abacus program and @{term "take n"} takes the first
       
  1267   @{text n} elements from a list.
       
  1268   
       
  1269   The @{text Goto}
       
  1270   instruction is easiest to translate requiring only one state, namely
       
  1271   the Turing machine program:
       
  1272 
       
  1273   \begin{center}
       
  1274   @{text "translate_Goto l"} @{text "\<equiv>"} @{thm (rhs) tgoto.simps[where n="l"]}
       
  1275   \end{center}
       
  1276 
       
  1277   \noindent
       
  1278   where @{term "l"} is the state in the Turing machine program 
       
  1279   to jump to. For translating the instruction @{term "Inc R\<iota>"}, 
       
  1280   one has to remember that the content of the registers are encoded
       
  1281   in the Turing machine as a standard tape. Therefore the translated Turing machine 
       
  1282   needs to first find the number corresponding to the content of register 
       
  1283   @{text "R"}. This needs a machine
       
  1284   with @{term "(2::nat) * R\<iota>"} states and can be constructed as follows: 
       
  1285 
       
  1286   \begin{center}
       
  1287   \begin{tabular}[t]{@ {}l@ {\hspace{1mm}}c@ {\hspace{1mm}}l@ {}}
       
  1288   @{thm (lhs) findnth.simps(1)} & @{text "\<equiv>"} & @{thm (rhs) findnth.simps(1)}\\
       
  1289   @{thm (lhs) findnth.simps(2)} & @{text "\<equiv>"}\\
       
  1290   \multicolumn{3}{@ {}l@ {}}{\hspace{6mm}@{thm (rhs) findnth.simps(2)}}\\
       
  1291   \end{tabular}
       
  1292   \end{center}
       
  1293 
       
  1294   \noindent
       
  1295   Then we need to increase the ``number'' on the tape by one,
       
  1296   and adjust the following ``registers''. For adjusting we only need to 
       
  1297   change the first @{term Oc} of each number to @{term Bk} and the last
       
  1298   one from @{term Bk} to @{term Oc}.
       
  1299   Finally, we need to transition the head of the
       
  1300   Turing machine back into the standard position. This requires a Turing machine
       
  1301   with 9 states (we omit the details). Similarly for the translation of @{term "Dec R\<iota> l"}, where the 
       
  1302   translated Turing machine needs to first check whether the content of the
       
  1303   corresponding register is @{text 0}. For this we have a Turing machine program
       
  1304   with @{text 16} states (again the details are omitted). 
       
  1305 
       
  1306   Finally, having a Turing machine for each abacus instruction we need
       
  1307   to ``stitch'' the Turing machines together into one so that each
       
  1308   Turing machine component transitions to next one, just like in
       
  1309   the abacus programs. One last problem to overcome is that an abacus
       
  1310   program is assumed to calculate a value stored in the last
       
  1311   register (the one with the highest register). That means we have to append a Turing machine that
       
  1312   ``mops up'' the tape (cleaning all @{text Oc}s) except for the
       
  1313   @{term Oc}s of the last register represented on the tape. This needs
       
  1314   a Turing machine program with @{text "2 * R + 6"} states, assuming @{text R}
       
  1315   is the number of registers to be ``cleaned''.
       
  1316 
       
  1317   While generating the Turing machine program for an abacus program is
       
  1318   not too difficult to formalise, the problem is that it contains
       
  1319   @{text Goto}s all over the place. The unfortunate result is that we
       
  1320   cannot use our Hoare-rules for reasoning about sequentially composed
       
  1321   programs (for this each component needs to be completely independent). Instead we
       
  1322   have to treat the translated Turing machine as one ``big block'' and 
       
  1323   prove as invariant that it performs
       
  1324   the same operations as the abacus program. For this we have to show
       
  1325   that for each configuration of an abacus machine the @{term
       
  1326   step}-function is simulated by zero or more steps in our translated
       
  1327   Turing machine. This leads to a rather large ``monolithic''
       
  1328   correctness proof (4600 loc and 380 sublemmas) that on the
       
  1329   conceptual level is difficult to break down into smaller components.
       
  1330   
       
  1331   %We were able to simplify the proof somewhat
       
  1332 *}
       
  1333 
       
  1334 
       
  1335 section {* Recursive Functions and a Universal Turing Machine *}
       
  1336 
       
  1337 text {*
       
  1338   The main point of recursive functions is that we can relatively 
       
  1339   easily construct a universal Turing machine via a universal 
       
  1340   function. This is different from Norrish \cite{Norrish11} who gives a universal 
       
  1341   function for the lambda-calculus, and also from Asperti and Ricciotti 
       
  1342   \cite{AspertiRicciotti12} who construct a universal Turing machine
       
  1343   directly, but for simulating Turing machines with a more restricted alphabet.
       
  1344   Unlike Norrish \cite{Norrish11}, we need to represent recursive functions
       
  1345   ``deeply'' because we want to translate them to abacus programs.
       
  1346   Thus \emph{recursive functions} are defined as the datatype
       
  1347 
       
  1348   \begin{center}
       
  1349   \begin{tabular}{c@ {\hspace{4mm}}c}
       
  1350   \begin{tabular}{rcl@ {\hspace{4mm}}l}
       
  1351   @{term r} & @{text "::="} & @{term z} & (zero-function)\\
       
  1352             & @{text "|"}   & @{term s} & (successor-function)\\
       
  1353             & @{text "|"}   & @{term "id n m"} & (projection)\\
       
  1354   \end{tabular} &
       
  1355   \begin{tabular}{cl@ {\hspace{4mm}}l}
       
  1356   @{text "|"} & @{term "Cn n f fs"} & (composition)\\
       
  1357   @{text "|"} & @{term "Pr n f\<^isub>1 f\<^isub>2"} & (primitive recursion)\\
       
  1358   @{text "|"} & @{term "Mn n f"} & (minimisation)\\
       
  1359   \end{tabular}
       
  1360   \end{tabular}
       
  1361   \end{center}
       
  1362 
       
  1363   \noindent 
       
  1364   where @{text n} indicates the function expects @{term n} arguments
       
  1365   (in \cite{Boolos87} both @{text z} and @{term s} expect one
       
  1366   argument), and @{text fs} stands for a list of recursive
       
  1367   functions. Since we know in each case the arity, say @{term l}, we
       
  1368   can define an evaluation function, called @{term rec_exec}, that takes a recursive
       
  1369   function @{text f} and a list @{term ns} of natural numbers of
       
  1370   length @{text l} as arguments. Since this evaluation function uses 
       
  1371   the minimisation operator
       
  1372   from HOL, this function might not terminate always. As a result we also
       
  1373   need to inductively characterise when @{term rec_exec} terminates.
       
  1374   We omit the definitions for
       
  1375   @{term "rec_exec f ns"} and @{term "terminate f ns"}. Because of 
       
  1376   space reasons, we also omit the definition of
       
  1377   translating recursive functions into abacus programs. We can prove,
       
  1378   however, the following theorem about the translation: If @{thm (prem
       
  1379   1) recursive_compile_to_tm_correct3[where recf="f" and args="ns"]} 
       
  1380   holds for the recursive function @{text f} and arguments @{term ns}, then the
       
  1381   following Hoare-triple holds
       
  1382 
       
  1383   \begin{center}
       
  1384   @{thm (concl) recursive_compile_to_tm_correct3[where recf="f" and args="ns"]}
       
  1385   \end{center}
       
  1386 
       
  1387   \noindent
       
  1388   for the Turing machine generated by @{term "translate f"}. This
       
  1389   means the translated Turing machine if started
       
  1390   with the standard tape @{term "([Bk, Bk], <ns::nat list>)"} will terminate
       
  1391   with the standard tape @{term "(Bk \<up> k, <(rec_exec f ns)::nat> @ Bk \<up> l)"} for some @{text k} and @{text l}.
       
  1392 
       
  1393   Having recursive functions under our belt, we can construct a universal
       
  1394   function, written @{text UF}. This universal function acts like an interpreter for Turing machines.
       
  1395   It takes two arguments: one is the code of the Turing machine to be interpreted and the 
       
  1396   other is the ``packed version'' of the arguments of the Turing machine. 
       
  1397   We can then consider how this universal function is translated to a 
       
  1398   Turing machine and from this construct the universal Turing machine, 
       
  1399   written @{term UTM}. It is defined as 
       
  1400   the composition of the Turing machine that packages the arguments and
       
  1401   the translated recursive 
       
  1402   function @{text UF}:
       
  1403 
       
  1404   \begin{center}
       
  1405   @{text "UTM \<equiv> arg_coding ; (translate UF)"}
       
  1406   \end{center}
       
  1407 
       
  1408   \noindent
       
  1409   Suppose
       
  1410   a Turing program @{term p} is well-formed and  when started with the standard 
       
  1411   tape containing the arguments @{term args}, will produce a standard tape
       
  1412   with ``output'' @{term n}. This assumption can be written as the
       
  1413   Hoare-triple
       
  1414 
       
  1415   \begin{center}
       
  1416   @{thm (prem 3) UTM_halt_lemma2}
       
  1417   \end{center}
       
  1418   
       
  1419   \noindent
       
  1420   where we require that the @{term args} stand for a non-empty list. Then the universal Turing
       
  1421   machine @{term UTM} started with the code of @{term p} and the arguments
       
  1422   @{term args}, calculates the same result, namely
       
  1423 
       
  1424   \begin{center}
       
  1425   @{thm (concl) UTM_halt_lemma2} 
       
  1426   \end{center}
       
  1427 
       
  1428   \noindent
       
  1429   Similarly, if a Turing program @{term p} started with the 
       
  1430   standard tape containing @{text args} loops, which is represented
       
  1431   by the Hoare-pair
       
  1432 
       
  1433   \begin{center}
       
  1434   @{thm (prem 2) UTM_unhalt_lemma2}
       
  1435   \end{center}
       
  1436 
       
  1437   \noindent
       
  1438   then the universal Turing machine started with the code of @{term p} and the arguments
       
  1439   @{term args} will also loop
       
  1440 
       
  1441   \begin{center}
       
  1442   @{thm (concl) UTM_unhalt_lemma2} 
       
  1443   \end{center}
       
  1444 
       
  1445   %Analysing the universal Turing machine constructed in \cite{Boolos87} more carefully
       
  1446   %we can strengthen this result slightly by observing that @{text m} is at most
       
  1447   %2 in the output tape. This observation allows one to construct a universal Turing machine that works
       
  1448   %entirely on the left-tape by composing it with a machine that drags the tape
       
  1449   %two cells to the right. A corollary is that one-sided Turing machines (where the
       
  1450   %tape only extends to the right) are computationally as powerful as our two-sided 
       
  1451   %Turing machines. So our undecidability proof for the halting problem extends
       
  1452   %also to one-sided Turing machines, which is needed for example in order to
       
  1453   %formalise the undecidability of Wang's tiling problem \cite{Robinson71}.
       
  1454 
       
  1455   While formalising the chapter in \cite{Boolos87} about universal
       
  1456   Turing machines, an unexpected outcome of our work is that we
       
  1457   identified an inconsistency in their use of a definition. This is
       
  1458   unexpected since \cite{Boolos87} is a classic textbook which has
       
  1459   undergone several editions (we used the fifth edition; the material 
       
  1460   containing the inconsistency was introduced in the fourth edition
       
  1461   of this book). The central
       
  1462   idea about Turing machines is that when started with standard tapes
       
  1463   they compute a partial arithmetic function.  The inconsistency arises
       
  1464   when they define the case when this function should \emph{not} return a
       
  1465   result. Boolos at al write in Chapter 3, Page 32:
       
  1466 
       
  1467   \begin{quote}\it
       
  1468   ``If the function that is to be computed assigns no value to the arguments that 
       
  1469   are represented initially on the tape, then the machine either will never halt, 
       
  1470   \colorbox{mygrey}{or} will halt in some nonstandard configuration\ldots''
       
  1471   \end{quote}
       
  1472   
       
  1473   \noindent
       
  1474   Interestingly, they do not implement this definition when constructing
       
  1475   their universal Turing machine. In Chapter 8, on page 93, a recursive function 
       
  1476   @{term stdh} is defined as:
       
  1477 	
       
  1478   \begin{equation}\label{stdh_def}
       
  1479   @{text "stdh(m, x, t) \<equiv> stat(conf(m, x, t)) + nstd(conf(m, x, t))"}
       
  1480   \end{equation}
       
  1481   
       
  1482   \noindent
       
  1483   where @{text "stat(conf(m, x, t))"} computes the current state of the
       
  1484   simulated Turing machine, and @{text "nstd(conf(m, x, t))"} returns @{text 1}
       
  1485   if the tape content is non-standard. If either one evaluates to
       
  1486   something that is not zero, then @{text "stdh(m, x, t)"} will be not zero, because of 
       
  1487   the $+$-operation. On the same page, a function @{text "halt(m, x)"} is defined 
       
  1488   in terms of @{text stdh} for computing the steps the Turing machine needs to
       
  1489   execute before it halts (in case it halts at all). According to this definition, the simulated
       
  1490   Turing machine will continue to run after entering the @{text 0}-state
       
  1491   with a non-standard tape. The consequence of this inconsistency is
       
  1492   that there exist Turing machines that given some arguments do not compute a value
       
  1493   according to Chapter 3, but return a proper result according to
       
  1494   the definition in Chapter 8. One such Turing machine is:
       
  1495 
       
  1496   %This means that if you encode the plus function but only give one argument,
       
  1497   %then the TM will either loop {\bf or} stop with a non-standard tape
       
  1498 
       
  1499   %But in the definition of the universal function the TMs will never stop
       
  1500   %with non-standard tapes. 
       
  1501 
       
  1502   %SO the following TM calculates something according to def from chap 8,
       
  1503   %but not with chap 3. For example:
       
  1504   
       
  1505   \begin{center}
       
  1506   @{term "counter_example \<equiv> [(L, (0::nat)), (L, 2), (R, 2), (R, 0)]"}
       
  1507   \end{center}
       
  1508 
       
  1509   \noindent
       
  1510   If started with standard tape @{term "([], [Oc])"}, it halts with the
       
  1511   non-standard tape @{term "([Oc, Bk], [])"} according to the definition in Chapter 3---so no
       
  1512   result is calculated; but with the standard tape @{term "([Bk], [Oc])"} according to the 
       
  1513   definition in Chapter 8. 
       
  1514   We solve this inconsistency in our formalisation by
       
  1515   setting up our definitions so that the @{text counter_example} Turing machine does not 
       
  1516   produce any result by looping forever fetching @{term Nop}s in state @{text 0}. 
       
  1517   This solution implements essentially the definition in Chapter 3; it  
       
  1518   differs from the definition in Chapter 8, where perplexingly the instruction 
       
  1519   from state @{text 1} is fetched.
       
  1520 *}
       
  1521 
       
  1522 (*
       
  1523 section {* XYZ *}
       
  1524 
       
  1525 text {*
       
  1526 One of the main objectives of the paper is the construction and verification of Universal Turing machine (UTM). A UTM takes the code of any Turing machine $M$ and its arguments $a_1, a_2, \ldots, a_n$ as input and computes to the same effect as $M$ does on $a_1, a_2, \ldots, a_n$. That is to say:
       
  1527 \begin{enumerate}
       
  1528     \item If $M$ terminates and gives a result on $a_1, a_2, \ldots, a_n$, so does $UTM$ on input
       
  1529         $
       
  1530         code(M), a_1, a_1, a_2, \ldots, a_n
       
  1531         $.
       
  1532     \item If $M$ loops forever on $a_1, a_2, \ldots, a_n$, then $UTM$ does the same on $code (M), a_1, a_1, a_2, \ldots, a_n$.
       
  1533 \end{enumerate}
       
  1534 
       
  1535 The existence of UTM is the cornerstone of {\em Turing Thesis}, which says: any effectively computable function can be computed by a Turing Machine. The evaluation of Turing machine is obviously effective computable (otherwise, Turing machine is not an effect computation model). So, if the evaluation function of Turing machine can not be implemented by a Turing machine, the {\em Turing Thesis} would fail. Although people believe that UTM exists, few have gave one in close form and prove its correctness with the only exception of Asperti.
       
  1536 
       
  1537 
       
  1538 The method to obtain Universal Turing machine (UTM), as hinted by Boolos's book, is first constructing a recursive function recF (named Universal Function), which serves as an interpreter for Turing machine program, and then the UTM is obtained by $translate(recF)$. However, since any particular recursive function only takes fixed number of arguments determined by its construction,  no matter how recF is constructed, it can only server as interpret for Turing machines which take the fixed number of arguments as input. Our solution is to precede the $translate(recF)$ with a Turing machine which compacts multiple arguments into one argument using Wang's coding. Now, $recF$ is defined as a function taking two arguments, where the first is the code of Turing machine to be interpreted and the second is the packed arguments.
       
  1539 
       
  1540 The construction of recF roughly follows the idea in the book. Since the book gives no correctness proof of the construction (not even an informal one), we have to formulate the correctness statements and as well as their formal proofs explicitly. As an unexpected outcome of this formulation, we identified one inconsistency in Boolos' book. Every Turing machine is supposed to compute an arithmetic function which is possibly partial. When the TM is started with an argument where the function is undefined, the definition on Chapter 3 (page 32) says:
       
  1541 \begin{quote}
       
  1542 (e) If the function that is to be computed assigns no value to the arguments that are
       
  1543 represented initially on the tape, then the machine either will never halt, or will
       
  1544 halt in some nonstandard configuration such as $B_n11111$ or $B11_n111$ or $B11111_n$.
       
  1545 \end{quote}
       
  1546 According to this definition, a TM can signify a non-result either by looping forever or get into state 0 with a nonstandard tape. However, when we were trying to formalize the universal function in Chapter 8, we found the definition given there is not in accordance. On page 93, an recursive function $stdh$ is defined as:
       
  1547 	\begin{equation}\label{stdh_def}
       
  1548 stdh(m, x, t) = stat(conf(m, x, t)) + nstd(conf(m, x, t))
       
  1549 \end{equation}
       
  1550 Where $ stat(conf(m, x, t)) $ computes the current state of the simulated Turing machine, and the $nstd(conf(m, x, t))$ returns $1$ if the tape content is nonstandard. If either one evaluates to nonzero, stdh(m, x, t) will be nonzero, because of the $+$ operation. One the same page, a function $halt(m, x)$ is defined to in terms of $stdh$ to computes the steps the Turing machine needs to execute before halt, which stipulates the TM halts when nstd(conf(m, x, t)) returns $0$. According to this definition, the simulated Turing machine will continue to run after getting into state $0$ with a nonstandard tape. The consequence of this inconsistency is that: there exists Turing machines which computes non-value according to Chapter 3, but returns a proper result according to Chapter 8. One such Truing machine is:
       
  1551     \begin{equation}\label{contrived_tm}
       
  1552         [(L, 0), (L, 2), (R, 2), (R, 0)]
       
  1553     \end{equation}
       
  1554 Starting in a standard configuration (1, [], [Oc]), it goes through the following series of configurations leading to state 0:
       
  1555 \[
       
  1556 (1, [], [Oc]) \rightsquigarrow (L, 2) \rightsquigarrow  (2, [], [Bk, Oc]) \rightsquigarrow (R, 2)\rightsquigarrow (2, [Bk], [Oc]) \rightsquigarrow (R, 0)\rightsquigarrow  (0, [Bk, Oc], [])
       
  1557 \]
       
  1558 According to Chapter 3, this Turing machine halts and gives a non-result. According to Chapter 8, it will continue to fetch and execute the next instruction. The fetching function $actn$ and $newstat$ in \eqref{fetch-def} (taken from page 92) takes $q$ as current state and $r$ as the currently scanned cell.
       
  1559 \begin{equation}\label{fetch-def}
       
  1560 \begin{aligned}
       
  1561 	actn(m, q, r )  &= ent(m, 4(q - 1)  + 2 \cdot scan(r )) \\
       
  1562 newstat(m, q, r ) & = ent(m, (4(q - 1) + 2 \cdot scan(r )) + 1)
       
  1563 \end{aligned}
       
  1564 \end{equation}
       
  1565 For our instance, $q=0$ and $r = 1$. Because $q - 1 = 0 - 1 = 1 - 1 = 0$, the instruction fetched by \eqref{fetch-def} at state $0$ will be the same as if the machine is at state $0$. So the Turing machine will go through the follow execution and halt with a standard tape:
       
  1566 \[
       
  1567 (0, [Bk, Oc], []) \rightsquigarrow (L, 0) \rightsquigarrow (0, [Bk], [Oc])
       
  1568 \]
       
  1569 In summary, according to Chapter 3, the Turing machine in \eqref{contrived_tm} computes non-result and according to Chapter 8, it computes an identify function. 
       
  1570 *}
       
  1571 *)
       
  1572 
       
  1573 (*
       
  1574 section {* Wang Tiles\label{Wang} *}
       
  1575 
       
  1576 text {*
       
  1577   Used in texture mapings - graphics
       
  1578 *}
       
  1579 *)
       
  1580 
       
  1581 section {* Conclusion *}
       
  1582 
       
  1583 text {*
       
  1584   In previous works we were unable to formalise results about
       
  1585   computability because in Isabelle/HOL we cannot, for example,
       
  1586   represent the decidability of a predicate @{text P}, say, as the
       
  1587   formula @{term "P \<or> \<not>P"}. For reasoning about computability we need
       
  1588   to formalise a concrete model of computations. We could have
       
  1589   followed Norrish \cite{Norrish11} using the $\lambda$-calculus as
       
  1590   the starting point for formalising computability theory, but then we would have
       
  1591   to reimplement on the ML-level his infrastructure for rewriting
       
  1592   $\lambda$-terms modulo $\beta$-equality: HOL4 has a simplifer that
       
  1593   can rewrite terms modulo an arbitrary equivalence relation, which
       
  1594   Isabelle unfortunately does not yet have.  Even though, we would
       
  1595   still need to connect $\lambda$-terms somehow to Turing machines for
       
  1596   proofs that make essential use of them (for example the
       
  1597   undecidability proof for Wang's tiling problem \cite{Robinson71}).
       
  1598 
       
  1599   We therefore have formalised Turing machines in the first place and the main
       
  1600   computability results from Chapters 3 to 8 in the textbook by Boolos
       
  1601   et al \cite{Boolos87}.  For this we did not need to implement
       
  1602   anything on the ML-level of Isabelle/HOL. While formalising the six chapters
       
  1603   of \cite{Boolos87} we have found an inconsistency in Boolos et al's 
       
  1604   definitions of what function a Turing machine calculates. In
       
  1605   Chapter 3 they use a definition that states a function is undefined
       
  1606   if the Turing machine loops \emph{or} halts with a non-standard
       
  1607   tape. Whereas in Chapter 8 about the universal Turing machine, the
       
  1608   Turing machines will \emph{not} halt unless the tape is in standard
       
  1609   form. Like Nipkow \cite{Nipkow98} observed with his formalisation
       
  1610   of a textbook, we found that Boolos et al are (almost)
       
  1611   right. We have not attempted to formalise everything precisely as
       
  1612   Boolos et al present it, but use definitions that make our
       
  1613   mechanised proofs manageable. For example our definition of the
       
  1614   halting state performing @{term Nop}-operations seems to be
       
  1615   non-standard, but very much suited to a formalisation in a theorem
       
  1616   prover where the @{term steps}-function needs to be total.
       
  1617 
       
  1618    Norrish mentions that formalising Turing machines would be a
       
  1619   ``\emph{daunting prospect}'' \cite[Page 310]{Norrish11}. While
       
  1620   $\lambda$-terms indeed lead to some slick mechanised proofs, our
       
  1621   experience is that Turing machines are not too daunting if one is
       
  1622   only concerned with formalising the undecidability of the halting
       
  1623   problem for Turing machines.  As a point of comparison, the halting
       
  1624   problem took us around 1500 loc of Isar-proofs, which is just
       
  1625   one-and-a-half times of a mechanised proof pearl about the
       
  1626   Myhill-Nerode theorem. So our conclusion is that this part is not as
       
  1627   daunting as we estimated when reading the paper by Norrish
       
  1628   \cite{Norrish11}. The work involved with constructing a universal
       
  1629   Turing machine via recursive functions and abacus machines, we
       
  1630   agree, is not a project one wants to undertake too many times (our
       
  1631   formalisation of abacus machines and their correct translation is
       
  1632   approximately 4600 loc; recursive functions 2800 loc and the
       
  1633   universal Turing machine 10000 loc).
       
  1634   
       
  1635   Our work is also very much inspired by the formalisation of Turing
       
  1636   machines of Asperti and Ricciotti \cite{AspertiRicciotti12} in the
       
  1637   Matita theorem prover. It turns out that their notion of
       
  1638   realisability and our Hoare-triples are very similar, however we
       
  1639   differ in some basic definitions for Turing machines. Asperti and
       
  1640   Ricciotti are interested in providing a mechanised foundation for
       
  1641   complexity theory. They formalised a universal Turing machine
       
  1642   (which differs from ours by using a more general alphabet), but did
       
  1643   not describe an undecidability proof. Given their definitions and
       
  1644   infrastructure, we expect however this should not be too difficult 
       
  1645   for them.
       
  1646   
       
  1647   For us the most interesting aspects of our work are the correctness
       
  1648   proofs for Turing machines. Informal presentations of computability
       
  1649   theory often leave the constructions of particular Turing machines
       
  1650   as exercise to the reader, for example \cite{Boolos87}, deeming
       
  1651   it to be just a chore. However, as far as we are aware all informal
       
  1652   presentations leave out any arguments why these Turing machines
       
  1653   should be correct.  This means the reader is left
       
  1654   with the task of finding appropriate invariants and measures for
       
  1655   showing the correctness and termination of these Turing machines.
       
  1656   Whenever we can use Hoare-style reasoning, the invariants are
       
  1657   relatively straightforward and again as a point of comparison much smaller than for example the
       
  1658   invariants used by Myreen in a correctness proof of a garbage collector
       
  1659   written in machine code \cite[Page 76]{Myreen09}. However, the invariant 
       
  1660   needed for the abacus proof, where Hoare-style reasoning does not work, is
       
  1661   similar in size as the one by Myreen and finding a sufficiently
       
  1662   strong one took us, like Myreen, something on the magnitude of
       
  1663   weeks.
       
  1664 
       
  1665   Our reasoning about the invariants is not much supported by the
       
  1666   automation beyond the standard automation tools available in
       
  1667   Isabelle/HOL.  There is however a tantalising connection between our
       
  1668   work and very recent work by Jensen et al \cite{Jensen13} on
       
  1669   verifying X86 assembly code that might change that. They observed a
       
  1670   similar phenomenon with assembly programs where Hoare-style
       
  1671   reasoning is sometimes possible, but sometimes it is not. In order
       
  1672   to ease their reasoning, they introduced a more primitive
       
  1673   specification logic, on which Hoare-rules can be provided for
       
  1674   special cases.  It remains to be seen whether their specification
       
  1675   logic for assembly code can make it easier to reason about our
       
  1676   Turing programs. That would be an attractive result, because Turing
       
  1677   machine programs are very much like assembly programs and it would
       
  1678   connect some very classic work on Turing machines to very
       
  1679   cutting-edge work on machine code verification. In order to try out
       
  1680   such ideas, our formalisation provides the ``playground''. The code
       
  1681   of our formalisation is available from the
       
  1682   Mercurial repository at \url{http://www.dcs.kcl.ac.uk/staff/urbanc/cgi-bin/repos.cgi/tm/}.
       
  1683   \medskip
       
  1684 
       
  1685   \noindent
       
  1686   {\bf Acknowledgements:} We are very grateful for the extremely helpful
       
  1687   comments by the anonymous reviewers.
       
  1688 *}
       
  1689 
       
  1690 
       
  1691 
       
  1692 (*<*)
       
  1693 end
       
  1694 end
       
  1695 (*>*)