From: Thomas Walker Lynch
-
- A
- Put more formally, given a set of instantiable objects and a collection of instances made from them, for these objects to be symbols, two conditions must be met. First, it must be possible to define an instance comparison operation, denoted
- It follows from this definition that the distinct equivalence classes can be used as a proxy for the instantiable objects themselves. That is, a person can name either the instantiable object or the equivalence class, and then through this correspondence, find the other. -
- -
- In the context of real machines, the symbol itself can be defined as a factory that produces symbol instances. A new symbol instance of the given symbol is then made, say, by calling the factory's
- A
- Any two symbol instances returned directly from two distinct factories will always evaluate to
- Given an original, all copies
- Given any two originals, say A and B, it is established that A is not equal to B, as discussed above. Note also that A is not equal to any copy stemming from B, and B is not equal to any copy stemming from A. -
- -- Though symbol instances are integer like in that copy and equality comparison operations can be used with them, symbol instances are disallowed from being used with other integer operators. Symbols cannot be compared for greater than or less than; they cannot be incremented, added, nor subtracted, etc. -
- -- Within a process, a reference to the factory can be used as a symbol instance, which will cause the factory to become trivial. Making a new instance will merely require copying the factory reference, and there will be nothing in memory that the base factory reference is pointing to. -
- -
- In general, memory addresses are built in symbol instances, hence within the context of a single process run, a program can make use of these symbols. However, this diminishes the size of the address space and leaves the memory at those addresses unused. A common hedge is then to use references into a dictionary, where the data looked up in the dictionary is the
- Such symbol names are non structural strings, so they do not need to follow the rules of symbols. For example, a program written where references to strings were used as symbol instances, could give multiple, or all, strings the same name, and the program would function. Conventionally, the names are made to be distinct so as to avoid confusion. The hazard here is that a programmer will then conflate the string name with the symbol instance, and perform symbol operations with it. -
- -
- An alternative implementation is to have the factory return an integer value. Each factory has a base integer that is distinct from that of other factories. Calling
- As another alternative, each factory can be given a base string, and then
- At the time of this writing many machines use 64 bit words. This is equivalent to 8 ASCII characters, while the average size of an identifier is about 5 characters. Hence the approach of using a string as a symbol might not be as inefficient as it seems to be at first. Using strings has advantages. Symbol instances can carry semantic clues for the programmer. There is no hazard of conflating the string instance with the name, as they are the same. Also, a string instance will have integrity across contexts, such as between invocations or when passed between processes (note the section below on crossing context boundaries). A drawback is in cases there is no language support, the strings are typically ad hoc so the guarantee of distinctness becomes merely a contract with the programmer. -
- -- If a symbol persists across contexts (such as across scopes or processes), it must remain distinct from all other symbols in its new context. -
- -- One way to meet this requirement is to find a scope encompassing both contexts and to place the symbol factory there. Another solution is to give each context a distinct root symbol and to use an array of symbols in place of the imported symbol. Yet another approach is to associate an imported symbol with a new symbol in the given new context using a correspondence map. -
- -
- When utilizing memory addresses as symbols in a virtual memory environment, the convention is to disallow addresses in one process from being used in another. If that isolation is insufficient, it is often adequate to use indexes instead of addresses, taking the address to the base of the data structure. Though the absolute address of the data structure might differ across contexts, the relative offset remains constant. Another approach is to reserve memory address blocks and to guarantee imported pages have the exact same addresses as before, though they might be imported sequentially to reuse the memory block. In architecture, this is generally known as the
- Copying symbol instances is an integral part of the operation of the Turing machine. Typically the programmed control steps are used as a cost metric for running a program. Such steps integrate operations of copying symbols to and from the tape. Thus from a pure step count perspective the cost of the symbol copy is inconsequential, not due to any behavior of a symbol copy, but rather due the symbol copy being subsumed within the definition of the step.
-- However, this is feels unsatisfactory. Here we are tying to build a bridge from computation theory to architecture, and thus we want a step to be a constant time occurrence at least in the average, or at least approximately. To model the symbol copy time, a symbol could be copied a tranche of bits per step, thus giving the copy a step count. Then, if symbols were to grow in tranche count as a program ran longer, then symbol copy of ever longer symbols would be computationally consequential. -
- -- Fortunately, the Turing Machine is defined with a finite alphabet and a couple of additional symbols. As these are part of the machine definition, and thus do not change at run time, there is no growth in size, and the time to copy them is inconsequential. -
- -- On a real machine, the factory would be used to make the data alphabet and a couple of additional symbols. As these are set up before the machine runs, and thus before we count steps, these actions are computationally inconsequential. -
- -- An alphabet is another name for 'a set of symbols'. Because it is simply a set, an infinite number of distinct alphabets can exist, and a set of symbols could be finite or infinite.
- -For a Turing machine there are a fixed number of alphabets that are all finite. The set of data symbols, control symbols, and controller state name symbols, are all finite and set in advance. -
- -
- The
- The
- A
A
A
Any programming object that holds other objects is a container, whereas a dictionary is a specific type of key access container.
- -
- A
- A
- The value of a neighbor property is a non-null single reference to a cell. The value of a data property is strictly an instance of an alphabet symbol, or alternatively, an instance of the empty symbol. -
- -- A tape is a set containing exactly one leftmost cell and an infinite number of interstitial cells. For each cell in the set, called cell A, if cell A has a right neighbor that is cell B, then cell B's left neighbor is cell A. Similarly, if cell A has a left neighbor of cell B, then cell B's right neighbor is cell A. Furthermore, any cell in the set must be reachable by traversing right neighbors starting from the leftmost cell, in a finite number of steps. -
- -- To say that a tape is infinite, and to simultaneously require that any cell can be reached in a finite number of steps, means that after reaching said cell, there will always be further cells to the right. Consequently, though any cell can be reached in finite hops starting at the leftmost cell, a finite traversal of the tape can not visit all of the cells. This seeming contradiction is at the very heart of the definition of the countable infinity in mathematics. -
- -
- In conventional computation theory, once a tape is defined, the cell neighbor properties values are fixed. Cells don't move, new cells cannot be added, and cells existing on the tape cannot be removed. This fits the definition of a
- Nor can a cell data property be removed; however, unlike for cell neighbor property values, the cell data property value can be changed while the Turing Machine is running. In fact some people would say this is the whole point of running a Turing Machine. -
- -- An empty tape is filled with empty symbols. However, as we noted above, a Turing Machine cannot visit all the cells on a tape, so a Turing Machine cannot erase a tape in advance for another Turing Machine to use. Say a Turing Machine tried to erase a tape by writing the empty symbol, then stepping right, then repeating. At some point it must halt. When it halts some number of cells will have been written with the empty symbols, but there will be further cells to the right of the cell the machine halted at, which have not yet been erased. So for example, if a machine wrote 10 cells with the empty symbol, then it might be the case that the prior user of the tape had written data to 11 of the cells. Without historical knowledge the eraser machine can not know where to stop. So here we see another meaning of infinity, it speaks to the situation of not having historical knowledge. And thus, we are left to decree into existence an empty tape, or as the mathematicians say, empty tapes are available by definition. -
- -- The tape is intentionally defined in such a manner that there is no meaning to 'in between' two cells. The head of the machine is always on exactly one cell, with the option of stepping to neighbor cells. Taking a step is an atomic operation; there is no meaning to 'during the step'. Turing Machines are state machines controlled by a clock. A person only asks questions of them when the machine is in a defined state. -
- -- Mathematically, a Turing Machine tape can be expressed as a path graph. However, a tape model and a path graph model imply different ontological contexts. The neighbor property of a Turing Machine tape cell specifically informs a clock driven atomic step function where to place the machine head next. The machine only has defined meaning at the state points on the programmed controller. In contrast, a path graph exists in the wider context of graph theory. A path graph has edges and each edge can be focused on, said to be traversed over, and given general properties. These are things we explicitly excluded in the tape definition. If we were to move the tape from the context of the machine and into the more abstract mathematical context by modeling the tape with a path graph, then we would do so for the purpose of analyzing the tape, which is a higher order and more abstract activity. However, in the current exercise we are not reaching towards the more abstract; rather, we are reaching in the other direction, towards machine architecture. -
- -
- The tape head consists of a reference to exactly one of the tape cells and a set of four functions:
- A person can also say that the head indexes the head cell. This utilizes the classical mechanical definition, where an index is a mark for aligning gears. This physical meaning contrasts with an index integer used for addressing an array. The architectural definition of the Turing Machine developed here relies strictly upon the topological properties of the tape, independent of the definition of Natural Numbers. Addresses, which do rely on Natural Numbers, are discussed further on in this volume. This represents a minor divergence from Alan Turing's original paper, as he took it as a given that numbers naturally paired with the squares. We explicitly establish that pairing only after deriving Natural Numbers using the Turing Machine itself. -
- - - -The customer programmed portion of the programmed control consists of:
-A programmer uses a Natural Number to reference a state. Hence the initial state reference and halt state reference are set to Natural Numbers. It is not required but it is conventional to use 0 as the initial state.
- -A next state specifier is a pair consisting of an identifer to be matched as a first of the pair, and a next symbol reference as a next component, where each identifier has the form:
- -As multiple TTUs can be plugged in, an identifier starts with a TTU id. There are two buffers that on the TTU interface that interface can read,
The default next state list is a list of next state specifier. This list is checked first, i.e. has precedence, over the state dictionary next state list
- -Each entry in the state dictionary consists of one TTU command, followed by a next state list.
- -The TTU command set consists of:
-Note that the write value, x must be a symbol from either the data alphabet or be the empty symbol.
- -The structural portion of the programmed controller:
-The comparators are used to used to match the identifier with a the values read from each of the buffers. Note that if the same next state is specified for the same start state, then it is the same as though the identifiers are in disjunction. Also the no-op command to create conjunctive decisions. Hence as a shorthand notation arcs can be labeled with propositions made from the buffer values.
- -Upon reset the current state register is written with the initial state. When the current state register is set to the halt state, the machine stops. If no next state is found for a given state, the error state is written to the current_state_register and the machine halts.
- -On the rising edge of the clock, the TTU writes the data and status buffers, and the state command is written to the TTU command buffer. On the falling edge of the clock, the TTU completes the state command, and the next state is written to the current state register.
- -Here is an example customer defined programmed controller for incrementing a unary number:
- -- The distinct empty symbol can be any symbol that is excluded from the alphabet. Only instances of alphabet symbols or the empty symbol are permitted to be written to the tape. -
- -- Intuitively, a person might consider that the alphabet symbols are useful while the empty symbol is merely taking up space while waiting to be displaced, in the same manner that a person considers a bookshelf to be empty rather than being full of air. (And if a person puts a bookshelf underwater, is it still empty, or is it full of water?). -
- -- If a physical machine receives power without the reset signal being held, it can land in an illegal state. This is hazardous as the machine might become permanently stuck in a configuration that ignores subsequent reset commands, it might operate unpredictably, or it might even suffer physical hardware damage. To avoid these outcomes, systems are designed to hold the reset line active while the power comes up. Asserting the reset signal, rather than recycling power, is what actually causes a machine to land in a known initial state. Consequently, we must include a reset feature. -
- -- This design assumes that when reset is released, that the machine immediately starts running. This is fine for our purposes, but surely the deluxe model would have a separate 'go' button and the associated logic. -
- -- The tape transport unit, TTU, handles mounting, unmounting, reading, writing, and moving, the tape. In this volume we will talk about stepping the head. This should be interpreted in a relative sense, as a real TTU will move the tape rather than the head. Our machine is designed such that the customer can plug in more than one TTU unit. Each unit has its own read buffer, status buffer, and head. A tape can be mounted or unmounted from each unit. At the election of the operator, the tape can be unmounted from one TTU, shelved perhaps, then unshelved and mounted back on the any TTU, the same one, a different one on the same machine, or a TTU on another machine. -
- -- The constant executor should not be conflated with the Turing Machine program. For a microcode controlled machine, the procedure will be found in microcode memory, and it will be executed as though a program. Each line of the procedure, when read, results in a set of bits being connected to the machine's control lines. Some of those control lines will control what the procedure does, and some will extend out into the data path and be used to configure execution units and gate data on to busses. -
- -
- For a hardwired machine, the operation program will be expressed with logic gates and flip flops (single bit memory registers). Whether a machine is microcode controlled, or hardware controlled is a question of
- The Turing Machine architecture specifies an infinite tape, which can neither be implemented, nor realized. We will introduce a computationally inconsequential modification in a later chapter that causes the tape to be finite. -
- - -The immutable structural components:
-The fixed logic internal to the machine:
-Accessories:
-Each highlighted term is a short name for the associated item.
- - - -- The following procedure is embodied as further control logic in the Turing Machine. This procedure is fired upon receiving a step pulse. At the time the procedure is entered, the head is stable upon a cell. We list phases so as to avoid any apparent race conditions. This does not dictate to the designers that the clock must have phases, though that isn't excluded either. -
- -Deterministic (Uniplex) programmed control procedure
- -Upon each step pulse:
- -Phase 1:
-Phase 2:
-Phase 3:
-Phase 4:
-
- The
- In addition, encoding a machine's control logic as parseable data on tape establishes an ontology of analysis, a framework where a machine can analyze another machine to establish some properties the other machine might have. We say 'some' because at least one limitation has been proven. Alan Turing proved that such an analyst cannot in general determine if said other machine has the property that it would halt for any input when run. -
- -
- We can optimize this representation. Instead of storing the state tables verbatim, we can list a sequence of instructions directly on the tape. To achieve this, the architecture expands to support two distinct categories of instructions: the physical tape transport instructions we defined previously, and a newly introduced category of
- Because the original state tables allowed for non linear execution paths, the instruction sequence on the tape cannot always execute in a straight line. Therefore, the architect must include at least two control instructions: a halt instruction and a test and branch instruction. The sequencer starts at the first instruction in the program, perhaps at the leftmost cell on the tape, and evaluates it. If it is a control instruction, the sequencer acts upon it directly to alter the flow of execution or stop the machine. Otherwise, if it is a physical instruction for the head unit, the sequencer passes it down to the tape transport. -
- -- Because we have not yet derived Natural Numbers or memory addresses in this architecture, a test and branch instruction cannot jump to a numerical address. Instead, it must operate topologically. A topological branch instruction simply commands the sequencer to scan the tape for a specific target symbol, and resume executing instructions from that physical location. -
- -- As noted in the prior section, an instruction consists of an instruction code and potentially an argument. There are many choices that can be made in instruction set design. Among those choices, almost all will be inconsequential from a computation theoretic point of view, but almost all will introduce strict efficiency trade offs in physical hardware. -
- - -- In the prior two sections we discussed the configurable part of the Turing Machine control. Here we complete the picture by describing the fixed portion. -
- -Setup
-Reset
-Main:
-- A person can read this procedure with the caveat, "if we could realize such a machine, this is what we would do." Later, these directions can be modified and applied to the machine variation that has an expanding tape. -
- -- To start the machine we must first select a tape. Common choices are an empty tape, a tape with data on it the machine is to decide matches a given language pattern, or a tape with a Turing Machine on it to be analyzed. After the tape is selected it is mounted on the Turing Machine, then the reset button is hit. -
- -- After the reset button is released, the machine begins stepping. If the program is a computation, the machine will eventually halt. If the machine eventually halts, then we know the associated program was a computation. Otherwise we do not know. Any amount of time we wait where the machine has not halted, we will not know that it will ever halt. Hence, we cannot in general use 'running a Turing Machine' as a means to determine if a given program is computational. (We could instead try to answer the question 'is it computational' through analysis, but there too, Turing has shown that in general that will not work either.) -
- -- In common books and papers about the Turing Machine, a step is defined as one step of the programmed controller, i.e. one pass through the four phase procedure given above. Decider proofs ask if the comparator will match the halt state within a finite number of steps. Time complexity proofs take a formulation of step count to reach the halt state, parameterized against the size of the input, and report the order of the highest term as it is asymptotically dominant. Hence we speak of constant, linear, polynomial, and exponential time complexity algorithms. A similar method of analysis, that of memory usage with step count, parameterized against input size, is used for space complexity. -
- -
- For a real machine, the step pulse will be derived from the machine clock. The clock will have a constant period, so there is a constant duration of time that will be the same for each pass through the execution procedure. Thus, if we replace the step count with a count of clock ticks, we will get the same decider and complexity results as we would have from step counts. This fits the definition we have been using for
- Given that we have an architectural definition for a Turing Machine, and will modify this in a later chapter to define a realizable Turing Complete architecture, it is possible to invert the foundation of mathematics. Instead of mathematics preceding computation, we posit that given a Turing Machine exists, all of mathematics is an interpretation of what can be done with it. -
- -- We begin by defining the tape cell as a location in a physical memory, which provides us with arrays of charge configurations. -
- -- We then define the symbol in computational terms, as done in the prior section. This begins with memory addresses, represented as charge arrays, acting as primitive symbols, and extends to the symbol factory, copy operations, and instance comparison. -
- -- Logic is then defined on top of relay switch logic, as Shannon and others have already done. A machine that requires all inputs to be the '1' symbol to produce a '1' symbol output is a conjunction machine, and so forth. -
- -- On top of this we can define the Peano Machine, a counter, and then use that machine as the definition of Natural Numbers. -
- -- Where Gödel reduced logic to natural numbers, we go the other direction to expand upon logic from natural numbers. -
- -- An axiomatic proof is then a decider that is built up from subroutine calls to the axioms. We might then quantify over all possible compositions of our subroutines in analysis and ask if it is possible that a contradiction decider would return Y or N. -
- -- Frege's set theory is then the analysis of a logic program against an enumeration of inputs to choose if a proposed symbol is in a set. Perhaps executing such a program is left to first order analysis, or perhaps execution is not practical, and evaluation is left to second order analysis. -
- -- Russell's Paradox will then be expressed as a Turing Machine that can be analyzed in the second order, but cannot be analyzed in the first order. That is, the paradox exists merely in the first order as it will never halt when run. However, it is not a paradox in the second order. It is, of course, through second order analysis that we are able to describe why Russell's Set description does not resolve in the first order. -
- -- With the language of Computational Naturalism it is possible to restate every statement ever made by any mathematician; we might say that the mere fact that a mathematician was able to state something qualifies its membership into Zermelo's S set. -
- -- Given our knowledge that a universal halting problem analyzer that decides if a Turing Machine program halts does not exist, it is desirable to have rules that guide our writing only Turing Machine programs that are known to halt. This can be done through construction, as proposed by Russell, or through axioms of separation, mapping, and choice, as proposed by Zermelo and others. But then we know from the completeness and correctness theorems, that when such guiding rules are applied, there will exist Turing Machine programs that do halt, but whose definition cannot be constructed, nor surmised using the said axioms. -
- -- This brings us back to the reference from the Zermelo discussion in the introduction. Specifically, the question posed is if our finding through second order analysis that Russell's paradoxical set formulation will not run in the first order and define a set, does this mean that we are merely using S to state that we are tossing out sets that cannot be defined? The answer is it is not quite this simple. Had Frege said, 'we merely dismiss such sets', we would not have the formalization for the second order analysis. Throwing out Russell's paradox simply because we ran it and it never halted is not a practical approach. Instead, we omit it specifically from S because analyzing R reveals that it fails to define a first order halting machine, and S, by definition, only holds first order halting machines. Zermelo's language is precise and formal. However, it is this bothersome nuance, now articulated here, which caused us to scratch our heads when reading Zermelo the first time. -
- -- Russell's set formulation, R, can be analyzed to determine that it would not halt if it were run. We still keep it as a second order object, and have even given it a name, R. However, this begs the question, are there machines that cannot even be analyzed in the second order to ascertain if they would return a result in first order analysis, i.e., when they are run? If Gödel has a say here, a person would wager that such machines exist. But then, is there an option for analysis in the third order? Is Turing's halting proof a third order analysis as it reasons about running the second order analyzer? Or is it merely a recursive application of second order analysis? -
- - -
- In mathematics,
- In computation theory,
- This analytical perspective has been present from the very beginning of the field. Alan Turing's formulation of the halting problem relies explicitly on one machine examining another. To properly evaluate the limits of this analytical capacity, the examining machine must necessarily be given definitions of programs that loop infinitely. Consequently, the foundational proofs of computer science formally establish non computational programs as legitimate objects of analytical study. -
- -
- We call a program that examines another program so as to deduce properties of its results an
- Turing Machines that halt in a finite number of steps for any finite input within a stipulated domain are said to be
- By definition, first order analysis is the running of programs, and it has its place. - Generally, when we want to know what output a computational machine will produce, the fastest route to this knowledge is to run the program. Most programs written to solve problems are most effectively run to solve those problems rather than analyzed to deduce what they will produce. -
- -- Now suppose we quantify the inputs to a computational machine over a domain and want to know a property of the machine. Perhaps, say, that it always produces an even number. If the quantification is over a large set, then it might be faster to study the machine than it would be to run the machine on every input in the domain while checking its output. -
- -
- Further suppose that the quantification is over an infinite input space. Then the only option for answering a question about the properties of results from such a machine is to analyze it. This is second order analysis, also called simply
- Famously, we know that universally an analyzer cannot determine if a machine is computational. This knowledge was derived by reasoning about the properties of a hypothetically existing analyzer machine. This is a third order analysis activity. -
- -
- As an analyzer does not run the machine being studied, it is not required to be a machine that halts. Suppose we have a machine that produces an infinite sequence of digits to a tape without halting. A limit analyzer could examine that machine and, in some cases, determine if it has asymptotic behavior. For example, recognizing that appending a binary fractional sequence of
- In their 1990 paper, "Exact Real Arithmetic: Formulating Real Numbers as Functions," Hans-Juergen Boehm and Robert Cartwright presented a system using Turing Machines to represent 'constructive real numbers', or exact real arithmetic. This directly implements a core concept from Alan Turing's 1936 paper of the "computable number."
- Let us employ Boehm and Cartwright's constructive real numbers, though in
- Consider an illustrative example. We start by defining a fundamental language for communicating with the head and tape transport unit. The statements we communicate to our tape transport unit will be explicit physical commands:
- Suppose our goal is to subtract 3 from 5 in the second order. Consider a Turing Machine representation named
Similarly, the AST for the number 3:
- -- If we were to dynamically evaluate these ASTs in the first order, the Arabic representation of each number would be physically written in unary code on the tape. -
- -
- For the second order difference operation, we compose the ASTs to create a new program. Here we extract the body of the second operand's AST and substitute every
We pass our two natural number ASTs to this composer, and we get as a result a newly synthesized AST.
- -- I called this 'primitive' because it is missing the simplification. This sort of simplification is also known as compiler code optimization. Optimizations can be operation specific, or general in nature. Here we will send the primitive composition's body to an analyzer which scans the steps and removes the redundant operations. -
- -
- Because of the purity of the Lisp syntax, we are able to present a remedial simplifier example here. A
- For a program containing branched control logic, the simplifier would require a deep recursive walk of the AST to ensure operations aren't annihilated across conditional boundaries. For our explicit natural number generators, a linear scan of the
After giving the difference program to the simplifier, we get:
- -This technique of composing Turing Machine programs in the presence of simplification is closely related to that of symbol computation and expression simplification that we find in math tools such as Mathematica. We can imagine our Turing Machines as functions with names, and then symbolic computation leaves them unevaluated as here. Then the Mathematica
- Generally it is more efficient to perform arithmetic in the first order. Also, it is easier to write Turing Machine control programs if we take Natural Number arithmetic as already available, say, from a subroutine library. On processors fixed word length arithmetic is built into the hardware. Where second order computation becomes useful is in places where a result cannot be computed in the first order. -
- -- The IEEE 754 floating point standard includes error algebra tags. These are explored in depth by Popova, Evgenija D. "On a Formally Correct Implementation of IEEE Computer Arithmetic." Journal of Universal Computer Science 1, no. 7 (1995): 560 569. This is a form of second order arithmetic, because each of the error tags is standing in for a machine that did not complete. When a computation fails to result in a first order object, this becomes a gateway for replacing the result with a second order object. -
- -- Let us take the multiplicative inverse of the additive identity as an example, AKA division by zero. In the second order, when we divide, say 6/0, the machine will not reduce. It will return a second order value: -
- -Now consider the compiler optimization like simplification of this expression:
- -The result will be:
- -
- There is no special help here. Hence,
- The divide machine cannot be run to produce a value, as any value from the field assigned to it would lead to contradictions. Stated more precisely, for
- When a machine is 1) programmed to perform a function
- When an evaluator erases the input and leaves only the result in its place, we say it is a substitution evaluator. It is an inconsequential modification to add multiple tapes each with their own tape head to a Turing Machine, so it is possible that an evaluator will have a dedicated tape for the input, a dedicated tape for the output, and have zero or more additional tapes for scratch work. In which case, instead of substitution, one tape is mounted as an input, the machine is run until it halts, and then separately the result tape can be unmounted to potentially be used in a downstream computation. -
- -
- In a variation of analytical evaluation, we can instead mount an initial value for a function, and call a machine to repeatedly
- The difference between adjacent function values in the above sequence is called the first finite difference. The forward first difference is defined as:
-
- A second difference can be defined as the difference between two adjacent first differences. A second difference can be added to a prior first difference to create the next first difference, which could then be added to a prior function value to extend the function to its next value. This pattern can be extended to any number of levels. -
- -- The mechanical application of finite differences was famously leveraged by Charles Babbage in the design of his Difference Engine. By examining the discrete changes between consecutive outputs of a polynomial function, a person can observe that the higher order differences eventually reduce to a constant. This structure allows the computation of subsequent sequential values using only addition, bypassing the need for complex multiplication machinery. -
- -
- Let us construct a forward difference pyramid for the polynomial
| Count ( |
- 1st Diff ( |
- 2nd Diff ( |
- |
|---|---|---|---|
| 0 | -0 | -1 | -2 | -
| 1 | -1 | -3 | -2 | -
| 2 | -4 | -5 | -2 | -
| 3 | -9 | -7 | -- |
| 4 | -16 | -- | - |
- In order to design for indefinite extension, the Turing Machine tape must retain the function value alongside with its forward differences. Because the second difference is constant higher order differences are all zero. Hence the tape requires a three component vector to hold the differences. -
- -
- Here is the sequence of tape states as the machine is repeatedly called to extend the function from its initial conditions at
- For Call 1, the input tape is the Initial Tape. In Call 1 the machine will take the function value on the input tape, 0, and add the first difference, 1, writing the result 1, to the result tape. The machine will then continue on and take the first difference on the input tape, 1, and add the second difference on the input tape, 2, writing the result first difference to the result tape, 3. Then finishing up, the machine will not find a third difference on the input tape, so it will copy the second difference found on the input tape as the second difference for the result tape. -
- -
- For Call 2, the input tape is the result tape from Call 1. Execution then proceeds identically to Call 1. This pattern repeats for all successive calls. A person can see the values of
- The extension function can be called any number of times when the initial tape is identical to row 0 of the table of finite differences. No other row is needed from the table of finite differences. -
- -- This follows from the mechanical procedure given above for computing the next row of the table from any given row. -
- -
- Let the
- To make this precise, let us define the
- Thus, this lemma claims that to compute
- Note that to compute the
- For an arbitrary
- There is a strict linear progression here. The computation of any component
- The exact algebraic composition of this mechanical expansion is formalized by Newton's calculus of finite differences
-
- Because the binomial coefficient
-
- As a consequence of this lemma, we know that for any finite number of calls, i.e. finite
- A polynomial of degree
- Taking successive finite differences reduces the degree of the polynomial by exactly one at each step. Consequently, the
- If an initial difference vector
- Consider an extent of
- When a person extends the extent to
- Extending to
- Continuing to
- Once
- To observe the structural integrity of this progression, a person can array these relationships into a system of equations mapping the initial tape to the polynomial constants: -
- -| Difference | -Equation | -
|---|---|
- A pattern emerges. Because each successive forward difference operator annihilates the lowest power of
- To observe the formal mechanics of this progression, a person can alternatively array these relationships into a matrix equation mapping the polynomial constants,
- For any extent
- The main diagonal contains strictly non zero factorials, ensuring the matrix is invertible. By inverting this matrix, a person replaces the cascading back substitution with a direct, closed form equation to recover any constant
-
- Thus, extending this procedure
- This mechanical recovery of standard polynomial constants is completely analogous to Newton's interpolation formula
-
- Because the
- Here is the table of finite differences for the function
| Count ( |
- 1st Diff ( |
- 2nd Diff ( |
- 3rd Diff ( |
- |
|---|---|---|---|---|
| 0 | -1 | -1 | -1 | -1 | -
| 1 | -2 | -2 | -2 | -2 | -
| 2 | -4 | -4 | -4 | -- |
| 3 | -8 | -8 | -- | - |
| 4 | -16 | -- | - | - |
- The first difference of
- Instead of attempting to write an infinite sequence to a physical tape, a person can encapsulate the generation logic within a dedicated Turing Machine. In the tradition of constructive arithmetic associated with Boehm, this generator machine acts as a virtual tape. When the primary extension machine requires the next difference component, it queries the generator machine, which computes and yields the value on demand. This lazy evaluation strategy elegantly handles functions with infinite difference sequences without exhausting finite memory. -
- -If we desire to compose recurrence functions, in the first order or the second order, the call counts must first be synchronized.
- -Say for example, we have a machine called fizz that adds 3 to the input on the tape, and another machine called buzz that adds 5 to the input on the tape, and we wanted to compose the two machines. We would have to define what a call to the resultant machine means to the machines in composition.
- -If one call to the resultant machine makes the equivalent of one call to the fizz, and one to buzz, the the resultant machine can be simplified to add 8 to its input tape each time it is called. In contrast if one call to the resultant machine makes the equivalent of 5 calls to fizz, and 3 calls to buzz, then the resultant machine reduces to adding 30 to the input tape per call. The two machines are very different.
- -Performing operations with recurrence functions requires integrating a call algebra in addition to integrating the machines. Often this is handled by considering the machines being composed to be subroutines, and the outer controller than explicitly calls them. The call algebra can then be dynamic depending on the input. Calls can be skipped due to being inside conditionals, or performed an arbitrary number of times in loops. Though simple control structures that are static are more math like, and are more likely to be more affected by optimizations (simplifications).
- -
- Here we circle back to the division by zero problem, though this time while extending functions. Let us begin with the two functions,
- We cannot do function based arithmetic on these until we synchronize them. Suppose that for each call of the
- Now suppose we want to express the quotient of these two functions. -
- -
-
-
-
- Evaluating this form in the first order at the point
- Suppose we move to a second order evaluation, and for places the computation does not work, we return the machine that isn't evaluating. That is similar to what we did to get
| Count ( |
- Quotient ( |
- 1st Diff Ratio ( |
- |
|---|---|---|---|
| 0 | -31/15 | -1/3 | -- |
| 1 | -30/12 | -2/3 | -- |
| 2 | -28/9 | -4/3 | -- |
| 3 | -24/6 | -8/3 | -- |
| 4 | -16/3 | -16/3 | -- |
| 5 | -32/3 | -- | |
| 6 | -32/3 | -64/3 | -- |
| 7 | -96/6 | -128/3 | -- |
| 8 | -224/9 | -256/3 | -- |
| 9 | -480/12 | -512/3 | -- |
- The quotient machine,
- I included the first difference along with the evaluation results in the table above. When building a first difference table an interesting thing happens at the singularity, the first difference and the function itself coincide, note calls 4 and 5. This makes sense because
Ostensibly it looks like we have happened upon a discrete version of L'Hôpital's rule, that we merely use the first difference quotient instead of the function quotient at the singularity. But alas, the coincidence occurs at
- Perhaps if we were performing nonstandard analysis, and extending by increments of epsilon in the domain at each step, the nonstandard analysis naturalization function would find that the differential value can be used as the value at the singularity. But here we are discussing finite differences
- So then, perhaps we set the value at the singularity to
-
-
-
- As Newton pointed out, we can know the differences on the
- For
- As the second order evaluation returned
- The L'Hôpital evaluator will discover that a transcendental constant is required. It will be returned as a higher order object, a machine definition, because the value can not be written to the tape. -
- -The resulting
-
-
-
-
- I find it fascinating to watch the transcendental difference values march down the table, then all cancel out after
- So the value of
And for the victory lap, evaluation versus higher order computation and function extension:
- -| Count ( |
- Direct Evaluation ( |
- Extended Quotient Vector ( |
-
|---|---|---|
| 0 | -31/15 | -31/15 | -
| 1 | -30/12 | -30/12 | -
| 2 | -28/9 | -28/9 | -
| 3 | -24/6 | -24/6 | -
| 4 | -16/3 | -16/3 | -
| 5 | -||
| 6 | -32/3 | -32/3 | -
| 7 | -96/6 | -96/6 | -
| 8 | -224/9 | -224/9 | -
| 9 | -480/12 | -480/12 | -
The fundamental claim of computational analysis is that all functions can be viewed as discrete entities. Take this simple function:
- -It is said to be a continuous function over the real field. However, from a computational perspective, it is a string of 8 discrete symbols. A person might ask then, "If the function is not continuous, then how can a person take a derivative?" Often people view a derivative as a tangent line to a curve drawn on a plot. The computational analyst's answer is to use a machine that manipulates the symbols; it will move the 3 down in front of the
The point of this chapter is to state that computational analysis exists, rather than to present a comprehensive computational analysis system. If a person is looking for practical systems for extending functions that expand precision, or for second order computation, there are options.
- -Hans J. Boehm and Robert Cartwright's work of expanding the precision of a computation on demand continued to mature. Boehm, while working at Google, authored a Java constructive reals library that powers the bundled Android calculator. When a person types in an expression, the system builds an Abstract Syntax Tree (AST) of the expression. The display interface determines how many digits fit on the screen and demands exactly that much precision from the root of the tree. The root function then recursively demands progressively higher precision from its operand functions until it achieves the strict error bounds required to guarantee every digit displayed on the screen is mathematically correct
Wolfram Mathematica utilizes a true second order computation system by keeping expressions in their exact symbolic form for as long as possible. An expression like
The approach I used differs from both of these approaches. Like them, the first step is to build the AST, but then the tree is evaluated in two phases. The first phase analyzes the tree, while createing error propagation expressions either per computation step or for atomic computation blocks. These take the form of symbolic expressions with error
None of these computation systems, that of Boehm and Cartwright, Mathematica, nor my error analysis approach, makes use of the IEEE 754 standard floating point arithmetic. Rather they all require the use of variable precision. In the case of Boehm and Cartwright's this occurs through the serialization implied through lazy calls for more precision. In the case of Mathematica it is explicit in the significance arithmetic. In my error analysis approach, the means for variable precision was the High Radix Online Arithmetic
Hence what would be useful for a replacement of the IEEE 754, would be variable precision number standard. There is one being proposed by John Gustafson called the Posit number representation
This section reviewed finite difference methods as a means to implement function extensions. A person should notice that finite differences are one among many methods for extending functions, and they are not always the best choice. In modern computing it is not common to implement function extensions. Rather it is more common to increment a value across a domain, while completely repeating the evaluation for each new domain value, for example when computing values to place on a plot. However, independent of their importance in applied computing, function extension and difference methods are of theoretical importance for analysis, particularly when applied to nonstandard analysis. These speak to the thesis of computational naturalism in the derivation of mathematics, rather than as a proposed method of implementing computational programs. -
- - -
- A person can define a Turing Machine that is identical to the recursive definition of Natural Numbers as given by Peano.
- In contrast, a function extension version of the Natural Number sequence generator can be run. The function extension machine would be given as input a prior function extension result, or an initial empty tape. It would then modify the tape to contain the next Natural Number, as per the sequence that the Natural Number machine would write, if it could be run. This is accomplished through two subroutine calls:
- To say that Natural Number A is smaller than Natural Number B is to say that A would occur on the Natural Number Machine tape to the left of B, if the machine were run. Conversely, if B were said to be greater than A, that would mean B occurs further to the right. It is a simple matter for a programmer to write a decider machine for this. The decider is given two input tapes for the two numbers to compare, and it keeps a head on each. It then steps forward until neither head has an 's' under it. If empty symbols are found simultaneously on both tapes, then the two numbers are equal; otherwise, the number with an empty symbol under the head is the lesser number. -
- -
- As such, a person can assign a Natural Number to each cell of a given tape by using a mechanical procedure. Given a machine, say
- The Natural Number found on
- An
- Would it be computationally consequential if binary Arabic representation were used instead of unary for addresses? For unary representation each increment was constant time, but with Arabic addresses, increments have a carry. Would the carry cause stepping to the right, combined with calling the address machine, to become slower and slower as the machine steps further and further? -
- -- For this discussion, the Arabic representation address is variable precision, so it will grow as the count becomes larger. The empty symbol will serve as the terminator. -
- -
- For
Here
The loop form here is worth taking note of, as it will come up again. The controller executes a first action, that of a
- Each row shows an input tape, and actions taken to write the result tape. For any given row, the result tape is the same as the input tape on the next row down. The table lists 7 increments, which is sufficient to reach the maximum count that can be held by a 3 bit counter. -
- -| input | -action | -cost (steps) | -
|---|---|---|
| 0 | -write 1, halt (result is maximum 1 bit count) | -2 | -
| 1 | -write 0, step, write 1, halt | -4 | -
| 01 | -write 1, halt (result is maximum 2 bit count) | -2 | -
| 11 | -write 0, step, write 0, step, write 1, halt | -6 | -
| 001 | -write 1, halt | -2 | -
| 101 | -write 0, step right, write 1, halt | -4 | -
| 011 | -write 1, halt (result is maximum 3 bit count) | -2 | -
| 111 | -- | - |
- The number of programmable controller state transition steps required to reach a maximum 1 bit, 2 bit, and 3 bit count are:
- For an
- To find the average cost per increment to reach each maximum, an analyst divides by the total number of increments, which is
- This simplifies algebraically to: -
- -
- As the address space grows, the bit width
- Consequently, maintaining an Arabic address on a secondary Address Machine remains a constant time operation in the amortized sense, making it computationally inconsequential to the complexity class of the base machine. However, if a problem were to increment and decrement repeatedly around a binary power count, the behavior would be the limiting logarithmic time due to the length of the counter. An unlucky situation like this is called
- The model used here to define an address is analogous to keeping a pointer into memory. Each step then increments or decrements the pointer. Conventional processors do the converse of the Turing Machine model presented here. For a processor, the address is the base object, while the head location is what is implied by the address. On processors, pointers will be one word in width. In small geometries where computation element delay dominates, two operand adders tend towards logarithmic complexity evaluation times against bit width, and the constants are small. Because of this, it is practical to perform word width addition operations atomically in one machine cycle. In fact, for some machines, the adder time likely sets the clock period. Such an adder will be used for address arithmetic; consequently, a programmer cannot arrange a program to expose aliasing in the address increment time to the real world. It remains a theoretical observation. -
- -- An address is sent on a trip through the memory hierarchy to locate the corresponding memory cell, ultimately landing on a memory decoder over a physically implemented memory. Address decoders resemble carry chains, and they also have logarithmic physical evaluation times as word width grows. Hence, a fixed width word holding an address gets decoded in approximately constant time measured in clock ticks. However, the trip through the memory hierarchy is not negligible. -
- -- Direct address decoding operates independently of reference locality. This fundamentally differs from a Turing Machine head, which incurs a linear computation cost strictly proportional to the distance traveled. However, direct decoding is only the base of the memory hierarchy. -
- -- It is possible that decoding occurs separately in a row and column manner, and changes in the lower bits of the address walk a buffered row that was found in a prior access. This makes access to neighbor cell addresses within a row a low expense operation. However, this depends on memory implementation. One layer up, it is common for memory to be made of interleaved banks, so neighbor access that remains in the leaf collection is generally faster than that which requires fetching a new leaf set. -
- -- There will, however, be a more dominant effect. For programs with islands of locality of reference, instructions or data will be discovered in a cache. Caches bring in two types of locality: that of access within a cache line, which makes neighbor walks that stay in the line fast, and cache line prefetch and replacement policies, which assume for any given fetch address that a subsequent fetch will be nearby in memory. These effects lead to similar memory behavior as a head on tape, where a single step to a neighbor is faster than taking many steps to find memory further away, but there is not a one to one correspondence. -
- -- Memory accesses into the processor local memory file are even faster. If locality of reference, even in an abstract sense, remains tight, then memory cells can be accessed in a minimal amount of time. -
- -
- For programs with large memory footprints and sparse memory access patterns, the dominant factor becomes the virtual memory subsystem. Here locality again comes into play as the translation lookaside buffer provides stateful location context, and the neighbor relationship between pages is sometimes taken into account for performance reasons. However, once a program starts performing at virtual memory page fetch times instead of cache access, or even local system memory access times, the program is said to be
- In summary then, using Arabic representation for addressing is not statistically computationally consequential. On the other hand, the idea of using a decoded address in place of a tape head raises computational model issues. So much so that it would not be an exaggeration to say that the very goal of modern computer architecture is to ensure that, within an execution context, address decode does not become computationally consequential. Architects employ a memory hierarchy to do this, and that memory hierarchy rewards locality of reference, but access times are not linear in time relative to distance from prior access. Instead they are clumped into a constant time access abstract concept of locality groups where the time to access each group grows exponentially with the distance from the processor. -
- -- Let us put this into perspective. Suppose in ancient Roman times that a clock tick for a computer was scaled to be one day long, so that the action involves sending letters rather than variable values. Under this scale, a single nanosecond of real world execution time equates to three days. Suppose a program initiated a read request for a location in memory on the Ides of March, the date when Caesar was assassinated on -0043-03-15. Surely that was a big day for posting letters. The following table provides the historical date that the variable value would finally be loaded into the processor, depending on the memory tier being accessed: -
- -| Memory Tier | -Real World Latency | -Scaled Delay | -Scaled Arrival Era | -Historical Context | -
|---|---|---|---|---|
| L1 Cache Hit | -1 ns | -3 days | --0043-03-18 | -Three days after the assassination. | -
| DRAM (Main memory) | -100 ns | -300 days | --0042-01-09 | -Nearly a year later, during the Liberators' civil war. | -
| NVMe SSD Page Swap | -15 µs | -45,000 days | -0080 | -123 years later, exactly as the Colosseum is completed in Rome. | -
| SATA SSD Page Swap | -100 µs | -300,000 days | -0778 | -821 years later, during the reign of Charlemagne and the Frankish Empire. | -
| Magnetic HDD Page Swap | -10 ms | -30,000,000 days | -82092 | -Tens of thousands of years in the future, long after current human civilizations are dust. | -
- In computer architecture, there is a rule that the slower the access time, the larger the amount of data that should be transferred. The idea is then that of access time per bit, instead of access time per fetch. A common example given is that of a station wagon of hard drives driven across the country.
- We call a subset of contiguous cells from a tape an
The left neighbor cell to the leftmost cell of a given area is considered to be the left neighbor cell to the area. Similarly, the right neighbor cell to the rightmost cell of a given area is considered to be the right neighbor cell to the area. If the given area is located at the left end of the tape, then it has no left neighbor cell. If the given area is open on the right, then it has no right neighbor cell. -
- -A
If the head is on the leftmost cell, there is no left side area.
- -- A nonempty tape, one with at least one cell holding an alphabet symbol, can be partitioned into the following areas: -
- -- A noncomputational tape is one that cannot be initialized by a Turing Machine, but can still be surmised to exist, perhaps in analysis due to its properties. The empty tape is an example. The tape holding the Natural Numbers is another example. For noncomputational tapes that have the property that the active area is open on the right, there is no right empty tail. -
- -- The existence of a finite given area implies a three area partition: the left side, the given area, and the right side. If the given area is located at the left end of the tape, there is no left side area. If the given area is open on the right, there is no right side area. -
- -
-
- The active area partition of a tape only works for tapes that have at least one alphabet cell. As soon as a machine does its first write of an alphabet symbol, it is known the tape has at least one alphabet symbol. However, what if a tape of unknown status, whether completely empty or containing an alphabet cell, is mounted on a tape machine, and it is desired that the machine recognize if the tape is empty or has an alphabet cell? This is the equivalent problem of looking for the leftmost cell of an active area. -
- -- Recognizing that a tape is empty is generally impossible. Suppose it were attempted, and a machine started scanning the tape rightward from the leftmost cell; for every cell that is discovered to be empty, the machine would have to scan further rightward to check for an alphabet cell. If the tape is truly empty, the recognizer would never stop scanning, so no decision would ever be rendered. -
- -- In general, a Turing Machine cannot step across a tape reading cells to recognize the rightmost cell of the active area, or equivalently, the leftmost cell of the right empty tail. Suppose a recognizer attempted this by starting in the active area and stepping right, and the machine discovered an empty cell. The machine would be unable to distinguish between the case of said empty cell being embedded within the active area (meaning more alphabet cells lie further to the right), or the case where said cell is genuinely the leftmost cell of the right tail. To resolve the ambiguity, the machine would be obligated to continue stepping right. Yet, there would never come a time where finding another empty cell would avoid leading back to the exact same case ambiguity, so the machine would forever step right without returning a decision. -
- -- It follows that if knowledge of the end of the active area is needed, this information must be encoded as a message. For example, a special symbol can be reserved in the alphabet specifically to serve as the end of active area marker. Each time a machine steps beyond the current end of active area marker and does a write, it writes the marker in the right neighbor cell, and goes back and erases the old mark. This method is related to communications theory and the science of signaling. Here, the active area marker is an out of band control signal. -
- -- If a tape is written by an initializing tape machine, unmounted, and then mounted on a second analyzing tape machine, the analyzing tape machine is starting with a populated tape. Similarly, a mathematician can, by decree, define an initial tape that holds predefined alphabet symbols. In such a scenario, the initializing machine and the analyzing machine must use a shared communication protocol for signaling the end of the active area. They cannot operate independently or the analyzing machine would not be able to find the end of the active area. This shared protocol then represents information held by a mediator, said mediator could be used at a higher level to write the control for the two machines, or it could be consulted when the two machines are run. Hence, the mediator is either an author, or a service provider, or possibly both. -
- -- By definition, a computation must finish in a finite number of steps. It follows that the active area when a Turing Machine halts a computation will always be finite. Consequently, if a Turing Machine initially starts working with a tape that was computed by another Turing Machine, the length of the input will be finite. Still, that input will be in the active area, so the receiving Turing Machine will need to read control data left on the tape under a common communication protocol to be able to find the bounds of the input area. -
- -- When an input tape is provided as a general mathematical object, either decreed by definition or perhaps abstracted from 'what a Turing Machine computation would produce in the limit of step count', then the input can be either finite or infinite. -
- -- Because of the impossibility of recognizing certain tape features, when a tape is written by one Turing Machine, then used by another, there must be some sort of system for messaging control. There are two approaches for mixing data and control together: one is in band signaling, while the other is out of band signaling. -
- -
-
- In contrast,
A given finite area that is not sitting on the end of the tape will have a left neighbor area and right neighbor area that are not in the area. If the given area is sitting on the end of the tape there will be no left neighbor area. If the area is open on the right, there will be no right neighbor area.
- -Now imagine we define a Turing Machine such that when it steps right, it steps to the right neighbor area, and when it steps left, if there is a left area, it steps to that, otherwise it returns a
An example of this from conventional computing is where memory is accessed in units of bytes, but a program works with units of words.
- -As established, the Turing Machine head transport returns a distinct
Various portions of this text have mentioned calling a Turing Machine as a subroutine. This is described as unmounting the tape from the calling machine, mounting it on the subroutine machine, running the subroutine machine until it halts, then unmounting the tape from the subroutine machine, and mounting it back on the calling machine. However, this would be a manual process. To automate the process, we use a Universal Turing Machine. It has the definition for the calling machine and the subroutine machine on its tape. We can add an additional tape to the machine to hold the stack. Then a subroutine call happens much as it does in conventional software. -
- -A gasket machine is actually a set of subroutines with one corresponding to each of the tape transport commands. -
- -
- There is a small problem, in that the
Now suppose defining a Turing Machine that initially has the head on the leftmost cell of a specific area. When step left is called, the tape transport immediately returns the left of leftmost symbol, independent of whether the area is actually at the physical left end of the tape or not. -
- --Now suppose defining a Turing Machine that initially has the head on the leftmost cell of a specific area. When step left is called, the tape transport immediately returns the left of leftmost symbol, independent of whether the area is actually at the physical left end of the tape or not. -
- -Suppose further that this area is finite. If the machine attempts to step right from the rightmost cell of this finite area, the tape transport returns, in analogy,
- When a Turing Machine operates on a finite virtual tape, the structural logic of the partitions established earlier must be updated to reflect the absolute rightward boundary. -
- -We defined a tape as having a single feature, that of a leftmost cell, along with a linear neighbor topology. When a tape is mounted it gains a second feature, that of the cell the head is on. The leftmost cell was fixed in place, while any other single cell on the tape can be featured as the cell the head is on. When we introduced areas, we picked up two new features, that of the leftmost cell of the area, and the rightmost cell of the area. Again, those features could coincide with the former features. We noted that the features partitioned a tape thus defining more areas, and more features. -
- -- When cells were defined we noted that they were sets, and that these sets had identity and could be referred to. We needed that to be the case so as to build the tape topology using neighbor properties. Had the tape been singly linked, perhaps we could have used the cells to represent themselves in the properties, but when we doubly linked it, a given cell had to appear in two places, as the right neighbor of its left neighbor, and the left neighbor of its right neighbor, so we stipulated the sets as being identifiable. Initially we did not say how they would be identified. This is common in mathematics, but we soon cleared this up by formalizing the concept of a symbol. -
- -- When discussing symbols we noted they could be natural numbers, and even went so far as to point out that addresses were symbols, though we had not yet defined them. They are familiar to anyone involved in computing, so again, it did not present a serious problem. Here we have now formalized them. -
- -- So we now have two means for identifying a feature. One means is to state its address, and the other is to put a tape machine head on it. -
- -As we noted in the section discussing area, an area has two distinguishing features, being that it has a leftmost cell, and a rightmost cell. That definition is topological. If we start with the leftmost cell of a tape, we are either already on the leftmost cell of a defined area, or we can step right to find it. At the point of finding it we know this leftmost cell is part of the area, then we are either already on the rightmost cell, or we can continue to step right on cells in the area until we find the rightmost cell in the area. The right neighbor of the rightmost cell in the area, and all cells to that right of that, are excluded from the area. -
- -With addresses we can now define an area with two addresses, two natural numbers, the address of the leftmost cell, and that of the rightmost cell. All natural numbers greater than or equal to the address of the leftmost cell, or less than or equal to the address of the rightmost cell, are addresses of cells that are in the area. This feels more satisfactory for most of us, as now we are talking about arithmetic rather than graph topology. Though should the topology of the tape be generalized, this could become limiting. It reminds me of Frege's admonition that perhaps math should be built on top of geometry. -
- -The
In an analogous manner to defining an address space for a tape, we can define an address space for an area. Accordingly, the leftmost cell of the area is assigned address zero, and the address increments cell by cell going to the right. A finite area will have a finite address space, with the address of the rightmost cell being the largest address in the address space. -
- -It is interesting that the extent of an area will be the same, whether it is calculated from the address space of the tape, or the address space of the area. In fact, the extent will always be identical to the largest address in the address space. We will use the Greek symbol omega,
If cells in an area are transacted, the cost of the area is the cost of a cell multiplied by the count of cells. Vincent Atanasoff probably found himself needing to know such a count when ordering capacitors. The count of cells in an area is also known as the area's
The count of cells in an area, the length of an area, and the cardinality of the address space for an area are all the same number,
So we find an interesting situation with the cardinality of an address space for an area that is open on the right. It goes like this.
- -This follows from its definition; it is literally the increment from the Natural Numbers Machine.
- -Cardinality is produced by repeatedly calling the
At the end of the second step in the procedure for producing the cardinality, the tape of the
Composing the
By Lemma 2, cardinality is a Natural Number. By Lemma 3 cardinality is not in the address space. By Lemma 4 the address space is identical to the Natural Numbers.
- -The resolution lies in the computational reality of Step 2. For an area that is open on the right, the stepping of machine
So then can we add a property to cardinality, such that a second order analysis could use this property to continue downstream analysis? In short we could say that cardinality has no first order value, but it has a second order one. This is analogous to inventing a new type of number, analogous to a complex number with a second component. I.e., there is no 'real' solution, but there is an 'imaginary' one. Or analogous to error algebra, where a number value is replaced with a rule on how to handle downstream operations when it is given as an input. -
- -Such a value would be a new Turing Machine, one that composes a call to the never halting Natural Number machine followed by an increment operation. It cannot be run, but it perfectly explains the situation to an analyst. Perhaps we name this machine
- Had extent been used instead of cardinality, we would lack the final increment step in the three step computing procedure. However, step 2 still cannot complete. Rather than a value, the result of the second order analysis would be a machine that produces ever larger Natural Numbers. We can call this machine
- Now here is an interesting result: -
- -- Neither machine can be run. However we can compose the two machines, then simplify the composition. When we do so, the ever larger Natural Number machines annihilate each other, and the increment machine remains. The increment machine can be run, so we end up with an output value. -
- - -Consider the case of a partitioned tape. Then consider that we write a gasket, such that we have a higher level Turing Machine that considers each of the areas of the partition as a cell. So then, initially the Turing machine starts with its head on the leftmost area, stepping right steps to the right neighbor area etc. In this manner we abstract the concept of a cell to areas. A length then becomes a count of areas; however the
Suppose we unmount a tape from a halted Turing Machine, say machine T0, and then mount the tape on another Turing Machine as input, say machine T1. Suppose we do this so that machine T1 may calculate the length of the output made by the first machine. When we do this, we run into some problems.
- -Firstly, for a conventional Turing Machine, the tape that is mounted on T1 will be infinite, so no computational T1 machine will be able to process it unless there is a message on the tape telling T1 where the end of the input is. For our TTCA machines, if T0 starts with a null tape, and then expands it, and T0 is computational, then at the time T0 halts, the tape will be finite. T1 can then use the continuation of stepping beyond rightmost to know that it has processed all of its input.
- -If a Turing Machine does nothing then halts, it will implement an identity relationship between input and output. If we do not want the input given to a machine to 'bleed through', we will have to erase it. A computational TTCA Machine starting from a null tape can only produce finite tapes, so T1 can erase whatever T0 writes to the tape. However, if we are analyzing, instead of running the TTCA machine, we might discover that the tape length would be infinite if the machine could be run. We know that if we pass an infinite tape to a computational TTCA, it would not be able to erase the tape. Fortunately we can derive this fact through analysis and proof without having to run the computational machine to see if it erased the tape.
- -Hence if we allow for infinite inputs, we should add an 'erase-to-end-of-tape' command to our machines, so that the computational machines may leave a tape with only their outputs on them. Our erase-to-end-of-tape command will be executed in a single step.
- -Once an input tape is mounted, T0 is a computational TTCA machine given a finite tape, its output is a finite tape, and that is taken to be the input for T1.
- -T0 is required to provide meta information about the length of the active area. This approach is known as
T0 updates a dedicated table where it keeps track of the location of data objects and their lengths. Such a table is called a
We adopt a convention of maintaining a
Each machine has two tapes, an input tape, and an output tape.
- -A compact area is one that has only alphabet symbols (no empty-symbols). We can extend this concept to say that the
The approach we use in modern computing is often the 3nd one listed above, that of the type system. We carefully account for the length of each instance of data. Then we build up each larger instance from smaller ones, and while doing so, we add the lengths of the smaller instances to calculate the length of the larger instance. All programs then specify when they make or compose instances and their types.
- -A system for creating the appearance of many tapes over a single tape is called a memory manager or a memory allocation system. It is typically better to use one of these and multiple tape models rather than solving the problem of moving objects around in memory in an ad hoc manner.
- -Here is an important question for the TTCA model: is it possible to define a memory manager that creates the appearance of multiple expanding tapes over the top of a single expandable tape? This problem is solved for managing files on a hard disk. However, all current file systems break at some point when pumped. So the question being asked here is equivalent to asking if a files system can be made without such architectural limits. The answer to this is yes, it is possible, as we will see in a later chapter of this book.
- -Hence there are multiple conventions we may use for implementing the abstraction of multiple tapes on a tape machine. Multiple tape machine are equivalent in power to one tape machines, but sometimes they are easier to think about.
- -Now as we have multiple tapes it is fairly easy to show that having multiple tape machines is equivalent to having one machine. We first view the multiple tapes worked on by the multiple machines as the multiple tapes of one machine. We then compose the state controllers in series, where the halt state of one is the initial state of the next one. Thus we may also conclude that having multiple tape machines is not more expressive than having one tape machine. We may also look at our multiple composed state controllers as one multiplexed controller, and then conclude that having multiple machines will not have an order of speed or space usage advantage.
- -The advantage of having multiple tape machines each perhaps having multiple tapes is that sometimes it is easier to think about. It is a method of partitioning the problem.
- -Suppose our machines have two tapes where one is called the
- A tape area and partitioning can be an abstraction defined by a function rather than merely by a leftmost and rightmost cell. Such areas can have different topologies than those of the base tape. A familiar example for most computer scientists is utilizing software to create the appearance of a two dimensional array over a linear memory. -
- -- Accordingly, suppose there is a three tape Universal Turing Machine gasket machine that holds the definition of a base machine on a first tape. It calls the base machine as a subroutine to access the base machine's tape (the second tape), and it uses its own tape to organize the tape abstraction. Then this outer machine can present to its user a variety of transforms of the base machine's tape. -
- -- As an example, a gasket machine could partition the base machine's tape into two areas, one consisting of the odd addressed cells, and the other of the even addressed cells. Though these two areas consist of noncontiguous cells on the base tape, when viewed through the gasket machine, they appear perfectly contiguous. In this case, each area will have a leftmost cell and remain open on the right. -
- -
- When the base machine tape cells behind an abstract area are physically contiguous, we say that the abstract area is
Suppose we have a Turing Machine that is designed to mark an area based on some property of the symbols.
- -Suppose further that starting with the head on the first cell, our Turing Machine will step right zero or more times until it finds a cell that holds a symbol that has the special property.
- -Once it finds such a cell it will write an area marker symbol to that cell, step right, and repeat writing area marker cells until it finds a cell that holds a symbol that lacks the area property. At which point the machine halts.
- -Once an area is marked, we can go back and run a length measuring machine that counts the sequence of marks.
- -However we have a couple of problems, if there is no cell on the tape that has the special property. The area marking machine will step right without halting while looking for the marker. As a second problem, if the all the cells to right of the leftmost area cell, the area marker machine will never halt. -
- - - -Now suppose we employ a second order analysis.
- -Instead of running our area marker Turing Machine, we examine its definition and the definition of the machine that generated the tape data, to learn if such a machine will ever halt.
- -Although we know that it is not possible in general to analyze machines to know if they will halt, or not, it is certainly possible to do so in some cases, and this is one of those cases.
- -Upon analysis of our area marking machine we make a startling discovery: inputs exist for which the area marker will never halt.
- -In one case, if there is no leftmost symbol with the property that defines the area we are looking for, the marker machine will search forever.
- -In the second case, once the area is found, it is open on the right and it never ends.
- -We might say that inputs that have no leftmost symbol have an area of
This is an abstract concept, because our area marking and area measuring machines will never be run then halt and return a length measure of zero.
- -Instead we might arrive at this conclusion that a non-existent area has zero length through inductive reasoning: Say we have an area of length
As we repeat this, then eventually we will have an area of length 1 as discovered by our length assigning machine. Now we remove 1 more element.
- -Each time we removed an element before, it made the length smaller by 1, so we reason that 1-1 = 0. The area is now length zero.
- -We cannot go any further because there are no more elements to be removed.
- -In this case we arbitrarily imagined a longer area. No such longer area was stated in the problem formulation.
- -In real world programming, this is the difference between having a container that by implication will hold elements, and lacking the container entirely.
- -By applying the limit logic, we have implied that an area exists.
- -If running the area maker machine is asserting the existence of such an area, then it makes sense to speak of a zero length area.
- -However, if we are not making this assertion, then there is no area so the issue of length is irrelevant. This is a nuanced problem.
- -Note, then, that zero length is a second order concept. We cannot mark nor measure it, and given our first order definition for an area, nor can we even represent such an area at a first order.
- -There must be some external structure present that implies the existence of the area for zero length to even make sense.
- -This insight explains a lot of the pain related to the processing of end cases in computing. It will come up again in this volume when we examine the question of the emptiness of containers, see the section .
- -It also explains why loops so often need to be primed or given special case guards, which operates identically to adding a layer of analysis. We will discuss this further later when introducing the first-rest pattern see, .
- -It is interesting that non-existence has collided with zero length. This seems to be a contradiction, as something that does not exist should not have any length at all.
- -All of this happens at the second order, at the order of analysis. At this order we can make a distinction between an area that we have given a name to, and perhaps a location, as compared to an area for which we have done neither of these things.
- -Thus for purposes of second order analysis we will say that an area exists if it has a name or a location, even if it has zero length.
- -We will say an area does not exist if it has neither a name or a location. Again, execution of our first order area marking and length machines cannot provide us with any such information.
- -Let us ask a question, what is it that an address is actually locating? Let us consider this question in the light of an example. Suppose we have the tape sequence of:
- -Now consider that we have an address of '2'. If we read tape address 2 we get back the letter 'c'. So the address is locating the 'c'. Now suppose we write at address 2. Say we write '
Now we write '
It would appear that the answer to our question is that address 2 is locating different things at different times. First it was, c, then
Addresses speak to the structure of the tape rather than the values held on the tape. So as to facilitate this interpretation, we note that a sequence consists of a sequence of
This operates similarly to a small extension to the already existing concept of a variable in mathematics. In mathematics we allow that a variable can take on different values, though its name never changes. Now we are going to say that a cell can take on different values, though its address never changes. Furthermore, as the cell is part of the sequence, we are going to say the cell itself has a left neighbor or right neighbor, excluding the value in the cell.
- -The address of a cell is the number of steps required to reach the cell when starting from the leftmost cell on the tape. The leftmost cell has an address of zero. It might seem intuitive to set the address of an area on the tape to be that of the first cell in the area. If we require that an area have at least one cell to exist, this approach works even for machines with a cell delete command.
- -Suppose that we are deleting the cells in an area. The delete command affects the cell to the right of the cell the head is on. Hence to delete all the cells of an area, the head is placed on the left neighbor cell to the area. Say that we delete an area of three cells. We will call delete three times. It seems unsatisfactory to say the area no longer exists after the three deletes because the head locating the area never moved. I.e. we still have a location marker for the area, so we could, for example, call append and put a cell back into the area. For the area to truly not exist, it would not have a location.
- -Thus it seems more satisfactory to locate an area by its left neighbor cell, than to locate it by its leftmost cell.
- -The inverse case also suggests that the cell to the left of an area defines its address. I.e. if we call append to grow an area, it grows to the right of the cell the head is on. According to this definition of area location, the rightmost cell locates a currently zero length right tail of the tape that will potentially be grown.
- -In a sense what we are doing while exploring the meaning of area, existence, and zero length with these delete and append examples is performing a discrete limit in analogy to a limiting operation in calculous. To support having such a limit operation, the location of an area is that of the left neighbor of the leftmost cell in the area.
- -Not all is satisfactory. When using the left neighbor of an area as the location for an area, we cannot locate an area that starts on the leftmost cell of the tape. If we make this a special case, then we have failed to make a first order definition for area, because the special case information will have to be stored in a higher level structure that describes attributes of the tape.
- -Nor can this use the left cell approach work in the case of multiple areas.
- -Suppose we have two adjacent areas.
- -
- Here we show a first area, say a0, that includes cells 7, 8 and 9. And a second area, say a1, that includes cells 10, 11, and 12. Thus, by the convention of using the address of the cell to the left of an area as the areaâs address, a0 has an address of 6, while area a1 has an address of 9. Because the areas are adjacent, the address of area a1 is the same as the address of the rightmost cell in area a0.
- -We know that area a0 is located to the left of area a1 because a0's address is less than a1's. I.e. 6 < 9.
- -Suppose we delete cell 10. Though cell 10 is gone, our addresses remain consecutive, so what was cell 11, is now called cell 10, etc. and the diagram appears much as before, though area a1 is now only 2 in length:
- -
- Now we delete the cell at address 10 two more times, and all the area a1 is gone. During the deletion, and just after, the head will be on the rightmost cell of area a0, i.e. on cell 9. We can now say we have an area of zero length located at cell 9.
- -
- Now suppose after deleting the area a1, as just described, we continue on to delete area a0. Each time we delete the leftmost cell of a1 the rest of area a1 moves left by one. Hence, after the first deletion the address for empty area a1 becomes 8. Area a0 is still located to the left of a1, because 6 < 8:
- -
- Finally when all cells in area a0 have been deleted, a1 has collapsed into a0. Both have the address of 6, so the order between them can no longer be derived from looking at the base addresses. Should we attempt to reverse the steps above, and only be given the machine at its final state we would have to begin by guessing what the order was between the two areas, a0 and a1.
- -So again, there is either missing information, or some information is not stored on the tape we are discussing.
- -As yet another problem case that is either not possible or requires external information, if an area includes the leftmost cell of the tape, then its location cannot be described with an address.
- -Hence this approach of using a discrete analogy to limits has led to some unsatisfactory end cases. We will visit this subject of areas on tape in the section, Area as a mapped tape and present a higher order approach for defining area location that avoids such end cases.
- -For a given Turing Machine, the input is the sole determiner of the output. I.e. each time the same input is given, we get the same output. The input and output are mathematical objects, hence Turing Machines are functions. However, it is common in computer science to speak of Turing Machines as 'solving problems' rather than saying they are functions. This is because we often think of the inputs and outputs of Turing Machines as being something other than mathematical objects. For example, when a Turing Machine sorts sequences found on its input, we might say that it solves a sorting problem.
- -Turing Machines will differ due to differing alphabets, state controller graphs, associated commands, start, and halt states. The choice of empty-symbol is inconsequential as long as it is distinct from the alphabet. As we will see in the later discussion on variations, the choice of alphabet is not very important. For two alphabets of the same cardinality we can setup a one to one mapping, and for those of differing cardinalities we can use sequences of alphabet symbols that map to alphabet symbols. For example, given an alphabet of âTâ and âFâ, and a second alphabet of âtâ, âfâ, âxâ, âzâ we may make the following map:
- -Then given this mapping, we may use two cells for each one cell for any {âfâ, âtâ, âxâ, âzâ} alphabet machine, and then use the only the {âTâ, âFâ} alphabet.
- -There are a countably infinite number of permutations for alphabets, state controller graphs, associated commands, start and halt states, hence there are a countably infinite number of Turing Machines that fit our definition. However, there are an uncountably infinite number of mathematical functions. Consequently, we must expect that some functions cannot be computed with Turing Machines.
- -There might be multiple Turing Machines that perform the same function. A set of such machines forms a functional equivalence class. Within a functional class there will be a class of members related in that they all use the smallest number of steps when considered against the limit of input length. We discuss this further in the section on complexity.
- -Of special importance to computation theory is the existence among all these infinite Turing Machines of a class of machines that read their state controller definition from the tape as an input. This is the
An interesting aspect of the Turing Machine procedure is that it introduces the concept of stepping the machine. With the addition of some simple constraints it becomes possible to map the parts of the Turing Machine abstraction to the parts of some real machines. These constraints may take the form of such things as bounds on the length of the inputs, or the addition of out-of-resource errors. Because such constraints do not affect the 'normal' workings of the machine, the derived relationship between a Turing Machine step, and that of a unit of real time might not be that complicated. Indeed, except for some enumerable cases this relationship might even be so simple as to assign to a step an approximately constant amount of time.
- -Because of the existence of a relationship between steps and time, particularly when it is a simple one, it is very interesting for us to know how many steps a Turing Machine will take.
- -There are many ways to measure the complexity of a Turing Machine. Among these is something called the time complexity, which is a function that relates the length of the input to the number of steps required to reach the halt state.
- -To derive time complexity we typically start with a step count formula which maps the length of Turing Machine input to the worst case largest number of steps. We then consider the behavior of this formula as input length goes towards infinity. To get this, we take the highest order term from the step count formula. Conventional results are constant time, polynomial time, or exponential time.
- -We can derive the 'worst case length of the area written or read by the machine during computation' function in an analogous manner as for the step count function. This function is known as the
The order of time or space complexity will remain the same against certain variations of our Turing Machine definition. For example, if we double all the states by adding a second state that we always visit, where this second state does nothing, the number of steps would double but the functionality would not change. Order of complexity also would not change. A fixed time machine before doubling up on the states would still be a fixed time machine afterward. It is simply that the number of steps would be twice as large, but still a fixed number relative to the size of the input. A polynomial time machine would still be polynomial time, simply with double size constants. We say that changes which do not change order of complexity, nor existence proofs, are
Suppose we have a complete Turing Machine functionality class. We say that it is complete because all possible machines for implementing the function are in this class. Some machines in this class will have a different order of time complexity than others. Now we consider the set of minimum order of time complexity machines from this class. As the larger set was complete, the set built against this constraint will also be complete relative to the constraint. We then say that this minimum order of time complexity is a property of the problem being solved, rather than being a property of a particular machine.
- -In the first section of this chapter we gave a rather conventional definition for a Turing Machine. In the prior section, Complexity, we noted that we can analyze Turing Machines to find their time and space complexities. In this section we will discuss some variations that a person finds in the literature.
- -A variation on the conventional Turing Machine definition is allowed when it can be proven that the variation never causes existence, order of time complexity, nor order of space complexity results to change, and in this respect is inconsequential. Earlier we gave the example of doubling up the states as being such a variation, though that is an excluded variation typically.
- -Some Turing Machine descriptions describe a tape with no end in either the left or right directions, i.e. a tape that is open in both directions.
- -This feature adds no richness of expression, because we can get the same behavior from a Turing Machine with a single ended tape. To do this we partition the single ended tape into odd addressed cells and even addressed cells. The odd cells are said to be the right side of the tape, and the even ones the left side. We then rewrite any tape controller based on a bidirectional tape to instead use the 'odd' and 'even' channels instead of the left and right sides of the tape.
- -This same approach form can be used to show that multiple tapes, or even multi-dimensional tapes, add no expressive power. The good news is that such variations can be used whenever convenient, and we will get the same results.
- -Going in the other direction, the open in both directions tape is not a simplification. There is still a start cell, being the cell that the head is initially placed on. And as noted above, the topology around this start cell is no different, it is simply a question of the adjectives we use for describing it.
- -Without loss of generality, we may replace the alphabet with a single symbol, say 's' (short for successor). This is because symbols in any alphabet can be placed into correspondence with a sequences of 's' symbols. For example, the symbols of the alphabet of {w, x, y, z} can be placed into one to one correspondence with the sequences in the manner of {<w, s>, <x, ss>, <y, sss>, <z, ssss>}. We will need to put the empty-symbol between any such sequences on the tape, so that two sequences can be distinguished from one longer sequence.
- -Alternatively we can adopt a two symbol alphabet instead of a single symbol, where the second alphabet symbol is an end of sequence marker.
- -In contemporary computing we use an alphabet of two symbols, {0, 1}, and fixed length sequences. No end marker is needed when the sequences to be placed into correspondence are of fixed length. So for example, the symbols in the alphabet {dog, cat, mouse, fish} may have the correspondence of {<dog, 00>, <cat, 01>, <mouse, 10>, <fish 11>}. Conventional fixed sequence lengths are 8, 16, 32, and 64. So for example, when the sequence length is 8, any alphabet of 256 symbols or less may be placed into correspondence. A conventional correspondence table is that of the ASCII code.
- -The fixed length to be used can depend on computational context. (In contrast, UTF8 does not use fixed length sequences, so there must exist at least one end of sequence marker.)
- -Another alternative to end of sequence markers for variable length sequences is to externally account for sequences lengths. We call such an accounting system a type system.
- -When we use a fixed sequence of {1, 0} to stand for symbols, it is expensive to reserve a sequence for the empty-symbol. This expense is due both to losing the use of a symbol in the alphabet, and in the complexity of control circuitry when keeping track of it.
- -The empty-symbol functions as a property of the machine rather than simply another alphabet member, because the tape initially has an infinite tail of empty-symbols. A computational Turing Machine is limited to taking a finite number of steps. Thus it cannot compute a tape initialized with an empty-symbol (or any other value).
- -However we can add a constraint on all Turing Machine controllers that requires of controllers that they never write the empty-symbol, and always write an alphabet symbol to a cell before reading it. Then, because a cell is never read before being written, it does not matter what we write into it for initialization. We may even use an alphabet symbol. Consequently this constraint allows us to eliminate the empty-symbol. This gives us the following Turing Machine variation:
- -To validate that this is an inconsequential Turing Machine variation, rather than a description of new abstraction that is not a Turing Machine, we must show two things: Firstly, that any of the now disallowed controllers never compute something that cannot be computed in the presence of the constraint. And secondly, that there are same complexity class alternatives for any disallowed controller.
- -1. When attempting to step into the inactive area, instead keep a counter for the number of steps the machine would take. Only allow reads or writes or head movement when the counter is no longer needed due to the head having moved back into the active area.
- -2. Write an alphabet character and change the inactive area traversed into an active area.
- -The active area on the tape can grow at most by one unit for each machine step. This largest growth occurs when the Turing Machine steps right and writes an alphabet character in every visited state. This means that for computational machines that start with a tape that has a finite input (active area), the output (active area) will be finite. This also means that space complexity can never be larger than time complexity.
- -A fixed value is one that is provided with a Turing Machine definition, and does not change while the machine runs. Suppose we chose a fixed length Turing Machine tape. The tape would then have a rightmost cell. That cell would have no right neighbor, but would have a left neighbor. We would also add another error, that of right from rightmost. This error would be invoked when the controller attempted to step right from the rightmost cell.
- -Consider a machine that does not step out of the active area, has constant space complexity, and where this space complexity is less than the fixed length for the finite tape; such a machine would never trip the right from rightmost error, and thus there would be no difference between a finite tape and an infinite one.
- -Now suppose that we bound the length of the input, and that the maximum space required for such inputs or shorter ones is less than or equal to the length of the tape. Then again, the right from rightmost error would never be taken, and thus the tape would be indistinguishable from an infinite one. (Today we typically pad programs with lots of memory and long address words in hopes this will be the case.) An analogous argument can be made if we bound the number of steps that may be taken.
- -Now consider the case where we do not fix the length of the input, nor the number of steps allowed, and that space complexity is such that space usage grows with growing input length, at least for very long inputs. For such machines we can always find an input of sufficient length to trip the right from rightmost error.
- -As another approach to finite computing we can run computations twice. For a given input we first run the Turing Machine variation that does not step out of active area but still has an infinite tape. We watch this machine closely while it is running and find the bound on the active area. Now we can make a second machine that has a fixed length tape at least as long as our active area measurement but is otherwise the same. Now with this second machine we can run the same input and there will be no right of rightmost error, and thus there will be no difference between having the finite tape or an infinite one.
- -Unlike for the constant space complexity proposal, and the bounded input length proposal, which only work for small subsets of potential inputs, this 'run twice' proposal derives a finite machine that works for any given input which a Turing Machine works for. Though, unfortunately, in all cases the second run will be moot, as we could have simply taken the output from the first run.
- -In a variation on the run it twice approach, instead of running the first machine, we might instead analyze it and should we be able to surmise a maximum tape length, we could use that.
- -In yet another approach we can extend the finite tape as needed. We place a control layer over the finite tape. When a step right command from the Turing controller invokes the right from rightmost error, the lower layer allocates memory, lengthens the tape, and then performs the requested step right. As long as this occurs in fixed time, (or of sufficient lesser order time than the dominate order of the time complexity), and as long as there is indeed more memory to allocate - this Turing Machine variation will yield the same order of computational complexity as one with an an infinite tape.
- -I propose the following Turing Machine variation:
- -In our original Turing Machine model, the controlling state machine commands were limited to, do-nothing, step-left, step-right, write, with reading as an implied command. To this list we add append. The append command may only be called when the head is on the rightmost tape cell. This is not limiting because the command may be called from a state that is at the end of an arc triggered by the right from rightmost error. When we have no empty-symbol, append accepts an alphabet symbol and performs a write into the new cell. This is not limiting because if need be, a person can always perform an extraneous write of an alphabet symbol.
- -With this extendable tape model all Turing Machine components remain finite during computation, though some are arbitrarily large. This variation is more suited for creating a mapping between a Turing Machine and a real program running on a real machine. Specifically, a computation requiring
The Turing Machine state controller has a command symbol tied to each state. The Turing Machine procedure then has us take action based on this symbol. This is our current command set:
- -We are going to relieve the constraint that append can only occur from rightmost. Our new append is functionally identical to adding a cell to the rightmost extremity, and then shifting all the symbols over by one cell starting at the new cell and ending when the new rightmost has been written - and then doing the requested write of x on the right neighbor cell.
- -We will also include the inverse function for append. delete(append(x)) reads x while deleting the cell that x was in. The current Turing Machine model can emulate this function by shifting all the symbols in cells the right of the head left by one, and then simply not using the rightmost cell.
- -We are also going to support multiplexed state controllers. Our multiplexed Turing Machine will have multiple heads. One for each separate thread of execution through the state controller. As explained in the following chapters, supporting multiplexing makes our machine more complex, especially in the presence of the delete command. However, we defer that discussion to the relevant chapters.
- -In cases where successive states are visited in a fixed order it is convenient to combine the commands. We have developed the concept of a command statement to support this:
- -The left direction is specified with a minus sign, otherwise the direction is taken as right going. So the letter s is the step-right command, and -s is the step-left command. The command s3 steps right three times.
- -The command a appends and writes a new cell to the right of the head. We use two special characters from the UTF character set to signify the rightmost and leftmost of the tape. This one looks like a little tape with its left cell inked in,
In some cases it is possible to implement higher performance implementations for commands when the programmer tells us some additional information. For example a
We can concatenate the command letters into a string to summarize what would happen sequentially in adjacent state transitions. If these compound commands need arguments, then they are pulled from the argument list in order as they are needed. For example, as means to append, with the parameter for the append taken from the argument list, and then to step.
- -We support multiplexing with the command e, which is short for entangled. This operator returns what appears to be a second independent machine, but this apparently independent second machine actually shares the same tape with the first machine. It is functionally identical to giving one machine two heads, and thus the ability to have state sets.
- -The command esr is a compound command referring to sequentially applying three other commands. The e says to make an entangled copy of the head. The s says to step this copy, and the r says to do the read. The analogous esw does a write as the last step. This sort of combination of letters to make more complex commands was inspired by Lisp's car and cdr compositions. Though this is functionally what the command does, its actual implementation might be completely different.
- -The combination of multiplexing and cell deletion leads to a hazard where one thread can delete a cell the head is on in another thread. We add a collision error continuation to our multiplexed Turing Machine interface because of this situation.
- -The modifications to the Turing Machine leading to our TTCA machine were inconsequential, in that for order of complexity and existence proofs we may swap one machine for the other and the results will be the same.
- -The original Turing Machine had an infinite tape. In contrast the TTCA machine has a surprising property: for computational problems all of its components remain finite. This follows from the fact that during computation a machine makes a finite number of steps, so the tape can only be expanded to be a finite size.
- -- Let us take the example of adding two Arabic representation numbers. Logically this is considered to be a logarithmic time problem. We break the operands into fixed length pieces, and adding them in pairs results in a carry per block. By recursively pairing the blocks and applying the carries, we generate wider carries. Thus we can show that in terms of the logic gates that must be traversed, the sum is a log time operation. -
- -- Physics comes to a different conclusion. In the worst case, a carry into the least significant bit can affect the sum bit some physical distance away. As the operands get longer, this distance grows in proportion. So given the propagation of information at a fixed speed, the bounding evaluation time against growing operand width is linear time. Even if it is log time in gate count, at some point the interconnect delay will dominate. -
- -- The logical analysis of the adder given above allowed for unbounded resources, because as the adder operand increases in size, the number of block adders increases without bounds. In any realization there will be a limit on the number of blocks that can be added in parallel. These groups are then processed one by one, and the carry is propagated between them. Consequently, as the operands grow in length without bounds, the adder evaluation time becomes proportional to the number of groups processed. Processing groups in series is a linear time algorithm. -
- -- It is notable that the time-multiplexed use of computer resources produces the same linear time result as the physics of information propagation analysis for the adder. -
- -- A Turing Machine program faces a situation analogous to physical constraints. Given the operands are found on the tape, and the carry-in can affect the msb of the sum, the head will have to move ever more cells rightward to convey that lsb information up to the msb. Based solely on the propagation time of that information, addition is found to be a linear time algorithm. This propagation remains computation class limiting even if the Turing Machine is given an unbounded number of independent heads. -
- -- There appears to be alignment among physical limitations, resource limited computing, and steps spent by Turing Machines while they carry information across a linear tape. This alignment indicates that a reasonable realization will be computation theoretic inconsequential. -
- -
- At this point we have arrived at questions of the
- From Babbage's Analytical Engine of 1842 up to the transition to mechanical relays and vacuum tubes in the 1940s, calculating machines were implemented with gears. The basic principle is apparent to anyone who has seen a mechanical odometer. Consider adding numbers for example: given two odometers, step one back at the same time as stepping a second one forward; when the first one reaches zero, the second will hold the sum. This process can be optimized, but the general idea remains the same. For such machines, a step is a rotation of the main shaft. -
- -
- The Harvard Mark I machine had a main axle speed that maxed out at 3000 RPMs, say 2700 RPMs to keep our math simple. Then this is 2700 steps per minute. The ENIAC was a similar implementation, but one that called out the use of circular shift registers of vacuum tubes instead of mechanical gears. Because there were 10 tubes in a ring register, it took 10 clock ticks to complete one 'rotation'. The clock rate maxed out at 450 kilohertz. That would be one rotation every
- Yet, the same program when run on the Mark I took the same number of steps as on the ENIAC. But more importantly, a linear time algorithm on the Mark I was still a linear time algorithm on the ENIAC, etc. Thus, these implementation differences were computation theoretic inconsequential. -
- -- It feels unsatisfactory to leave out the tremendous difference in clock rates. So let us address this feeling by naming an ENIAC main shaft 'rotation' as a standard 'step'. If we do this, then a Mark I shaft rotation would be 1000 ENIAC steps. Yet, this would merely affect the linear constant in the step count formulas. The same programs can be run, with the same inputs, and asymptotic behavior is the same for both machines, because computation classes do not include the constants on the step count equation. Constant time remains constant; linear, polynomial, and exponential time classes are the same as before. Programs that decide questions would get the same answers when they completed. -
- -- Because we made an ENIAC shift register turn completion a 'standard step', we have a relative measure, so there is something we can do to create a computation theoretic consequential difference. Suppose we have two ENIAC machines, and we send one speeding away from Earth at an exponentially increasing rate, i.e. increasing red shift, and we observe it from Earth. We will observe that the clock on the traveling ENIAC is growing ever slower, and that a linear time program running on it will be observed to have exponential time behavior. Unfortunately, relativity does not smile upon us, as the people on the spaceship would not see the inverse, a speeding computation on Earth, but rather they would also observe a slowing one. -
- -- So then, instead we send a spaceship towards Earth, with increasing blue shift, and we would observe that spaceship's ENIAC getting faster and faster. This is still not a computation theoretic speedup, because it is not asymptotic. In finite time, said spaceship would run into Earth, or pass it by and then be red shifting. -
- -- A designer could purposely slow the clock on a second ENIAC so as to emulate red shift. For this to be more than mere theater there would have to be physical reason to run a slower clock than necessary, for example perhaps for conserving an ever dwindling battery. But slowing computation down, or even stopping it, is typically not useful. However, going the other direction, an ever faster clock does not work, as there is a finite maximum physical clock speed. -
- -- We get an increasing blue shift situation with Moore's law. If every generation transistors become exponentially smaller, and thus faster, and we consider step times in years, hopping from new realization to new realization, then indeed linear time algorithms on a single realization would be log time algorithms on the generational computer. But chances are this is not an asymptotic, i.e. limit to infinity, phenomenon either. -
- -- Superscalar and VLIW computers execute multiple instructions in parallel. Real data dependencies put limitations on how many instructions are available to be executed in parallel, but even discounting this, if a program were executed N instructions at a time, its time to execute would divide by N. This merely affects the linear component of the equation mapping step count to input length, and thus does not change the computation class. Superscalar and VLIW architectures do not affect decisions; indeed they are transparent to programs, so decider problem results cannot change. Hence these techniques are not computation theoretic consequential. -
- -- In general, by definition, organizations do not change a program's view of the machine, as that is part of the architecture. So organizations will not affect decider results. Also, the memory operations will be the same, as that is viewable state, so space complexity does not change unless time complexity changes. -
- -- The realization sets fixed resources, so any attempt at parallelization will be bounded, as in the superscalar and VLIW discussion above. Thus at best it can divide the execution time by N. -
- -- Some organizations can arrange computation in a manner that the base clock can run faster than for other organizations. However, clocks run at a fixed maximum speed. On modern systems they can slow down to reduce heat dissipation or battery consumption, but that does not make programs faster. So if one organization has a faster clock than another, the ratio is merely a linear term contributor. Apart from stopping, there is nothing a clock can do to participate in the decision making of the program. -
- -- Caching of values sent to the system memory again does not participate in the decision making of a program. We are at best looking at improvements in the linear term. -
- -- Branch prediction saves the time required to do a full fetch, but fundamentally it does not change the data flow graph of the program. The same decisions are made. -
- -
- Suppose that an organization keeps the operands for a function in a content-addressable memory. When the operands are recognized, it then immediately returns the looked-up value. This approach, called
- Common decisions made at the architecture level are those for supporting RISC or CISC, the bit layout and handling of operands, the size of the internal register file, how DMA is to be handled, whether to use memory-mapped I/O or have explicit instructions for it, how interrupts are to be implemented and the number of entries in the interrupt table, what special registers are present and what features are available through them, how virtual memory and its user and process IDs are to be implemented with the possible use of a translation lookaside buffer, what onboard execution units will have direct instructions, the built-in data types, questions of unaligned accesses, bus standards to be supported, if sleep modes are to be present, how the machine will get booted, the security rings that will be supported, details of the hardware virtualization layer, special support for the OS, how the system stack will be handled, potential partitioning of address space, support for large buffers, and memory sharing features: none of these are computation theoretic consequential. -
- -- As architecture enters the gray area with organization, cache architecture, bus layouts, bus buffers, direct inclusion of write buffers, perhaps a stack cache, prefetch buffers and split-transaction buses: none of these are computation theoretic consequential either. -
- -- Said features certainly affect performance, but none participate in the decisions the program makes, change the number of execution steps by more than a linear ratio, or alter the memory complexity of the program. -
- - - - -Because our TTCA Turing Machine has finite sized components, we may create a software model for the TTCA Turing Machine without having to make assumptions of the sort that âvery large approximates the infiniteâ. Rather we can show a one-to-one mapping of code and data in the software model and the TTCA variation of the Turing Machine. Consequently, the software model and theoretic model are isomorphic.
- -It follows that we can use our TTCA Turing Machine software to make theoretical statements about computation in the form of programs. By following this path we will learn some interesting things in this chapter about analysis, the meaning of emptiness, data type, the properties of non-destructive vs destructive programming styles, and multi-threaded programming among other things.
- -The Turing Machine, and our variation of it, may be partitioned into two parts. One part of the part consists of the tape head and the tape. We call this the Tape Transport Unit, as that is the name used for the mechanism that does this work on real tape storage units. The other part of the part is the Controller.
- -The Tape Transport Unit accepts commands for reading, writing, and moving the head. (In real Tape Transport Units the head is in a fixed position and we move the tape, but the relative affect is the same.) Our modified model adds commands for extending the tape. During normal operation these commands only come from the controller.
- -We have two types of controllers. One type of controller is a state machine. Its design is an integral part of the Turing Machine. To step the Turing Machine means to step this state machine to its next state. The state machine definition exists before the Turing Machine takes its first step, and its definition remains intact for as long as said Turing Machine exists.
- -When we speak of a Turing Machine without adding further words to the term as qualifiers, we mean that it uses this type of controller. For clarity we can call this a Directly Controlled Turing Machine.
- -The second type of controller is the Universal Controller, and a Turing Machine that uses this type of controller is called a Universal Turing Machine. The Universal Controller reads the definition of a state machine controller off of the tape. Hence the Universal Turing Machine may emulate any Directly Controlled Turing Machine. We can also call this an Indirectly Controlled Turing Machine. Here the qualifier âIndirectlyâ is intended in the sense it is used in assembly languages, meaning the data is not present in the controller, but rather it must be fetched from memory.
- -With our Tape Machine library, your program is the controller, and the library implements the Tape Transport Unit. (In the future I will rename this library to âTTUâ from the current âTMâ. Also the use of the term âfunctionâ will be changed to âroutineâ.)
- -Your program that uses the TTU library is in a sense direct control, because the program is already defined before the first step of the machine, and with the possible exception of self-modifying code, it does not change until the program exits, and thus the process no longer exists. On the other hand, your program is loaded from memory by the processor, thus demonstrating that the processor is an indirect, i.e. universal, controller. Either interpretation works depending on how broad of a view we want to take.
- -TM is presented as an iteration library on the de facto package manager for Lisp quicklisp. Alternatively, a person may clone the repository www.github.com/Thomas-Walker-Lynch/tm and then checkout the latest release tag, which as of this writing is v0.7-alpha. After installing the code cd into the tm directory and run your lisp interpreter. Inside your lisp interpreter type the commands (load âloadâ) and (test-all). test-all should return with a message that all of the tests passed.
- -It is possible that the threading tests, 'ts1-' might fail if your machine is heavily loaded or very slow, as they have timing built into them, but this is unlikely. Then type either (use-package :tm) or (in-package :tm) depending on what your objectives are.
- -The examples in this chapter either come from the tm/test directories, or from the tm/docs/examples directory. At the time they were placed in the book, they executed correctly, and I have endeavored to keep the examples up to date.
- -This is what it looks like when I follow install using the git clone method:
- -Notice I used git tag to see the releases. At this time, v0.7-alpha is the latest, so I checked that out. If you want the unstable latest code rather than the stable latest release, leave out the git checkout command.
- -The TM Library makes use of Unicode. There is no getting around it. This is discussed further in the next section. In addition TM defines synonyms for commands such as 'not equal', which is the one command shown at the end of the transcript given above.
- -For your convenience there is a file "emacs-keys" in the docs directory of the distribution. It sets the C-x g name SPC command to enter one of the Unicode characters that are used in the library. Here 'name' is a nickname.
- -So to type the character capital delta after emacs-keys has been loaded, type C-x g D SPC. Actually Î occurs twice in Unicode, once as capital delta, and once as a symbol for 'increment' in mathematics. We consider the increment version to only be there for typography purposes. We only use capital delta, even when it is for an increment variable.
- -I've limited the use of Unicode mostly to things that 'probably would have been this way had Unicode been around before'. This includes conventional notation and a couple of symbol extensions that were needed to facilitate the TM access language.
- -In the file src-0/fundamental.lisp find synonym bindings for the usual operators and common symbols such as â§, â¨, â¥, â¤, λ, â , etc.
- -Specific to the library we use the character '
We use 'â' in continuation function names, and 'â³' as a loop operator.
- -The
Since I had symbols for leftmost and rightmost, I started using them generally to mean leftmost or rightmost wherever it was convenient. For example, to shorten up the names of continuations so that parameter lists would fit on a line.
- -In Lisp a quoted list is taken as being literal. However the result of modifying a literal is undefined, and often leads to bad results. Hence we provide the macro q which returns a quoted list which is not a literal.
- -When a form enclosed in parentheses, ( ... ), is evaluated the head is taken as the name of a function, looked up and called. The list members are also evaluated, and then passed as arguments to said function. If we don't want the head treated specially, but rather want to define a list, we can use a front item of #'list, which is the function to create a list.
- -We have defined a macro called L that like #'list, creates a list, but which also has some extra functionality.
- -We also provide a reader macro for L as braces.
- -If the apparent function open, #'o, appears inside of a call to L, then the arguments of the #'o function are included directly in the resulting list:
- -Quoted non-literals can also occur within such an L list:
- -L acts identically to a quasiquote turned inside out. Whereas the default in quasiquote is to quote items, and a comma operator turns that off, the default in L is to evaluate items, and a q operator turns that off. Quasiquote has an @ marker to open up lists, while L has an o operator to open up lists. Inside of a quasiquote we could get in trouble if the name of a variable starts with an @ character; if such a variable appears after a comma, quasi quote will consider the variable name without the @ sign is to be opened and included. There is no analogous problem with the o operator because it only appears in the function channel. (The problem with quasiquote is that it uses 'in-band signaling' which mixes control with data in one channel.).
- -In Lisp the head of an evaluated list is taken as a function name. Consider this example that curries a two parameter function into a unary function by replacing one parameter with a constant argument of 3:
- -When we compile this function we get two errors:
- -The variable F is defined but never used.
- -and
- -undefined function: F
- -The first f is in the parameter list of the function definition, so it is taken as a variable name. In contrast the f in the body is at the head of an evaluated list, so it is taken as a function name. Hence there is a disconnect, and we get error messages describing this disconnect.
- -The Lisp operator #' indicates that the symbol that follows is a function name to be taken literally, and not a variable name. This gets our function name into the data space for use as an argument. The Lisp function funcall accepts as a first argument the name of a function to be called, while the remaining arguments are passed through to said function as its arguments:
- -In the definition for curry-three we do not get interpreter/compiler errors. This is because f is consistently used as a variable name. funcall will use the value of the variable f as the name of a function to call.
- -In the second line we define a function to pass into curry-three. I put something simple here for sake of discussion. plus is defined to be a function that takes two arguments and sums them.
- -In the third line we use the #' operator to tell Lisp that plus is a function name to be used literally as a value. This will be a value passed into curry-three no differently than had we put a number or string instance as an argument. Inside of curry-three the #'plus becomes the value of the variable f. Then the funcall function will use this value as a function name, and then call it.
- -This is how function pointers are handled in Lisp as it does not have an explicit pointer type.
- -Actually we didn't need to define the function plus, because '+' is already a function. We don't have reserved operator symbols in Lisp, instead we have loose rules on what can be used for function names.
- -We introduce a shortcut with the TM Library. Normally a list to be evaluated is in parenthesis, and its head is taken literally as a function name. With the TM Library loaded, when a list in square brackets is evaluated, the head is taken as a variable name, and the value of this variables is the function to be loaded. It is a nice coincidence that square brackets mean indirect addressing in many assembly languages.
- -We implemented this feature with a reader macro which simply turns the square bracket list into a regular list and inserts the funcall as its head. This occurs before the Lisp evaluate phase sees the syntax.
- -Using the square brackets we may define curry-three as:
- -Here is another example. Suppose that instead of passing #'plus in as an argument, that we first assigned it to a variable and then pass the variable value as an argument:
- -Here the value assigned to the variable our-fun is a function name. The variable is then used as any other, and its value is passed in as an argument to curry-three. Note, all arguments are evaluated before the function is called, so variables are replaced with their values. And as we know, inside curry-three, funcall will take the function name value from the corresponding parameter and call it as a function.
- -Things can become a little confusing when the variable name has the same name as the function.
- -Here #'plus is the function name as data. plus when it appears as the head of an evaluated list is a function name, otherwise it is a variable name. It is little wonder that the Lisp dialect Scheme put function names and variables name in the same space. However by doing so they had to provide some automatic conversions between variable names and function names.
- -When evaluated:
- -- Let us put this into perspective. Suppose in ancient Roman times that a clock tick for a computer was scaled to be one day long. Under this scale, a single nanosecond of real world execution time equates to three days. Suppose a program initiated a read request for a location in memory on the Ides of March, the date when Caesar was assassinated on -0043-03-15. The following table provides the historical date that the variable value would finally be loaded into the processor, depending on the memory tier being accessed: -
- -| Memory Tier | -Real World Latency | -Scaled Delay | -Scaled Arrival Era | -Historical Context | -
|---|---|---|---|---|
| L1 Cache Hit | -1 ns | -3 days | --0043-03-18 | -Three days after the assassination. | -
| DRAM (Main memory) | -100 ns | -300 days | --0042-01-09 | -Nearly a year later, during the Liberators' civil war. | -
| NVMe SSD Page Swap | -15 µs | -45,000 days | -0080 | -123 years later, exactly as the Colosseum is completed in Rome. | -
| SATA SSD Page Swap | -100 µs | -300,000 days | -0778 | -821 years later, during the reign of Charlemagne and the Frankish Empire. | -
| Magnetic HDD Page Swap | -10 ms | -30,000,000 days | -82092 | -Tens of thousands of years in the future, long after current human civilizations are dust. | -
- The latency table above speaks to the physical reality that constrains all programs, entirely independent of their theoretical complexity class. This illustrates why computer architects spend almost their entire effort designing machines that execute as many instructions per cycle as possible, operating within a memory subsystem mathematically optimized to keep data in the lowest latency tiers. As a demonstration of this industry focus, there is not a single chapter dedicated to computation theory in Hennessy and Patterson's definitive textbook on the subject
| Chapter 1 | -Fundamentals of Quantitative Design and Analysis | -
| Chapter 2 | -Memory Hierarchy Design | -
| Chapter 3 | -Instruction Level Parallelism and Its Exploitation | -
| Chapter 4 | -Data Level Parallelism in Vector, SIMD, and GPU Architectures | -
| Chapter 5 | -Thread Level Parallelism | -
| Chapter 6 | -Warehouse Scale Computers | -
| Chapter 7 | -Domain Specific Architectures | -
| Chapter 8 | -The Future of Computing | -
- Professor Gonzalez once observed that the primary purpose of computer architecture is to execute the customer's programs as rapidly as possible. IBM later amended this philosophy to add 'for what they paid for,' famously designing a computer model where performance was artificially restricted unless the customer paid to have a physical hardware jumper removed. Within this prevailing design philosophy, the graceful handling of computational end cases, where most formal theoretical questions arise, is deemed secondary because such cases do not occur frequently in the critical execution path. -
- -- The primary data structure of Lisp is the list, and its programs are designed fundamentally around list traversal. In this sense, the language closely mirrors the pure formal execution of a Turing Machine. Throughout the 1980s, companies such as Symbolics, Lisp Machines Incorporated, Texas Instruments, and Xerox produced computers based on architectures designed specifically to run Lisp natively. However, when Sun Microsystems introduced their workstations, the industry discovered these general purpose machines were relatively inexpensive and offered higher performance for the exact same Lisp programs. The commercial mandate to execute programs quickly decisively defeated formal architectural purity. -
- -- A counterexample to this trend occurred during the 1980s when two competing floating point standards emerged. The proposal from DEC allowed for optimally fast computation provided the behavior was well documented. Under this model, the bottom few bits of a computation could be imprecise, and following an interrupt, a program would be required to do diagnostic work to determine the specific instruction that caused the fault. The reasoning was that floating point computation is approximate by its very nature, and because end case interrupts occur infrequently, it makes no sense to sacrifice performance on workhorse computations to accelerate rare anomalies. -
- -- The competing standard, initially backed by Intel and soon adopted as the IEEE standard, demanded accuracy to the last bit for each operation, alongside synchronized interrupts. This predictable structure permitted a program to overflow, promote the value, and seamlessly continue an operation. It also specified the use of error tags that participate in a higher order error algebra. This standard ultimately prevailed because its precision guarantees and deterministic predictability provided the necessary foundation for the formal analysis of programs. -
- -- This continuous tension between pure formal models and practical execution speed remains a defining characteristic of the field, driving the structural logic behind modern mechanisms dealing with instruction pipelines, branch prediction, and memory aliasing. -
- -- James Stirling introduced these numbers in his 1730 publication, Methodus Differentialis, a text that directly expanded upon the foundational work laid by Newton. -
- -- The profound utility of Stirling numbers lies in their function as the definitive translation layer between continuous mathematics and discrete mathematics. In the context of the Turing Machine architecture, they are the exact mechanisms that bridge the continuous abstract polynomial with the discrete mechanical steps of the machine. -
- -- To understand their mechanical role, a person must look at the mathematical basis used in each domain. -
- -
- In continuous calculus, the natural basis for polynomials is standard exponentiation,
- However, in the calculus of finite differences, standard exponents are clumsy. Because the Turing Machine evaluates discrete jumps, the natural basis is the falling factorial, denoted as
-
- When a person applies the discrete forward difference operator,
- The Stirling numbers of the second kind are the coefficients required to project the continuous basis onto the discrete basis. They express standard powers as a sum of falling factorials: -
- -
-
- In combinatorics,
- In the Turing Machine architecture, the polynomial coefficients
- The signed Stirling numbers of the first kind perform the exact inverse operation. They reconstruct standard continuous powers from falling factorials: -
- -
-
- Combinatorially, the unsigned magnitude of
- In the context of the quotient machine or the coefficient recovery matrix, taking the inverse of the matrix formed by the second kind inherently generates a matrix composed of the first kind. This provides the direct algorithmic path to extract the continuous polynomial identity from the discrete mechanical state of the tape. -
- -- They essentially prove that no information is lost when moving a polynomial from the abstract realm into the physical constraints of a stepping machine. -
- -