<p>So the actual question, which dates back to the very definition of the Turing Machine, is this: when a <em>square</em> from Turing's paper has not yet been written to, does it hold an empty symbol, or is it actually empty?</p>
- <p>As defined in texts such as Hopcroft and Ullman, a Turing Machine cannot function when a tape cell does not read a symbol, because the next state function is defined such that it must be given a symbol. A machine simply fails if a scanned cell is void of symbols.</p>
+ <p>As defined in texts such as Hopcroft and Ullman, a Turing Machine cannot function when a tape cell does not read a symbol, because the next state function is defined such that it must be given a symbol. A machine breaks if a scanned cell is void of symbols.</p>
<p>Imagine a tape machine, called machine A, where, upon attempting to read an empty cell, the machine head instead returns a control symbol representing that the cell was empty. To accomplish this, the head would have to do some work; it would have to be able to detect emptiness, and then choose to return the empty symbol instead of a read value. This feature would fix the problem of not having any defined next state behavior for an empty cell. Furthermore, suppose the inverse process was also special in that upon attempting to write the empty symbol, the machine takes action, emptying the cell out. This would facilitate an erase operation.</p>
- <p>Now imagine machine B, where a yet-to-be-used cell on a tape directly holds the symbol. Because it is merely another symbol, reads and writes occur exactly as they do for other symbols.</p>
+ <p>Now imagine machine B, where a yet-to-be-used cell on a tape directly holds the empty symbol. Because it is merely another symbol, reads and writes occur exactly as they do for other symbols.</p>
- <p>As long as the cost of the empty cell fix is constant time, the differences between machine A and machine B are computationally inconsequential. However, for machine A, the mathematician is greatly inconvenienced if he cares to write down the contents of the tape, as he will need some means of communicating that a tape cell is empty. A mathematician is wont to invent a symbol to express this meaning. The cup, empty box, or null set symbol are all possible choices. Let us not lose sight of the level of analysis, however. We are discussing the computation theoretic Turing Machine, and doing so in the realm of forms. Given that our discussion is in the abstract, machines A and B are in fact the same, the only difference being that the description for machine A is less elegant. Thus, we will recognize that an empty tape, one that has not been written to, is full of empty symbols.</p>
+ <p>As long as the cost of the empty cell fix is constant time, the differences between machine A and machine B are computationally inconsequential. However, for machine A, the mathematician is greatly inconvenienced if he cares to write down the contents of the tape, as he will need some means of communicating that a tape cell is empty. As mathematicians are wont to do, he would invent a symbol to express this meaning. The cup, empty box, or null set symbol are all possible choices. Let us not lose sight of the level of analysis, however. We are discussing the computation theoretic Turing Machine, and doing so in the realm of forms. Given that our discussion is in the abstract, machines A and B are in fact the same, the only difference being that the description for machine A is less elegant. Thus, we will recognize that an empty tape, one that has not been written to, is full of empty symbols.</p>
<p>Computational theorists often describe a two-step process. First, a Turing Machine writes a string to be studied onto a tape initially filled with all empty symbols; second, the tape is moved to another Turing Machine whose purpose is to recognize a property of the string being studied. In this process, a tape is used as a communication medium, and it follows that communication theory can be applied to this messaging scenario. Messages sent on a channel must be formatted so they can be placed on the channel and later recovered. The specification for such structuring is called a communication <RT·term>protocol</RT·term>. The protocol implies a higher authority, as both the sender and the receiver must have knowledge of the same designed-in protocol. In a sense, a protocol is the meta-message sent before the message itself.</p>
<p>A common technique programmers use for embedding strings with terminators within other strings is to embed escape characters. This is another in-band protocol, and it is inefficient. The escape sequences grow exponentially with nesting levels. Also, such strings with embedded escape sequences cannot be interpreted without knowledge of the intended nesting level of the string author, which requires the interpreter of the string to know the author's intentions.</p>
- <p>For the modified computational Turing machine presented later in this chapter, there will be a separate control alphabet, as for the Hopcroft-Ullman interpretation. However, due to the reasons presented in this section, that alphabet will be part of the alphabet <RT·math>Σ</RT·math> rather than distinct from it. Programmers then must explicitly design communication protocols that suit the problem they are working on, and those protocols become opaque for examination by a higher authority.</p>
+ <p>For the modified computational Turing machine presented later in this chapter, there will be a separate control alphabet, as for the Hopcroft-Ullman interpretation. However, due to the reasons presented in this section, that alphabet will be part of the alphabet <RT·math>Σ</RT·math> rather than distinct from it. Programmers then must explicitly design communication protocols that suit the problems they are working on, and those protocols become opaque for examination by a higher authority.</p>
- <h2>The <RT·code>unspecified</RT·code></h2>
+ <h2>The <RT·code>unspecified</RT·code> symbol</h2>
<p>In the first edition of this book, I introduced a "no read until after write" rule while working towards an architectural Turing Machine so as to sideline the empty symbol, because real machines do not have them. This did not replace the need for a communication protocol for sending messages between machines, but it did make it possible to remove the empty symbol from programmed controller definitions.</p>
<p>Core memory, and later system memory, was random access and initially fully accessible. The data would be whatever scrambled mess the machine booted with, or in early virtual memory systems, whatever was left over from the prior use of the page. The approach of recycling pages was a security hazard, so today a page is initially allocated from a read-only zero page, and due to a copy-on-write trap, a new page will be created in memory then scrubbed with zeros. If the computational Turing Machine's empty symbol maps to a word of zeros, then the empty symbol remains a poor model, because generally the data message, say sent between the <em>input</em> writer and the <em>recognizer</em> receiver, will also contain many zeros. The advantage is that if a programmer attempts to dereference a zero pointer, a segmentation fault occurs. So in this system, the program is again burdened with maintaining the "no read until after a write" rule.</p>
- <p>A violation of "read only after a write" could be detected by a modified computation theoretic Turing Machine if, instead of an empty symbol, the initial tape is filled with the <RT·code>unspecified</RT·code> symbol. The end objective is to detect an erroneous condition, which is useful for debugging and testing. Normally, Turing Machine design does not concern itself with those design steps, as it is busy answering questions about known working programs. Though perhaps an algorithm could be studied for this very quality of not ever making decisions based on unspecified data. Nor do real machines have an <RT·code>unspecified</RT·code> symbol; rather, a program reads garbage from memory locations with unspecified data. However, there is some precedent with hardware simulators, which typically support an <RT·code>x</RT·code> standing for an 'unknown' logic value.</p>
+ <p>A violation of "read only after a write" could be detected by a modified computation theoretic Turing Machine if, instead of an empty symbol, the initial tape is filled with the <RT·code>unspecified</RT·code> symbol. The end objective is to detect an erroneous condition, which is useful for debugging and testing. Conventionally, mathematicians do not concern themselves with the test and debug phases of programming a Turing Machine, but rather concern themselves with answering computation theoretic questions about known working Turing Machine programs. Though perhaps an algorithm could be studied for this very quality of not ever making decisions based on unspecified data. Nor do real machines have an <RT·code>unspecified</RT·code> symbol; rather, a program reads garbage from memory locations with unspecified data. There is precedent for an <RT·code>x</RT·code>, <em>unknown</em>, logic state in hardware simulators.</p>
<p>Like the <RT·code>empty</RT·code> symbol, <RT·code>unspecified</RT·code> is a meta-symbol. It describes the data, or lack thereof, rather than being the data. Specifically, the <RT·code>unspecified</RT·code> symbol says that there is a singular alphabet symbol at the memory location, but the machine is not being instructed as to which symbol it is. Because the Turing Machine state transition function requires a specific symbol value, reading an <RT·code>unspecified</RT·code> symbol would break the machine. Of course, that would be a bad thing, so some sort of modification to the Turing Machine definition is required for working with an <RT·code>unspecified</RT·code> symbol.</p>
- <p>The three reasons that data can be unspecified are that it was not initialized, that the history that led up to it is unknown by the program doing the read, or that it was written from the output of a true random number generator. Technically, the output of a pseudo-random number generator belongs in the 'unknown history' category. An example of purposefully ignoring history would be a program that reverses a string without looking at the values being reversed. A string reverse function need not be apprised of the value of the string being reversed; it need only be aware of the structure given to it according to the protocol followed by the machine that wrote the string.</p>
+ <p>The three reasons that data can be unspecified are that it was not initialized, that the history that led up to it is unknown or ignored by the program doing the read, or that it was written from the output of a true random number generator. Technically, the output of a pseudo-random number generator belongs in the 'unknown or ignored history' category.</p>
- <p>Given the conventional Turing Machine definition, it is impossible to write a string reverse function that does not look at the value of the data being reversed. This is because reading the value under the head is integrated into the machine definition, so it always happens, and it always gates the next state transition function.</p>
+ <p>An example of purposefully ignoring history would be a program that reverses a string without looking at the values being reversed. A string reverse function need not be apprised of the value of the string being reversed; it need only be aware of the structure given to it according to the protocol followed by the machine that wrote the string. However, given the conventional Turing Machine definition, it is impossible to write a string reverse function that does not look at the value of the data being reversed. This is because reading the value under the head is integrated into the machine definition, so it always happens, and it always gates the next state transition function.</p>
<h2>The TTCA computation theoretic Turing Machine</h2>
- <p>A goal of the computation theorist in defining a Turing Machine is to make the math concise and elegant. This notation qualifies. However, the goal of the computer architect is to define a machine that is intuitive to design and test, and that performs well. Perhaps if a computer architect were to define the computational Turing Machine, this change in emphasis would favor a different definition.</p>
+ <p>A goal of the computation theorist in defining a Turing Machine is to make the math concise and elegant. However, the goal of the computer architect is to define a machine that is intuitive to design and test, and that performs well. Perhaps if a computer architect were to define the computation theoretic Turing Machine, this change in emphasis would favor a different definition.</p>
<p>The following modifications will be made to the computation theoretic Turing Machine definition so as to support the <RT·code>unspecified</RT·code> symbol.</p>
<ol>
<li>Move to a Moore style programmed state controller, so that actions can be managed separately from state transitions.</li>
- <li>Among the new explicit actions, have two read instructions—a state transition gating symbol read, and a data symbol read—along with two variables to hold the read results.</li>
- <li>To match the two read functions, the write function can specify which of the read buffer contents to put on the tape.</li>
- <li>If the <RT·code>unspecified</RT·code> symbol is read into a register, the machine transitions to the predefined unspecified-decision state rather than failing.</li>
+ <li>Among the new explicit actions, have two read instructions: a state transition gating symbol read, and a data symbol read, while targeting dedicated registers.</li>
+ <li>To match the two read functions, the write function can specify to write a constant symbol, or the contents of one of the read registers.</li>
+ <li>If the <RT·code>unspecified</RT·code> symbol is read into the state transition gating register, the machine transitions to the predefined <RT·code>unspecified_decision</RT·code> state.</li>
</ol>
- <p>For ease of programming, the new machine will have three layers of next-state functions. First used is the state function that takes into account both the current state and the control read value. If no next state is defined by it, then a second next-state function is called; in this case, the current state is not an operand. This is for defining default arcs. If a next state is still not defined, then we move to a third next-state function which is unconditional. This is the state the machine goes to if there is no next state specified and there is no default next state defined.</p>
+ <p>For ease of programming, the new machine will have three layers of next-state functions. The first one takes into account both the current state and the gate register value. If there is no match for the state and gate register value, then a second next-state function is called; in this case, the current state is not an operand. This is for defining default next state transitions. If a next state is still not defined, the machine moves to a third next-state function which is unconditional. Hence, this is the state the machine goes to if there is no next state specified and there is no default next state defined.</p>
<p>For clarity of presentation, the definition will be split into two parts: that which is fixed as part of the Turing Machine definition, and that which is programmable.</p>