44 apply - |
44 apply - |
45 apply(rule_tac [!] eq_reflection) |
45 apply(rule_tac [!] eq_reflection) |
46 by (auto split: if_splits prod.split list.split simp add: tstep.simps) |
46 by (auto split: if_splits prod.split list.split simp add: tstep.simps) |
47 |
47 |
48 abbreviation |
48 abbreviation |
49 "halt p inp out == \<exists>n. steps (1, inp) p n = (0, out)" |
49 "run p inp out == \<exists>n. steps (1, inp) p n = (0, out)" |
50 |
50 |
51 lemma haltP_def2: |
51 lemma haltP_def2: |
52 "haltP p n = (\<exists>k l m. |
52 "haltP p n = (\<exists>k l m. |
53 halt p ([], exponent Oc n) (exponent Bk k, exponent Oc l @ exponent Bk m))" |
53 run p ([], exponent Oc n) (exponent Bk k, exponent Oc l @ exponent Bk m))" |
54 unfolding haltP_def |
54 unfolding haltP_def |
55 apply(auto) |
55 apply(auto) |
56 done |
56 done |
|
57 |
|
58 lemma tape_of_nat_list_def2: |
|
59 shows "tape_of_nat_list [] = []" |
|
60 and "tape_of_nat_list [n] = exponent Oc (n+1)" |
|
61 and "ns\<noteq> [] ==> tape_of_nat_list (n#ns) = (exponent Oc (n+1)) @ [Bk] @ (tape_of_nat_list ns)" |
|
62 apply(auto simp add: tape_of_nat_list.simps) |
|
63 apply(case_tac ns) |
|
64 apply(auto simp add: tape_of_nat_list.simps) |
|
65 done |
|
66 |
|
67 lemma tshift_def2: |
|
68 fixes p::"tprog" |
|
69 shows "tshift p n == (map (\<lambda> (a, s). (a, (if s = 0 then 0 else s + n))) p)" |
|
70 apply(rule eq_reflection) |
|
71 apply(auto simp add: tshift.simps) |
|
72 done |
|
73 |
57 |
74 |
58 consts DUMMY::'a |
75 consts DUMMY::'a |
59 |
76 |
60 notation (latex output) |
77 notation (latex output) |
61 Cons ("_::_" [78,77] 73) and |
78 Cons ("_::_" [78,77] 73) and |
128 data-structures at hand are ``structurally'' defined, like lists, |
147 data-structures at hand are ``structurally'' defined, like lists, |
129 natural numbers, regular expressions, etc. Such data-structures come |
148 natural numbers, regular expressions, etc. Such data-structures come |
130 with convenient reasoning infrastructures (for example induction |
149 with convenient reasoning infrastructures (for example induction |
131 principles, recursion combinators and so on). But this is \emph{not} |
150 principles, recursion combinators and so on). But this is \emph{not} |
132 the case with Turing machines (and also not with register machines): |
151 the case with Turing machines (and also not with register machines): |
133 underlying their definition is a set of states together with a |
152 underlying their definitions are sets of states together with |
134 transition function, both of which are not structurally defined. This |
153 transition functions, all of which are not structurally defined. This |
135 means we have to implement our own reasoning infrastructure in order |
154 means we have to implement our own reasoning infrastructure in order |
136 to prove properties about them. This leads to annoyingly fiddly |
155 to prove properties about them. This leads to annoyingly fiddly |
137 formalisations. We noticed first the difference between both, |
156 formalisations. We noticed first the difference between both, |
138 structural and non-structural, ``worlds'' when formalising the |
157 structural and non-structural, ``worlds'' when formalising the |
139 Myhill-Nerode theorem, where regular expressions fared much better |
158 Myhill-Nerode theorem, where regular expressions fared much better |
147 We are not the first who formalised Turing machines in a theorem |
166 We are not the first who formalised Turing machines in a theorem |
148 prover: we are aware of the preliminary work by Asperti and Ricciotti |
167 prover: we are aware of the preliminary work by Asperti and Ricciotti |
149 \cite{AspertiRicciotti12}. They describe a complete formalisation of |
168 \cite{AspertiRicciotti12}. They describe a complete formalisation of |
150 Turing machines in the Matita theorem prover, including a universal |
169 Turing machines in the Matita theorem prover, including a universal |
151 Turing machine. They report that the informal proofs from which they |
170 Turing machine. They report that the informal proofs from which they |
152 started are not ``sufficiently accurate to be directly useable as a |
171 started are \emph{not} ``sufficiently accurate to be directly useable as a |
153 guideline for formalization'' \cite[Page 2]{AspertiRicciotti12}. For |
172 guideline for formalization'' \cite[Page 2]{AspertiRicciotti12}. For |
154 our formalisation we followed mainly the proofs from the textbook |
173 our formalisation we followed mainly the proofs from the textbook |
155 \cite{Boolos87} and found that the description there is quite |
174 \cite{Boolos87} and found that the description there is quite |
156 detailed. Some details are left out however: for example, it is only |
175 detailed. Some details are left out however: for example, it is only |
157 shown how the universal Turing machine is constructed for Turing |
176 shown how the universal Turing machine is constructed for Turing |
184 (represented by @{term Bk} and @{term Oc}, respectively, in our |
203 (represented by @{term Bk} and @{term Oc}, respectively, in our |
185 formalisation). Traditionally the content of a cell can be any |
204 formalisation). Traditionally the content of a cell can be any |
186 character from a finite alphabet. Although computationally equivalent, |
205 character from a finite alphabet. Although computationally equivalent, |
187 the more restrictive notion of Turing machines in \cite{Boolos87} makes |
206 the more restrictive notion of Turing machines in \cite{Boolos87} makes |
188 the reasoning more uniform. In addition some proofs \emph{about} Turing |
207 the reasoning more uniform. In addition some proofs \emph{about} Turing |
189 machines will be simpler. The reason is that one often needs to encode |
208 machines are simpler. The reason is that one often needs to encode |
190 Turing machines---consequently if the Turing machines are simpler, then the coding |
209 Turing machines---consequently if the Turing machines are simpler, then the coding |
191 functions are simpler too. Unfortunately, the restrictiveness also makes |
210 functions are simpler too. Unfortunately, the restrictiveness also makes |
192 it harder to design programs for these Turing machines. Therefore in order |
211 it harder to design programs for these Turing machines. In order |
193 to construct a \emph{universal Turing machine} we follow the proof in |
212 to construct a \emph{universal Turing machine} we therefore do not follow |
|
213 \cite{AspertiRicciotti12}, instead follow the proof in |
194 \cite{Boolos87} by relating abacus machines to Turing machines and in |
214 \cite{Boolos87} by relating abacus machines to Turing machines and in |
195 turn recursive functions to abacus machines. The universal Turing |
215 turn recursive functions to abacus machines. The universal Turing |
196 machine can then be constructed as a recursive function. |
216 machine can then be constructed as a recursive function. |
197 |
217 |
198 \smallskip |
218 \smallskip |
288 such that @{term "tl [] == []"} holds. The third clause |
308 such that @{term "tl [] == []"} holds. The third clause |
289 implements the move of the head one step to the left: we need |
309 implements the move of the head one step to the left: we need |
290 to test if the left-list @{term l} is empty; if yes, then we just prepend a |
310 to test if the left-list @{term l} is empty; if yes, then we just prepend a |
291 blank cell to the right-list; otherwise we have to remove the |
311 blank cell to the right-list; otherwise we have to remove the |
292 head from the left-list and prepend it to the right-list. Similarly |
312 head from the left-list and prepend it to the right-list. Similarly |
293 in the clause for a right move action. The @{term Nop} operation |
313 in the fourth clause for a right move action. The @{term Nop} operation |
294 leaves the the tape unchanged. |
314 leaves the the tape unchanged (last clause). |
295 |
315 |
296 Note that our treatment of the tape is rather ``unsymmetric''---we |
316 Note that our treatment of the tape is rather ``unsymmetric''---we |
297 have the convention that the head of the right-list is where the |
317 have the convention that the head of the right-list is where the |
298 head is currently positioned. Asperti and Ricciotti |
318 head is currently positioned. Asperti and Ricciotti |
299 \cite{AspertiRicciotti12} also considered such a representation, but |
319 \cite{AspertiRicciotti12} also considered such a representation, but |
311 definition above, and by using the @{term update} function |
331 definition above, and by using the @{term update} function |
312 cover uniformely all cases including corner cases. |
332 cover uniformely all cases including corner cases. |
313 |
333 |
314 Next we need to define the \emph{states} of a Turing machine. Given |
334 Next we need to define the \emph{states} of a Turing machine. Given |
315 how little is usually said about how to represent them in informal |
335 how little is usually said about how to represent them in informal |
316 presentations, it might be surprising that in a theorem prover we have |
336 presentations, it might be surprising that in a theorem prover we |
317 to select carfully a representation. If we use the naive representation |
337 have to select carfully a representation. If we use the naive |
318 where a Turing machine consists of a finite set of states, then we |
338 representation where a Turing machine consists of a finite set of |
319 will have difficulties composing two Turing machines: we |
339 states, then we will have difficulties composing two Turing |
320 would need to combine two finite sets of states, possibly |
340 machines: we would need to combine two finite sets of states, |
321 renaming states apart whenever both machines share |
341 possibly renaming states apart whenever both machines share |
322 states.\footnote{The usual disjoint union operation does not preserve types, unfortunately.} This |
342 states.\footnote{The usual disjoint union operation in Isabelle/HOL |
323 renaming can be quite cumbersome to reason about. Therefore we made |
343 cannot be used as it does not preserve types.} This renaming can be |
324 the choice of representing a state by a natural number and the states |
344 quite cumbersome to reason about. Therefore we made the choice of |
325 of a Turing machine will always consist of the initial segment |
345 representing a state by a natural number and the states of a Turing |
326 of natural numbers starting from @{text 0} up to the number of states |
346 machine will always consist of the initial segment of natural |
327 of the machine. In doing so we can compose |
347 numbers starting from @{text 0} up to the number of states of the |
328 two Turing machine by ``shifting'' the states of one by an appropriate |
348 machine. In doing so we can compose two Turing machine by |
329 amount to a higher segment and adjust some ``next states'' in the other. |
349 shifting the states of one by an appropriate amount to a higher |
|
350 segment and adjusting some ``next states'' in the other. |
330 |
351 |
331 An \emph{instruction} @{term i} of a Turing machine is a pair consisting of |
352 An \emph{instruction} @{term i} of a Turing machine is a pair consisting of |
332 an action and a natural number (the next state). A \emph{program} @{term p} of a Turing |
353 an action and a natural number (the next state). A \emph{program} @{term p} of a Turing |
333 machine is then a list of such pairs. Using the following Turing machine |
354 machine is then a list of such pairs. Using as an example the following Turing machine |
334 program (consisting of four instructions) as an example |
355 program, which consists of four instructions |
335 |
356 |
336 \begin{center} |
357 \begin{equation} |
337 \begin{tikzpicture} |
358 \begin{tikzpicture} |
338 \node [anchor=base] at (0,0) {@{thm dither_def}}; |
359 \node [anchor=base] at (0,0) {@{thm dither_def}}; |
339 \node [anchor=west] at (-1.5,-0.42) {$\underbrace{\hspace{21mm}}_{\text{1st state}}$}; |
360 \node [anchor=west] at (-1.5,-0.42) {$\underbrace{\hspace{21mm}}_{\text{1st state}}$}; |
340 \node [anchor=west] at ( 1.1,-0.42) {$\underbrace{\hspace{17mm}}_{\text{2nd state}}$}; |
361 \node [anchor=west] at ( 1.1,-0.42) {$\underbrace{\hspace{17mm}}_{\text{2nd state}}$}; |
341 \node [anchor=west] at (-1.5,0.65) {$\overbrace{\hspace{10mm}}^{\text{@{term Bk}-case}}$}; |
362 \node [anchor=west] at (-1.5,0.65) {$\overbrace{\hspace{10mm}}^{\text{@{term Bk}-case}}$}; |
342 \node [anchor=west] at (-0.1,0.65) {$\overbrace{\hspace{6mm}}^{\text{@{term Oc}-case}}$}; |
363 \node [anchor=west] at (-0.1,0.65) {$\overbrace{\hspace{6mm}}^{\text{@{term Oc}-case}}$}; |
343 \end{tikzpicture} |
364 \end{tikzpicture} |
344 \end{center} |
365 \label{dither} |
345 |
366 \end{equation} |
346 \noindent |
367 |
347 the reader can see we have organised our Turing machine programs so |
368 \noindent |
348 that segments of two belong to a state. The first component |
369 the reader can see we have organised our Turing machine programs so |
349 of the segment determines what action should be taken and which next |
370 that segments of two belong to a state. The first component of the |
350 state should be transitioned to in case the head reads a @{term Bk}; |
371 segment determines what action should be taken and which next state |
|
372 should be transitioned to in case the head reads a @{term Bk}; |
351 similarly the second component determines what should be done in |
373 similarly the second component determines what should be done in |
352 case of reading @{term Oc}. We have the convention that the |
374 case of reading @{term Oc}. We have the convention that the first |
353 first state is always the \emph{starting state} of the Turing machine. |
375 state is always the \emph{starting state} of the Turing machine. |
354 The 0-state is special in that it will be used as the \emph{halting state}. |
376 The zeroth state is special in that it will be used as the |
355 There are no instructions for the 0-state, but it will always |
377 ``halting state''. There are no instructions for the @{text |
356 perform a @{term Nop}-operation and remain in the 0-state. |
378 0}-state, but it will always perform a @{term Nop}-operation and |
357 |
379 remain in the @{text 0}-state. Unlike Asperti and Riccioti |
|
380 \cite{AspertiRicciotti12}, we have chosen a very concrete |
|
381 representation for programs, because when constructing a universal |
|
382 Turing machine, we need to define a coding function for programs. |
|
383 This can be easily done for our programs-as-lists, but is more |
|
384 difficult for the functions used by Asperti and Ricciotti. |
|
385 |
358 Given a program @{term p}, a state |
386 Given a program @{term p}, a state |
359 and the cell being read by the head, we need to fetch |
387 and the cell being read by the head, we need to fetch |
360 the corresponding instruction from the program. For this we define |
388 the corresponding instruction from the program. For this we define |
361 the function @{term fetch} |
389 the function @{term fetch} |
362 |
390 |
374 \end{tabular} |
402 \end{tabular} |
375 \end{center} |
403 \end{center} |
376 |
404 |
377 \noindent |
405 \noindent |
378 In this definition the function @{term nth_of} returns the @{text n}th element |
406 In this definition the function @{term nth_of} returns the @{text n}th element |
379 from a list, if it exists (@{term Some}-case), or if it does not, it |
407 from a list, provided it exists (@{term Some}-case), or if it does not, it |
380 returns the default action @{term Nop} and the default state 0 |
408 returns the default action @{term Nop} and the default state @{text 0} |
381 (@{term None}-case). In doing so we slightly deviate from the description |
409 (@{term None}-case). In doing so we slightly deviate from the description |
382 in \cite{Boolos87}: if their Turing machines transition to a non-existing |
410 in \cite{Boolos87}: if their Turing machines transition to a non-existing |
383 state, then the computation is halted. We will transition in such cases |
411 state, then the computation is halted. We will transition in such cases |
384 to the 0th state with the @{term Nop}-action. However, with introducing the |
412 to the @{text 0}-state. However, with introducing the |
385 notion of \emph{well-formed} Turing machine programs we will exclude such |
413 notion of \emph{well-formed} Turing machine programs we will later exclude such |
386 cases. A program @{term p} is said to be well-formed if it satisfies |
414 cases and make the @{text 0}-state the only ``halting state''. A program |
387 the following three properties |
415 @{term p} is said to be well-formed if it satisfies |
|
416 the following three properties: |
388 |
417 |
389 \begin{center} |
418 \begin{center} |
390 \begin{tabular}{l@ {\hspace{1mm}}c@ {\hspace{1mm}}l} |
419 \begin{tabular}{l@ {\hspace{1mm}}c@ {\hspace{1mm}}l} |
391 @{term "t_correct p"} & @{text "\<equiv>"} & @{term "2 <= length p"}\\ |
420 @{term "t_correct p"} & @{text "\<equiv>"} & @{term "2 <= length p"}\\ |
392 & @{text "\<and>"} & @{term "iseven (length p)"}\\ |
421 & @{text "\<and>"} & @{term "iseven (length p)"}\\ |
396 |
425 |
397 \noindent |
426 \noindent |
398 The first says that @{text p} must have at least an instruction for the starting |
427 The first says that @{text p} must have at least an instruction for the starting |
399 state; the second that @{text p} has a @{term Bk} and @{term Oc} instruction for every |
428 state; the second that @{text p} has a @{term Bk} and @{term Oc} instruction for every |
400 state, and the third that every next-state is one of the states mentioned in |
429 state, and the third that every next-state is one of the states mentioned in |
401 the program or being the 0-state. |
430 the program or being the @{text 0}-state. |
402 |
431 |
403 A \emph{configuration} @{term c} of a Turing machine is a state together with |
432 A \emph{configuration} @{term c} of a Turing machine is a state together with |
404 a tape. This is written as @{text "(s, (l, r))"}. If we have a |
433 a tape. This is written as @{text "(s, (l, r))"}. If we have a |
405 configuration and a program, we can calculate |
434 configuration and a program, we can calculate |
406 what the next configuration is by fetching the appropriate next state |
435 what the next configuration is by fetching the appropriate action and next state |
407 and action from the program, and updating the state and tape accordingly. |
436 from the program, and by updating the state and tape accordingly. |
408 This single step of execution is defined as the function @{term tstep}: |
437 This single step of execution is defined as the function @{term tstep} |
409 |
438 |
410 \begin{center} |
439 \begin{center} |
411 \begin{tabular}{l} |
440 \begin{tabular}{l} |
412 @{text "step (s, (l, r)) p"} @{text "\<equiv>"}\\ |
441 @{text "step (s, (l, r)) p"} @{text "\<equiv>"}\\ |
413 \hspace{10mm}@{text "let (a, s) = fetch p s (read r)"}\\ |
442 \hspace{10mm}@{text "let (a, s) = fetch p s (read r)"}\\ |
414 \hspace{10mm}@{text "in (s', update (l, r) a)"} |
443 \hspace{10mm}@{text "in (s', update (l, r) a)"} |
415 \end{tabular} |
444 \end{tabular} |
416 \end{center} |
445 \end{center} |
417 |
446 |
418 \noindent |
447 \noindent |
419 It is impossible in Isabelle/HOL to lift this function realising |
448 where @{term "read r"} returns the head of the list @{text r}, or if @{text r} is |
|
449 empty it returns @{term Bk}. |
|
450 It is impossible in Isabelle/HOL to lift the @{term step}-function realising |
420 a general evaluation function for Turing machines. The reason is that functions in HOL-based |
451 a general evaluation function for Turing machines. The reason is that functions in HOL-based |
421 provers need to be terminating, and clearly there are Turing machine |
452 provers need to be terminating, and clearly there are Turing machine |
422 programs which are not. We can however define an evaluation |
453 programs that are not. We can however define an evaluation |
423 function so that it performs exactly @{text n} steps: |
454 function so that it performs exactly @{text n} steps: |
424 |
455 |
425 \begin{center} |
456 \begin{center} |
426 \begin{tabular}{l@ {\hspace{1mm}}c@ {\hspace{1mm}}l} |
457 \begin{tabular}{l@ {\hspace{1mm}}c@ {\hspace{1mm}}l} |
427 @{thm (lhs) steps.simps(1)} & @{text "\<equiv>"} & @{thm (rhs) steps.simps(1)}\\ |
458 @{thm (lhs) steps.simps(1)} & @{text "\<equiv>"} & @{thm (rhs) steps.simps(1)}\\ |
429 \end{tabular} |
460 \end{tabular} |
430 \end{center} |
461 \end{center} |
431 |
462 |
432 \noindent |
463 \noindent |
433 Recall our definition of @{term fetch} with the default value for |
464 Recall our definition of @{term fetch} with the default value for |
434 the 0th state. In case a Turing program takes in \cite{Boolos87} less |
465 the @{text 0}-state. In case a Turing program takes in \cite{Boolos87} less |
435 then @{text n} steps before it halts, then in our setting the evaluation |
466 then @{text n} steps before it halts, then in our setting the @{term steps}-evaluation |
436 does not halt, but rather transitions to the 0th state and remain there |
467 does not actually halt, but rather transitions to the @{text 0}-state and |
437 performing @{text Nop}-actions. |
468 remains there performing @{text Nop}-actions until @{text n} is reached. |
438 |
469 |
439 Given some input tape @{text "(l\<^isub>i,r\<^isub>i)"}, we can define when a program |
470 Given some input tape @{text "(l\<^isub>i,r\<^isub>i)"}, we can define when a program |
440 @{term p} halts generating an output tape @{text "(l\<^isub>o,r\<^isub>o)"}: |
471 @{term p} generates a specific output tape @{text "(l\<^isub>o,r\<^isub>o)"} |
441 |
472 |
442 \begin{center} |
473 \begin{center} |
443 \begin{tabular}{l} |
474 \begin{tabular}{l} |
444 @{term "halt p (l\<^isub>i,r\<^isub>i) (l\<^isub>o,r\<^isub>o)"} @{text "\<equiv>"}\\ |
475 @{term "runs p (l\<^isub>i, r\<^isub>i) (l\<^isub>o,r\<^isub>o)"} @{text "\<equiv>"}\\ |
445 \hspace{6mm}@{text "\<exists>n. nsteps (1, (l\<^isub>i,r\<^isub>i)) p n = (0, (l\<^isub>o,r\<^isub>o))"} |
476 \hspace{6mm}@{text "\<exists>n. nsteps (1, (l\<^isub>i,r\<^isub>i)) p n = (0, (l\<^isub>o,r\<^isub>o))"} |
446 \end{tabular} |
477 \end{tabular} |
447 \end{center} |
478 \end{center} |
448 |
479 |
449 \noindent |
480 \noindent |
450 where 1 stands for the starting state and 0 for the halting state, or |
481 where @{text 1} stands for the starting state and @{text 0} for our final state. |
451 in our settin it should better be called the final state. |
482 A program @{text p} with input tape @{term "(l\<^isub>i, r\<^isub>i)"} \emph{halts} iff |
|
483 |
|
484 \begin{center} |
|
485 @{term "halts p (l\<^isub>i, r\<^isub>i) \<equiv> |
|
486 \<exists>l\<^isub>o r\<^isub>o. runs p (l\<^isub>i, r\<^isub>i) (l\<^isub>o,r\<^isub>o)"} |
|
487 \end{center} |
|
488 |
|
489 \noindent |
452 Later on we need to consider specific Turing machines that |
490 Later on we need to consider specific Turing machines that |
453 start with a tape in standard form and halt the computation |
491 start with a tape in standard form and halt the computation |
454 in standard form. By this we mean |
492 in standard form. To define a tape in standard form, it is |
|
493 useful to have an operation @{term "tape_of_nat_list DUMMY"} that |
|
494 translates |
|
495 lists of natural numbers into tapes. |
|
496 |
|
497 \begin{center} |
|
498 \begin{tabular}{l@ {\hspace{1mm}}c@ {\hspace{1mm}}l} |
|
499 @{thm (lhs) tape_of_nat_list_def2(1)} & @{text "\<equiv>"} & @{thm (rhs) tape_of_nat_list_def2(1)}\\ |
|
500 @{thm (lhs) tape_of_nat_list_def2(2)} & @{text "\<equiv>"} & @{thm (rhs) tape_of_nat_list_def2(2)}\\ |
|
501 @{thm (lhs) tape_of_nat_list_def2(3)} & @{text "\<equiv>"} & @{thm (rhs) tape_of_nat_list_def2(3)}\\ |
|
502 \end{tabular} |
|
503 \end{center} |
|
504 |
|
505 |
|
506 |
|
507 |
|
508 By this we mean |
455 |
509 |
456 \begin{center} |
510 \begin{center} |
457 @{thm haltP_def2[where p="p" and n="n", THEN eq_reflection]} |
511 @{thm haltP_def2[where p="p" and n="n", THEN eq_reflection]} |
458 \end{center} |
512 \end{center} |
459 |
513 |