25 tcopy_init ("copy\<^bsub>begin\<^esub>") and |
25 tcopy_init ("copy\<^bsub>begin\<^esub>") and |
26 tcopy_loop ("copy\<^bsub>loop\<^esub>") and |
26 tcopy_loop ("copy\<^bsub>loop\<^esub>") and |
27 tcopy_end ("copy\<^bsub>end\<^esub>") and |
27 tcopy_end ("copy\<^bsub>end\<^esub>") and |
28 step0 ("step") and |
28 step0 ("step") and |
29 steps0 ("steps") and |
29 steps0 ("steps") and |
|
30 exponent ("_\<^bsup>_\<^esup>") and |
30 (* abc_lm_v ("lookup") and |
31 (* abc_lm_v ("lookup") and |
31 abc_lm_s ("set") and*) |
32 abc_lm_s ("set") and*) |
32 haltP ("stdhalt") and |
33 haltP ("stdhalt") and |
33 tcopy ("copy") and |
34 tcopy ("copy") and |
34 tape_of_nat_list ("\<ulcorner>_\<urcorner>") and |
35 tape_of_nat_list ("\<ulcorner>_\<urcorner>") and |
245 al~\cite{Boolos87} only consider tapes with cells being either blank |
246 al~\cite{Boolos87} only consider tapes with cells being either blank |
246 or occupied, which we represent by a datatype having two |
247 or occupied, which we represent by a datatype having two |
247 constructors, namely @{text Bk} and @{text Oc}. One way to |
248 constructors, namely @{text Bk} and @{text Oc}. One way to |
248 represent such tapes is to use a pair of lists, written @{term "(l, |
249 represent such tapes is to use a pair of lists, written @{term "(l, |
249 r)"}, where @{term l} stands for the tape on the left-hand side of |
250 r)"}, where @{term l} stands for the tape on the left-hand side of |
250 the head and @{term r} for the tape on the right-hand side. We have |
251 the head and @{term r} for the tape on the right-hand side. We use |
251 the convention that the head, abbreviated @{term hd}, of the |
252 the notation @{term "Bk \<up> n"} (similarly @{term "Oc \<up> n"}) for lists |
252 right-list is the cell on which the head of the Turing machine |
253 composed of @{term n} elements of @{term Bk}. We also have the |
253 currently scannes. This can be pictured as follows: |
254 convention that the head, abbreviated @{term hd}, of the right-list |
|
255 is the cell on which the head of the Turing machine currently |
|
256 scannes. This can be pictured as follows: |
254 % |
257 % |
255 \begin{center} |
258 \begin{center} |
256 \begin{tikzpicture} |
259 \begin{tikzpicture} |
257 \draw[very thick] (-3.0,0) -- ( 3.0,0); |
260 \draw[very thick] (-3.0,0) -- ( 3.0,0); |
258 \draw[very thick] (-3.0,0.5) -- ( 3.0,0.5); |
261 \draw[very thick] (-3.0,0.5) -- ( 3.0,0.5); |
302 |
305 |
303 \noindent |
306 \noindent |
304 We slightly deviate |
307 We slightly deviate |
305 from the presentation in \cite{Boolos87} by using the @{term Nop} operation; however its use |
308 from the presentation in \cite{Boolos87} by using the @{term Nop} operation; however its use |
306 will become important when we formalise halting computations and also universal Turing |
309 will become important when we formalise halting computations and also universal Turing |
307 machines. Given a tape and an action, we can define the |
310 machines. Given a tape and an action, we can define the |
308 following tape updating function: |
311 following tape updating function: |
309 |
312 |
310 \begin{center} |
313 \begin{center} |
311 \begin{tabular}{l@ {\hspace{1mm}}c@ {\hspace{1mm}}l} |
314 \begin{tabular}{l@ {\hspace{1mm}}c@ {\hspace{1mm}}l} |
312 @{thm (lhs) update.simps(1)} & @{text "\<equiv>"} & @{thm (rhs) update.simps(1)}\\ |
315 @{thm (lhs) update.simps(1)} & @{text "\<equiv>"} & @{thm (rhs) update.simps(1)}\\ |
359 %possibly renaming states apart whenever both machines share |
362 %possibly renaming states apart whenever both machines share |
360 %states.\footnote{The usual disjoint union operation in Isabelle/HOL |
363 %states.\footnote{The usual disjoint union operation in Isabelle/HOL |
361 %cannot be used as it does not preserve types.} This renaming can be |
364 %cannot be used as it does not preserve types.} This renaming can be |
362 %quite cumbersome to reason about. |
365 %quite cumbersome to reason about. |
363 We follow the choice made in \cite{AspertiRicciotti12} |
366 We follow the choice made in \cite{AspertiRicciotti12} |
364 representing a state by a natural number and the states in a Turing |
367 by representing a state with a natural number and the states in a Turing |
365 machine program by the initial segment of natural numbers starting from @{text 0}. |
368 machine program by the initial segment of natural numbers starting from @{text 0}. |
366 In doing so we can compose two Turing machine programs by |
369 In doing so we can compose two Turing machine programs by |
367 shifting the states of one by an appropriate amount to a higher |
370 shifting the states of one by an appropriate amount to a higher |
368 segment and adjusting some ``next states'' in the other. |
371 segment and adjusting some ``next states'' in the other. |
369 |
372 |
370 An \emph{instruction} of a Turing machine is a pair consisting of |
373 An \emph{instruction} of a Turing machine is a pair consisting of |
371 an action and a natural number (the next state). A \emph{program} @{term p} of a Turing |
374 an action and a natural number (the next state). A \emph{program} @{term p} of a Turing |
372 machine is then a list of such pairs. Using as an example the following Turing machine |
375 machine is then a list of such pairs. Using as an example the following Turing machine |
373 program, which consists of four instructions |
376 program, which consists of four instructions |
374 |
377 % |
375 \begin{equation} |
378 \begin{equation} |
376 \begin{tikzpicture} |
379 \begin{tikzpicture} |
377 \node [anchor=base] at (0,0) {@{thm dither_def}}; |
380 \node [anchor=base] at (0,0) {@{thm dither_def}}; |
378 \node [anchor=west] at (-1.5,-0.64) |
381 \node [anchor=west] at (-1.5,-0.64) |
379 {$\underbrace{\hspace{21mm}}_{\text{\begin{tabular}{@ {}l@ {}}1st state\\[-2mm] |
382 {$\underbrace{\hspace{21mm}}_{\text{\begin{tabular}{@ {}l@ {}}1st state\\[-2mm] |
383 \node [anchor=west] at (-1.5,0.65) {$\overbrace{\hspace{10mm}}^{\text{@{term Bk}-case}}$}; |
386 \node [anchor=west] at (-1.5,0.65) {$\overbrace{\hspace{10mm}}^{\text{@{term Bk}-case}}$}; |
384 \node [anchor=west] at (-0.1,0.65) {$\overbrace{\hspace{6mm}}^{\text{@{term Oc}-case}}$}; |
387 \node [anchor=west] at (-0.1,0.65) {$\overbrace{\hspace{6mm}}^{\text{@{term Oc}-case}}$}; |
385 \end{tikzpicture} |
388 \end{tikzpicture} |
386 \label{dither} |
389 \label{dither} |
387 \end{equation} |
390 \end{equation} |
388 |
391 % |
389 \noindent |
392 \noindent |
390 the reader can see we have organised our Turing machine programs so |
393 the reader can see we have organised our Turing machine programs so |
391 that segments of two belong to a state. The first component of such a |
394 that segments of two belong to a state. The first component of such a |
392 segment determines what action should be taken and which next state |
395 segment determines what action should be taken and which next state |
393 should be transitioned to in case the head reads a @{term Bk}; |
396 should be transitioned to in case the head reads a @{term Bk}; |
399 0}-state, but it will always perform a @{term Nop}-operation and |
402 0}-state, but it will always perform a @{term Nop}-operation and |
400 remain in the @{text 0}-state. Unlike Asperti and Riccioti |
403 remain in the @{text 0}-state. Unlike Asperti and Riccioti |
401 \cite{AspertiRicciotti12}, we have chosen a very concrete |
404 \cite{AspertiRicciotti12}, we have chosen a very concrete |
402 representation for programs, because when constructing a universal |
405 representation for programs, because when constructing a universal |
403 Turing machine, we need to define a coding function for programs. |
406 Turing machine, we need to define a coding function for programs. |
404 This can be easily done for our programs-as-lists, but is more |
407 This can be directly done for our programs-as-lists, but is |
405 difficult for the functions used by Asperti and Ricciotti. |
408 slightly more difficult for the functions used by Asperti and Ricciotti. |
406 |
409 |
407 Given a program @{term p}, a state |
410 Given a program @{term p}, a state |
408 and the cell being read by the head, we need to fetch |
411 and the cell being read by the head, we need to fetch |
409 the corresponding instruction from the program. For this we define |
412 the corresponding instruction from the program. For this we define |
410 the function @{term fetch} |
413 the function @{term fetch} |
523 \end{tabular} |
526 \end{tabular} |
524 \end{center} |
527 \end{center} |
525 \caption{Copy machine}\label{copy} |
528 \caption{Copy machine}\label{copy} |
526 \end{figure} |
529 \end{figure} |
527 |
530 |
528 {\it |
531 We often need to restrict tapes to be in \emph{standard form}, which means |
529 As in \cite{Boolos87} we often need to restrict tapes to be in standard |
532 the left list of the tape is either empty or only contains @{text "Bk"}s, and |
530 form.} |
533 the right list contains some ``clusters'' of @{text "Oc"}s separted by single |
|
534 blanks and can be followed by some blanks. To make this formal we define the |
|
535 following function |
|
536 |
|
537 \begin{center} |
|
538 foo |
|
539 \end{center} |
|
540 |
|
541 \noindent |
|
542 A 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}, |
|
543 @{text l} and @{text "n\<^isub>i"}. Note that the head in a standard tape ``points'' to the |
|
544 leftmost @{term "Oc"} on the tape. |
|
545 |
531 |
546 |
532 Before we can prove the undecidability of the halting problem for our |
547 Before we can prove the undecidability of the halting problem for our |
533 Turing machines, we need to analyse two concrete Turing machine |
548 Turing machines, we need to analyse two concrete Turing machine |
534 programs and establish that they are correct---that means they are |
549 programs and establish that they are correct---that means they are |
535 ``doing what they are supposed to be doing''. Such correctness proofs are usually left |
550 ``doing what they are supposed to be doing''. Such correctness proofs are usually left |
547 whose three components are given in Figure~\ref{copy}. To the prove |
562 whose three components are given in Figure~\ref{copy}. To the prove |
548 correctness of these Turing machine programs, we introduce the |
563 correctness of these Turing machine programs, we introduce the |
549 notion of total correctness defined in terms of |
564 notion of total correctness defined in terms of |
550 \emph{Hoare-triples}, written @{term "{P} p {Q}"}. They realise the |
565 \emph{Hoare-triples}, written @{term "{P} p {Q}"}. They realise the |
551 idea that a program @{term p} started in state @{term "1::nat"} with |
566 idea that a program @{term p} started in state @{term "1::nat"} with |
552 a tape satisfying @{term P} will after @{text n} steps halt (have |
567 a tape satisfying @{term P} will after some @{text n} steps halt (have |
553 transitioned into the halting state) with a tape satisfying @{term |
568 transitioned into the halting state) with a tape satisfying @{term |
554 Q}. We also have \emph{Hoare-pairs} of the form @{term "{P} p \<up>"} |
569 Q}. We also have \emph{Hoare-pairs} of the form @{term "{P} p \<up>"} |
555 realising the case that a program @{term p} started with a tape |
570 realising the case that a program @{term p} started with a tape |
556 satisfying @{term P} will loop (never transition into the halting |
571 satisfying @{term P} will loop (never transition into the halting |
557 state). Both notion are formally defined as |
572 state). Both notion are formally defined as |
575 \end{tabular} |
590 \end{tabular} |
576 \end{center} |
591 \end{center} |
577 |
592 |
578 \noindent |
593 \noindent |
579 We have set up our Hoare-style reasoning so that we can deal explicitly |
594 We have set up our Hoare-style reasoning so that we can deal explicitly |
580 with looping and total correctness, rather than have notions for partial |
595 with total correctness and non-terminantion, rather than have notions for partial |
581 correctness and termination. Although the latter would allow us to reason |
596 correctness and termination. Although the latter would allow us to reason |
582 more uniformly (only using Hoare-triples), we prefer our definitions because |
597 more uniformly (only using Hoare-triples), we prefer our definitions because |
583 we can derive simple Hoare-rules for sequentially composed Turing programs. |
598 we can derive simple Hoare-rules for sequentially composed Turing programs. |
584 In this way we can reason about the correctness of @{term "tcopy_init"}, |
599 In this way we can reason about the correctness of @{term "tcopy_init"}, |
585 for example, completely separately from @{term "tcopy_loop"} and @{term "tcopy_end"}. |
600 for example, completely separately from @{term "tcopy_loop"} and @{term "tcopy_end"}. |
586 |
601 |
587 \begin{center} |
602 \begin{center} |
588 \begin{tabular}{lcl} |
603 \begin{tabular}{l@ {\hspace{3mm}}lcl} |
589 \multicolumn{1}{c}{start tape}\\ |
604 & \multicolumn{1}{c}{start tape}\\[1mm] |
|
605 \raisebox{2.5mm}{halting case:} & |
590 \begin{tikzpicture} |
606 \begin{tikzpicture} |
591 \draw[very thick] (-2,0) -- ( 0.75,0); |
607 \draw[very thick] (-2,0) -- ( 0.75,0); |
592 \draw[very thick] (-2,0.5) -- ( 0.75,0.5); |
608 \draw[very thick] (-2,0.5) -- ( 0.75,0.5); |
593 \draw[very thick] (-0.25,0) -- (-0.25,0.5); |
609 \draw[very thick] (-0.25,0) -- (-0.25,0.5); |
594 \draw[very thick] ( 0.25,0) -- ( 0.25,0.5); |
610 \draw[very thick] ( 0.25,0) -- ( 0.25,0.5); |
613 \draw[fill] (-0.15,0.1) rectangle (0.15,0.4); |
629 \draw[fill] (-0.15,0.1) rectangle (0.15,0.4); |
614 \draw[fill] ( 0.35,0.1) rectangle (0.65,0.4); |
630 \draw[fill] ( 0.35,0.1) rectangle (0.65,0.4); |
615 \node [anchor=base] at (-1.7,0.2) {\ldots}; |
631 \node [anchor=base] at (-1.7,0.2) {\ldots}; |
616 \end{tikzpicture}\\ |
632 \end{tikzpicture}\\ |
617 |
633 |
618 \begin{tikzpicture} |
634 \raisebox{2.5mm}{non-halting case:} & |
|
635 \begin{tikzpicture} |
619 \draw[very thick] (-2,0) -- ( 0.25,0); |
636 \draw[very thick] (-2,0) -- ( 0.25,0); |
620 \draw[very thick] (-2,0.5) -- ( 0.25,0.5); |
637 \draw[very thick] (-2,0.5) -- ( 0.25,0.5); |
621 \draw[very thick] (-0.25,0) -- (-0.25,0.5); |
638 \draw[very thick] (-0.25,0) -- (-0.25,0.5); |
622 \draw[very thick] ( 0.25,0) -- ( 0.25,0.5); |
639 \draw[very thick] ( 0.25,0) -- ( 0.25,0.5); |
623 \draw[very thick] (-0.75,0) -- (-0.75,0.5); |
640 \draw[very thick] (-0.75,0) -- (-0.75,0.5); |