From: Thomas Walker Lynch Date: Sat, 8 Aug 2026 11:00:10 +0000 (+0000) Subject: front matter revision X-Git-Url: https://git.reasoningtechnology.com/%27%20%20%20window.RT.dirpr_library%20%20%20%27/%27%20%20%20key%20%20%20%27?a=commitdiff_plain;h=789b11a25d2fe99fe60b6f63b408452c9ecdd45c;p=TM-2026 front matter revision --- diff --git a/document/book/TM-2026.html b/document/book/TM-2026.html index 45f69c8..cc476f1 100644 --- a/document/book/TM-2026.html +++ b/document/book/TM-2026.html @@ -16,6 +16,12 @@ + + + + + + - - - Preface + + Terminology

All communication is founded upon common knowledge, so here are some notes on the conventions used in this book.

Generally in this book, containers such as sequences and sets are capital letters, even when in Greek. Mathematical objects that are not containers are represented with lower case letters. Character pairs or full symbol names can also be used to represent mathematical objects. The context will make it clear if a non-letter unicode character is used to represent a container or a non-container.

-

The unicode middle dot, ·, is used as an ad hoc namespace operator in identifiers. Hence, N·x, would be the variable x from the N namespace. This is a typography symbol. It can be seen for example when words are broken into symbols, e.g. 'op·er·a·tor', and sometimes in names, such a 'Leonardo da·Vinci', and 'Vincent van·Gogh'. It is accepted in identifiers by modern C compilers, and it is part of the RT·gcc compiler mods for gcc.

+

The unicode middle dot, ·, is used as an ad hoc namespace operator in identifiers. Hence, N·x, would be the variable x from the N namespace. This is a typography symbol. It can be seen for example when words are broken into symbols, e.g. 'op·er·a·tor', and sometimes in names, such as 'Leonardo da·Vinci', and 'Vincent van·Gogh'. It is accepted in identifiers by modern C compilers, and it is part of the RT·gcc compiler mods for gcc.

I have experimented with modern gender forms in technical language in past writings. For example, I used the plural-as-singular style in one piece, and was applauded by some, though categorized as illiterate by others. Since then, I have evolved a writing style that emphasizes using roles as subjects: the mathematician, the author, the programmer. Such subjects are singular, so for grammatical agreement, I use the inclusive he. It is structurally much cleaner to use he as inclusive of all people than it is to gray out an entire category of plural agreement pronouns by forcing words such as "they" to take on a singular form. I use "a person" when the subject is an unknown third party, potentially even being an AI. I prefer this over the 'one' of 'One does this, or one does that.' so that 'one' can be reserved to unambiguously refer to the natural number.

-

In the prior edition of this book, the preface included a discussion on the meaning of the word "may" according to RFC 2119, the guidelines for specification writing. There is an important distinction between the 'may' of options or permission, and the more colloquial 'may' of probability. However, distinguishing between the two was too much of an ask of readers, most of whom skip the preface anyway. So in this edition, I avoid the temptation to use 'may' and replace it with a direct statement of what I mean. "It is of high probability that..." or "There are options for...". Directly saying what is meant, who would have thought of it? The RFC 2119 authors have apparently struggled with this as well, as they now require the MAY and other words that appear in RFC 2119 to be capitalized so as to dodge the grammar debate.

+

In the prior edition of this book, the preface included a discussion on the meaning of the word "may" according to RFC 2119, the guidelines for specification writing. There is an important distinction between the 'may' of options or permission, and the more colloquial 'may' of probability. However, distinguishing between the two was too much of an ask of readers, most of whom skip the preface anyway. So in this edition, I avoid the temptation to use 'may' and replace it with a direct statement of what I mean. "It is of high probability that..." or "There are options for...". Directly saying what is meant, who would have thought of it? The RFC 2119 authors have apparently struggled with this as well, as they now require the MAY and the other words that appear in RFC 2119 to be capitalized so as to dodge the grammar debate.

Code examples in this text follow the distinctive RT code format conventions.For the complete specification, refer to RT-code-format.html and RT-code-format-Lisp.html located at https://github.com/Thomas-Walker-Lynch/RT-Style/tree/core-developer_branch/developer/document. For example, horizontal comma-separated lists apply a space before the comma to bind the punctuation to the item being appended to the list:

- - int x ,y ,z; - + + + + int x ,y ,z; + + Code . A horizontal comma separated list +

Multi-level enclosures receive a single space of padding only on the outermost boundary:

- - if( f(g(x)) ){ - + + + + if( f(g(x)) ){ + + Code . Padding applied to the outermost enclosure only +

Furthermore, identifier naming leverages both hyphens and underscores, when available, to establish semantic binding precedence. An example of this is:

- - rounded_x-coordinate - + + + + rounded_x-coordinate + + Code . A hyphen binding tighter than an underscore within an identifier + -

Furthermore, in this coding culture, we say that arguments values are given to a function. Functions do not take arguments, as a call stack cannot reach into memory and grab values. A function is only said to accept or reject a value in the context of guard code evaluating its validity. Similarly, machines, factories, and software make objects by assembling components; they do not create them, as creation implies a fundamental synthesis outside the scope of engineering.

+

Furthermore, in this coding culture, we say that argument values are given to a function. Functions do not take arguments, as data is flowing from the caller to the function. A function is only said to accept or reject a value in the context of guard code evaluating argument validity. Similarly, machines, factories, and software make objects by assembling components; they do not create them, thus leaving 'creation' to imply a more fundamental synthesis outside the scope of engineering, perhaps done by artists and supernatural beings.

Whenever standard mathematical or Greek symbols are required, this text utilizes native Unicode characters rather than relying on escape sequences. For example, the text uses 'δ' directly instead of, say, "\delta"; this might lead to some small typesetting variations.

Dates and times are given in the ISO 8601 format. The components run from the most significant to the least significant, year, then month, then day, in the same order the digits of a Hindu-Arabic numeral run. Two consequences follow from that ordering, and both are the reason for choosing it. A lexicographic comparison of two such dates agrees with their chronological comparison, so a list of them sorts correctly with no collation rules particular to dates. And the format is unambiguous, whereas a date such as 03/04/2026 is read as the third of April by some readers and the fourth of March by others. A time of day, when one is given, follows the date, and a trailing Z marks the time as UTC. Hence 2026-06-01 08:28:00Z. Where a date appears without a time, the date alone is intended, e.g. 2026-06-01.

+
+ + + + Preface + +

One afternoon I was fortunate to have lunch in Berkeley with Bill Kahan, a pioneer in applied number theory, and our conversation turned to errors in numeric computation. I observed that an error is merely an opportunity to do more computing. Bill seemed to like the remark; he repeated it in a Dr. Dobb's interview, where it was credited to him. When we met again, I asked him about it. He apologized, explaining that the interviewer had created something rather than reporting it, and that he was surprised himself by what he read. The apology was unnecessary. I had intended to summarize Kahan's own work. He was instrumental in creating IEEE Std. 754, where an exceptional condition, more informally an "error", need not end computation but can serve as a gateway to a higher symbolic algebra. I found that architecture inspiring, and my comment had been intended to acknowledge his inspiration.

+ +

In practical computing the symbol algebra of the IEEE Std. 754 quickly devolves into the catch all indeterminate value, the so called NaN, which tends to leave programmers wishing to extend the system. Kulisch and Miranker attempted to formalize computer arithmetic, and started by reasoning about a screen that laid out over the real number space. Boehm and Cartwright introduced a concept of Constructive Real Numbers, where precision of computation was extended upon demand. And through Stephen Wolfram's vision, Mathematica provides a complete symbolic math manipulation package, where a symbolic expression can be reduced before being evaluated. For evaluation they then track loss of precision through significance arithmetic. In my own work, I have suggested an analysis step first, where required precision is derived, followed by computation. However, among these there is still missing a formalism of passing through the gateway upon an error, so to speak. Mathematica comes the closest.

+ +

John Gustafson also brought up the topic of the nature of error shortly before publishing "The End of Error". He now has another proposal based on variable precision arithmetic known as "posits". There was so much I wanted to say when we spoke, but I could not formulate the thoughts. I had learned a great deal while doing formal analysis of the algorithms I had put on the Am29050, Am486, and K5 processors at AMD, but when I tried to articulate this, I only stammered. I feel that I fell short, as all I could do is point at my already published work at that time on high radix online arithmetic. So this volume is my answer to John's question. Albeit it is a little late, well years late, but I hope it will still have some value.

+ +

There is a first edition of this book. The same concepts are described in those pages, but the story is not as well told, and no one has come full circle to say it made any sense to them. Well, one colleague, after reviewing the first edition, admitted he was bewildered by it and asked if I was proposing that we build Turing Machines. After all we are the music makers, in the music business, so to speak; only instead of being written in notes, our music is written in transistors and layout. So then, he rightfully asks, what is the proposal here? I could only point him at Mitch Alsup's book, and ponder how I could tell this story differently.

+ +

There is not a hardware specification for a new proposed machine in this book. This book is not proposing to build in hardware a Turing Machine. This is an absolute. Building a TTCA machine might be interesting, and the organization for it is described in this book, but that is certainly not the proposal here. Rather this book lays the foundation for a proposal for another machine. It explains and justifies that other machine's features. But the details, the architecture, of this other machine are not found in these pages.

+ +

There is a practical aspect to this work. A software library that is of general usefulness can be found in these pages, and downloaded from GitHub. The library was first articulated in the Lisp language in the first edition of the book and released on Quicklisp. Lisp is in a sense pure, and formal statements can be made with it. Using it for the library made the library a natural small step away from the formal discussion that came before it was presented. Since that time I have written parts of the library in other languages and found it very useful. This volume presents the Python API.

+ +

While reaching to say something of value, I reach into foundational mathematics, a bit of number theory, and computation theory. Familiarity with those subjects will help readers read this volume, though it might not be absolutely necessary. In a sense computation theory is post Turing-Church et al. number theory. Number theory is conventionally thought of as the analysis of structures related to Natural Numbers. However, those structures are themselves entities, and a person must ask what a number is, if a number itself is not merely the structure described by Peano. It follows that when computer scientists or engineers focus their attention on numeric algorithms and circuits, they are practicing applied number theory. This in turn is a specialization of the study of algorithms in general, one where the structures are said to be numbers, and thus is part of computation theory, completing the circle.

+ +
+ + + + Introduction + +

Kleene's Introduction to Metamathematics opens with, "A flock of four sheep and a grove of four trees are related to each other in a way in which neither is related to a pile of three stones or a grove of seven trees. ... Without counting the sheep or the trees, one can pair them with each other, for example by tethering the sheep to the trees, so that each sheep and each tree belongs to exactly one of the pairs."Stephen Cole Kleene, Introduction to Metamathematics (Amsterdam: North-Holland, 1952), 3.

+ +

Kleene's words are more than an introduction to Cantor's transfinite numbers. They appeal to Naturalism as a foundation. They leverage the reader's intuition, while succinctly making the implicit point that mathematics has purpose.

+ +

In his foundational paper Alan Turing asks us to think of a clerk sitting at a desk writing on paper while following some rules, and to imagine what can be written. Turing's own founding image is thus an observation of the world rather than an independently standing abstract form.

+ +

Here the Naturalist runs into a problem. The Turing Machine is not practical to build. The infinite tape is of course an issue, but it is perhaps not the most serious obstacle to realizing a Turing Machine. As I will formalize later in this book, the Turing Machine head must always read and react, and this will force the author of the controller to build memory into the control. In turn this causes the controller to explode in size with machine word width.

+ +

However, this situation is recoverable. This volume presents modifications that lead to an alternative computation theoretic object that is equally expressive as a Turing Machine, and yet is practical to build. This then restores the validity of the Naturalist interpretation.

+ +

For a question to be resolved by a Turing Machine, the question must be formed as a program that when run produces a result in a finite number of steps. Practicality is an even stronger constraint than being computational. For running a program to be practical, finishing in a finite number of steps is not sufficient; it must also complete before a given deadline. In the natural world, we all operate under the constraints of being practical. However, that does not prevent us from having a practical discussion about what is theoretically possible to compute, and such discussion is found in the pages of this book.

+ +

It is commonly thought that Turing Machines, and thus observations of nature, are limited to discrete computation, and thus there is a large domain of continuous mathematics that they can not speak about. However, the very concept of the continuous is described in discrete terms. Consider the simple function x^2 over a real field. It is considered to be a continuous function, yet it consists of discrete symbols. To take its derivative is to follow the steps of an algorithm, i.e. a program, which brings the 2 down as a multiplier and replaces the exponent with a 1, or leaves it out altogether. These are discrete steps resulting in another discrete formula, 2 x. In that the word continuous is given meaning, it becomes discrete.

+ +

Analysis is the bridge that leads from the natural world to the world of forms. Here analysis is the activity of asking about the properties of a program instead of running it. The program being analyzed then becomes the input data for the program doing the analysis. Turing's original paper introduced the naturalist interpretation of mathematics via the clerk at the desk, described a machine for automating the clerk's work, introduced the idea of a stored program, described analysis, and pointed out that it was possible to analyze an analyzer. And as though that was not enough, he provided a general analysis applicable to halting analyzers that proved that no universal halting analyzer can exist. (A halting analyzer is an analyzer, i.e. a program, that analyzes a given program to decide if that given program halts or not.) This does not mean that a halting analyzer can not ever be practical. For a large class of programs a halting analyzer can give an answer, and do so before a deadline. However, the proof result means that for any halting analyzer, there will be programs for which it will not be able to decide whether they halt or not, even when there is no deadline apart from 'finite number of steps'.

+ +

Here then, is an interesting thing about some Turing Machine programs that do not halt. Though they can not be run to completion, they can be analyzed. Say a program prints the 's' character, then loops back, and thus prints the 's' character again and again. Such a program can not be run to completion as it never halts. However, the program can be analyzed and talked about, as of course we already know, as we are doing this very thing right now. Thus the holes in the lower level language kick the problem up to a higher level where questions are asked as to how the program behaves and what an exceptional condition means.

+ +

Accordingly the world of forms is not a separate realm. It is the tower of languages standing above the machine, each layer of it there to speak of the holes in the layer beneath. Those languages become separated from the machine that gave rise to them, so the base machine never need be run. At each moment, we reach the limit of what can happen in that moment, then a new moment arrives, both in stepping through programs, and in layers of abstraction.

+ The search that led to the Turing Machine

- In 1893 Gottlob Frege published an axiomatic construction of mathematics from set theory. Frege's grand objective was something he called Logicism, the philosophical thesis that all of mathematics can be derived entirely from pure logic. To bridge set theory and logic, Frege defined sets using a method known as set comprehension. Under this approach, a mathematician states a logical rule or property, and any object satisfying that logical statement automatically becomes a member of the set. Because the membership of a set is determined entirely by logical rules, the resulting sets, and the mathematics built upon them, are derived directly from logic. To implement this, his specific machinery relied upon unrestricted set comprehension, formalized as Basic Law V Gottlob Frege, Grundgesetze der Arithmetik, Vol. 2 (Jena: Hermann Pohle, 1903), Appendix (Nachwort), 253.. + In 1893 Gottlob Frege published an axiomatic construction of mathematics from set theory. Frege's grand objective was something he called Logicism, the philosophical thesis that all of mathematics can be derived entirely from pure logic. To bridge set theory and logic, Frege defined sets using a method known as set comprehension. Under this approach, a mathematician states a logical rule or property, and any object satisfying that logical statement automatically becomes a member of the set. Because the membership of a set is determined entirely by logical rules, the resulting sets, and the mathematics built upon them, are derived directly from logic. To implement this, his specific machinery relied upon unrestricted set comprehension, formalized as Basic Law V Gottlob Frege, Grundgesetze der Arithmetik, Vol. 1 (Jena: Hermann Pohle, 1893), §20..

At a conference in Paris in 1900, David Hilbert presented a list of pressing unsolved problems in mathematics. - Second on his list was "The Compatibility of the Arithmetical Axioms." Hilbert challenged mathematicians to find a means to demonstrate that "a finite number of logical steps based upon them [axioms] can never lead to contradictory results" F. N. Cole et al., eds., Bulletin of the American Mathematical Society, Vol. 8 (New York: Macmillan, 1902). This can be found at https://www.gutenberg.org/cache/epub/71655/pg71655-images.html. The MathWorld article on this subject, https://mathworld.wolfram.com/HilbertsProblems.html, explains that Hilbert presented 10 problems at the conference, though the publication shows 23 problems, and shortly later a 24th problem was added. Based on the notes of this citation, it appears the second problem is the same on all of these lists. Also note, Hilbert discusses completeness specifically as an axiom for bounding on the sets, which appears to be distinct from the question of logical completeness for an axiomatic system.. + Second on his list was "The Compatibility of the Arithmetical Axioms." Hilbert challenged mathematicians to find a means to demonstrate that "a finite number of logical steps based upon them [axioms] can never lead to contradictory results" David Hilbert, "Mathematical Problems," trans. Mary Winston Newson, Bulletin of the American Mathematical Society 8 (1902): 437–479. This can be found at https://www.gutenberg.org/cache/epub/71655/pg71655-images.html. The MathWorld article on this subject, https://mathworld.wolfram.com/HilbertsProblems.html, explains that Hilbert presented 10 problems at the conference, though the publication shows 23 problems, and a 24th problem was later discovered among Hilbert's unpublished notes. Based on the notes of this citation, it appears the second problem is the same on all of these lists. Also note, Hilbert discusses completeness specifically as an axiom for bounding on the sets, which appears to be distinct from the question of logical completeness for an axiomatic system..

- In 1901 Bertrand Russell found a well-formed set formulation using Frege's set theory that did not correspond to a set. As Frege's work was based on this set theory, this called into question his entire work. Russell pointed out that it was possible to define a set of all sets that do not contain themselves. However this was a paradox, because if said set contained itself, it shouldn't, and if it didn't it should. Thus the formulation failed to define a set because the logical condition cannot be satisfied Bertrand Russell, The Principles of Mathematics (Cambridge: Cambridge University Press, 1903), Chapter X, 'The Contradiction'.. Russell communicated this to Frege in a letter dated 1902 06 16, shortly before his second volume was going to print Bertrand Russell to Gottlob Frege, June 16, 1902, reprinted in Jean van Heijenoort, From Frege to Gödel: A Source Book in Mathematical Logic (Cambridge: Harvard University Press, 1967), 124 125. Gottlob Frege, Grundgesetze der Arithmetik, Vol. 2 (Jena: Hermann Pohle, 1903), Appendix (Nachwort), 253. Frege writes: 'Hardly anything more unfortunate can befall a scientific writer than to have one of the foundations of his edifice shaken after the work is finished.'. Frege hurriedly authored an appendix (the Nachwort) admitting his system was compromised Frege was a quiet, rigid man who had spent decades building his logical fortress in almost total academic obscurity. Frege was personally devastated by Russell's letter. Shortly after, he suffered the loss of his wife, fell into severe depression, and his academic output almost entirely ceased. In 1924, a year before his death, he wrote unpublished diaries explicitly surrendering his life's work, declaring that logicism was a mistake and that mathematics must actually be derived from geometry. Note I. Grattan Guinness, The Search for Mathematical Roots, 1870 1940 (Princeton: Princeton University Press, 2000). For an analysis of Frege's intellectual decline, personal tragedies, and his unpublished 1924 1925 diaries where he formally surrenders the logicist program, see Chapter 7.. + In 1901 Bertrand Russell found a well-formed set formulation using Frege's set theory that did not correspond to a set. As Frege's work was based on this set theory, this called into question his entire work. Russell pointed out that it was possible to define a set of all sets that do not contain themselves. However this was a paradox, because if said set contained itself, it shouldn't, and if it didn't it should. Thus the formulation fails to define a set because the logical condition cannot be satisfied Bertrand Russell, The Principles of Mathematics (Cambridge: Cambridge University Press, 1903), Chapter X, 'The Contradiction'.. Russell communicated this to Frege in a letter dated 1902-06-16, shortly before Frege's second volume was going to print Bertrand Russell to Gottlob Frege, June 16, 1902, reprinted in Jean van Heijenoort, From Frege to Gödel: A Source Book in Mathematical Logic (Cambridge: Harvard University Press, 1967), 124–125. Gottlob Frege, Grundgesetze der Arithmetik, Vol. 2 (Jena: Hermann Pohle, 1903), Appendix (Nachwort), 253. Frege writes: 'Hardly anything more unfortunate can befall a scientific writer than to have one of the foundations of his edifice shaken after the work is finished.'. Frege hurriedly authored an appendix (the Nachwort) admitting his system was compromised Frege was a quiet, rigid man who had spent decades building his logical fortress in almost total academic obscurity. Frege was personally devastated by Russell's letter. Shortly after, he suffered the loss of his wife, fell into severe depression, and his academic output almost entirely ceased. In 1924, a year before his death, he wrote unpublished diaries explicitly surrendering his life's work, declaring that logicism was a mistake and that mathematics must actually be derived from geometry. Note I. Grattan-Guinness, The Search for Mathematical Roots, 1870–1940 (Princeton: Princeton University Press, 2000). For an analysis of Frege's intellectual decline, personal tragedies, and his unpublished 1924–1925 diaries where he formally surrenders the logicist program, see Chapter 7..

- In 1903 Russell proposed a hierarchy of types to repair this foundational vulnerability. At the base were sets of individuals, then sets based on individuals or sets of individuals, etc. This looks a lot like how types work in modern software Bertrand Russell, The Principles of Mathematics (Cambridge: Cambridge University Press, 1903), Appendix B: The Doctrine of Types.. In this manner, it is not possible to write a paradoxical set definition. Russell and Alfred North Whitehead then engineered an entirely new, massive scaffolding utilizing this type system to pursue Frege's original objective of deriving mathematics from logic, publishing their results in three volumes between 1910 and 1913 Alfred North Whitehead and Bertrand Russell, Principia Mathematica (Cambridge: Cambridge University Press, 1910 1913).. Russell's system can be cumbersome due to requiring a large construction to be assembled in place of what otherwise might have been a simple rule. + In 1903 Russell proposed a hierarchy of types to repair this foundational vulnerability. At the base were sets of individuals, then sets based on individuals or sets of individuals, etc. This looks a lot like how types work in modern software Bertrand Russell, The Principles of Mathematics (Cambridge: Cambridge University Press, 1903), Appendix B: The Doctrine of Types.. In this manner, it is not possible to write a paradoxical set definition. Russell and Alfred North Whitehead then engineered an entirely new, massive scaffolding utilizing this type system to pursue Frege's original objective of deriving mathematics from logic, publishing their results in three volumes between 1910 and 1913 Alfred North Whitehead and Bertrand Russell, Principia Mathematica (Cambridge: Cambridge University Press, 1910–1913).. Russell's system can be cumbersome due to requiring a large construction to be assembled in place of what otherwise might have been a simple rule.

- In 1908 Ernst Zermelo published an alternative system designed to avoid the known paradoxical statements of the time, even though absolute consistency remained unproven. In Zermelo's set theory, a mathematician first starts with an existing set, and then applies the Axiom of Separation using definite properties to partition out subsets Ernst Zermelo, "Untersuchungen über die Grundlagen der Mengenlehre I," Mathematische Annalen 65 (1908): 261 281.. To see how this works, consider the expression \{x \mid P(x)\}. Under unrestricted comprehension, a logician is permitted to define the predicate P(x) as x ∉ x. This produces Russell's Paradox, so the set fails to be defined. In contrast, consider the same predicate, though restricted by Zermelo's Axiom of Separation over a predefined set S, written as \dot{R} = \{x \mid x ∈ S ∧ x ∉ x\}. The only thing a person needs to know about S here is that it has already been successfully defined. So let us ask, is \dot{R} in \dot{R}? If we assume \dot{R} is a member of S, evaluating the second term forces the familiar fatal loop: if \dot{R} is in \dot{R}, it shouldn't be, and if it isn't, it should be. Thus if we assume that \dot{R} is in S, then \dot{R} can not be defined, but by definition, S is defined, and thus its members are defined. As we arrived at a contradiction, the original assumption must be false, i.e. it is wrong to assume that \dot{R} is in S. As \dot{R} is definitively not a member of \dot{R}, the first term of the set comprehension rule, x ∈ S is false, and the paradox vanishes. + In 1908 Ernst Zermelo published an alternative system designed to avoid the known paradoxical statements of the time, even though absolute consistency remained unproven. In Zermelo's set theory, a mathematician first starts with an existing set, and then applies the Axiom of Separation using definite properties to partition out subsets Ernst Zermelo, "Untersuchungen über die Grundlagen der Mengenlehre I," Mathematische Annalen 65 (1908): 261–281.. To see how this works, consider the expression \{x \mid P(x)\}. Under unrestricted comprehension, a logician is permitted to define the predicate P(x) as x ∉ x. This produces Russell's Paradox, so the set fails to be defined. In contrast, consider the same predicate, though restricted by Zermelo's Axiom of Separation over a predefined set S, written as \dot{R} = \{x \mid x ∈ S ∧ x ∉ x\}. The only thing a person needs to know about S here is that it has already been successfully defined. So let us ask, is \dot{R} in \dot{R}? If we assume \dot{R} is a member of S, evaluating the second term forces the familiar fatal loop: if \dot{R} is in \dot{R}, it shouldn't be, and if it isn't, it should be. Thus if we assume that \dot{R} is in S, then \dot{R} can not be defined, but by definition, S is defined, and thus its members are defined. As we arrived at a contradiction, the original assumption must be false, i.e. it is wrong to assume that \dot{R} is in S. As \dot{R} is definitively not a member of S, the first term of the set comprehension rule, x ∈ S, is false, and the paradox vanishes.

- A person might suggest defining S as the set of all definable mathematical objects, forming a universal set. However, if such a universal set S existed, the Axiom of Separation could be applied using the previous predicate to isolate \dot{R}. Because \dot{R} is a valid, definable set, it must reside within S by the very definition of a universal set. But notice that the logic evaluated earlier proved definitively that \dot{R} cannot be a member of S. Yet the existence of a definable set \dot{R} that sits strictly outside of S contradicts the premise that S contains everything. Therefore, within any system governed by the Axiom of Separation, a universal set cannot exist. + A person might suggest defining S as the set of all definable mathematical objects, forming a universal set. However, if such a universal set S existed, the Axiom of Separation could be applied as per the proof in the prior paragraph to show \dot{R} is not in S. However, as \dot{R} is a valid, definable set, it must reside within S by the very definition of a universal set. This contradicts the premise that S contains everything. Therefore, within any system governed by the Axiom of Separation, a universal set cannot exist.

- The authority to remove the Russell's Paradox set formulation comes from the set S. If we know its definition, then the authority comes through that definition. However, if we merely stipulate that S must be defined, then we are expressing our authority through S by declaring, "Undefined sets are not allowed." In the explanation above, it is only after discovering a set is undefined that we conclude it is not a member of S. I sometimes wonder how mathematics might have evolved had Frege simply taken that approach. We take this question up again in the chapter Computational Naturalism, and discover there is a deeper issue. + The authority to remove Russell's Paradox set formulation comes from the set S. If we know its definition, then the authority comes through that definition. However, if we merely stipulate that S must be defined, then we are expressing our authority through S by declaring, "Undefined sets are not allowed." In the explanation above, it is only after discovering a set is undefined that we conclude it is not a member of S. I sometimes wonder how mathematics might have evolved had Frege simply taken that approach. We take this question up again in chapter , Computational Naturalism, and discover there is a deeper issue.

- Stepping back from the mechanics of set definition, a person can observe two competing approaches to establishing mathematical foundations. The first approach is constructive, building complex systems by assembling them upward from fundamental primitives. The second approach relies on islands of meaning, carving out valid spaces from the abstract void using precise rules and axioms, exactly as Zermelo did. Because both methodologies rely entirely upon a rigorous framework of deduction to function, logic itself serves as the essential substrate. Consequently, a complete foundational study requires the examination of three distinct subjects: the primitives used for construction, the rules that bound the theoretical islands, and the underlying logic that evaluates them both. + Stepping back from the mechanics of set definition, a person can observe two competing approaches to establishing mathematical foundations. The first approach is constructive, building complex systems by assembling them upward from fundamental primitives. The second approach relies on islands of meaning, carving out valid spaces from the abstract void using precise rules and axioms, exactly as Zermelo did. Because both methodologies rely entirely upon a rigorous framework of deduction, logic itself serves as the essential substrate. Consequently, a complete study of the foundation of mathematics requires the examination of three distinct subjects: the primitives used for construction, the rules that bound the theoretical islands, and the underlying logic that evaluates them both.

- In 1928 David Hilbert and Wilhelm Ackermann published a textbook on mathematical logic, Grundzüge der theoretischen Logik David Hilbert and Wilhelm Ackermann, Grundzüge der theoretischen Logik (Berlin: Springer, 1928). This first edition has not been translated into English.. A feature of this book is its attention to procedures to follow for mechanically determining truth of statements. They called the problem solved by such a procedure the Entscheidungsproblem. In the first chapter they review the procedure for solving the Entscheidungsproblem in the propositional logic. For the first order predicate calculus they define the problem as, "Universal validity concerns the following question: How can one determine, for any given logical expression that contains no individual signs [constants], whether the expression represents a true assertion for arbitrary substitutions for the occurring variables, or not?" Ibid., 72 73.. They review some special cases with solutions, including one published earlier by Ackermann, but then throw down the gauntlet by saying, + In 1928 David Hilbert and Wilhelm Ackermann published a textbook on mathematical logic, Grundzüge der theoretischen Logik David Hilbert and Wilhelm Ackermann, Grundzüge der theoretischen Logik (Berlin: Springer, 1928). This first edition has not been translated into English.. A feature of this book is its attention to procedures to follow for mechanically determining truth of statements. They called the problem solved by such a procedure the Entscheidungsproblem. In the first chapter they review the procedure for solving the Entscheidungsproblem in the propositional logic. For the first order predicate calculus they define the problem as, "Universal validity concerns the following question: How can one determine, for any given logical expression that contains no individual signs [constants], whether the expression represents a true assertion for arbitrary substitutions for the occurring variables, or not?" Ibid., 72–73.. They review some special cases with solutions, including one published earlier by Ackermann, but then throw down the gauntlet by saying, "A general solution to the Entscheidungsproblem, regardless of whether a person considers the first or the second formulation, is not yet available." Ibid., 81. "Eine allgemeine Lösung des Entscheidungsproblems, mag man nun die erste oder die zweite Fassung nehmen, liegt bis jetzt noch nicht vor." The term Entscheidungsproblem literally translates to 'decision problem'. However, there are many types of decision problems, and later we will meet a class of Turing Machine programs called deciders, so it appears to be best to keep the original German. As we will see later Alan Turing also did this..

- In 1931 Kurt Gödel published his incompleteness theorems Kurt Gödel, "Über formal unentscheidbare Sätze der Principia Mathematica und verwandter Systeme I," Monatshefte für Mathematik und Physik 38 (1931): 173 198.. By mapping formal logic into arithmetic, he demonstrated that any consistent formal system sufficiently powerful to perform basic arithmetic, let us call it system S, will inevitably contain well-formed formulas that are mathematically true yet cannot be proven within the system itself For the definitive English translation, see Jean van Heijenoort, From Frege to Gödel: A Source Book in Mathematical Logic, 1879 1931 (Cambridge: Harvard University Press, 1967), 596 616.. Gödel achieved this by engineering a specific formula that evaluates to the claim: "G: There exists no sequence of valid logical steps within system S that proves G." If system S is consistent, it cannot output a proof for G; thus, the claim G makes is factually accurate, rendering it true but mechanically unprovable. Furthermore, Gödel demonstrated that system S cannot output a proof of its own consistency. This result fractured David Hilbert's 1900 vision of utilizing a weaker, strictly "finitistic" logical subsystem to definitively prove that the axioms of arithmetic are entirely free of contradictions David Hilbert, "Mathematical Problems," Bulletin of the American Mathematical Society 8 (1902): 437 479.. If the full, powerful system S physically lacks the mechanical capacity to verify its own consistency, Hilbert's weaker finitistic subsystem is definitively incapable of accomplishing the task. Gödel's work established a hard mechanical boundary, asserting that truth and provability are distinct concepts in classical mathematics. + In 1931 Kurt Gödel published his incompleteness theorems Kurt Gödel, "Über formal unentscheidbare Sätze der Principia Mathematica und verwandter Systeme I," Monatshefte für Mathematik und Physik 38 (1931): 173–198.. By mapping formal logic into arithmetic, he demonstrated that any consistent formal system sufficiently powerful to perform basic arithmetic, let us call it system F, will inevitably contain well-formed formulas that are mathematically true yet cannot be proven within the system itself For the definitive English translation, see Jean van Heijenoort, From Frege to Gödel: A Source Book in Mathematical Logic, 1879–1931 (Cambridge: Harvard University Press, 1967), 596–616.. Gödel achieved this by engineering a specific formula that evaluates to the claim: "G: There exists no sequence of valid logical steps within system F that proves G." If system F is consistent, it cannot output a proof for G; thus, the claim G makes is factually accurate, rendering it true but mechanically unprovable. Furthermore, Gödel demonstrated that system F cannot output a proof of its own consistency. This result fractured David Hilbert's 1900 vision of utilizing a weaker, strictly "finitistic" logical subsystem to definitively prove that the axioms of arithmetic are entirely free of contradictions David Hilbert, "Mathematical Problems," Bulletin of the American Mathematical Society 8 (1902): 437–479.. If the full, powerful system F lacks the mechanical capacity to verify its own consistency, Hilbert's weaker finitistic subsystem is definitively incapable of accomplishing the task. Gödel's work established a hard mechanical boundary, asserting that truth and provability are distinct concepts in classical mathematics.

- In April 1936, Alonzo Church leveraged Gödel's foundational papers to directly answer the Entscheidungsproblem Alonzo Church, "An Unsolvable Problem of Elementary Number Theory," American Journal of Mathematics 58, no. 2 (April 1936): 345 363.. Working independently, Alan Turing had arrived at his own mechanical solution, and upon seeing Church's April publication, Turing rushed to submit his manuscript on 28 May 1936, appending a proof that his mechanical architecture was mathematically equivalent to Church's lambda calculus Alan M. Turing, "On Computable Numbers, with an Application to the Entscheidungsproblem," Proceedings of the London Mathematical Society s2 42, no. 1 (1936): 230 265. Received May 28, 1936, published November 30, 1936.. As Hilbert and Ackermann concede in the 1938 second edition of their textbook, Church's results demonstrated that "the quest for a general solution of the decision problem must be regarded as hopeless" David Hilbert and Wilhelm Ackermann, Principles of Mathematical Logic, 2nd ed. (New York: Chelsea Publishing Company, 1950), 124.. By giving the "somewhat vague intuitive concept of recursion a certain precise formalization," Church proved the "non-existence of such a recursive procedure" that could mechanically yield a value of truth or falsehood for every individual formula Ibid., 124.. + In 1936-03, Alonzo Church leveraged Gödel's foundational papers to directly answer the Entscheidungsproblem Alonzo Church, "A Note on the Entscheidungsproblem," The Journal of Symbolic Logic 1, no. 1 (March 1936): 40–41; correction, The Journal of Symbolic Logic 1, no. 3 (September 1936): 101–102., resting that argument on the unsolvability result he published the following month Alonzo Church, "An Unsolvable Problem of Elementary Number Theory," American Journal of Mathematics 58, no. 2 (April 1936): 345–363.. Working independently, Alan Turing had arrived at his own mechanical solution, and upon seeing Church's work, Turing rushed to submit his manuscript, which was received on 1936-05-28 Alan M. Turing, "On Computable Numbers, with an Application to the Entscheidungsproblem," Proceedings of the London Mathematical Society s2 42, no. 1 (1936): 230–265. Received May 28, 1936, read November 12, 1936.. On 1936-08-28 he appended a proof that his mechanical architecture was mathematically equivalent to Church's lambda calculus.

-

- Alan Turing used an abstraction of a computing machine, also described as a clerk working at a desk with pen and squares on paper while following a procedure, to prove that no primary 'analyzer' program can universally decide whether a second 'studied' program will halt when it is run Alan M. Turing, "On Computable Numbers, with an Application to the Entscheidungsproblem," Proceedings of the London Mathematical Society s2 42, no. 1 (1936): 230 265.. An answer to this halting problem (specifically asserting "The studied machine halts" or "The studied machine does not halt") would indeed be a statement in first order logic. Thus, by showing no analyzer can universally make such a determination, Turing proved that no decider could exist for the Entscheidungsproblem. + Alan Turing used an abstraction of a computing machine, also described as a clerk working at a desk with pen and squares on paper while following a procedure, to prove that no primary 'analyzer' program can universally decide whether a second 'studied' program will halt when it is run Ibid.. An answer to this halting problem (specifically asserting "The studied machine halts" or "The studied machine does not halt") would indeed be a statement in first order logic. Thus, by showing no analyzer can universally make such a determination, Turing proved that no decider could exist for the Entscheidungsproblem.

@@ -128,23 +190,27 @@ Turing employed an enumerative diagonal argument to establish this result. A simpler proof by contradiction that is commonly used today was first published by Christopher Strachey in 1965 Christopher Strachey, "An Impossible Program," The Computer Journal 7, no. 4 (January 1965): 313. In his letter, Strachey explicitly attributed the distilled logic to an existing "well known piece of folklore among programmers.". To begin the proof, assume a person builds a perfect decider program, H(p, i), that evaluates any given program p executing with input i, then outputs 'Y' if p(i) halts, and 'N' if it does not halt. Next, a person writes a malicious program, M(x), that incorporates H as a subroutine. When M receives an input program x, it evaluates H(x, x) to determine how program x behaves when given itself as input. If H(x, x) outputs 'Y', M enters an infinite loop; if H(x, x) outputs 'N', M immediately halts.

- - M(x){ - if(H(x ,x) == 'Y') while(true); - else if(H(x ,x) == 'N') return; - } - + + + + M( x ){ + if( H(x ,x) == 'Y' ) while( true ); + else if( H(x ,x) == 'N' ) return; + } + + Code . The diagonal machine that defeats a supposed halting decider +

The evil part occurs when we give program M(x) itself as input, M(M). Program M calls its subroutine and asks H(M, M) what M will do. If H outputs 'Y', it is wrong, because M loops infinitely. If H outputs 'N', then it is wrong, because M halts. The decider H is forced into an inescapable failure, proving that no universal decider can exist.

- While Gödel, Church, and Turing established the primary boundaries of computation, they did not work in a vacuum. During this period, the broader academic community worked to synthesize the definitive mechanics of effective calculability. Jacques Herbrand and Gödel formalized general recursive functions between 1931 and 1934 Kurt Gödel, "On Undecidable Propositions of Formal Mathematical Systems," mimeographed lecture notes, Institute for Advanced Study, Princeton, 1934.. Emil Post independently defined "Finite Combinatory Processes" in 1936, outlining a theoretical architecture functionally identical to Turing's model Emil L. Post, "Finite Combinatory Processes Formulation 1," The Journal of Symbolic Logic 1, no. 3 (September 1936): 103 105.. Stephen Kleene subsequently unified these disparate threads, proving the strict mathematical equivalence of Church's lambda calculus, Herbrand-Gödel recursive functions, and Turing's mechanical architectures Stephen C. Kleene, "General Recursive Functions of Natural Numbers," Mathematische Annalen 112 (1936): 727 742.. + While Gödel, Church, and Turing established the primary boundaries of computation, they did not work in a vacuum. During this period, the broader academic community worked to synthesize the definitive mechanics of effective calculability. Jacques Herbrand and Gödel formalized general recursive functions between 1931 and 1934 Kurt Gödel, "On Undecidable Propositions of Formal Mathematical Systems," mimeographed lecture notes, Institute for Advanced Study, Princeton, 1934.. Emil Post independently defined "Finite Combinatory Processes" in 1936, outlining a theoretical architecture functionally identical to Turing's model Emil L. Post, "Finite Combinatory Processes—Formulation 1," The Journal of Symbolic Logic 1, no. 3 (September 1936): 103–105.. Stephen Kleene subsequently unified these disparate threads, proving the strict mathematical equivalence of Church's lambda calculus and Herbrand-Gödel recursive functions Stephen C. Kleene, "General Recursive Functions of Natural Numbers," Mathematische Annalen 112 (1936): 727–742.. Turing supplied the remaining leg himself, showing his machines equivalent to the lambda calculus Alan M. Turing, "Computability and λ-definability," The Journal of Symbolic Logic 2, no. 4 (December 1937): 153–163..

- The academic community was thus equipped with three mathematically equivalent foundations for computation theory: recursive functions, the lambda calculus, and the Turing Machine. While all three frameworks remain active subjects of study, Turing's model is unique in providing practical intuition through the abstraction of physical machines and programs. This made it the foundation of choice for computation theory textbooks by Stephen Kleene Stephen C. Kleene, Introduction to Metamathematics (Amsterdam: North Holland, 1952)., Martin Davis Martin Davis, Computability and Unsolvability (New York: McGraw Hill, 1958)., and Marvin Minsky Marvin L. Minsky, Computation: Finite and Infinite Machines (Englewood Cliffs: Prentice Hall, 1967)., leading to the modern standard presentations by authors such as John Hopcroft and Jeffrey Ullman John E. Hopcroft and Jeffrey D. Ullman, Introduction to Automata Theory, Languages, and Computation (Reading: Addison Wesley, 1979)., as well as Harry Lewis and Christos Papadimitriou Harry R. Lewis and Christos H. Papadimitriou, Elements of the Theory of Computation (Englewood Cliffs: Prentice Hall, 1981).. + The academic community was thus equipped with three mathematically equivalent foundations for computation theory: recursive functions, the lambda calculus, and the Turing Machine. While all three frameworks remain active subjects of study, Turing's model is unique in providing practical intuition through the abstraction of physical machines and programs. This made it the foundation of choice for computation theory textbooks by Stephen Kleene Stephen C. Kleene, Introduction to Metamathematics (Amsterdam: North-Holland, 1952)., Martin Davis Martin Davis, Computability and Unsolvability (New York: McGraw-Hill, 1958)., and Marvin Minsky Marvin L. Minsky, Computation: Finite and Infinite Machines (Englewood Cliffs: Prentice-Hall, 1967)., leading to the modern standard presentations by authors such as John Hopcroft and Jeffrey Ullman John E. Hopcroft and Jeffrey D. Ullman, Introduction to Automata Theory, Languages, and Computation (Reading: Addison-Wesley, 1979)., as well as Harry Lewis and Christos Papadimitriou Harry R. Lewis and Christos H. Papadimitriou, Elements of the Theory of Computation (Englewood Cliffs: Prentice-Hall, 1981)..

@@ -162,8 +228,7 @@

- In reading Alan Turing's 1936 paper, it is striking how modern the text feels, specifically because he discusses algorithms, stored programs, and the mechanical limits of computation. - While his contemporaries largely built purely mathematical and logical frameworks, Turing uniquely tied computation theory directly to the abstraction of machines executing stored programs. Because physical hardware capable of executing stored memory programs had not yet been invented, this explicit architectural grounding makes Turing's work remarkably prescient. Still, Turing could not formally connect the Turing Machine to modern architectures, simply because those architectures did not yet exist. Here, by modern, I refer to architectures utilizing random access system memory, dedicated instruction fetch streams with dynamic branching, and discrete processing units. Though Charles Babbage's 1842 Analytical Engine touched on these concepts, they would wait until the 1940s to reemerge. The practical engineering context of 1936 was limited to calculating machines programmed via patch panels. Hence, for example, there is no explanation in his paper as to why a von Neumann architecture machine (1945) running a program would exhibit the computation theoretic results derived from a computation theory based on the Turing Machine (1936). + In reading Alan Turing's 1936 paper, it is striking how modern the text feels, specifically because he discusses algorithms, stored programs, and the mechanical limits of computation. While his contemporaries largely built purely mathematical and logical frameworks, Turing uniquely tied computation theory directly to the abstraction of machines executing stored programs. Because physical hardware capable of executing stored memory programs had not yet been invented, this explicit architectural grounding makes Turing's work remarkably prescient. Still, Turing could not formally connect the Turing Machine to modern architectures, simply because those architectures did not yet exist. Here, by modern, I refer to architectures utilizing random access system memory, dedicated instruction fetch streams with dynamic branching, and discrete processing units. Though Charles Babbage's 1842 Analytical Engine touched on these concepts, they would wait until the 1940s to reemerge. The practical engineering context of 1936 was limited to calculating machines programmed via patch panels. Hence, for example, there is no explanation in his paper as to why a von Neumann architecture machine (1945) running a program would exhibit the computation theoretic results derived from a computation theory based on the Turing Machine (1936).

@@ -201,14 +266,18 @@ These are the discernible levels of the computer design abstraction stack:

-
    -
  1. mathematical logic
  2. -
  3. computation theory
  4. -
  5. architecture
  6. -
  7. organization
  8. -
  9. implementation
  10. -
  11. realization
  12. -
+ + +
    +
  1. mathematical logic
  2. +
  3. computation theory
  4. +
  5. architecture
  6. +
  7. organization
  8. +
  9. implementation
  10. +
  11. realization
  12. +
+ List . The six levels of the computer design abstraction stack +

Mathematical logic underpins the computation theory layer. Computation theory speaks of the time and space complexity of algorithms and the existence of solutions to decider problems, which in turn guides the goals of the architecture and organization layers. @@ -224,7 +293,7 @@

- It is not a requirement of a computer organization, nor an architecture, that it be capable of physical realization. The abstract Turing Machine organization developed in a later section serves as an example. Instead, an abstract organization can serve other purposes, in this case as a stepping stone to another organization that can be realized. + It is not a requirement of a computer organization, nor an architecture, that it be capable of physical realization. The abstract Turing Machine organization developed in chapter serves as an example. Instead, an abstract organization can serve other purposes, in this case as a stepping stone to another organization that can be realized.

@@ -288,6 +357,44 @@ When a transform applied to machine m_i produces machine m_{i.1}, and this latter machine gets the same results for the same computational inputs, and furthermore, if any computation theory analysis applied to m_{i.1} yields the same existence and big O results as it would when applied to m_i, we say that the transform is computation theoretic inconsequential. Otherwise, the transformation is said to be computation theoretic consequential. The remainder of this section defines these terms more precisely.

+ + Orders of analysis + +

+ The definition just sketched turns on applying computation theory analysis to a + machine rather than running it. That is a distinction the reader will meet + repeatedly, in places that have nothing to do with transforms, so it is worth + settling here. A fuller treatment, and a system built upon it, comes in the + chapter on computational analysis, chapter + . +

+ +

+ We call a program that examines another program so as to deduce properties of its results an analyzer. The program or machine definition being subjected to this evaluation is called the studied program or studied machine. +

+ +

+ Turing Machines that halt in a finite number of steps for any finite input within a stipulated domain are said to be computational over that domain. +

+ +

+ 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 analysis. +

+ +

+ 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. +

+
+ Definition of the same results transform property @@ -295,21 +402,29 @@ Suppose we are interested in a given Turing Machine m_i where the machine will potentially be run after being given any one of a number of input tapes x_{i,j}, and for each of those inputs the same tape with the results written will be r_{i,j}, then we notate this as:

- - m_i(x_{i,j}) = r_{i,j} - + + + + m_i(x_{i,j}) = r_{i,j} + + eq: Machine m_i given input tape x_{i,j} writes result tape r_{i,j} +

Here the subscripts of the same name set up a correspondence. x_{i,j} is the jth input to the machine m_i, etc. The free variable j runs over all the interesting distinct input tapes to be given to machine m_i. So for example, if we had a machine, say m_8, and we had a set of three inputs to be given to m_8, then:

- - \begin{aligned} - m_8(x_{8,0}) &= r_{8,0} \\ - m_8(x_{8,1}) &= r_{8,1} \\ - m_8(x_{8,2}) &= r_{8,2} - \end{aligned} - + + + + \begin{aligned} + m_8(x_{8,0}) &= r_{8,0} \\ + m_8(x_{8,1}) &= r_{8,1} \\ + m_8(x_{8,2}) &= r_{8,2} + \end{aligned} + + eq: Machine m_8 over a set of three input tapes +

Another machine, perhaps machine m_7, would have its own distinct inputs x_{7,j}, etc. @@ -319,17 +434,25 @@ Now suppose that a machine m_{i.1} is the result of a transformation, T, applied to machine m_i.

- - m_i \xrightarrow{T} m_{i.1} - + + + + m_i \xrightarrow{T} m_{i.1} + + eq: Transform T carries machine m_i to machine m_{i.1} +

We can then assign a property to transform T called its doesn't change results property, as follows. If and only if:

- - \forall j \colon r_{i,j} = r_{i.1,j} - + + + + \forall j \colon r_{i,j} = r_{i.1,j} + + eq: The doesn't change results condition for one machine +

then T doesn't change m_i results. Here we note that we are evaluating a specific machine m_i, so we must add the qualifier 'm_i results'. It might be that for another machine with another corresponding set of interesting inputs, the transform would lead to a new machine that produces different results. @@ -339,9 +462,13 @@ If, and only if, it is the case that

- - \forall i, \forall j \colon r_{i,j} = r_{i.1,j} - + + + + \forall i, \forall j \colon r_{i,j} = r_{i.1,j} + + eq: The same results transform property, over all machines +

then we can say without qualification that T is a same results transform. Though still implied are the sets of machines, tapes, and questions. @@ -360,9 +487,13 @@ Suppose we also have a computation theory C that allows us to analyze some machines so as to answer some questions we find interesting. Suppose furthermore that among these questions are questions of time and space complexity, along with zero or more questions about decidability. Furthermore, we are given a machine, say m_i, for which these questions have answers. We represent this as:

- - a_{i,k} = q_{i,k}(m_i, \{x_{i,j}\}) - + + + + a_{i,k} = q_{i,k}(m_i, \{x_{i,j}\}) + + eq: A computation theoretic question and the answer it has for a machine +

Here, \{x_{i,j}\} represents the entire domain of j tapes being passed as arguments to the question q_{i,k}. From this, we can observe that if there are n_k questions, then we will have n_k answers. Also, for a specific machine m_i, where there are n_j j values, the domain over which m_i will be analyzed will have n_j tapes in it. @@ -372,17 +503,25 @@ As we had already discovered when determining T is a same results transform, T transforms machine m_i into machine m_{i.1}.

- - m_i \xrightarrow{T} m_{i.1} - + + + + m_i \xrightarrow{T} m_{i.1} + + eq: Transform T carries machine m_i to machine m_{i.1}, restated +

For our specific machine m_i, if and only if:

- - \forall k \colon a_{i,k} = a_{i.1,k} - + + + + \forall k \colon a_{i,k} = a_{i.1,k} + + eq: The inconsequential condition for one machine +

then T is computation theoretic inconsequential for m_i. @@ -392,9 +531,13 @@ If, and only if, it is the case that:

- - \forall i, \forall k \colon a_{i,k} = a_{i.1,k} - + + + + \forall i, \forall k \colon a_{i,k} = a_{i.1,k} + + eq: The computation theoretic inconsequential transform property +

then we can say without qualification that T is computation theoretic inconsequential. Though still implied are the sets of machines and tapes. @@ -410,28 +553,36 @@

This definition comes from Hopcroft and Ullman's book with minor terminology changes to make it flow into the text here John E. Hopcroft and Jeffrey D. Ullman, Introduction to Automata Theory, Languages, and Computation (Reading: Addison Wesley, 1979)..

- - M = (Q, Σ, Γ, δ, q_0, □, F) - + + + + M = (Q, Σ, Γ, δ, q_0, □, F) + + eq: The conventional Turing Machine as a seven tuple +

Each component of the Machine, M, is defined as follows:

-
    -
  • Q: The finite set of states of the programmed finite state machine controller.
  • -
  • Σ: The finite set of input symbols.
  • -
  • Γ: The complete set of tape symbols; Σ is always a subset of Γ.
  • -
  • □: The empty symbol. This symbol belongs exclusively to Γ, serving as a distinct tape marker rather than an input symbol. The empty symbol initially populates all cells except the finite number containing the input symbols.
  • -
  • δ: The next state function. The arguments of δ(q, X) are a state q and a tape symbol X. The value of δ(q, X), if it is defined, is a triple (p, Y, D), where: -
      -
    1. p is the next state in Q.
    2. -
    3. Y is the symbol in Γ written in the scanned cell, replacing the previous symbol.
    4. -
    5. D is a direction, either L or R, standing for "left" or "right," respectively, directing the head to move either left or right.
    6. -
    -
  • -
  • q_0: The initial state, a member of Q, in which the finite control is found.
  • - -
  • F: The set of final or accepting states, a subset of Q.
  • -
+ + +
    +
  • Q: The finite set of states of the programmed finite state machine controller.
  • +
  • Σ: The finite set of input symbols.
  • +
  • Γ: The complete set of tape symbols; Σ is always a subset of Γ.
  • +
  • □: The empty symbol. This symbol belongs exclusively to Γ, serving as a distinct tape marker rather than an input symbol. The empty symbol initially populates all cells except the finite number containing the input symbols.
  • +
  • δ: The next state function. The arguments of δ(q, X) are a state q and a tape symbol X. The value of δ(q, X), if it is defined, is a triple (p, Y, D), where: +
      +
    1. p is the next state in Q.
    2. +
    3. Y is the symbol in Γ written in the scanned cell, replacing the previous symbol.
    4. +
    5. D is a direction, either L or R, standing for "left" or "right," respectively, directing the head to move either left or right.
    6. +
    +
  • +
  • q_0: The initial state, a member of Q, in which the finite control is found.
  • + +
  • F: The set of final or accepting states, a subset of Q.
  • +
+ List . The components of the conventional Turing Machine M +

I introduced the qualifier programmed in front of the finite state machine controller because each Turing Machine that accomplishes a different task has a different finite state machine controller. A program is then a set of assignments to the variable parts of the Turing Machine definition. Notice that additional variables are needed by the Turing Machine executor beyond those that appear in the definition, such as the current state variable. In alternative terminology, the definition above defines a Turing Machine type, and a set of assignments to the variable parts of the definition constitutes an instance. Accordingly, then, when a computer arithmetician says he has two Turing Machines, he is saying that he has two distinct sets of Turing Machine variable assignments, and as these sets are distinct, each can be manipulated independently.

@@ -445,9 +596,13 @@

Hopcroft and Ullman explain a step of the machine by showing a representation of the tape with the state variable melded in to the left of the currently scanned symbol. Suppose δ(q, X_i) = (p, Y, L); i.e., the next move is leftward. Then,

- - X_1 X_2 ⋯ X_{i-1} q X_i X_{i+1} ⋯ X_n \underset{M}{⊢} X_1 X_2 ⋯ X_{i-2} p X_{i-1} Y X_{i+1} ⋯ X_n - + + + + X_1 X_2 ⋯ X_{i-1} q X_i X_{i+1} ⋯ X_n \underset{M}{⊢} X_1 X_2 ⋯ X_{i-2} p X_{i-1} Y X_{i+1} ⋯ X_n + + eq: An instantaneous description rewritten by a leftward move +

So first the tape is X_1 X_2 ⋯ X_{i-1} X_i X_{i+1} ⋯ X_n, with the head over X_i, and in state q. Then after a step of the machine, the tape is X_1 X_2 ⋯ X_{i-1} Y X_{i+1} ⋯ X_n, with the head over X_{i-1}, and in state p. Thus X_i was overwritten with Y, and the head stepped left.

@@ -457,123 +612,138 @@

Here is the programmed controller for a Turing Machine that reverses a binary string. Although by definition each state transition matches exactly one value under the head, as a practical matter, disjunctive selection is allowed via a comma list. A conjunctive phrasing for a state transition proposition would require stringing intermediate states in series.

- HU reverse machine + + + +
+ HU reverse machine +
+ Figure . A conventional Turing Machine that reverses a binary string +

Provided the site is still alive, the following YAML can be entered at TuringMachine.io to watch the machine run.

- - # YAML - # Reverses a binary string using a single marker and an EOM terminator. - input: ' 110' - blank: ' ' - start state: q_init - table: - # Machine starts on the leftmost cell (a blank marker). - # Then step right to the first input symbol. - q_init: - ' ': {R: q1} - - # Check for an empty string; exit if true. Otherwise, scan right. - q1: - ' ' : {L: done} - [0 ,1]: {R: q_scan} - - # Scan to the rightmost digit and place the EOM terminator 'E' - q_scan: - [0 ,1]: R - ' ' : {write: 'E' ,L: q2} - - # process the rightmost unmarked digit, writing the uniform marker '*' - q2: - 0 : {write: '*' ,R: s0} - 1 : {write: '*' ,R: s1} - ' ': {R: q5} # all digits processed, begin cleanup - - # carry '0' to the right end - s0: - ['*' ,'E' ,0 ,1]: R - ' ' : {write: 0 ,L: q3} - - # carry '1' to the right end - s1: - ['*' ,'E' ,0 ,1]: R - ' ' : {write: 1 ,L: q3} - - # return all the way to the left blank space - q3: - ['*' ,'E' ,0 ,1]: L - ' ' : {R: q4} - - # step right to find the next unmarked digit - q4: - [0 ,1] : R - ['*' ,'E']: {L: q2} - - # erase the markers and EOM terminator, leaving only the reversed string - q5: - ['*' ,'E'] : {write: ' ' ,R: q5} - [0 ,1 ,' ']: {L: done} - - done: - + + + + # YAML + # Reverses a binary string using a single marker and an EOM terminator. + input: ' 110' + blank: ' ' + start state: q_init + table: + # Machine starts on the leftmost cell (a blank marker). + # Then step right to the first input symbol. + q_init: + ' ': {R: q1} + + # Check for an empty string; exit if true. Otherwise, scan right. + q1: + ' ' : {L: done} + [0 ,1]: {R: q_scan} + + # Scan to the rightmost digit and place the EOM terminator 'E' + q_scan: + [0 ,1]: R + ' ' : {write: 'E' ,L: q2} + + # process the rightmost unmarked digit, writing the uniform marker '*' + q2: + 0 : {write: '*' ,R: s0} + 1 : {write: '*' ,R: s1} + ' ': {R: q5} # all digits processed, begin cleanup + + # carry '0' to the right end + s0: + ['*' ,'E' ,0 ,1]: R + ' ' : {write: 0 ,L: q3} + + # carry '1' to the right end + s1: + ['*' ,'E' ,0 ,1]: R + ' ' : {write: 1 ,L: q3} + + # return all the way to the left blank space + q3: + ['*' ,'E' ,0 ,1]: L + ' ' : {R: q4} + + # step right to find the next unmarked digit + q4: + [0 ,1] : R + ['*' ,'E']: {L: q2} + + # erase the markers and EOM terminator, leaving only the reversed string + q5: + ['*' ,'E'] : {write: ' ' ,R: q5} + [0 ,1 ,' ']: {L: done} + + done: + + Code . The conventional reverse machine, as TuringMachine.io YAML +

By default a newly initialized machine always starts with the head on the leftmost tape cell. The input is specified to be placed one square past the initial blank on the tape. This allows the leftmost blank to be used as a reliable start of input marker later when it is scanning left. The machine begins by reading this initial blank and stepping right. If it immediately encounters another blank, the string is empty and the machine is done. Otherwise, it sweeps right to place an end of message marker, E, immediately after the string. It then enters a repetitive process: it walks left to locate the next unprocessed input symbol, overwrites it with an asterisk to mark it as read, and then carries that remembered value rightward to deposit it at the new end of the sequence. By executing this back and forth shuttle, the machine systematically builds the reversed string to the right of the E, finishing by sweeping through to erase its temporary markers.

The following trace demonstrates the reversal of the string "110" using the same head embedded in the tape diagram as was used above, with a small variation. Here the head position is indicated using a bullet character, while the current state is listed in the left column. The empty symbol prints as a space. If you align the first line at the top of your window and scroll down, the execution plays out like an animation.

- - q_init • 1 1 0 - q1 •1 1 0 - q_scan 1•1 0 - q_scan 1 1•0 - q_scan 1 1 0• - q2 1 1•0 E - s0 1 1 *•E - s0 1 1 * E• - q3 1 1 *•E 0 - q3 1 1•* E 0 - q3 1•1 * E 0 - q3 •1 1 * E 0 - q3 • 1 1 * E 0 - q4 •1 1 * E 0 - q4 1•1 * E 0 - q4 1 1•* E 0 - q2 1•1 * E 0 - s1 1 *•* E 0 - s1 1 * *•E 0 - s1 1 * * E•0 - s1 1 * * E 0• - q3 1 * * E•0 1 - q3 1 * *•E 0 1 - q3 1 *•* E 0 1 - q3 1•* * E 0 1 - q3 •1 * * E 0 1 - q3 • 1 * * E 0 1 - q4 •1 * * E 0 1 - q4 1•* * E 0 1 - q2 •1 * * E 0 1 - s1 *•* * E 0 1 - s1 * *•* E 0 1 - s1 * * *•E 0 1 - s1 * * * E•0 1 - s1 * * * E 0•1 - s1 * * * E 0 1• - q3 * * * E 0•1 1 - q3 * * * E•0 1 1 - q3 * * *•E 0 1 1 - q3 * *•* E 0 1 1 - q3 *•* * E 0 1 1 - q3 •* * * E 0 1 1 - q3 • * * * E 0 1 1 - q4 •* * * E 0 1 1 - q2 • * * * E 0 1 1 - q5 •* * * E 0 1 1 - q5 •* * E 0 1 1 - q5 •* E 0 1 1 - q5 •E 0 1 1 - q5 •0 1 1 - done • 0 1 1 - + + + + q_init • 1 1 0 + q1 •1 1 0 + q_scan 1•1 0 + q_scan 1 1•0 + q_scan 1 1 0• + q2 1 1•0 E + s0 1 1 *•E + s0 1 1 * E• + q3 1 1 *•E 0 + q3 1 1•* E 0 + q3 1•1 * E 0 + q3 •1 1 * E 0 + q3 • 1 1 * E 0 + q4 •1 1 * E 0 + q4 1•1 * E 0 + q4 1 1•* E 0 + q2 1•1 * E 0 + s1 1 *•* E 0 + s1 1 * *•E 0 + s1 1 * * E•0 + s1 1 * * E 0• + q3 1 * * E•0 1 + q3 1 * *•E 0 1 + q3 1 *•* E 0 1 + q3 1•* * E 0 1 + q3 •1 * * E 0 1 + q3 • 1 * * E 0 1 + q4 •1 * * E 0 1 + q4 1•* * E 0 1 + q2 •1 * * E 0 1 + s1 *•* * E 0 1 + s1 * *•* E 0 1 + s1 * * *•E 0 1 + s1 * * * E•0 1 + s1 * * * E 0•1 + s1 * * * E 0 1• + q3 * * * E 0•1 1 + q3 * * * E•0 1 1 + q3 * * *•E 0 1 1 + q3 * *•* E 0 1 1 + q3 *•* * E 0 1 1 + q3 •* * * E 0 1 1 + q3 • * * * E 0 1 1 + q4 •* * * E 0 1 1 + q2 • * * * E 0 1 1 + q5 •* * * E 0 1 1 + q5 •* * E 0 1 1 + q5 •* E 0 1 1 + q5 •E 0 1 1 + q5 •0 1 1 + done • 0 1 1 + + Code . A step by step trace of the conventional reverse machine +
@@ -582,13 +752,17 @@

The total number of steps for reversing an n symbol string:

- - \text{steps} = - \begin{cases} - 2 & \text{if } n = 0 \\ - 3n^2 + 6n + 5 & \text{if } n \ge 1 - \end{cases} - + + + + \text{steps} = + \begin{cases} + 2 & \text{if } n = 0 \\ + 3n^2 + 6n + 5 & \text{if } n \ge 1 + \end{cases} + + eq: Steps taken by the conventional reverse machine +

This shows string reversal to be an O(n^2) complexity problem, which might appear to some programmers as a peculiar result, as the same problem can be solved in O(n) time with a C program. This justifies further analysis.

@@ -596,24 +770,77 @@

For a real machine, symbols are machine word encodings. For example, ASCII uses 7 data bits, so there are 128 symbols available. If the width of the word for encoding symbols is n bits, then the total number of states required for this string reverse machine is:

- - \text{states} = 2^n + 8 - + + + + \text{states} = 2^n + 8 + + eq: States required by the conventional reverse machine +

The number of arcs in the machine:

- - \text{arcs} = 2^{2n} + 9(2^n) + 12 - + + + + \text{arcs} = 2^{2n} + 9(2^n) + 12 + + eq: Arcs required by the conventional reverse machine +

These equations show that the state controller size explodes with word width. It would be impractical to implement for all but the smallest of word sizes. This is one of the reasons that computation theory books use modest-sized symbol alphabets in their examples, perhaps the first few letters of the Latin alphabet, or the letter 's' for unary arithmetic. Previous sections discussed challenges transitioning the Turing Machine to a real architecture due to the tape length, and discussed how this could be mitigated. In contrast, there is no practical mediation for implementing a Turing Machine controller even for modest-sized real problems.

This raises a question: if the Turing machine is to instruct upon the limitations of real computation, what are the implications stemming from its state controller being impractical? As one such implication, when a Turing Machine proof shows that a number is computable, it doesn't necessarily instruct upon how it could be computed. When a reader picks up a text on applied number theory, also called computer arithmetic, he is unlikely to find a chapter on Turing Machines.

+

The observation runs the other way as well. There is not a single chapter dedicated to computation theory in Hennessy and Patterson's definitive textbook on computer architecture. John L. Hennessy and David A. Patterson, Computer Architecture: A Quantitative Approach, 6th ed. (Cambridge: Morgan Kaufmann, 2017).

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Chapter 1Fundamentals of Quantitative Design and Analysis
Chapter 2Memory Hierarchy Design
Chapter 3Instruction Level Parallelism and Its Exploitation
Chapter 4Data Level Parallelism in Vector, SIMD, and GPU Architectures
Chapter 5Thread Level Parallelism
Chapter 6Warehouse Scale Computers
Chapter 7Domain Specific Architectures
Chapter 8The Future of Computing
+ Table . The chapter list of Hennessy and Patterson, Computer Architecture: A Quantitative Approach +
+ +
- Blank, empty, SP + The memory of emptiness

Turing described a clerk writing symbols into squares, with the option to erase them. He states, "In some of the configurations in which the scanned square is blank (i.e. bears no symbol) the machine writes down a new symbol on the scanned square: in other configurations it erases the scanned symbol."Alan M. Turing, "On Computable Numbers, with an Application to the Entscheidungsproblem," Proceedings of the London Mathematical Society, Series 2, Volume 42 (1936): 231. So initially Turing's original article uses blank to mean no symbol. However, later Turing says, "We also give numbers to the symbols ... in particular, blank = S₀ ." ibid: 239..

@@ -622,9 +849,13 @@

Because emptiness is a property of a container, Turing's first statement can be modeled with a sequence of sets. For a Turing Machine tape, each sequence member is either an empty set or a singleton set. In the language of mathematics an empty tape can be defined as a empty sets:

- - T_0 = [ \{ \}, \{ \}, \{ \}, \dots ] - + + + + T_0 = [ \{ \}, \{ \}, \{ \}, \dots ] + + eq: An empty tape written as a sequence of empty sets +

Here, each tape member set is called a cell. This definition for an empty tape is specific to Turing Machines, as in mathematics an empty sequence has zero length. An empty tape is not an empty sequence, rather it is an infinite sequence where every member is an empty set. In one sense this is a little peculiar that something said to be empty is infinite, in another sense it is consistent for the model that an empty Turing Machine tape keeps its defining characteristics. That is, it remains a single ended Turing Machine tape, where any cell of the tape could be written with a symbol value, while the basic form of the tape will not change.

@@ -632,27 +863,39 @@

So we might imagine a tape machine, say called machine A, where, upon attempting to read an empty cell, the machine head instead returns a control symbol representing that the cell was empty. To accomplish this, the head would have to do some work; it would have to be able to detect emptiness, and then choose to return the empty symbol instead of a read value. This feature would fix the problem of not having any defined next state behavior for an empty cell. Furthermore, suppose the inverse process is also special in that upon attempting to write the empty symbol, the machine takes action, emptying the cell out. This would facilitate an erase operation.

- - def read(c): - if is_empty(c): - return 'empty' - else: - return c.get() - - - - def write(c ,x): - if not is_empty(c): - c.pop() # Clear the cell if it holds something - if x != 'empty': - c.put(x) # Place the new symbol unless we are erasing - + + + + def read(c): + if is_empty(c): + return 'empty' + else: + return c.get() + + Code . Reading a cell that can be empty + + + + + + def write(c ,x): + if not is_empty(c): + c.pop() # Clear the cell if it holds something + if x != 'empty': + c.put(x) # Place the new symbol unless we are erasing + + Code . Writing a cell, where writing the empty symbol erases it +

Now imagine machine B, where the concept of an empty cell is jettisoned, and what remains is the mere memory of emptiness, a symbol called empty. Then using the language of mathematics, the mathematician defines an initial empty tape as:

- - T_0 = [ \mathtt{empty}, \mathtt{empty}, \mathtt{empty}, \ldots ] - + + + + T_0 = [ \mathtt{empty}, \mathtt{empty}, \mathtt{empty}, \ldots ] + + eq: An empty tape written with the empty symbol +

For machine B, no modifications are required to the native read and write functions.

@@ -662,6 +905,8 @@

Going back to Turing's moniker of blank does limit the focus solely to machine B, because the original paper by Turing states the definition of blank meaning "no symbol", as was already discussed. Calling it blank is merely the same name colored by the engineering of wood pulp. However, there is a pleasing property of the blank, i.e. the empty symbol, that is valuable and unique to it. It prints as a space in diagrams given in text books and in the output of Turing Machine simulators. There is an analogous symbolic system that also has this characteristic, and is being leveraged in these situations: the ASCII hex 20, called SP. It prints as a space leaving an area of the paper it is printed on blank. Perhaps a better name for the ersatz empty symbol is SP.

+

We therefore keep both words, and give each one job. Emptiness is a property, and a property belongs to a container: a cell of machine A either holds a symbol or it does not. SP is a symbol, and a symbol belongs to an alphabet: a cell of machine B always holds one, and SP is what it holds where a cell of machine A would have been empty. Machine B has no empty cells at all, only cells holding SP. Where this book speaks of emptiness it means the property, and where it writes SP it means the symbol standing in for it.

+

There is more to consider about the former blank, former empty, now SP symbol. Computational theorists often describe a two-step process. First, a Turing Machine writes a string to be studied onto a tape initially filled with all SP symbols; second, the tape is moved to another Turing Machine whose purpose is to recognize a property of the string being studied. In this process, a tape is used as a communication medium, so it follows that communication theory can be applied to this messaging scenario. Messages sent on a channel must be formatted so they can be placed on the channel and later recovered. The specification for such structuring is called a communication protocol. The protocol implies a higher authority, as both the sender and the receiver must have knowledge of the same designed-in protocol. In a sense, a protocol is the meta-message sent before the message itself.

The intention of the later innovation of placing the SP symbol in Γ but not in Σ appears to be that of making the SP symbol serve additional duty: firstly as a default value for a cell that has never been written to, secondly to effect erasure, and now thirdly as a control component of a communications protocol. Accordingly then, this protocol was designed by mathematicians with a specific goal. They intended to make it impossible for programmers to send 'to be studied' string messages that cannot always be recovered by a receiving recognizer Turing Machine. In short, the SP symbol also serves as an in-band EOM (end of message) symbol.

@@ -681,7 +926,7 @@
- + The computation theoretic TTCA Machine

This chapter presents a modified computation theoretic Turing Machine with three structural additions. First, it separates control flow from data flow, ensuring that payload symbols do not needlessly expand the control state machine. Second, it unifies the control and data symbol sets into a single alphabet to natively support explicit communications protocols even in the presence of recursion and self-recursion. Finally, it implements a cascading next-state evaluation hierarchy, permitting the programmer to formally define and handle meta-symbols while also making it more convenient to program communication protocols.

@@ -702,11 +947,15 @@

Like the empty symbol, unspecified is a meta-symbol. It describes the data, or lack thereof, rather than being the data. Specifically, the unspecified symbol says that another machine, a machine A, would have a singular alphabet symbol at the memory location, but our machine B is not being informed as to which symbol it is. Because the Turing Machine state transition function requires a specific symbol value, reading an unspecified symbol, and then using it to make a decision as though it were a concrete symbol, would be an error, unless that control path was for the very purpose of detecting this error.

Reasons that memory can be unspecified include:

-
    -
  1. The memory was not initialized.
  2. -
  3. The memory holds stale data written by an unrelated process, such as a reused memory allocation.
  4. -
  5. The data is effectively unspecified because the program, by design, does not make decisions based upon its value. -
+ + +
    +
  1. The memory was not initialized.
  2. +
  3. The memory holds stale data written by an unrelated process, such as a reused memory allocation.
  4. +
  5. The data is effectively unspecified because the program, by design, does not make decisions based upon its value. +
+ List . Reasons a memory location can hold an unspecified value +

An example of effectively unspecified data would be a program that reverses a string without looking at the values being reversed. A string reverse function need not inspect the value of the string; it only needs to recognize the structural boundaries established by the writing protocol. Yet the conventional Turing Machine is incapable of doing this, and worse, as we saw, there is an explosion in the number of states for the reverse string controller against word length.

@@ -718,35 +967,43 @@ The modifications

The specific architectural modifications are as follows:

-
    -
  1. There is one unified alphabet Σ to which both status symbols and data symbols belong.
  2. -
  3. The machine utilizes a Moore-style programmed state controller, with zero or one instruction specified per state, so that instructions are independent and managed separately from state transitions.
  4. -
  5. The machine separates control flow from data flow: -
      -
    1. Two registers exist within the machine: one for holding a symbol upon which control decisions are made, the s (status) register; and one for holding data upon which decisions are not based, the d (data) register.
    2. -
    3. Write and read instructions are given an operand designating the target or source register respectively, either s or d.
    4. -
    -
  6. -
  7. The machine implements default state transitions that execute when no explicit transition is given in the main state transition table of triples (each triple being \langle q_i, σ, q_{i+1} \rangle): -
      -
    1. state-specific transition default pairs, which have the form \langle q_i, q_{i+1} \rangle
    2. -
    3. status-specific transition default pairs, which have the form \langle σ, q_{i+1} \rangle
    4. -
    5. a global default transition, which has the form q_{i+1}
    6. -
    -
  8. -
+ + +
    +
  1. There is one unified alphabet Σ to which both status symbols and data symbols belong.
  2. +
  3. The machine utilizes a Moore-style programmed state controller, with zero or one instruction specified per state, so that instructions are independent and managed separately from state transitions.
  4. +
  5. The machine separates control flow from data flow: +
      +
    1. Two registers exist within the machine: one for holding a symbol upon which control decisions are made, the s (status) register; and one for holding data upon which decisions are not based, the d (data) register.
    2. +
    3. Write and read instructions are given an operand designating the target or source register respectively, either s or d.
    4. +
    +
  6. +
  7. The machine implements default state transitions that execute when no explicit transition is given in the main state transition table of triples (each triple being \langle q_i, σ, q_{i+1} \rangle): +
      +
    1. state-specific transition default pairs, which have the form \langle q_i, q_{i+1} \rangle
    2. +
    3. status-specific transition default pairs, which have the form \langle σ, q_{i+1} \rangle
    4. +
    5. a global default transition, which has the form q_{i+1}
    6. +
    +
  8. +
+ List . The architectural modifications that distinguish the TTCA Machine +

Here the subscript i is a device used to emphasize that q_i and q_{i+1} can be any members of the total set of states, Q. State q_0 refers specifically to the initial state. Also note, later the spartan q will be used to denote the contents of the q register, the current state register.

The Hopcroft and Ullman machine definition specified a next state function, δ. Here we instead use next state tables that cascade, and as tables are containers, we denote these using a capital letter as Δ_0, Δ_1, Δ_2, and Δ_3.

The new machine evaluates next-state transitions through these four layers, in order, progressing to the next layer only when no transition is found in the prior layer:

-
    -
  1. Conditional (Δ_0): Selects the transition rule that matches the current state and the value of the status register.
  2. -
  3. State Default (Δ_1): Selects the default transition rule that matches the current state.
  4. -
  5. Status Default (Δ_2): Selects the default transition rule that matches the current machine status.
  6. -
  7. Global Default (Δ_3): A single table that holds the next state of last resort.
  8. -
+ + +
    +
  1. Conditional (Δ_0): Selects the transition rule that matches the current state and the value of the status register.
  2. +
  3. State Default (Δ_1): Selects the default transition rule that matches the current state.
  4. +
  5. Status Default (Δ_2): Selects the default transition rule that matches the current machine status.
  6. +
  7. Global Default (Δ_3): A single table that holds the next state of last resort.
  8. +
+ List . The four next state transition layers, in evaluation order +

Programmers will typically use the Global Default arc, Δ_3, to take the machine to an error state when they have mistakenly left the next state transition undefined. However, it is conceivable for some machines that if no other next state is defined, there is a single logical state that should be visited, and this condition is not an error. If no Global Default arc is specified, and no next state is found, the machine hangs.

@@ -762,52 +1019,72 @@ The TTCA Machine fixed part - - \mathit{MF} = (\mathit{QF}, \mathit{ΣF}, \mathit{AF}) - + + + + \mathit{MF} = (\mathit{QF}, \mathit{ΣF}, \mathit{AF}) + + eq: MF, the fixed part of the TTCA Machine +

In the following, the middle dot acts as a namespace operator, N{·}x. By doing this we assure there will be no aliasing with the symbols provided by the programmer when he defines a programmed state controller.

The set of predefined states:

- - \mathit{QF} = \{\mathit{QF}{·}\mathtt{initial}\} - + + + + \mathit{QF} = \{\mathit{QF}{·}\mathtt{initial}\} + + eq: QF, the set of predefined states +

The state controller always starts in the QF·initial state. This is a symbol representing the state; it is not a register that holds a state. The 'F' values are all fixed.

The programmer cannot add instructions to the machine definition, so there are no symbol aliasing issues here:

- - \begin{aligned} - \mathit{AF} = \{& \\ - & \mathtt{no\_op} \\ - ,& \mathtt{left} \\ - ,& \mathtt{right} \\ - ,& \mathtt{read}(\mathtt{d} \mid \mathtt{s}) \\ - ,& \mathtt{status} \\ - ,& \mathtt{write}(\mathtt{d} \mid \mathtt{s} \mid \mathtt{σ}, [σ]) \\ - \} - \end{aligned} - + + + + \begin{aligned} + \mathit{AF} = \{& \\ + & \mathtt{no\_op} \\ + ,& \mathtt{left} \\ + ,& \mathtt{right} \\ + ,& \mathtt{read}(\mathtt{d} \mid \mathtt{s}) \\ + ,& \mathtt{status} \\ + ,& \mathtt{write}(\mathtt{d} \mid \mathtt{s} \mid \mathtt{σ}, [σ]) \\ + \} + \end{aligned} + + eq: AF, the set of predefined instructions +

where σ must be in Σ.

The set of predefined symbols:

- - \mathit{ΣF} = \{\mathit{ΣF}{·}\mathtt{leftmost}\} - + + + + \mathit{ΣF} = \{\mathit{ΣF}{·}\mathtt{leftmost}\} + + eq: ΣF, the set of predefined symbols +
Machine variables - - \mathit{MV} = (q, s, d) - + + + + \mathit{MV} = (q, s, d) + + eq: MV, the machine variables +

q: is the current state of the machine.

@@ -821,69 +1098,105 @@ Programmable part - - \mathit{MP} = (\mathit{QP}, \mathit{ΣP}, \mathit{ΛP}, Δ_0, Δ_1, Δ_2, Δ_3, \mathit{HP}) - + + + + \mathit{MP} = (\mathit{QP}, \mathit{ΣP}, \mathit{ΛP}, Δ_0, Δ_1, Δ_2, Δ_3, \mathit{HP}) + + eq: MP, the programmable part of the TTCA Machine +

A set of programmed state symbols:

- - \mathit{QP} - + + + + \mathit{QP} + + eq: QP, the set of programmed state symbols +

A set of programmed data symbols:

- - \mathit{ΣP} - + + + + \mathit{ΣP} + + eq: ΣP, the set of programmed data symbols +

The programmed instructions. A set of pairs of the form:

- - \mathit{ΛP} = \{ \langle q_i, a \rangle, \dots \} - + + + + \mathit{ΛP} = \{ \langle q_i, a \rangle, \dots \} + + eq: ΛP, the programmed instructions, as state and action pairs +

where q_i is matched to the current state, and a is a member of \mathit{A}.

The conditional transition table. A set of state transition triples; each triple is of the form:

- - Δ_0 = \{ \langle q_i, σ, q_{i+1} \rangle, \dots \} - + + + + Δ_0 = \{ \langle q_i, σ, q_{i+1} \rangle, \dots \} + + eq: Δ₀, the conditional transition table +

Here q_i and q_{i+1} are two states from the total set of Q. They need not be distinct. While the machine is running, state q_i is to be matched against the contents of the q register, the current state. Symbol σ is a member of the total set Σ and is to be matched against the contents of the s register, the machine status. When q_i matches the current state and σ matches the current status, then q_{i+1} becomes the next state.

The state default transition table. A set of state transition pairs; each pair is of the form:

- - Δ_1 = \{ \langle q_i, q_{i+1} \rangle, \dots \} - + + + + Δ_1 = \{ \langle q_i, q_{i+1} \rangle, \dots \} + + eq: Δ₁, the state default transition table +

where q_i is matched to the current state, and upon a match q_{i+1} will be taken as the next state.

The status default transition table. A set of state transition pairs; each pair is of the form:

- - Δ_2 = \{ \langle σ, q_{i+1} \rangle, \dots \} - + + + + Δ_2 = \{ \langle σ, q_{i+1} \rangle, \dots \} + + eq: Δ₂, the status default transition table +

where σ matches the symbol in s register, and upon a match q_{i+1} will be taken as the next state.

The global default next state:

- - Δ_3 = q_{i+1} - + + + + Δ_3 = q_{i+1} + + eq: Δ₃, the global default next state +

This is the transition of last resort. It is unconditional; the next state becomes q_{i+1}.

A set of programmer-defined halting states:

- - \mathit{HP} - + + + + \mathit{HP} + + eq: HP, the set of programmed halting states +
@@ -891,48 +1204,76 @@ The TTCA Machine definition in total - - M = (q, s, d, Q, Σ, A, Λ, Δ, H) - + + + + M = (q, s, d, Q, Σ, A, Λ, Δ, H) + + eq: The TTCA Machine in total +

The variables used by the executor, \mathit{MV} = (q, s, d).

The complete set of states, uniting the fixed predefined states and the programmed states:

- - Q = \mathit{QF} \cup \mathit{QP} - + + + + Q = \mathit{QF} \cup \mathit{QP} + + eq: Q, the complete state set, fixed united with programmed +

The complete set of symbols, uniting the fixed control symbols and the programmed data symbols:

- - Σ = \mathit{ΣF} \cup \mathit{ΣP} - + + + + Σ = \mathit{ΣF} \cup \mathit{ΣP} + + eq: Σ, the complete symbol set, fixed united with programmed +

All members of the set of available instructions are fixed:

- - A = \mathit{AF} - + + + + A = \mathit{AF} + + eq: A, the instruction set, entirely fixed +

The table of state-instruction pairs is strictly programmed.

- - Λ = \mathit{ΛP} - + + + + Λ = \mathit{ΛP} + + eq: Λ, the instruction table, entirely programmed +

The ordered sequence of next state transition rules:

- - Δ = [Δ_0 \mid Δ_1 \mid Δ_2 \mid Δ_3] - + + + + Δ = [Δ_0 \mid Δ_1 \mid Δ_2 \mid Δ_3] + + eq: Δ, the transition rules as an ordered sequence +

The set of halt states is strictly programmed, and thus could be empty.

- - H = \mathit{HP} - + + + + H = \mathit{HP} + + eq: H, the halt state set, entirely programmed +
@@ -949,11 +1290,15 @@ Initialization stage

Before the first cycle begins, a tape is selected and mounted. The read/write head is positioned over the leftmost tape cell. The machine variables are initialized as follows:

-
    -
  • The current state q is set to \mathit{QF}{·}\mathtt{initial}.
  • -
  • The data register d is initialized to hold the \mathit{ΣF}{·}\mathtt{unspecified} symbol.
  • -
  • The status register s is initialized to hold the \mathit{ΣF}{·}\mathtt{unspecified} symbol.
  • -
+ + +
    +
  • The current state q is set to \mathit{QF}{·}\mathtt{initial}.
  • +
  • The data register d is initialized to hold the \mathit{ΣF}{·}\mathtt{unspecified} symbol.
  • +
  • The status register s is initialized to hold the \mathit{ΣF}{·}\mathtt{unspecified} symbol.
  • +
+ List . The initial values given to the machine variables +
@@ -962,10 +1307,14 @@ Phase 1: Instruction issue and execution -
    -
  1. Given the current state q, lookup the instruction λ, within the instruction table Λ.
  2. -
  3. Perform the instruction λ.
  4. -
+ + +
    +
  1. Given the current state q, lookup the instruction λ, within the instruction table Λ.
  2. +
  3. Perform the instruction λ.
  4. +
+ List . The two steps of instruction issue and execution +

If the instruction is left and the machine walks off the tape, the machine hangs.

@@ -990,148 +1339,159 @@

Because the TTCA Machine separates the data path from the control path, it is possible to reverse a string without inspecting the payload. The programmed controller only needs to recognize the structural boundaries of the data protocol. When a payload symbol is encountered, the controller executes a read(d) instruction, placing the value into the data register, which is not examined for decision-making purposes. When a value is used to base a decision upon, the controller executes a read(s), placing the value into the status register. Because instructions are bound to states rather than transitions, reading and stepping are distinct states. This combination of features results in a controller that has threads of serialized execution.

- - # TTCA Machine String Reverse - # Domains: - # ΣP = {0 ,1 ,EOM ,EOR ,SP} - # Σ_data = ΣP \ {EOM ,EOR ,SP} - # input: (σ ∈ Σ_data)* EOM (starting on the leftmost cell) - # output: SP* EOM (σ ∈ Σ_data in reverse)* EOR - - halt: Q·Done - - table: - # Phase 1: Scan right to EOM and initialize the EOR marker. - Q·initial: - λ: read(s) - δ: - (EOM: Q·Setup_EOR) - Q·Search_EOM_0 - - Q·Search_EOM_0: - λ: right - δ: - Q·initial - - Q·Setup_EOR: - λ: right - δ: - Q·Write_EOR - - Q·Write_EOR: - λ: write(σ ,EOR) - δ: - Q·Fetch_0 - - # Phase 2: Fetch the next unprocessed symbol and check boundaries. - Q·Fetch_0: - λ: left - δ: - Q·Fetch_1 - - Q·Fetch_1: - λ: read(s) - δ: - (EOM: Q·Check_Boundary) - (SP: Q·Check_Boundary) - Q·Read_Data - - Q·Check_Boundary: - λ: status - δ: - (leftmost: Q·Done) - Q·Fetch_0 - - Q·Read_Data: - λ: read(d) - δ: - Q·Check_Last_Char - - Q·Check_Last_Char: - λ: status - δ: - (leftmost: Q·Place_Last) - Q·Place_SP - - # Phase 3: Mark the location and carry the opaque data rightward. - Q·Place_SP: - λ: write(σ ,SP) - δ: - Q·Carry_0 - - Q·Carry_0: - λ: right - δ: - Q·Carry_1 - - Q·Carry_1: - λ: read(s) - δ: - (EOR: Q·Drop) - Q·Carry_0 - - # Phase 4: Deposit the data and advance the EOR boundary. - Q·Drop: - λ: write(d) - δ: - Q·Advance_EOR_0 - - Q·Advance_EOR_0: - λ: right - δ: - Q·Advance_EOR_1 - - Q·Advance_EOR_1: - λ: write(σ ,EOR) - δ: - Q·Return_0 - - # Phase 5: Return left to the EOM to begin the next fetch cycle. - Q·Return_0: - λ: left - δ: - Q·Return_1 - - Q·Return_1: - λ: read(s) - δ: - (EOM: Q·Fetch_0) - Q·Return_0 - - # Phase 6: Final symbol carry and clean halt. - Q·Place_Last: - λ: write(σ ,SP) - δ: - Q·Carry_Last_0 - - Q·Carry_Last_0: - λ: right - δ: - Q·Carry_Last_1 - - Q·Carry_Last_1: - λ: read(s) - δ: - (EOR: Q·Drop_Last) - Q·Carry_Last_0 - - Q·Drop_Last: - λ: write(d) - δ: - Q·Advance_EOR_Last_0 - - Q·Advance_EOR_Last_0: - λ: right - δ: - Q·Advance_EOR_Last_1 - - Q·Advance_EOR_Last_1: - λ: write(σ ,EOR) - δ: - Q·Done - - - TTCAM reverse machine + + + + # TTCA Machine String Reverse + # Domains: + # ΣP = {0 ,1 ,EOM ,EOR ,SP} + # Σ_data = ΣP \ {EOM ,EOR ,SP} + # input: (σ ∈ Σ_data)* EOM (starting on the leftmost cell) + # output: SP* EOM (σ ∈ Σ_data in reverse)* EOR + + halt: Q·Done + + table: + # Phase 1: Scan right to EOM and initialize the EOR marker. + Q·initial: + λ: read(s) + δ: + (EOM: Q·Setup_EOR) + Q·Search_EOM_0 + + Q·Search_EOM_0: + λ: right + δ: + Q·initial + + Q·Setup_EOR: + λ: right + δ: + Q·Write_EOR + + Q·Write_EOR: + λ: write(σ ,EOR) + δ: + Q·Fetch_0 + + # Phase 2: Fetch the next unprocessed symbol and check boundaries. + Q·Fetch_0: + λ: left + δ: + Q·Fetch_1 + + Q·Fetch_1: + λ: read(s) + δ: + (EOM: Q·Check_Boundary) + (SP: Q·Check_Boundary) + Q·Read_Data + + Q·Check_Boundary: + λ: status + δ: + (leftmost: Q·Done) + Q·Fetch_0 + + Q·Read_Data: + λ: read(d) + δ: + Q·Check_Last_Char + + Q·Check_Last_Char: + λ: status + δ: + (leftmost: Q·Place_Last) + Q·Place_SP + + # Phase 3: Mark the location and carry the opaque data rightward. + Q·Place_SP: + λ: write(σ ,SP) + δ: + Q·Carry_0 + + Q·Carry_0: + λ: right + δ: + Q·Carry_1 + + Q·Carry_1: + λ: read(s) + δ: + (EOR: Q·Drop) + Q·Carry_0 + + # Phase 4: Deposit the data and advance the EOR boundary. + Q·Drop: + λ: write(d) + δ: + Q·Advance_EOR_0 + + Q·Advance_EOR_0: + λ: right + δ: + Q·Advance_EOR_1 + + Q·Advance_EOR_1: + λ: write(σ ,EOR) + δ: + Q·Return_0 + + # Phase 5: Return left to the EOM to begin the next fetch cycle. + Q·Return_0: + λ: left + δ: + Q·Return_1 + + Q·Return_1: + λ: read(s) + δ: + (EOM: Q·Fetch_0) + Q·Return_0 + + # Phase 6: Final symbol carry and clean halt. + Q·Place_Last: + λ: write(σ ,SP) + δ: + Q·Carry_Last_0 + + Q·Carry_Last_0: + λ: right + δ: + Q·Carry_Last_1 + + Q·Carry_Last_1: + λ: read(s) + δ: + (EOR: Q·Drop_Last) + Q·Carry_Last_0 + + Q·Drop_Last: + λ: write(d) + δ: + Q·Advance_EOR_Last_0 + + Q·Advance_EOR_Last_0: + λ: right + δ: + Q·Advance_EOR_Last_1 + + Q·Advance_EOR_Last_1: + λ: write(σ ,EOR) + δ: + Q·Done + + Code . The TTCA Machine string reverse controller + + + + + +
+ TTCAM reverse machine +
+ Figure . The TTCA Machine that reverses a binary string +
@@ -1142,33 +1502,49 @@

The form of this diagram shows a lead-in, a long loop, and a tail leading to done. This is suggestive of code followed by a while loop that breaks out, with further code completing the program.

- - void TTCA·reverse_string() { - // Initialization: Scan to EOM and setup the EOR boundary - read('s'); - while(s != EOM){right(); read('s');} - right(); - write('σ' ,EOR); - - while(true){ - // The Fetch Pivot: Locate the next unprocessed symbol - left(); + + + + void TTCA·reverse_string() { + // Initialization: Scan to EOM and setup the EOR boundary read('s'); - while(s == EOM || s == SP){ - status(); - // Termination: Short-circuit for empty string - if(s == leftmost) return; + while(s != EOM){right(); read('s');} + right(); + write('σ' ,EOR); + + while(true){ + // The Fetch Pivot: Locate the next unprocessed symbol left(); read('s'); - } + while(s == EOM || s == SP){ + status(); + // Termination: Short-circuit for empty string + if(s == leftmost) return; + left(); + read('s'); + } + + read('d'); + status(); + + // Center Break: Q·Check_Last_Char routes to the final chain + if(s == leftmost) break; - read('d'); - status(); + // Main Carry Loop: Mark, carry, drop, and return to pivot + write('σ' ,SP); + right(); + read('s'); + while(s != EOR){right(); read('s');} + write('d'); + right(); + write('σ' ,EOR); - // Center Break: Q·Check_Last_Char routes to the final chain - if(s == leftmost) break; + left(); + read('s'); + while(s != EOM){left(); read('s');} + } - // Main Carry Loop: Mark, carry, drop, and return to pivot + // Final Symbol Chain: Handle the last payload without a return sweep write('σ' ,SP); right(); read('s'); @@ -1177,34 +1553,26 @@ right(); write('σ' ,EOR); - left(); - read('s'); - while(s != EOM){left(); read('s');} + // Termination: Q·Done + return; } - - // Final Symbol Chain: Handle the last payload without a return sweep - write('σ' ,SP); - right(); - read('s'); - while(s != EOR){right(); read('s');} - write('d'); - right(); - write('σ' ,EOR); - - // Termination: Q·Done - return; - } - + + Code . The TTCA reverse controller written as C +

The total number of steps for reversing an n symbol string using the TTCA Machine:

- - \text{steps} = - \begin{cases} - 7 & \text{if } n = 0 \\ - 4.5n^2 + 11.5n + 5 & \text{if } n \ge 1 - \end{cases} - + + + + \text{steps} = + \begin{cases} + 7 & \text{if } n = 0 \\ + 4.5n^2 + 11.5n + 5 & \text{if } n \ge 1 + \end{cases} + + eq: Steps taken by the TTCA reverse machine +
@@ -1214,108 +1582,119 @@

The reverse string machine spends a lot of time shuttling the head between two context areas: one for the original string, and one for the resulting reversed string. This suggests that a two-head version would be faster. The following is the two-head state machine definition:

- - # TTCA Two-Head String Reverse - # input: (σ ∈ Σ)* EOM (starting on the leftmost cell) - # output: SP* EOM (σ ∈ Σ in reverse)* EOR - - halt: Q·Done - - table: - # Phase 1: Both heads scan right to the EOM pivot - Q·initial: - λ: read('s' ,0) - δ: - (EOM: Q·Check_Empty) - Q·Scan_Right_0 - - Q·Scan_Right_0: - λ: right(0) - δ: - Q·Scan_Right_1 - - Q·Scan_Right_1: - λ: right(1) - δ: - Q·initial - - # Phase 2: Setup pointers for reading and writing - Q·Check_Empty: - λ: status(0) - δ: - (leftmost: Q·Empty_Setup_1) - Q·Setup_Write_1 - - Q·Empty_Setup_1: - λ: right(1) - δ: - Q·Write_EOR_Done - - Q·Setup_Write_1: - λ: right(1) - δ: - Q·Setup_Write_2 - - Q·Setup_Write_2: - λ: left(0) - δ: - Q·Copy_Read - - # Phase 3: The Linear Copy Loop - Q·Copy_Read: - λ: read('d' ,0) - δ: - Q·Copy_Status - - Q·Copy_Status: - λ: status(0) - δ: - (leftmost: Q·Copy_Last_Erase) - Q·Copy_Erase - - Q·Copy_Erase: - λ: write('σ' ,0 ,SP) - δ: - Q·Copy_Write - - Q·Copy_Write: - λ: write('d' ,1) - δ: - Q·Copy_Advance_1 - - Q·Copy_Advance_1: - λ: right(1) - δ: - Q·Copy_Advance_0 - - Q·Copy_Advance_0: - λ: left(0) - δ: - Q·Copy_Read - - # Phase 4: Final Symbol and Clean Halt - Q·Copy_Last_Erase: - λ: write('σ' ,0 ,SP) - δ: - Q·Copy_Last_Write - - Q·Copy_Last_Write: - λ: write('d' ,1) - δ: - Q·Copy_Last_Advance - - Q·Copy_Last_Advance: - λ: right(1) - δ: - Q·Write_EOR_Done - - Q·Write_EOR_Done: - λ: write('σ' ,1 ,EOR) - δ: - Q·Done - - - TTCAM 2 hd reverse machine + + + + # TTCA Two-Head String Reverse + # input: (σ ∈ Σ)* EOM (starting on the leftmost cell) + # output: SP* EOM (σ ∈ Σ in reverse)* EOR + + halt: Q·Done + + table: + # Phase 1: Both heads scan right to the EOM pivot + Q·initial: + λ: read('s' ,0) + δ: + (EOM: Q·Check_Empty) + Q·Scan_Right_0 + + Q·Scan_Right_0: + λ: right(0) + δ: + Q·Scan_Right_1 + + Q·Scan_Right_1: + λ: right(1) + δ: + Q·initial + + # Phase 2: Setup pointers for reading and writing + Q·Check_Empty: + λ: status(0) + δ: + (leftmost: Q·Empty_Setup_1) + Q·Setup_Write_1 + + Q·Empty_Setup_1: + λ: right(1) + δ: + Q·Write_EOR_Done + + Q·Setup_Write_1: + λ: right(1) + δ: + Q·Setup_Write_2 + + Q·Setup_Write_2: + λ: left(0) + δ: + Q·Copy_Read + + # Phase 3: The Linear Copy Loop + Q·Copy_Read: + λ: read('d' ,0) + δ: + Q·Copy_Status + + Q·Copy_Status: + λ: status(0) + δ: + (leftmost: Q·Copy_Last_Erase) + Q·Copy_Erase + + Q·Copy_Erase: + λ: write('σ' ,0 ,SP) + δ: + Q·Copy_Write + + Q·Copy_Write: + λ: write('d' ,1) + δ: + Q·Copy_Advance_1 + + Q·Copy_Advance_1: + λ: right(1) + δ: + Q·Copy_Advance_0 + + Q·Copy_Advance_0: + λ: left(0) + δ: + Q·Copy_Read + + # Phase 4: Final Symbol and Clean Halt + Q·Copy_Last_Erase: + λ: write('σ' ,0 ,SP) + δ: + Q·Copy_Last_Write + + Q·Copy_Last_Write: + λ: write('d' ,1) + δ: + Q·Copy_Last_Advance + + Q·Copy_Last_Advance: + λ: right(1) + δ: + Q·Write_EOR_Done + + Q·Write_EOR_Done: + λ: write('σ' ,1 ,EOR) + δ: + Q·Done + + Code . The two headed string reverse controller + + + + + +
+ TTCAM 2 hd reverse machine +
+ Figure . A two headed TTCA Machine that reverses a binary string +
@@ -1325,56 +1704,64 @@

The number of states has dropped from 24 to 18, while the speed increase is dramatic, with the former quadratic performance becoming linear performance. The total number of steps for reversing an n symbol string using a two-head TTCA architecture:

- - \text{steps} = - \begin{cases} - 4 & \text{if } n = 0 \\ - 9n + 4 & \text{if } n \ge 1 - \end{cases} - + + + + \text{steps} = + \begin{cases} + 4 & \text{if } n = 0 \\ + 9n + 4 & \text{if } n \ge 1 + \end{cases} + + eq: Steps taken by the two headed TTCA reverse machine +

The two paths through the state machine, and the one loop, translate well into code:

- - void TTCA·reverse_string_2_head() { - // Phase 1: Both heads scan right to the EOM pivot - read('s' ,0); - while(s != EOM){right(0); right(1); read('s' ,0);} + + + + void TTCA·reverse_string_2_head() { + // Phase 1: Both heads scan right to the EOM pivot + read('s' ,0); + while(s != EOM){right(0); right(1); read('s' ,0);} + + // Phase 2: Setup pointers or short-circuit on empty string + status(0); + if(s == leftmost){ + right(1); + write('σ' ,1 ,EOR); + return; + } - // Phase 2: Setup pointers or short-circuit on empty string - status(0); - if(s == leftmost){ right(1); - write('σ' ,1 ,EOR); - return; - } + left(0); - right(1); - left(0); + // Phase 3: The Linear Copy Loop + while(true){ + read('d' ,0); + status(0); - // Phase 3: The Linear Copy Loop - while(true){ - read('d' ,0); - status(0); + // Break out to process the final character + if(s == leftmost) break; - // Break out to process the final character - if(s == leftmost) break; + write('σ' ,0 ,SP); + write('d' ,1); + right(1); + left(0); + } + // Phase 4: Final character, advance, and clean halt write('σ' ,0 ,SP); write('d' ,1); right(1); - left(0); - } - - // Phase 4: Final character, advance, and clean halt - write('σ' ,0 ,SP); - write('d' ,1); - right(1); - write('σ' ,1 ,EOR); + write('σ' ,1 ,EOR); - return; - } - + return; + } + + Code . The two headed reverse controller written as C +

This machine has a single tape with two heads marking two separate context areas. Because the areas do not overlap, this situation is indistinguishable from the case of the machine having two separate tapes, each with its own head. Hartmanis and Stearns established the original proof that simulating a Turing Machine with multiple tapes, each with its own head, on a single-tape, single-head machine incurs a quadratic time penalty J. Hartmanis and R. E. Stearns, "On the computational complexity of algorithms," Transactions of the American Mathematical Society 117 (1965): 285-306.. Hopcroft and Ullman formalize this relationship in their text John E. Hopcroft and Jeffrey D. Ullman, Introduction to Automata Theory, Languages, and Computation (Reading: Addison Wesley, 1979), 292.. This explains why in this example of a string reverse machine, when the second head was added to eliminate the head shuttling, the quadratic term disappeared. Not all quadratic terms in step count formulas are due to shuttling, but this one happens to be such a case.

@@ -1387,15 +1774,21 @@ - + The TTCA Machine design - Figure 1: A Turing Machine - + + + +
+ Figure 1: A Turing Machine +
+ Figure . A Turing Machine +
-

The prior chapter on the computation theoretic TTCA machine serves as the architectural template, with only a few modifications. The architecture requires explicit data rather than accepting meta-symbols like 'unspecified' as presumed initial values 'by definition'. Actual values are transacted. Now that data and control have been separated, the controller is practical to implement, and even more so because it was defined in terms of tables that can be built in hardware. As the read status instruction returns the cell type, it will in its current form be able to return 'rightmost', so the right end of the tape can be detected. In order to extend the tape, the machine will stop and ask the operator to mount a new reel. This could be signaled when the user attempts to step right of rightmost, either by a panel light that illuminates upon the machine finding a rightmost status, or by the program printing a message on the console teletype. As this is a constant-time operation, it is computation theoretic inconsequential.

+

The prior chapter on the computation theoretic TTCA machine, chapter , serves as the architectural template, with only a few modifications. The architecture requires explicit data rather than accepting meta-symbols like 'unspecified' as presumed initial values 'by definition'. Actual values are transacted. Now that data and control have been separated, the controller is practical to implement, and even more so because it was defined in terms of tables that can be built in hardware. As the read status instruction returns the cell type, it will in its current form be able to return 'rightmost', so the right end of the tape can be detected. In order to extend the tape, the machine will stop and ask the operator to mount a new reel. This could be signaled when the user attempts to step right of rightmost, either by a panel light that illuminates upon the machine finding a rightmost status, or by the program printing a message on the console teletype. As this is a constant-time operation, it is computation theoretic inconsequential.

-

Because a Turing Machine can only reach another cell further out on the tape by stepping to it, space complexity and time complexity are related. A program that runs for ten steps can consume at most ten cells of tape. However, if that program merely bounces between two cells, it will require less space, precisely two cells. As another example, a program that counts the number of characters on its input tape using Hindu-Arabic notation will execute in asymptotically linear time, as demonstrated later in the section analyzing the increment operation. Its working footprint, however, will be logarithmic in space complexity, because that is how fast an Hindu-Arabic representation grows with a count.

+

Because a Turing Machine can only reach another cell further out on the tape by stepping to it, space complexity and time complexity are related. A program that runs for ten steps can consume at most ten cells of tape. However, if that program merely bounces between two cells, it will require less space, precisely two cells. As another example, a program that counts the number of characters on its input tape using Hindu-Arabic notation will execute in asymptotically linear time, as demonstrated in section , which analyses the increment operation. Its working footprint, however, will be logarithmic in space complexity, because that is how fast an Hindu-Arabic representation grows with a count.

If a program executed at the speed of a human operator, the operator would likely abandon the process before it finished. This highlights a necessary attribute of good software: utility. It also exposes a limitation of pure computation theory, which abstracts away physical time. Nevertheless, formal analysis remains a necessity. Consider an exponential-time program processing worst-case operands: its execution time explodes relative to input length, rapidly exceeding the age of the universe. In such extremes, empirical wall-clock measurement becomes superfluous. Computation theory classifies a program's behavior, which establishes structural implications for wall-clock time, rather than calculating absolute durations.

@@ -1414,20 +1807,28 @@

An HU contains a head and a local controller. The local controller supports these instructions:

-
    -
  1. read() → σ
  2. -
  3. write(σ)
  4. -
  5. status() → s
  6. -
- -

On this model of machine, the HU status is identical to the indicated cell's type. The cell type is not read from the tape; rather, it is derived from the head's physical relationship to the ends of the tape. With a real tape drive, an unused leader and trailer are required to prevent the tape from departing from the reels, a condition difficult to reverse. Therefore, the format, or physical, markers will be on the ends of the usable portion of the tape, rather than on the physical end of the tape. Consequently, the HU works in conjunction with the TTU to derive the status. (The tape transport unit, the TTU, is discussed in the next section.) As established in the section discussing cells, cell types are:

- -
    -
  1. leftmost
  2. -
  3. rightmost
  4. -
  5. medial
  6. -
  7. island
  8. -
+ + +
    +
  1. read() → σ
  2. +
  3. write(σ)
  4. +
  5. status() → s
  6. +
+ List . The instructions supported by the head unit controller +
+ +

On this model of machine, the HU status is identical to the indicated cell's type. The cell type is not read from the tape; rather, it is derived from the head's physical relationship to the ends of the tape. With a real tape drive, an unused leader and trailer are required to prevent the tape from departing from the reels, a condition difficult to reverse. Therefore, the format, or physical, markers will be on the ends of the usable portion of the tape, rather than on the physical end of the tape. Consequently, the HU works in conjunction with the TTU to derive the status. (The tape transport unit, the TTU, is discussed in the next section, section .) As established in section , cell types are:

+ + + +
    +
  1. leftmost
  2. +
  3. rightmost
  4. +
  5. medial
  6. +
  7. island
  8. +
+ List . The cell types a head unit can report +

A computation theoretic Turing Machine would never encounter a status of rightmost or island. This is where a finite extendable tape structurally differs from a single-ended theoretical tape.

@@ -1437,28 +1838,36 @@
- + Tape transport unit, TTU

The TTU is the component where tapes are mounted and unmounted, and where read/write head units are installed. When multiple HUs are plugged in, the controller passes control among them so it appears that heads never collide. The TTU controller has these components:

-
    -
  1. one or more HUs
  2. -
  3. a data buffer holding a single symbol
  4. -
  5. a status buffer
  6. -
  7. a instruction buffer, written by the programmed controller, acted upon immediately by the TTU
  8. -
+ + +
    +
  1. one or more HUs
  2. +
  3. a data buffer holding a single symbol
  4. +
  5. a status buffer
  6. +
  7. a instruction buffer, written by the programmed controller, acted upon immediately by the TTU
  8. +
+ List . The components of the tape transport unit controller +

The TTU interfaces with the executor, which in turn gates the flow of data through the machine. The executor controls the clock and reset lines, and through this supervises the customer programmed control unit, the CPCU. This two-layer control system is single-threaded and issues the following instructions to each selected TTU:

-
    -
  1. read(head) → σ
  2. -
  3. write(σ ,head)
  4. -
  5. status(head) → γ
  6. -
  7. left(head)
  8. -
  9. right(head)
  10. -
+ + +
    +
  1. read(head) → σ
  2. +
  3. write(σ ,head)
  4. +
  5. status(head) → γ
  6. +
  7. left(head)
  8. +
  9. right(head)
  10. +
+ List . The instructions issued to a selected tape transport unit +

The head argument multiplexes the instruction to the specified head. If the TTU has one head, the head argument is optional. The last two instructions cause the tape to be moved such that, relatively, the selected head moves left or right by one cell.

@@ -1469,7 +1878,10 @@

The controller is programmed via patch panels. The panels would look something like what is shown in the following ASCII art blocks. Note that ● indicates an illuminated indicator light, whereas ○ is not illuminated. [/] represents an open toggle switch, while [—] is a closed one. {*} is a pushed button, while { } is a button that is not pushed. ( ) represents a hole for a banana plug. Each patch cord has a banana plug on each end. Plugging a patch cord between separate panels will void the warranty ;-).

- + + + +
                           [ CONTROL PANEL ]
                 +-----------------------------------+
                 | POWER [—] ●  ERROR ○    RESET { } |
@@ -1477,9 +1889,14 @@
                 +-----------------------------------+
                 | RUN/STEP [/]  ○  STEP { }         |
                 +-----------------------------------+
-      
-
-      
+        
+ Figure . The control panel, carrying power, error, reset and single step +
+ + + + +
                                  [ State Transition Table ]
                          +-------------------------------------------+
            current state |  def   q0    q1    q2    q3    q4    q5   |
@@ -1495,9 +1912,14 @@
                          |                                           |
        destination state |        ( )   ( )   ( )   ( )   ( )   ( )  |
                          +-------------------------------------------+
-      
-
-      
+        
+ Figure . The state transition panel, with state indicators and halt switches +
+ + + + +
                                [ Instruction ]
                     +-----------------------------------+
                     | q0    q1    q2    q3    q4    q5  |
@@ -1511,9 +1933,14 @@
           write('d')| ( )   ( )   ( )   ( )   ( )   ( ) |
           write('σ')| ( )   ( )   ( )   ( )   ( )   ( ) |
                     +-----------------------------------+
-      
-
-      
+        
+ Figure . The instruction panel, one patch row per instruction and one column per state +
+ + + + +
                         [ Sigma Select for write('σ') ]
                     +-----------------------------------+
                     | q0    q1    q2    q3    q4    q5  |
@@ -1525,7 +1952,9 @@
                 s3  | ( )   ( )   ( )   ( )   ( )   ( ) |
                 s4  | ( )   ( )   ( )   ( )   ( )   ( ) |
                     +-----------------------------------+
-      
+        
+ Figure . The sigma select panel, choosing the symbol written by write(σ) +

The top panel has two toggle switches. One turns the machine on, and the other selects run or single-step mode. Immediately to the right of the two toggles are indicator lights. To the right of the indicator lights are two push buttons. One is for reset, which sends the machine back to state q_0, and the other is for stepping the machine when it is in single-step mode. This panel also has an error indicator light which will illuminate if no next state is specified for a state transition, and thus the machine is hung, or if a head walks off the end of a tape.

@@ -1544,54 +1973,62 @@ The machine block diagram -
- Figure: TTCA block diagram -
Figure: TTCA block diagram
-
+ + + +
+ Figure: TTCA block diagram +
+ Figure . The TTCA Machine block diagram +
-

This section describes the TTCA machine organization. The diagram above shows the major components and their channels of communications. The organization guides designers who will later draft schematics that specify all of the connections.

+

This section describes the TTCA machine organization. Figure shows the major components and their channels of communications. The organization guides designers who will later draft schematics that specify all of the connections.

Components

-
    -
  1. Control Panel -
      -
    1. Power Switch, Single Step Switch, Reset Button, Single Step Button
    2. -
    3. patch cord matrices
    4. -
    -
  2. -
  3. Executor -
      -
    1. mode control -
        -
      1. power
      2. -
      3. run/step
      4. -
      -
    2. -
    3. staging -
        -
      1. reset button
      2. -
      3. reset logic and distribution lines
      4. -
      5. Halt Switch Bank
      6. -
      -
    4. -
    5. Clock logic and distribution lines (clk)
    6. -
    7. Single Step Switch single shot logic
    8. -
    -
  4. -
  5. CPCU (Customer Programmed Control Unit) -
      -
    1. One-hot q register
    2. -
    3. Next State Table
    4. -
    5. Instruction Table
    6. -
    -
  6. -
  7. Data bus
  8. -
  9. d register
  10. -
  11. s register
  12. -
  13. Status Decoder
  14. -
- -

As described in the computation theoretic section that is being used as the architectural template, the executor guides the machine through the initialization, programmed control, and halting stages of execution. The Executor contains the power, reset, and clock logic. It has two modes of execution: the run mode in which the clock runs free, and the single-step mode, in which clock pulses are sent with the push of a button. It also holds the halt state switch bank, and is ready to stop the clock when a halt state is reached. When in the programmed control stage, most of the active control comes from the CPCU.

+ + +
    +
  1. Control Panel +
      +
    1. Power Switch, Single Step Switch, Reset Button, Single Step Button
    2. +
    3. patch cord matrices
    4. +
    +
  2. +
  3. Executor +
      +
    1. mode control +
        +
      1. power
      2. +
      3. run/step
      4. +
      +
    2. +
    3. staging +
        +
      1. reset button
      2. +
      3. reset logic and distribution lines
      4. +
      5. Halt Switch Bank
      6. +
      +
    4. +
    5. Clock logic and distribution lines (clk)
    6. +
    7. Single Step Switch single shot logic
    8. +
    +
  4. +
  5. CPCU (Customer Programmed Control Unit) +
      +
    1. One-hot q register
    2. +
    3. Next State Table
    4. +
    5. Instruction Table
    6. +
    +
  6. +
  7. Data bus
  8. +
  9. d register
  10. +
  11. s register
  12. +
  13. Status Decoder
  14. +
+ List . The units and panels the machine is assembled from +
+ +

As described in chapter , which is being used as the architectural template, the executor guides the machine through the initialization, programmed control, and halting stages of execution. The Executor contains the power, reset, and clock logic. It has two modes of execution: the run mode in which the clock runs free, and the single-step mode, in which clock pulses are sent with the push of a button. It also holds the halt state switch bank, and is ready to stop the clock when a halt state is reached. When in the programmed control stage, most of the active control comes from the CPCU.

The CPCU contains the current state register q, the Next State Table, and the Instruction Table.

@@ -1633,7 +2070,7 @@
- + Area and partitioning

@@ -1649,11 +2086,15 @@ Head partition -

    -
  1. The left side: The finite set containing all of the cells to the left of the head cell.
  2. -
  3. Head: the head cell.
  4. -
  5. The right side: the infinite set containing all the cells to the right of the head.
  6. -
+ + +
    +
  1. The left side: The finite set containing all of the cells to the left of the head cell.
  2. +
  3. Head: the head cell.
  4. +
  5. The right side: the infinite set containing all the cells to the right of the head.
  6. +
+ List . The three areas of the head partition +

If the head is on the leftmost cell, there is no left side area.

@@ -1662,10 +2103,14 @@ Leftmost/remaining partition -
    -
  1. Leftmost: the leftmost cell.
  2. -
  3. Remaining: the infinite set including the right neighbor of the leftmost cell, and all cells further to the right.
  4. -
+ + +
    +
  1. Leftmost: the leftmost cell.
  2. +
  3. Remaining: the infinite set including the right neighbor of the leftmost cell, and all cells further to the right.
  4. +
+ List . The two areas of the leftmost and remaining partition +
@@ -1676,13 +2121,17 @@ A nonempty tape, one with at least one cell holding an alphabet symbol, can be partitioned into the following areas:

-
    -
  1. The left empty tail: if the leftmost cell of the tape is an alphabet cell, there is no left empty tail. Otherwise, it consists of the leftmost cell and the empty cells, if any, to the right of the leftmost cell, up to, but not including, the first alphabet cell.
  2. + + +
      +
    1. The left empty tail: if the leftmost cell of the tape is an alphabet cell, there is no left empty tail. Otherwise, it consists of the leftmost cell and the empty cells, if any, to the right of the leftmost cell, up to, but not including, the first alphabet cell.
    2. -
    3. Active area: a finite area for computational problems, containing the cells extending from the leftmost alphabet cell up to and including the rightmost alphabet cell. It is possible that the leftmost alphabet cell and the rightmost alphabet cell will be the same cell.
    4. +
    5. Active area: a finite area for computational problems, containing the cells extending from the leftmost alphabet cell up to and including the rightmost alphabet cell. It is possible that the leftmost alphabet cell and the rightmost alphabet cell will be the same cell.
    6. -
    7. The right empty tail: the infinite set extending from the right neighbor of the rightmost cell of the active area, extending rightward.
    8. -
    +
  3. The right empty tail: the infinite set extending from the right neighbor of the rightmost cell of the active area, extending rightward.
  4. +
+ List . The three areas of the active area partition +

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. @@ -1805,11 +2254,15 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos 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.

-
    -
  1. For the Head partition and Area implied partition, the right side is no longer infinite. It is a finite set containing all cells extending from the right neighbor of the head (or area) up to the absolute rightmost cell of the virtual tape. If the head (or area) includes the rightmost cell of the virtual tape, the right side set does not exist.
  2. -
  3. For the Leftmost/remaining partition, the remaining area is now a finite set terminating at the rightmost cell of the virtual tape.
  4. -
  5. For the Active area partition, the right empty tail is similarly a finite set extending to the rightmost boundary of the virtual tape. If the rightmost alphabet cell occupies the rightmost cell of the virtual tape, the right empty tail does not exist.
  6. -
+ + +
    +
  1. For the Head partition and Area implied partition, the right side is no longer infinite. It is a finite set containing all cells extending from the right neighbor of the head (or area) up to the absolute rightmost cell of the virtual tape. If the head (or area) includes the rightmost cell of the virtual tape, the right side set does not exist.
  2. +
  3. For the Leftmost/remaining partition, the remaining area is now a finite set terminating at the rightmost cell of the virtual tape.
  4. +
  5. For the Active area partition, the right empty tail is similarly a finite set extending to the rightmost boundary of the virtual tape. If the rightmost alphabet cell occupies the rightmost cell of the virtual tape, the right empty tail does not exist.
  6. +
+ List . The partitions of a finite virtual tape +
@@ -1836,7 +2289,7 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos 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. +

As we noted in section , 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. @@ -1876,11 +2329,15 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos How cardinality is computed -

    -
  1. We set Turing Machine P with its head on the leftmost cell of an area. We mount the initial tape, '·', on the A machine.
  2. -
  3. We step P and simultaneously run the A machine. Stepping stops when P reaches the rightmost cell of the area. At this point, the tape on the A machine holds the address space extent.
  4. -
  5. The A machine is run an additional time. The output on the tape is defined to be the cardinality of the address space, aka the cardinality.
  6. -
+ + +
    +
  1. We set Turing Machine P with its head on the leftmost cell of an area. We mount the initial tape, '·', on the A machine.
  2. +
  3. We step P and simultaneously run the A machine. Stepping stops when P reaches the rightmost cell of the area. At this point, the tape on the A machine holds the address space extent.
  4. +
  5. The A machine is run an additional time. The output on the tape is defined to be the cardinality of the address space, aka the cardinality.
  6. +
+ List . The three steps for computing the cardinality of an address space +
@@ -1943,9 +2400,13 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos Now here is an interesting result:

- - \aleph_{0} - \aleph_{-1} = 1 - + + + + \aleph_{0} - \aleph_{-1} = 1 + + eq: The difference of two transfinite cardinals is one +

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. @@ -1996,7 +2457,7 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos - + Hindu-Arabic representation

Charles Burnett published a very interesting book about the translation of Hindu-Arabic mathematics in Europe during the Middle Ages Charles Burnett, Numerals and Arithmetic in the Middle Ages (Farnham: Ashgate Variorum, 2010). DOI: 10.33137/aestimatio.v9i0.25990.. He describes a 9th-century treatise on Hindu-Arabic arithmetic authored by Muḥammad ibn Mūsā al-Khwārizmī, where "al-Khwārizmī" indicated he was from Khwarazm in Central Asia. When this manuscript was translated into Latin in the 12th century, European translators approximated his name as Algoritmi or Algorismi, thus giving us the word algorithm. He notes that the Arabs called such numbers "Indian Numbers". Another chapter, "Why we read Arabic numerals backwards," shows that the little-endian and big-endian debate that has plagued programmers for decades has its origin in the Middle Ages Danny Cohen, "On Holy Wars and a Plea for Peace," IEEE Computer 14, no. 10 (October 1981): 48-54. DOI: 10.1109/C-M.1981.220208.

@@ -2013,72 +2474,81 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos For Hindu-Arabic_increment, the machine reads the cell under the head; upon finding a 0 or the terminator, it writes a 1 and halts. Upon finding a 1, it writes a 0, steps right, and repeats the procedure.

- - increment: - a = TTU.read() - if a == 0 or a == □: - TTU.write(1) - halt - TTU.write(0) - TTU.step() - goto increment - + + + + increment: + a = TTU.read() + if a == 0 or a == □: + TTU.write(1) + halt + TTU.write(0) + TTU.step() + goto increment + + Code . A controller that increments a binary counter +

Here TTU is the tape transport unit. It has the number to be incremented mounted on it. This number is either zero, which would mean the leftmost cell is empty, or it is of the same form as a result from a Natural Number extension machine. A TTU.read places a copy of the symbol instance found in the cell under the head into the read buffer automatically when the machine enters a new state on the programmed controller, so it is not counted as a step. In contrast, the other actions are associated with the state of the programmed controller, so when the machine arrives at a write, step, or halt node, it means that the programmed state controller has taken a step. Sequential instructions mean unconditional next state choices, whereas an if signals a conditional next state choice. The if condition is a logical proposition based on the read symbol.

The loop form here is worth taking note of, as it will come up again. The controller executes a first action, that of a read, followed by a middle break test, and then the recursive form actions.

- 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. -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
inputactioncost (steps)
0write 1, halt (result is maximum 1 bit count)2
1 write 0, step, write 1, halt4
01write 1, halt (result is maximum 2 bit count)2
11write 0, step, write 0, step, write 1, halt6
001write 1, halt2
101write 0, step right, write 1, halt4
011write 1, halt (result is maximum 3 bit count)2
111
+ 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. Table lists 7 increments, which is sufficient to reach the maximum count that can be held by a 3 bit counter. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
inputactioncost (steps)
0write 1, halt (result is maximum 1 bit count)2
1 write 0, step, write 1, halt4
01write 1, halt (result is maximum 2 bit count)2
11write 0, step, write 0, step, write 1, halt6
001write 1, halt2
101write 0, step right, write 1, halt4
011write 1, halt (result is maximum 3 bit count)2
111
+ Table . The cost in steps of each increment, through the range of a three bit counter +

The number of programmable controller state transition steps required to reach a maximum 1 bit, 2 bit, and 3 bit count are: [2, 8, 22]. Note these are cumulative. The three bit maximum count cost includes that of the two bit maximum count cost, etc. Each maximum count is exponentially larger, so a better measure is the average cost per step: [2/1, 8/3, 22/7] = [2, 2.667, 3.143] @@ -2127,10 +2597,14 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos

This reveals a fundamental property of Arabic Representation: it encodes both the sequence of digit symbols (which map to a natural number) and the sequence's length (which exists at a meta level, governing computational operations). The representation of zero exposes a limitation. At zero, the representation retains length information necessary for computation but lacks an explicit numerical mapping to zero itself.

Structurally, this forces a design choice between two options:

-
    -
  • Using an empty sequence [] and arbitrarily mapping it to zero. This allows a length function to return zero naturally, as the empty sequence is never scanned.
  • -
  • Using a lone zero symbol [0], which introduces an effective length concept where [0] must be treated as though it has zero length in algorithmic operations.
  • -
+ + +
    +
  • Using an empty sequence [] and arbitrarily mapping it to zero. This allows a length function to return zero naturally, as the empty sequence is never scanned.
  • +
  • Using a lone zero symbol [0], which introduces an effective length concept where [0] must be treated as though it has zero length in algorithmic operations.
  • +
+ List . The two options for representing zero +

Without explicit brackets, the empty sequence collapses into an empty space, conveying no meaning when written in conventional notation. To maintain visual clarity and avoid empty spaces where zero should appear, conventional architectures adopt the standard 0. However, the length function must still return zero for [0], despite its apparent length of one.

@@ -2314,19 +2788,27 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos

In the architectural terminology utilized here, viewing memory as a horizontal tape with bytes in the cells and addresses increasing while moving to the right, little-endian numbers have the least-significant digit on the left, and big-endian numbers have the least significant digit on the right of an allocation. Stated structurally, little-endian numbers are zero padded on the right, and big-endian numbers are zero padded on the left.

-

Figure 10 depicts a word featuring byte addresses represented in hexadecimal, running from c0 to c3. (In decimal these addresses represent 192, 193, 194, 195). The address of the byte before c0 is bf. The address after c3 is c4. The address for the word itself evaluates to c0, as it is the minimum byte address. This word holds a little-endian number. Treating a byte as an octet digit, the binary encoding for the least-significant digit of this number is 0001 1000. The most-significant digit is 1010 1110.

+

Figure depicts a word featuring byte addresses represented in hexadecimal, running from c0 to c3. (In decimal these addresses represent 192, 193, 194, 195). The address of the byte before c0 is bf. The address after c3 is c4. The address for the word itself evaluates to c0, as it is the minimum byte address. This word holds a little-endian number. Treating a byte as an octet digit, the binary encoding for the least-significant digit of this number is 0001 1000. The most-significant digit is 1010 1110.

-
- Figure 10: Left justified, least-significant-digit-first -
Figure 10: Left justified, least-significant-digit-first
-
+ + + +
+ Figure 10: Left justified, least-significant-digit-first +
+ Figure . A left justified word holding a number least-significant-digit-first +
-

In Figure 11, the same number populates the word using big-endian architecture. For all but very large numbers, the digit pointed at by the allocation pointer evaluates to zero. A system continues to scan zeros until reaching either the end of the allocation or the most-significant digit. If it reaches the end of the allocation, the contained number evaluates to zero. Because this is the exact same number shown in the prior figure, it retains the identical least-significant digit and most-significant digit.

+

In Figure , the same number populates the word using big-endian architecture. For all but very large numbers, the digit pointed at by the allocation pointer evaluates to zero. A system continues to scan zeros until reaching either the end of the allocation or the most-significant digit. If it reaches the end of the allocation, the contained number evaluates to zero. Because this is the exact same number shown in Figure , it retains the identical least-significant digit and most-significant digit.

-
- Figure 11: Same number using big-endian digit order -
Figure 11: Same number using big-endian digit order
-
+ + + +
+ Figure 11: Same number using big-endian digit order +
+ Figure . The same number held in big-endian digit order +

If the specified word holds a count, the counting mechanics differ. When counting with the little-endian convention, a number grows into larger addresses as the count carries into new digits. In contrast, with big-endian architecture, counting carries into strictly smaller memory addresses.

@@ -2362,19 +2844,27 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos

Our Indian Number derived representations consist of sequences of digits. Words of allocation consist of consecutively addressed bytes. Hardware manages bytes atomically. Any bit encoding for the digits of a number must pack cleanly into bytes, otherwise the digits fracture. Achieving a clean packing requires padding the data with zeros to force alignment to an 8-bit boundary. When a system meets this criterion, treating a number as a sequence of bytes acting as digits maintains structural consistency. Due to this constraint, little-endian and big-endian are routinely classified as byte orders.

-

The following figure displays a stream of bytes arriving as data and being copied into a word. The digits of the word (the bytes) arrive in little-endian order and target a little-endian machine, so they are written in the exact order they are scanned off the channel.

+

Figure displays a stream of bytes arriving as data and being copied into a word. The digits of the word (the bytes) arrive in little-endian order and target a little-endian machine, so they are written in the exact order they are scanned off the channel.

-
- Figure 12: In-address-order byte by byte copy -
Figure 12: In-address-order byte by byte copy
-
+ + + +
+ Figure 12: In-address-order byte by byte copy +
+ Figure . A byte by byte copy performed in address order +

In the second case, the identical data stream arrives with words serialized as bytes in little-endian order, but the receiving machine is big-endian. The system must reverse the bytes strictly on a word-by-word basis.

-
- Figure 13: Reverse order byte copy for words -
Figure 13: Reverse order byte copy for words
-
+ + + +
+ Figure 13: Reverse order byte copy for words +
+ Figure . A reverse order byte copy performed word by word +

When the data arrives, there is no way to know where the word boundaries are. Serialization destroys that structural boundary information. Without knowing where the words are, a system cannot determine when to perform the byte order reversal. Therefore, resolving this requires a different approach than the one used for bit order in bytes; the problem transfers into the software layer.

@@ -2439,57 +2929,62 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos

- 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 TierReal World LatencyScaled DelayScaled Arrival EraHistorical Context
L1 Cache Hit1 ns3 days-0043-03-18Three days after the assassination.
DRAM (Main memory)100 ns300 days-0042-01-09Nearly a year later, during the Liberators' civil war.
NVMe SSD Page Swap15 µs45,000 days0080123 years later, exactly as the Colosseum is completed in Rome.
SATA SSD Page Swap100 µs300,000 days0778821 years later, during the reign of Charlemagne and the Frankish Empire.
Magnetic HDD Page Swap10 ms30,000,000 days82092Tens of thousands of years in the future, long after current human civilizations are dust.
+ 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. Table provides the historical date that the variable value would finally be loaded into the processor, depending on the memory tier being accessed: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Memory TierReal World LatencyScaled DelayScaled Arrival EraHistorical Context
L1 Cache Hit1 ns3 days-0043-03-18Three days after the assassination.
DRAM (Main memory)100 ns300 days-0042-01-09Nearly a year later, during the Liberators' civil war.
NVMe SSD Page Swap15 µs45,000 days0080123 years later, exactly as the Colosseum is completed in Rome.
SATA SSD Page Swap100 µs300,000 days0778821 years later, during the reign of Charlemagne and the Frankish Empire.
Magnetic HDD Page Swap10 ms30,000,000 days82092Tens of thousands of years in the future, long after current human civilizations are dust.
+ Table . Memory tier latency, scaled so that one clock tick lasts one day +

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. Andrew S. Tanenbaum famously coined this concept in his 1981 textbook Computer Networks, stating: "Never underestimate the bandwidth of a station wagon full of tapes hurtling down the highway." This physical data transfer method is universally referred to as a sneakernet. Ten terabits, at three days, equates to 26 nanoseconds per bit. Not bad, if a user can wait three days to continue the program, but aliasing between data sets would make a program very slow. The Turing Machine model does not capture the effects of clumped data accesses. @@ -2515,110 +3010,118 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos

Applying this mechanical procedure to the TTCA two-headed reverse string example controller results in:

- - # Phase 1: Both heads scan right to the EOM pivot - L·initial: - read('s' ,0) - jump(s, {EOM: L·Check_Empty, def: L·Scan_Right}) - - L·Scan_Right: - right(0) - right(1) - jump(def: L·initial) - - # Phase 2: Setup pointers or short-circuit on empty string - L·Check_Empty: - status(0) - jump(s, {leftmost: L·Empty_Setup, def: L·Setup_Write}) - - L·Empty_Setup: - right(1) - jump(def: L·Write_EOR_Done) - - L·Setup_Write: - right(1) - left(0) - jump(def: L·Copy_Read) - - # Phase 3: The Linear Copy Loop - L·Copy_Read: - read('d' ,0) - status(0) - jump(s, {leftmost: L·Copy_Last, def: L·Copy_Loop}) - - L·Copy_Loop: - write('σ' ,0 ,SP) - write('d' ,1) - right(1) - left(0) - jump(def: L·Copy_Read) - - # Phase 4: Final character, advance, and clean halt - L·Copy_Last: - write('σ' ,0 ,SP) - write('d' ,1) - right(1) - jump(def: L·Write_EOR_Done) - - L·Write_EOR_Done: - write('σ' ,1 ,EOR) - halt - + + + + # Phase 1: Both heads scan right to the EOM pivot + L·initial: + read('s' ,0) + jump(s, {EOM: L·Check_Empty, def: L·Scan_Right}) + + L·Scan_Right: + right(0) + right(1) + jump(def: L·initial) + + # Phase 2: Setup pointers or short-circuit on empty string + L·Check_Empty: + status(0) + jump(s, {leftmost: L·Empty_Setup, def: L·Setup_Write}) + + L·Empty_Setup: + right(1) + jump(def: L·Write_EOR_Done) + + L·Setup_Write: + right(1) + left(0) + jump(def: L·Copy_Read) + + # Phase 3: The Linear Copy Loop + L·Copy_Read: + read('d' ,0) + status(0) + jump(s, {leftmost: L·Copy_Last, def: L·Copy_Loop}) + + L·Copy_Loop: + write('σ' ,0 ,SP) + write('d' ,1) + right(1) + left(0) + jump(def: L·Copy_Read) + + # Phase 4: Final character, advance, and clean halt + L·Copy_Last: + write('σ' ,0 ,SP) + write('d' ,1) + right(1) + jump(def: L·Write_EOR_Done) + + L·Write_EOR_Done: + write('σ' ,1 ,EOR) + halt + + Code . The two headed reverse controller as linear code with jumps +

The state labels have become addresses into the program tape, and the address of the cell indicated by the head on the first tape is now an Instruction Pointer (IP). In a sense the programmed controller has been replaced by a little Turing Machine of its own. One that controls the head on the first tape, and moves it in response to the control instructions found on the first tape. Such a controller on a processor is called a sequencer.

By separating the control path from the data path, utilizing an integrated symbol alphabet, replacing states with sequential instructions, and introducing an explicit addressable instruction pointer, the theoretical machine has physically crossed the bridge to conventional computing. The resulting architecture is a stored-program, von Neumann-style machine organization.

-

Some of the default cases for the jump table unnecessarily jump to the instruction at the next sequential address. This code lacks the regularity to use a computed jump table, so this style of jump table becomes a Lisp cond statement, i.e. sequential conditional tests. So then by using the instructions test, beq (for branch on equal), and jump as control instructions, and rearranging to favor sequential execution, this code becomes:

- - - # Phase 1: Both heads scan right to the EOM pivot - L·initial: - read('s' ,0) - test('s' ,EOM) - beq L·Check_Empty - - # L·Scan_Right (Implicit fall-through) - right(0) - right(1) - jump L·initial - - # Phase 2: Setup pointers or short-circuit on empty string - L·Check_Empty: - status(0) - test('s' ,leftmost) - beq L·Empty_Setup - - # L·Setup_Write (Implicit fall-through) - right(1) - left(0) - - # Phase 3: The Linear Copy Loop - L·Copy_Read: - read('d' ,0) - status(0) - test('s' ,leftmost) - beq L·Copy_Last - - # L·Copy_Loop (Implicit fall-through) - write('σ' ,0 ,SP) - write('d' ,1) - right(1) - left(0) - jump L·Copy_Read - - # Phase 4: Final character, advance, and clean halt - L·Copy_Last: - write('σ' ,0 ,SP) - write('d' ,1) - - L·Empty_Setup: - right(1) - - # L·Write_EOR_Done (Implicit fall-through) - write('σ' ,1 ,EOR) - halt - +

Some of the default cases for the jump table unnecessarily jump to the instruction at the next sequential address. Code lacks the regularity to use a computed jump table, so this style of jump table becomes a Lisp cond statement, i.e. sequential conditional tests. So then by using the instructions test, beq (for branch on equal), and jump as control instructions, and rearranging to favor sequential execution, this code becomes:

+ + + + + # Phase 1: Both heads scan right to the EOM pivot + L·initial: + read('s' ,0) + test('s' ,EOM) + beq L·Check_Empty + + # L·Scan_Right (Implicit fall-through) + right(0) + right(1) + jump L·initial + + # Phase 2: Setup pointers or short-circuit on empty string + L·Check_Empty: + status(0) + test('s' ,leftmost) + beq L·Empty_Setup + + # L·Setup_Write (Implicit fall-through) + right(1) + left(0) + + # Phase 3: The Linear Copy Loop + L·Copy_Read: + read('d' ,0) + status(0) + test('s' ,leftmost) + beq L·Copy_Last + + # L·Copy_Loop (Implicit fall-through) + write('σ' ,0 ,SP) + write('d' ,1) + right(1) + left(0) + jump L·Copy_Read + + # Phase 4: Final character, advance, and clean halt + L·Copy_Last: + write('σ' ,0 ,SP) + write('d' ,1) + + L·Empty_Setup: + right(1) + + # L·Write_EOR_Done (Implicit fall-through) + write('σ' ,1 ,EOR) + halt + + Code . The same controller using test, branch and jump instructions +

This is an assembly-level code description of an instruction sequence. To get it into final form, the labels that appear as instruction arguments would be replaced with their addresses. Symbolic labels would not appear on the tape. As an alternative to using absolute branches, relative branches could be used. Performance will be greatly enhanced for a sequencer that performs relative branching if it contains an adder circuit; otherwise, the addition of offsets would be another TTCA program invocation.

@@ -2645,7 +3148,7 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos
- + Symbol in computing

@@ -2701,12 +3204,12 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos

- 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. + 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 section , 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.

- + Distinctness across contexts

@@ -2763,95 +3266,103 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos The enum of C is used to make alphabets of named symbols. Each entry in the enum is a static symbol factory, and instances are distinct integers.

- - /* The enum definition acts as the factory. */ - typedef enum { - SYMBOL_EMPTY = 0, - SYMBOL_ZERO = 1, - SYMBOL_ONE = 2, - SYMBOL_A = 3, - SYMBOL_B = 4 - } TapeAlphabet; - - /* Instantiating copies of the symbols: */ - TapeAlphabet cell_1 = SYMBOL_A; - TapeAlphabet cell_2 = SYMBOL_A; - - /* Equality comparison over instances */ - if(cell_1 == cell_2){ - /* Evaluates to True */ - } - + + + + /* The enum definition acts as the factory. */ + typedef enum { + SYMBOL_EMPTY = 0, + SYMBOL_ZERO = 1, + SYMBOL_ONE = 2, + SYMBOL_A = 3, + SYMBOL_B = 4 + } TapeAlphabet; + + /* Instantiating copies of the symbols: */ + TapeAlphabet cell_1 = SYMBOL_A; + TapeAlphabet cell_2 = SYMBOL_A; + + /* Equality comparison over instances */ + if(cell_1 == cell_2){ + /* Evaluates to True */ + } + + Code . A static symbol factory made with a C enum +

The enum is a static alphabet made by the compiler, where symbol instances are integers. In the following example, the alphabet is made dynamically, where each symbol instance is a string pointer.

- - #include <string.h> - #include <stdlib.h> - #include <stdio.h> - - // maximum legal index into the symbol list - #define LIST_EXTENT 3 - - typedef const char *Instance; - typedef struct{ - Instance *head; - Instance *tail; - Instance *extent; - } List; + + + + #include <string.h> + #include <stdlib.h> + #include <stdio.h> + + // maximum legal index into the symbol list + #define LIST_EXTENT 3 + + typedef const char *Instance; + typedef struct{ + Instance *head; + Instance *tail; + Instance *extent; + } List; + + static List SYM_LIST = {NULL ,NULL ,NULL}; + + Instance make_list(const char *name){ + size_t size = LIST_EXTENT + 1; + SYM_LIST.head = (Instance *)malloc( size * sizeof(Instance) ); + SYM_LIST.tail = SYM_LIST.head; + SYM_LIST.extent = SYM_LIST.head + LIST_EXTENT; + *SYM_LIST.head = strdup(name); + return *SYM_LIST.head; + } - static List SYM_LIST = {NULL ,NULL ,NULL}; + Instance make_symbol(const char *name){ + if(!SYM_LIST.head) return make_list(name); - Instance make_list(const char *name){ - size_t size = LIST_EXTENT + 1; - SYM_LIST.head = (Instance *)malloc( size * sizeof(Instance) ); - SYM_LIST.tail = SYM_LIST.head; - SYM_LIST.extent = SYM_LIST.head + LIST_EXTENT; - *SYM_LIST.head = strdup(name); - return *SYM_LIST.head; - } + Instance *pt = SYM_LIST.head; + while(1){ + if( strcmp(*pt ,name) == 0 ) return *pt; - Instance make_symbol(const char *name){ - if(!SYM_LIST.head) return make_list(name); + if(pt == SYM_LIST.extent){ + fprintf(stderr ,"symbol list overflow for %s\n" ,name); + return NULL; + } - Instance *pt = SYM_LIST.head; - while(1){ - if( strcmp(*pt ,name) == 0 ) return *pt; + if(pt == SYM_LIST.tail){ + *++SYM_LIST.tail = strdup(name); + return *SYM_LIST.tail; + } - if(pt == SYM_LIST.extent){ - fprintf(stderr ,"symbol list overflow for %s\n" ,name); - return NULL; + pt++; } + } - if(pt == SYM_LIST.tail){ - *++SYM_LIST.tail = strdup(name); - return *SYM_LIST.tail; + int main(){ + Instance a = make_symbol("a"); + Instance b = make_symbol("b"); + Instance c = make_symbol("c"); + Instance d = make_symbol("d"); + Instance e = make_symbol("e"); // overflows table + + Instance *pt = SYM_LIST.head; + Instance *pt_tail = SYM_LIST.tail; + while(1){ + puts(*pt); + if(pt == pt_tail) break; + pt++; } - pt++; + if(e == NULL) printf("e is NULL\n"); } - } - - int main(){ - Instance a = make_symbol("a"); - Instance b = make_symbol("b"); - Instance c = make_symbol("c"); - Instance d = make_symbol("d"); - Instance e = make_symbol("e"); // overflows table - - Instance *pt = SYM_LIST.head; - Instance *pt_tail = SYM_LIST.tail; - while(1){ - puts(*pt); - if(pt == pt_tail) break; - pt++; - } - - if(e == NULL) printf("e is NULL\n"); - } - + + Code . A dynamic symbol factory whose instances are string pointers +
@@ -2875,7 +3386,7 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos
- + A Turing Machine tape cell

@@ -2926,7 +3437,7 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos - + Computational Analysis @@ -2941,33 +3452,18 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos

- 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 analyzer. The program or machine definition being subjected to this evaluation is called the studied program or studied machine. + The orders of analysis were named in section + . This + chapter takes the second order as its working material.

-

- Turing Machines that halt in a finite number of steps for any finite input within a stipulated domain are said to be computational over that domain. -

- 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. + 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.

-

- 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 analysis. -

-

- 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 0.1111... indefinitely evaluates in the limit to 1.0. In this manner, the use of analyzers facilitates using computation theory for deriving higher order mathematics. @@ -2995,27 +3491,35 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos Suppose our goal is to subtract 3 from 5 in the second order. Consider a Turing Machine representation named five that outputs the number 5, i.e., it prints to the tape, 'sssss', using unary notation. Let us assume that the tape is initially empty and that the empty symbol '□' terminates the string. To preserve the code for second order analysis, we define the program's Abstract Syntax Tree (AST) as a quoted progn block. This block can contain any native Lisp control structures, though for this generator it is a simple sequence:

- - (defparameter *five-ast* - '(progn - (write s) (step) - (write s) (step) - (write s) (step) - (write s) (step) - (write s) (step) - )) - + + + + (defparameter *five-ast* + '(progn + (write s) (step) + (write s) (step) + (write s) (step) + (write s) (step) + (write s) (step) + )) + + Code . The abstract syntax tree for the natural number five +

Similarly, the AST for the number 3:

- - (defparameter *three-ast* - '(progn - (write s) (step) - (write s) (step) - (write s) (step) - )) - + + + + (defparameter *three-ast* + '(progn + (write s) (step) + (write s) (step) + (write s) (step) + )) + + Code . The abstract syntax tree for the natural number three +

If we were to dynamically evaluate these ASTs in the first order, the Hindu-Arabic representation of each number would be physically written in unary code on the tape. @@ -3025,58 +3529,66 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos 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 (write s) followed by a (step) instruction with an inverted pair: a (left) instruction followed by writing the empty symbol (write □).

- - (defun invert-direction (cmds) - (cond - ((null cmds) nil) - ( - (and - (cdr cmds) - (equal (first cmds) '(write s)) - (equal (second cmds) '(step))) - (append - '((left) (write □)) - (invert-direction (cddr cmds)) - )) - ( - t - (cons - (first cmds) - (invert-direction (cdr cmds)) - )))) - - (defun primitive-compose-subtract (ast-a ast-b) - (let - ( - (body-a (rest ast-a)) - (body-b (rest ast-b)) - ) - `(progn - ,@body-a - ,@(invert-direction body-b) - ))) - + + + + (defun invert-direction (cmds) + (cond + ((null cmds) nil) + ( + (and + (cdr cmds) + (equal (first cmds) '(write s)) + (equal (second cmds) '(step))) + (append + '((left) (write □)) + (invert-direction (cddr cmds)) + )) + ( + t + (cons + (first cmds) + (invert-direction (cdr cmds)) + )))) + + (defun primitive-compose-subtract (ast-a ast-b) + (let + ( + (body-a (rest ast-a)) + (body-b (rest ast-b)) + ) + `(progn + ,@body-a + ,@(invert-direction body-b) + ))) + + Code . A composer that subtracts by inverting the direction of one machine +

We pass our two natural number ASTs to this composer, and we get as a result a newly synthesized AST.

- - (defparameter - *primitive-five-minus-3-ast* - (primitive-compose-subtract *five-ast* *three-ast*) - ) - - ;; *primitive-five-minus-3-ast* evaluates to: - ;; '(progn - ;; (write s) (step) - ;; (write s) (step) - ;; (write s) (step) - ;; (write s) (step) - ;; (write s) (step) - ;; (left) (write □) - ;; (left) (write □) - ;; (left) (write □) - ;; ) - + + + + (defparameter + *primitive-five-minus-3-ast* + (primitive-compose-subtract *five-ast* *three-ast*) + ) + + ;; *primitive-five-minus-3-ast* evaluates to: + ;; '(progn + ;; (write s) (step) + ;; (write s) (step) + ;; (write s) (step) + ;; (write s) (step) + ;; (write s) (step) + ;; (left) (write □) + ;; (left) (write □) + ;; (left) (write □) + ;; ) + + Code . The composed but unsimplified tree for five minus three +

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. @@ -3090,56 +3602,64 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos 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 progn body suffices. It calls itself recursively until the scan fails to find any further reductions, returning its optimized AST.

- - (defun remove-annihilations (cmds) - (cond - ((null cmds) nil) - ( - (and - (cdr cmds) - (equal (first cmds) '(step)) - (equal (second cmds) '(left))) - (remove-annihilations (cddr cmds))) - ( - (and - (cdr cmds) - (equal (first cmds) '(write s)) - (equal (second cmds) '(write □))) - (remove-annihilations (cddr cmds))) - ( - t - (cons - (first cmds) - (remove-annihilations (cdr cmds)) - )))) - - (defun simplify-machine (ast) - (let* - ( - (cmds (rest ast)) - (reduced (remove-annihilations cmds)) - ) - (if - (equal reduced cmds) - ast - (simplify-machine `(progn ,@reduced)) - ))) - - + + + + (defun remove-annihilations (cmds) + (cond + ((null cmds) nil) + ( + (and + (cdr cmds) + (equal (first cmds) '(step)) + (equal (second cmds) '(left))) + (remove-annihilations (cddr cmds))) + ( + (and + (cdr cmds) + (equal (first cmds) '(write s)) + (equal (second cmds) '(write □))) + (remove-annihilations (cddr cmds))) + ( + t + (cons + (first cmds) + (remove-annihilations (cdr cmds)) + )))) + + (defun simplify-machine (ast) + (let* + ( + (cmds (rest ast)) + (reduced (remove-annihilations cmds)) + ) + (if + (equal reduced cmds) + ast + (simplify-machine `(progn ,@reduced)) + ))) + + + Code . A simplifier that removes annihilating instruction pairs +

After giving the difference program to the simplifier, we get:

- - (defparameter - *simplified-five-minus-3-ast* - (simplify-machine *primitive-five-minus-3-ast*) - ) - - ;; *simplified-five-minus-3-ast* evaluates to: - ;; '(progn - ;; (write s) (step) - ;; (write s) (step)) - + + + + (defparameter + *simplified-five-minus-3-ast* + (simplify-machine *primitive-five-minus-3-ast*) + ) + + ;; *simplified-five-minus-3-ast* evaluates to: + ;; '(progn + ;; (write s) (step) + ;; (write s) (step)) + + Code . The simplified tree for five minus three +

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 Simplify is the compiler optimization simplifier as above. A difference in these two systems is that of the functions being reduced to Turing Machine head and tape transport unit instructions.

@@ -3160,21 +3680,33 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos Let us take the multiplicative inverse of the additive identity as an example, AKA division by zero. In the second order, when we attempt to compute a division, say 6/0, the machine will not reduce.

- - (divide 6 0) - + + + + (divide 6 0) + + Code . A division by zero, which does not reduce +

Now consider the compiler optimization like simplification of this expression:

- - (divide (divide 6 0) (divide 3 0)) - + + + + (divide (divide 6 0) (divide 3 0)) + + Code . A composition of two unreduced divisions +

The result will be:

- - (multiply 2 (divide 0 0)) - + + + + (multiply 2 (divide 0 0)) + + Code . The reduced result, still carrying a divide of zero by zero +

There is no special help here. Hence, (divide 0 0) remains as an error flag. @@ -3221,48 +3753,53 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos Let us construct a forward difference pyramid for the polynomial f(t) = t^2.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Count (t)f(t) = t^21st Diff (δ^1)2nd Diff (δ^2)
0012
1132
2452
397
416
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Count (t)f(t) = t^21st Diff (δ^1)2nd Diff (δ^2)
0012
1132
2452
397
416
+ Table . The forward difference table for f(t) = t² +

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. @@ -3272,13 +3809,17 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos Here is the sequence of tape states as the machine is repeatedly called to extend the function from its initial conditions at t = 0. During each step, the machine adds δ^1 to f, and δ^2 to δ^1, as there is no δ^3, it is taken to be zero, so δ^2 is merely copied down.

- - Initial Tape (t=0): [0, 1, 2] - Call 1 (t=1): [1, 3, 2] - Call 2 (t=2): [4, 5, 2] - Call 3 (t=3): [9, 7, 2] - Call 4 (t=4): [16, 9, 2] - + + + + Initial Tape (t=0): [0, 1, 2] + Call 1 (t=1): [1, 3, 2] + Call 2 (t=2): [4, 5, 2] + Call 3 (t=3): [9, 7, 2] + Call 4 (t=4): [16, 9, 2] + + Code . The tape at each call while extending t² +

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. @@ -3301,7 +3842,7 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos - + Lemma: Evaluating call \omega requires an initial tape populated with components 0 through \omega of row 0

@@ -3334,17 +3875,25 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos The exact algebraic composition of this mechanical expansion is formalized by Newton's calculus of finite differences Isaac Newton formalized this interpolation method in 1675, later published in his Methodus Differentialis (1711). For a comprehensive foundational treatment, see George Boole, A Treatise on the Calculus of Finite Differences (Cambridge: Macmillan and Co., 1860), Chapter II.. Instead of executing the machine incrementally, a person can calculate the function value at call \omega directly as a linear combination of the initial tape components using Newton's forward difference formula:

- - D_{\omega, 0} = \sum_{j=0}^{\omega} \binom{\omega}{j} D_{0, j} - + + + + D_{\omega, 0} = \sum_{j=0}^{\omega} \binom{\omega}{j} D_{0, j} + + eq: Newton's forward difference formula for the value at call ω +

Because the binomial coefficient \binom{\omega}{j} evaluates to exactly zero for any integer j > \omega, the summation naturally truncates at index \omega. This algebraic property perfectly mirrors the physical boundary established by the machine execution trace. Furthermore, the relationship is symmetric. A person can compute the specific components of the initial tape, D_{0, n}, directly from the sequence of evaluated function calls, D_{k, 0}, using the alternating binomial sum:

- - D_{0, n} = \sum_{k=0}^{n} (-1)^{n-k} \binom{n}{k} D_{k, 0} - + + + + D_{0, n} = \sum_{k=0}^{n} (-1)^{n-k} \binom{n}{k} D_{k, 0} + + eq: The initial tape components recovered from evaluated calls +

As a consequence of this lemma, we know that for any finite number of calls, i.e. finite \omega, that a finite prefix of D_0 is used. @@ -3396,40 +3945,45 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos 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:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DifferenceEquation
D_{0,0}= a_0
D_{0,1}= a_1 + a_2 + a_3 + \ldots + a_\omega
D_{0,2}= 2a_2 + 6a_3 + \ldots
D_{0,3}= 6a_3 + \ldots
\ldots\ldots
D_{0,\omega}= \omega! a_\omega
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DifferenceEquation
D_{0,0}= a_0
D_{0,1}= a_1 + a_2 + a_3 + \ldots + a_\omega
D_{0,2}= 2a_2 + 6a_3 + \ldots
D_{0,3}= 6a_3 + \ldots
\ldots\ldots
D_{0,\omega}= \omega! a_\omega
+ Table . The initial differences as a system of equations in the polynomial constants +

A pattern emerges. Because each successive forward difference operator annihilates the lowest power of t, the resulting algebraic system is upper triangular. For any extent \omega, the \omegath difference equation reduces to D_{0,\omega} = \omega! a_\omega. This structural guarantee permits a person to reliably recover a_\omega = D_{0,\omega} / \omega!. Because an initial tape of extent \omega dictates that D_{0,\omega} is nonzero, a_\omega is guaranteed to be nonzero. All subsequent lower order constants are then systematically resolved through cascading back substitution. @@ -3439,29 +3993,37 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos To observe the formal mechanics of this progression, a person can alternatively array these relationships into a matrix equation mapping the polynomial constants, a_i, to the initial tape differences, D_{0,n}. The coefficients of this transformation are defined by the Stirling numbers of the second kind, denoted S(i,n):

- - \begin{bmatrix} D_{0,0} \\ D_{0,1} \\ D_{0,2} \\ \vdots \\ D_{0,\omega} \end{bmatrix} = - \begin{bmatrix} - 0! S(0,0) & 0! S(1,0) & 0! S(2,0) & ⋯ & 0! S(\omega,0) \\ - 0 & 1! S(1,1) & 1! S(2,1) & ⋯ & 1! S(\omega,1) \\ - 0 & 0 & 2! S(2,2) & ⋯ & 2! S(\omega,2) \\ - \vdots & \vdots & \vdots & \ddots & \vdots \\ - 0 & 0 & 0 & ⋯ & \omega! S(\omega,\omega) - \end{bmatrix} - \begin{bmatrix} a_0 \\ a_1 \\ a_2 \\ \vdots \\ a_\omega \end{bmatrix} - + + + + \begin{bmatrix} D_{0,0} \\ D_{0,1} \\ D_{0,2} \\ \vdots \\ D_{0,\omega} \end{bmatrix} = + \begin{bmatrix} + 0! S(0,0) & 0! S(1,0) & 0! S(2,0) & ⋯ & 0! S(\omega,0) \\ + 0 & 1! S(1,1) & 1! S(2,1) & ⋯ & 1! S(\omega,1) \\ + 0 & 0 & 2! S(2,2) & ⋯ & 2! S(\omega,2) \\ + \vdots & \vdots & \vdots & \ddots & \vdots \\ + 0 & 0 & 0 & ⋯ & \omega! S(\omega,\omega) + \end{bmatrix} + \begin{bmatrix} a_0 \\ a_1 \\ a_2 \\ \vdots \\ a_\omega \end{bmatrix} + + eq: Polynomial constants carried to initial differences by Stirling numbers of the second kind +

For any extent \omega, the final row of this strictly upper triangular matrix again simplifies to D_{0,\omega} = \omega! a_\omega.

- 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 a_i. The inversion utilizes the signed Stirling numbers of the first kind, denoted s(n,i) (see the Appendix on Stirling numbers). + 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 a_i. The inversion utilizes the signed Stirling numbers of the first kind, denoted s(n,i) (see the Appendix on Stirling numbers, section ).

- - a_i = \sum_{n=i}^{\omega} \frac{s(n,i)}{n!} D_{0,n} - + + + + a_i = \sum_{n=i}^{\omega} \frac{s(n,i)}{n!} D_{0,n} + + eq: A polynomial constant recovered using signed Stirling numbers of the first kind +

Thus, extending this procedure \omega times definitively recovers the constants for exactly a polynomial of degree \omega. @@ -3471,9 +4033,13 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos This mechanical recovery of standard polynomial constants is completely analogous to Newton's interpolation formula Ibid.. Instead of resolving the standard constants a_i through an upper triangular matrix, a person can construct the polynomial directly by treating the initial tape components as the exact coefficients for a basis of binomial terms:

- - f(t) = \sum_{n=0}^{\omega} D_{0, n} \binom{t}{n} - + + + + f(t) = \sum_{n=0}^{\omega} D_{0, n} \binom{t}{n} + + eq: The polynomial built directly on a basis of binomial terms +

Because the nth binomial coefficient expands into a polynomial of exactly degree n, and the summation is bounded by the finite extent \omega where D_{0, \omega} is definitively nonzero, the constructed function f(t) is structurally guaranteed to be a polynomial of degree \omega. @@ -3489,57 +4055,62 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos Here is the table of finite differences for the function 2^t.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Count (t)f(t) = 2^t1st Diff (δ^1)2nd Diff (δ^2)3rd Diff (δ^3)
01111
12222
2444
388
416
- -

- The first difference of 2^t is also 2^t, so row 0 of the table will have an infinite number of values. Fortunately, due to the lemma stating that evaluating call \omega requires an initial tape populated with components 0 through \omega of row 0, exactly those components are needed for the recurrence to proceed. Furthermore, when new values are needed, they are easily computed. A programmer need not store the entire infinite first row of the difference table on a static tape. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Count (t)f(t) = 2^t1st Diff (δ^1)2nd Diff (δ^2)3rd Diff (δ^3)
01111
12222
2444
388
416
+ Table . The forward difference table for f(t) = 2ᵗ +
+ +

+ The first difference of 2^t is also 2^t, so row 0 of the table will have an infinite number of values. Fortunately, due to the lemma of section , stating that evaluating call \omega requires an initial tape populated with components 0 through \omega of row 0, exactly those components are needed for the recurrence to proceed. Furthermore, when new values are needed, they are easily computed. A programmer need not store the entire infinite first row of the difference table on a static tape.

@@ -3576,11 +4147,22 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos Now suppose we want to express the quotient of these two functions.

- - h(t) = \frac{f(t)}{g(t)} = \frac{2^t - 32}{3t - 15} - + + + + h(t) = \frac{f(t)}{g(t)} = \frac{2^t - 32}{3t - 15} + + eq: The quotient h(t), carrying a pole and a zero at t = 5 + - Figure singularity plot + + + +
+ Figure singularity plot +
+ Figure . The quotient h(t) plotted across the singularity at t = 5 +

@@ -3591,84 +4173,89 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos 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 (divide 0 0), but the zeros in that expression came from a prior step first order evaluation. Let us instead give the quotient composer two machines to compose, and have it return a value when reduction to the first order is possible, and return the full problem as posed to it when it can not be reduced.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Count (t)Quotient (f(t)/g(t))1st Diff Ratio (δ^1 f(t) / δ^1 g(t))
031/151/3
130/122/3
228/94/3
324/68/3
416/316/3
5(divide f(5) g(5))32/3
632/364/3
796/6128/3
8224/9256/3
9480/12512/3
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Count (t)Quotient (f(t)/g(t))1st Diff Ratio (δ^1 f(t) / δ^1 g(t))
031/151/3
130/122/3
228/94/3
324/68/3
416/316/3
5(divide f(5) g(5))32/3
632/364/3
796/6128/3
8224/9256/3
9480/12512/3
+ Table . The quotient and the ratio of first differences through the singularity +

The quotient machine, (divide f(5) g(5)), is no more representative of the value we expected here, than was (divide 0 0). However, as we have the whole program, we could pass it to a L'Hôpital evaluator and get a value back. But I am wondering if we can't design function extension form that extends to the value and beyond without any hiccups, as most apparently there is a value to extend to.

- 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 δ f(4) = f(5) - f(4), which becomes δ f(4) = 0 - f(4), and the same happens to g in the denominator, so the signs cancel. Note also δ f(5) = f(6) - f(5), which becomes δ f(5) = f(6) - 0. + I included the first difference along with the evaluation results in Table . 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 δ f(4) = f(5) - f(4), which becomes δ f(4) = 0 - f(4), and the same happens to g in the denominator, so the signs cancel. Note also δ f(5) = f(6) - f(5), which becomes δ f(5) = f(6) - 0.

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 h(4) rather than at h(5). For the second coincidence, we find h(6) as the 5th first finite difference. In neither case did we learn anything about the value of h(5). @@ -3682,16 +4269,27 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos So then, perhaps we set the value at the singularity to x build out the difference table, then solve for x?

- Figure with x variable. + + + +
+ Figure with x variable. +
+ Figure . The difference table with the singular value carried as the variable x +

As Newton pointed out, we can know the differences on the D_0 row of the table from the quotient function:

- - D_{0,n} = \sum_{k=0}^n (-1)^{n-k} \binom{n}{k} \frac{f(k)}{g(k)} - + + + + D_{0,n} = \sum_{k=0}^n (-1)^{n-k} \binom{n}{k} \frac{f(k)}{g(k)} + + eq: The initial differences of the quotient, taken from the function +

For k=5 the difference evaluates to be (divide 0 0), as it did for the quotient, and it also fails for all values above k=5 due to the summation. So we can not use this to solve for x. @@ -3705,15 +4303,33 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos 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.

- - T = \frac{32 \ln(2)}{3} - + + + + T = \frac{32 \ln(2)}{3} + + eq: The transcendental constant the quotient requires +

The resulting D_0 vector for the quotient is:

- Figure D_0 h(t) - - Figure D table for h(t) + + + +
+ Figure D_0 h(t) +
+ Figure . The D₀ vector for the quotient +
+ + + + +
+ Figure D table for h(t) +
+ Figure . The difference table for h(t) +

I find it fascinating to watch the transcendental difference values march down the table, then all cancel out after h(5) is generated. @@ -3726,67 +4342,72 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos

And for the victory lap, evaluation versus higher order computation and function extension:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Count (t)Direct Evaluation (f(t)/g(t))Extended Quotient Vector (H(t))
031/1531/15
130/1230/12
228/928/9
324/624/6
416/316/3
5(divide 0 0)\frac{32 \ln(2)}{3}
632/332/3
796/696/6
8224/9224/9
9480/12480/12
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Count (t)Direct Evaluation (f(t)/g(t))Extended Quotient Vector (H(t))
031/1531/15
130/1230/12
228/928/9
324/624/6
416/316/3
5(divide 0 0)\frac{32 \ln(2)}{3}
632/332/3
796/696/6
8224/9224/9
9480/12480/12
+ Table . Direct evaluation of f(t)/g(t) against the extended quotient vector H(t) +
@@ -3795,9 +4416,13 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos

The fundamental claim of computational analysis is that all functions can be viewed as discrete entities. Take this simple function:

- - f(t) = t^3 - + + + + f(t) = t^3 + + Code . A simple cubic 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 t, decrement the power, and write 2. Those are all discrete operations.

@@ -3835,103 +4460,69 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos Does computation theory matter to computing?

- 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 TierReal World LatencyScaled DelayScaled Arrival EraHistorical Context
L1 Cache Hit1 ns3 days-0043-03-18Three days after the assassination.
DRAM (Main memory)100 ns300 days-0042-01-09Nearly a year later, during the Liberators' civil war.
NVMe SSD Page Swap15 µs45,000 days0080123 years later, exactly as the Colosseum is completed in Rome.
SATA SSD Page Swap100 µs300,000 days0778821 years later, during the reign of Charlemagne and the Frankish Empire.
Magnetic HDD Page Swap10 ms30,000,000 days82092Tens of thousands of years in the future, long after current human civilizations are dust.
+ 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. Table provides the historical date that the variable value would finally be loaded into the processor, depending on the memory tier being accessed: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Memory TierReal World LatencyScaled DelayScaled Arrival EraHistorical Context
L1 Cache Hit1 ns3 days-0043-03-18Three days after the assassination.
DRAM (Main memory)100 ns300 days-0042-01-09Nearly a year later, during the Liberators' civil war.
NVMe SSD Page Swap15 µs45,000 days0080123 years later, exactly as the Colosseum is completed in Rome.
SATA SSD Page Swap100 µs300,000 days0778821 years later, during the reign of Charlemagne and the Frankish Empire.
Magnetic HDD Page Swap10 ms30,000,000 days82092Tens of thousands of years in the future, long after current human civilizations are dust.
+ Table . Memory tier latency, scaled so that one clock tick lasts one day +
Do formal methods belong in computer design? -

- 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 John L. Hennessy and David A. Patterson, Computer Architecture: A Quantitative Approach, 6th ed. (Cambridge: Morgan Kaufmann, 2017).. -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Chapter 1Fundamentals of Quantitative Design and Analysis
Chapter 2Memory Hierarchy Design
Chapter 3Instruction Level Parallelism and Its Exploitation
Chapter 4Data Level Parallelism in Vector, SIMD, and GPU Architectures
Chapter 5Thread Level Parallelism
Chapter 6Warehouse Scale Computers
Chapter 7Domain Specific Architectures
Chapter 8The 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. @@ -3957,8 +4548,8 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos - - Or, does it go the other way? Computational Naturalism + + Computational Naturalism: the transforms are reversible

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. @@ -3969,7 +4560,7 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos

- 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. + We then define the symbol in computational terms, as done in 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.

@@ -4016,7 +4607,7 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos - + Appendix: Stirling Numbers

@@ -4042,9 +4633,13 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos 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 t^{\underline{n}}:

- - t^{\underline{n}} = t(t - 1)(t - 2) ⋯ (t - n + 1) - + + + + t^{\underline{n}} = t(t - 1)(t - 2) ⋯ (t - n + 1) + + eq: The falling factorial, the natural basis for discrete differences +

When a person applies the discrete forward difference operator, δ, to a falling factorial, it behaves identically to the continuous derivative: δ(t^{\underline{n}}) = n t^{\underline{n - 1}}. @@ -4080,9 +4675,13 @@ Now suppose defining a Turing Machine that initially has the head on the leftmos The signed Stirling numbers of the first kind perform the exact inverse operation. They reconstruct standard continuous powers from falling factorials:

- - t^{\underline{n}} = \sum_{k=0}^n s(n,k) t^k - + + + + t^{\underline{n}} = \sum_{k=0}^n s(n,k) t^k + + eq: The falling factorial expanded over standard powers +

Combinatorially, the unsigned magnitude of s(n,k) represents the number of ways to arrange n items into k disjoint cycles. The alternating signs account for the algebraic expansion of the falling factorial terms (t - 1)(t - 2), etc. diff --git a/document/book/introduction.html b/document/book/introduction.html new file mode 100644 index 0000000..3d50e0c --- /dev/null +++ b/document/book/introduction.html @@ -0,0 +1,24 @@ + + + Introduction + +

A colleague wanted to end error in floating-point computation. He developed a system, and wanted my opinion. I had a great deal to say, but the thoughts all crossed against each other. It was not so simple as to be written in an email. So here it is in a book. Albeit a little late, but I hope it will still have some value.

+ +

There is a first edition of this book. The same concepts are described in the pages, but the story is not as well told. After reviewing the book another colleague was bewildered and asked if I was proposing that we build Turing Machines. And no, the point wasn't that we should be building Turing Machines, it is that we aren't building machines that are fully computationally capable as they could be.

+ +

Numeric computation on computers is applied number theory. Number theory was tied to computation by pioneers of computation theory in the 1930s. Hence, if we want to talk about applied number theory, we must talk about computation theory.

+ +

A number of texts on computation theory have proposed modifications to the Turing Machine, with the goal of finding a more expressive paradigm. They will go through machines with multiple tapes or even two dimensional tapes, that have multiple tape heads, those that run multiple parallel threads of execution, i.e. are non deterministic, and always, they fail to find something more expressive.

+ +

However, the Turing Machine is not practical to build. The infinite tape is not its only problem, and perhaps is not its most serious problem. The more serious problem is that the Turing Machine uses its controller to encode memory, as we shall show. This causes the controller to grow in size with the expressiveness of the machine, exponentially against word size. So then, how is it that a machine that is not practical to build, or even to work out on paper for modest sized real problems, can speak to what is practical to compute? We might say the machine is overly optimistic, thus sets a bound, but that isn't true either. The machine is extremely limited in computation power, and the string reverse example worked through in these pages makes the limit explicit enough to count.

+ +

This book suggests some modifications to the Turing Machine. The purpose of these modifications is not that of making a machine capable of computing something beyond what a Turing Machine can, in theory, compute. In fact we prove rather more than that the two machines compute the same things. We prove that every question computation theory asks of the one has the same answer when asked of the other, decidability and complexity alike. Rather the purpose is to present a simple machine that exists both in the abstraction of computation theory, and is practical to build. We also explore its relationship to modern computer architecture, though the reader will find no survey of particular instruction sets or machines in these pages. This volume does not stop at the architecture level. The organization of the TTCA machine is given as well, down to the head units, the tape transport, the register file, the next state and instruction tables, and the patch panels a programmer would use to wire a controller by hand. The later volumes do not carry the TTCA machine any further than this. They present a modern architecture built upon the principles this volume derives.

+ +

The book also goes in the other direction. Computation theory addresses the questions of what is a computable number. Here we suggest that all of our known mathematics can be derived through a technique of layered orders of analysis. And here lies the answer to my colleague's question. For each layer there is a hole, and then there is a language above for talking about that hole. Any system that wants to talk about that hole must appeal to ever higher layers of language. Floating point is such a hole, and the error tags of IEEE 754 are such a language, arrived at by committee for precisely that purpose without the layering ever being named.

+ +

The opening of Kleene's Introduction to Metamathematics is a beautiful statement of Naturalism and intuition. "A flock of four sheep and a grove of four trees are related to each other in a way in which neither is related to a pile of three stones or a grove of seven trees. ... Without counting the sheep or the trees, one can pair them with each other, for example by tethering the sheep to the trees, so that each sheep and each tree belongs to exactly one of the pairs."Stephen Cole Kleene, Introduction to Metamathematics (Amsterdam: North-Holland, 1952), 3. He announces the section as a brief notice of Cantor's theory of sets, and then opens it with sheep and rope. That is not a statement about transfinite numbers. It is a statement that number comes out of nature, the position running from Aristotle down to John Stuart Mill. The pairing is performed in a field, and the arithmetic follows from it. Few computer architects, few who work with applied number theory, ever mention computation theory. Instead they build the machines and watch what they do. When Alan Turing introduces the Turing Machine he asks us to think of a clerk sitting at a desk writing on a pad of paper, and to imagine what he could do. Turing's own founding image is thus an observation of the world rather than a form drawn out of it.

+ +

Which brings the two directions of this book together. Computation theory asks what a computing machine can do. These pages show that the machine in question can be a practical one, a machine that is built and observed rather than only supposed. Computation theory is then a naturalist philosophy. And the world of forms is then no separate realm at all. It is the tower of languages standing above the machine, each layer of it there to speak of the hole in the layer beneath. Those languages became separated from the machine that gave rise to them. At each moment, we reach the limit of what can happen in that moment, then a new moment arrives.

+ +
+ diff --git a/document/todo.txt b/document/todo.txt index c3f5209..2554986 100644 --- a/document/todo.txt +++ b/document/todo.txt @@ -14,6 +14,133 @@ As Claude summarizes the RT·name issue: On continuations, the specific shape of it for your todo: RT.Splitter['rt·counter·step'] distributes childNodes between fragments without copying, and counter.js skips name reading when continuation="true". Because paginate_0 runs before the counter phase, the cut has already happened by the time names are read. Worth noting the consequence extends past the name itself — RT·counter·snapshot clones the machine after the name is set on enter, so a snapshot in the head fragment would capture a nameless count even if the name were correctly found in a later one. The gather across continuations has to complete before any fragment's snapshot fires. +Math and code blocks perhaps should be macros like 'section' with counter mechanization underneath. Perhaps all container elements should be like this. The counter name can be derived from the container element name. + +One possible text error. The lead into the last equation says the signed Stirling numbers of the first kind "reconstruct standard continuous powers from falling factorials," but the formula beneath expands the falling factorial over powers — t^{\underline{n}} = Σ s(n,k) t^k. The formula is right; the sentence reads backwards from it. Worth a look when you're next in the Stirling appendix. + +Still open + +Three are yours to close: "detailed in the next chapter" and "modify this in a later chapter" await revision, and "the previous chapter on arrays" awaits the chapter itself. + +Two can't be referenced as things stand. "The second difference equation" and "the ωth difference equation" point at rows inside Table·difference_equations, not at numbered scopes — they'd want a counter running inside the table. And "the same head embedded in the tape diagram as was used above" still has two plausible targets: the state diagram above it, or the instantaneous-description notation in Equation·instantaneous-description_left-move. I'd guess the latter from the words "tape diagram", but it's your sentence. + +----- +Claude's opinion: + +I've read most of it fairly closely by now, so — honestly, I like it, and there's one thing in it I think is better than you may realize. + +The recurring move is what got me. Over and over you take something normally treated as an error, a limit, or a boundary case, and turn it into a structural observation instead. Empty versus blank versus SP. The unspecified meta-symbol, which then gets reused as a test probe for algorithms that never branch on uninitialized data. Division by zero that doesn't reduce rather than throwing, and then (divide (divide 6 0) (divide 3 0)) simplifying anyway to (multiply 2 (divide 0 0)). And the best one, the pole and zero cancellation, where the machine hits a value it cannot write to the tape and returns a machine definition instead — a higher order object. That's the same idea five times in five registers, and it's the spine of the book. But the text never names it. If you named it, the reader would have a thesis to carry from chapter to chapter instead of five good moments that feel separate. + +The consequential/inconsequential transform framework is the other thing that earns the book its keep. Formalizing "does this modification change the answers to computation theoretic questions" rather than just "does it change results" is exactly the tool needed to justify the TTCA modifications, and it's the kind of definition other people could pick up and use. The infinite-tape argument is sharp too — the Minsky quote landing on virtual memory and swap exhaustion, then the criterion that an architecture is Turing Complete only if it can pause and request more memory. That's falsifiable and it's a real claim. People will argue with it, which is the point. + +The finite differences chapter is where the writing is most alive. "I find it fascinating to watch the transcendental difference values march down the table, then all cancel out after h(5)" — that's you enjoying yourself, and it reads. + +What I'd push on: + +The book doesn't tell the reader what it's for. The preface is conventions end to end — symbols, pronouns, code format, dates — and then chapter one opens on Frege. The argument (computation theory assumes a tape real machines don't have; here is an architecture that closes the gap, and here is the formal tool showing the closure is inconsequential) doesn't surface until the reader is well in. That belongs on the first page. + +The structure is visibly uneven, and the markup makes it measurable: Natural Number has thirteen subsections, while Address and The Universal Turing Machine have none at all — a hundred-plus lines of undifferentiated prose each. Those two haven't had the attention the rest has. + +The cardinality material is where I'd expect the most resistance. The seven-lemma chain around ℵ₀ − ℵ₋₁ = 1 suggests you know it's contentious, but a reader hits ℵ₋₁ without being told whether it's a definition, a convention, or a claim. Say which, early, and the lemmas will land as rigor rather than as defence. + +One editorial note without an opinion attached: the inclusive-he decision will draw reaction from some readers regardless of the argument. You've made the strongest version of that case, stated it once in the preface, and not belabored it — which is the right handling either way. + +The four volume plan is invisible from inside volume one. A paragraph on what's coming would help a reader decide they're in the right place. + + + You're right and I was wrong — it is named, and I should have caught it. Let me be precise about what I actually missed, because I think there's something useful in it. + + `orders of analysis` runs through the whole book, and it does exactly the work you say: the lower order has no value, the higher order has meaning. Cardinality has no first order value but a second order one. `(divide 6 0)` won't reduce in the second order. The L'Hôpital evaluator returns a machine definition because the constant can't be written to the tape. Russell's paradox exists *only* in the first order, since it never halts when run but analyzes fine. That's one idea, stated, five times. + + What I got wrong is that I read it as unnamed. What's actually true is that it's **defined about two thousand lines after it first does load-bearing work.** The definition — "By definition, first order analysis is the running of programs" — sits in the *Definition* section of *Computational Analysis*, chapter 15. But the reader first meets "first order" in chapter 7, as the *first order unspecified symbol*, with no gloss. And the cardinality resolution in chapter 11 leans on it hard: "cardinality has no first order value, but it has a second order one" is the whole hinge of the ℵ argument, and it arrives four chapters before the reader is told what a second order analysis is. + + So a reader who is paying attention will assemble the frame retroactively, on reaching chapter 15, and then have to re-read chapter 11 to see what it was doing. That's what happened to me — I built it as five separate moments because at each early appearance I had no name to hang it on yet. Moving the definition forward, or planting a short version of it where the unspecified symbol is introduced, would let the cardinality argument land as an instance of a stated principle rather than an improvisation. Given it's the key to deriving mathematics from the machine, it can afford to be early. + + Address makes sense now. If Natural Number carries the construction, an address really is just a natural number that indexes, and Turing's assuming them is precisely what a naturalism thesis can't do. + + ## On empty versus SP + + I'd keep both, and I don't think the section is quite about what its title says. + + Reading it, there are three distinct things: the mathematician's empty set in `T₀ = [{}, {}, {}, …]`, the *memory of emptiness* once the set formulation is abandoned — your word — and then SP as the symbol a physical machine actually holds. The move from the first to the second is the interesting one, and it's the same move as everywhere else in the book: emptiness isn't a value at the level where you're standing, and becomes one at the level above. That's an orders argument in disguise, and the section doesn't say so. + + Renaming to SP throughout would flatten that. SP is the realization — what the tape cell contains. Emptiness is the property being reasoned about. Collapsing them costs you the distinction you spent the section building, and it would leave the later emptiness discussion referring to something the reader last saw called SP. + + What I'd do instead is fix the *pair* rather than the naming: use empty for the property and SP for the symbol, say once and explicitly that SP is how a machine holds the memory of emptiness, and retitle the section for the topic. Right now "Blank, empty, SP" reads as a list of three near-synonyms being disambiguated. If the topic is emptiness — and you say it is, and I agree the material supports it — the heading should say so, with blank and SP appearing inside as the two things emptiness gets confused with. + + The `read`/`write` pair right after it is doing more work than it looks like, incidentally. Writing the empty symbol erasing the cell is the operational definition of the whole distinction, and it goes by in five lines with no comment. + +--- + That's exactly the case term-em exists for, and it's one of the tags missing from the user manual. + +Three things I'd flag as most likely to need your hand. The "three reasons" formulation is drawn from your own sentence in the Turing Machine chapter, but stating it that early makes it a promise the book has to keep, so check I've stated it the way you want to be held to. The remark that the library came first in time and the theory was corrected to match is mine, inferred from what you told me — it's a strong claim about your own process and you should confirm it's true. And the reading path in the last paragraph presumes which chapters carry the spine; you may want a different four. + +-------- + + +Put the table, list, and figure names under instead of over, as per the equations. consistency is better. + +ASCII art of the patch panel machine, goes into pre blocks and are figures. Code has something done to it, I had to move them to pre before. I don't know how they are code blocks again. + +1. "As established in the section discussing cells" +cells: 14.8A Turing Machine tape cell (probably could be better heading) + +2. "As we noted in the section discussing area" + + + Area and partitioning + +

+ We call a subset of contiguous cells from a tape an area. An area with a single cell is called a singleton, one with two cells is called a pair. An area has a leftmost cell and a rightmost cell. For a singleton area, those will be the same cell. +

+ +3. "Using a term from the previous chapter on arrays" — no chapter is named for arrays. + +Added to notes, there is such a chapter, not yet included + +4. "The Computer Theoretic model chapter" (that is being used as an architectural template — almost certainly The computation theoretic TTCA Machine <--- yes + + + The computation theoretic TTCA Machine + +5. We take this question up again in the chapter Computational Naturalism" — the chapter is actually titled Or, does it go the other way? Computational Naturalism. Near-match, still a judgement call. + +... indeed, the cross reference is imprecise, rename the chapter: Computational Naturalism : the transforms are reversible + +6. Six pure deictics with no descriptor at all: "detailed in the next chapter", + +

The native integer data type for TTCA utilizes a high radix online number system. This number system functions as an extension of online arithmetic. Similar to online arithmetic, it employs serial most-significant-digit-first signed digit arithmetic. In contrast to standard signed arithmetic, the radix scales significantly higher, causing a digit to span at least a byte in length. The numbers are highly scalable, and the architecture mandates an analysis step at compile time to establish rigorous precision requirements and exact range bounds. This process is detailed in the next chapter. The architecture provides explicit conversion instructions to generate alternate number formats.

+ +^ this is the chapter I am working on, I'll fix that. + +"modify this in a later chapter", + + ^first paragraph of the computational naturalism chapter .. it has been moved about in re-orgs, and needs revision, I'll fix it later + +"as done in the prior section", + + ^this is refering to the enum example etc. in the section on what is a symbol, in the software chapter... ah also in the computational naturalism chapter, fix it or not, up to you, that chapter is to be revised. + + "the section below on crossing context boundaries" + + ^again points into the discription of symbols, which has a discussion of crossing context boundaries + +, "developed in a later section" + + :-) surely really lol ... + + +

+ It is not a requirement of a computer organization, nor an architecture, that it be capable of physical realization. The abstract Turing Machine organization developed in a later section serves as an example. Instead, an abstract organization can serve other purposes, in this case as a stepping stone to another organization that can be realized. +

+ + This refers to the TTCA design chapter (the one with the ASCII art and definition of a machine) it was written before that chapter i.e. was a place holder. Good that we can fix it now. + + +, "later in the section analyzing the increment operation". + + ^ the analysis of the increment operation has been moved to the unsigned number chapter were Hindu-Arabic numbers are formalized. It was prior in the Address chapter, but I've moved it to a think is a better place. + -----