doc work
authorThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Fri, 5 Jun 2026 16:52:11 +0000 (16:52 +0000)
committerThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Fri, 5 Jun 2026 16:52:11 +0000 (16:52 +0000)
document/TM-2026.html

index 020f6d3..76f5f7a 100644 (file)
         Turing's <RT-term>a-machine</RT-term> utilizes binary. George Boole's work (1847, 1854) was well established by then, so from a theoretical standpoint, it was a sensible simplification. However, utilizing binary within the context of a machine effectively bridged the gap to the more practically minded engineers of the time. Alan Turing's paper arrived at the same time that switched telephone networks had reached a scale that made them difficult to maintain without systematic approaches. These networks were built upon electromechanical relays, which were decisively binary devices. At least seven men in addition to Alan Turing appear to have independently contemplated the intersection of Boolean algebra, logic, and physical computing: Victor Shestakov (1935, proposed mapping Boolean algebra to electromechanical relay circuits), Konrad Zuse (1936, adopted base 2 architecture to bypass the physical complexity of decimal mechanical gears), Akira Nakashima (1936, published the mathematical equivalence of Boolean algebra and two-terminal switching networks), Louis Couffignal (1936, proved calculating machines must shift to binary linkages to reduce physical friction), Claude Shannon (1937, published the definitive mathematical proof mapping Boolean algebra to electrical relays), George Stibitz (1937, constructed the first electromechanical binary adder), and John Vincent Atanasoff (1937, adopted binary to keep the vacuum tube count of electronic circuits physically viable).
       </p>
 
-
-      <h1>Symbol</h1>
+      <h1>The computer manufacturing abstraction stack</h1>
 
       <p>
-        A <RT-term>symbol</RT-term> is a distinct mathematical object capable of being instantiated. Within a given context, any instance of a specific symbol evaluates as equal to any other instance of that identical symbol, and evaluates as not equal to any instance of a different symbol. (As a matter of convenience in this document, sequences of letters and/or digits are utilized for symbol instances.)
+        There are a number of discernable levels to the computer manufacturing abstraction stack, going from the highest down to the lowest level:
       </p>
 
-      <p>
-        Put more formally, given a set of instantiable objects and a collection of instances created from them, for these objects to be symbols, two structural conditions must be met. First, it must be possible to define an instance comparison operation, denoted <RT-math>=</RT-math>, that acts as an equivalence relation to partition the collection into discrete equivalence classes. Second, this partitioning must result in a strict one-to-one correspondence between the resulting equivalence classes and the original instantiable objects from which the member instances were derived.
-      </p>
+      <ol>
+        <li><RT-term>mathematical logic</RT-term></li>
+        <li><RT-term>computation theory</RT-term></li>
+        <li><RT-term>architecture</RT-term></li>
+        <li><RT-term>organization</RT-term></li>
+        <li><RT-term>implementation</RT-term></li>
+        <li><RT-term>realization</RT-term></li>
+      </ol>
 
       <p>
-        It follows from this definition that the distinct equivalence classes can be used as a proxy for the instantiable objects themselves. That is, a person can name either the instantiable object or the equivalence class, and then through this correspondence, find the other and definitively know the class members.
+        The bottom level is concrete, while the others are abstract.
       </p>
 
-
-<h2>The factory interpretation</h2>
-
       <p>
-        In the context of real machines, the symbol itself can be defined as a factory that produces symbol instances. A new symbol instance of the given symbol is created by calling the factory's <RT-code>make</RT-code> function. All of the symbol instances created by the factory constitute the members of the corresponding equivalence class.
+        A <RT-term-em>realization</RT-term-em> is a physical box full of plastic, metal, fiberglass, and silicon, along with a smattering of exotic materials. A realization is created by <RT-term>manufacturing engineers, technicians, and product line workers</RT-term>, with the assistance of some of the most sophisticated machines ever built by humankind.
       </p>
 
       <p>
-        A <RT-term>symbol instance</RT-term> newly minted by the factory is said to <RT-neologism>come direct from the factory</RT-neologism>. A <RT-term>symbol instance</RT-term> direct from the factory is also called an <RT-neologism>original</RT-neologism>.
+        The <RT-term-em>implementation</RT-term-em> instructs the manufacturing teams very specifically on what is to be built. For a microprocessor chip, this consists of instructions for cutting the lithography masks, the package to be used, and the production test programs to be run. The masks embody the placement of all the wiring, the location of doping wells, and the placement of transistor gates, including their specific sizes. The implementation is done by <RT-term>design engineers</RT-term> with the assistance of design synthesis tools and CAD tools.
       </p>
 
-      <h3>Required properties of symbol factories</h3>
-
       <p>
-        Any two <RT-term>symbol instance</RT-term>s returned directly from two distinct factories will always evaluate to <RT-code>False</RT-code> during an equality comparison. In other words, two distinct <RT-neologism>original</RT-neologism>s will always be not equal.
+         <RT-term-em>Organization</RT-term-em> is the register-transfer level description of the machine, which includes internal buses, external buses and the state machines that implement the protocols used, control units, interrupt structures, methods of doing I/O, and ALU layout. It dictates the logical arrangement of hardware and the procedures that force the data to flow to satisfy the architectural constraints. The organization is created by a <RT-term>design architect</RT-term>. This level, and the next level, are defined in detail in the classic text by Hamacher, Vranesic, and Zaky <RT-cite ref="V. Carl Hamacher, Zvonko G. Vranesic, and Safwat G. Zaky, Computer Organization, 2nd Edition, McGraw Hill, 1984"></RT-cite>.
       </p>
 
       <p>
-        Given an <RT-neologism>original</RT-neologism>, all copies <RT-neologism>stemming from</RT-neologism> it will be equal to each other and to the <RT-neologism>original</RT-neologism>. By <RT-neologism-em>stemming from</RT-neologism-em>, this definition includes all direct copies and copies of copies.
+        An <RT-term-em>architecture</RT-term-em> provides the programmer's view of the computer. This includes all ilks of programmers, including OS programmers, driver programmers, and application programmers. This is sometimes called the instruction set architecture. In addition to specifying the instructions, it includes specifying the behavior of the interrupt subsystem, the method of doing I/O (typically memory-mapped or dedicated I/O instructions), DMA, the special registers and their effects, and the standards to be followed for each if any. More recently, this also includes specifying how programs can make use of secure areas. The architecture is specified by an <RT-term>architect</RT-term>.
       </p>
 
       <p>
-        Given any two <RT-neologism>original</RT-neologism>s, say <var>A</var> and <var>B</var>, it is established that <var>A</var> is not equal to <var>B</var>, as discussed above. Note also that <var>A</var> is not equal to any copy <RT-neologism>stemming from</RT-neologism> <var>B</var>, and <var>B</var> is not equal to any copy <RT-neologism>stemming from</RT-neologism> <var>A</var>.
+        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.
       </p>
 
       <p>
-        Though <RT-term>symbol instance</RT-term>s are integer-like in that copy and equality comparison operations can be used with them, <RT-term>symbol instance</RT-term>s are strictly disallowed from being used with other integer operators. <RT-term>Symbol</RT-term>s cannot be compared for greater-than or less-than; they cannot be incremented, added, nor subtracted.
+        The Turing Machine is a computation theory object that is suggestive of a simple architecture; however, a little work is needed to create that architecture analog. The fundamentals are present, the read/write head, the tape, the procedure for using the tape, but other components are missing. The manipulation of symbols remains ungrounded. The tape is not well defined. The use of emptiness is non-architecture like. The tape transport is not articulated, though it is implied. The read buffer that holds a value read so the state controller can use it is not identified as a component. As we proceed, we will likely discover other missing components.
       </p>
 
-      <h2>Instance implementation</h2>
-
       <p>
-        A reference to the factory can be used as a symbol instance, which will cause the factory to become trivial, because making a new instance merely requires copying the factory reference. In this case, there will be nothing in memory that the base factory reference is pointing to. 
+        It is not a requirement of a computer architecture that it can be realized. The Turing Machine architecture developed in a later section serves as an example. Instead, an architecture can serve other purposes, in this case as a stepping stone to another architecture that could be realized.
       </p>
 
       <p>
-        In general, memory addresses are built-in symbol instances, hence within the context of a single process run, a program can make use of these symbols. However, this diminishes the size of the address space and leaves the memory at those addresses unused. A common hedge is then to use references into a dictionary, where the data looked up in the dictionary is the <RT-term>name</RT-term> of the symbol.
+        We can now further articulate the goal of these volumes: to first capture the Turing Machine as an architecture, and then to transform that architecture step by step, without making any changes of consequence relative to computation theoretic results, into a modern computer architecture that could be implemented. A secondary goal is to learn something along the way.
       </p>
 
-      <p>
-        Such symbol names are non-structural strings, so do not need to follow the rules of symbols. For example, a program written purely to use references as strings could give multiple, or all, strings the same name, and would function. Conventionally, the names are also required to be distinct to avoid confusion.
-      </p>
 
-      <p>
-        An alternative implementation is to have the factory return an integer value. Each factory has a base integer that is distinct from that of other factories. Calling <RT-code>make</RT-code> then returns the base integer.
-      </p>
+<h1>Symbol</h1>
 
-      <p>
-        As another alternative, each factory can be given a base string, and then <RT-code>make</RT-code> returns the string. At the time of this writing many machines use 64 bit words for storing integers or addresses. That 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 the advantages that symbol instances can carry semantic clues for the programmer, and that it has integrity across contexts, such as between processes (note the section below on crossing context boundaries). The drawback is that the strings are typically ad hoc so the guarantee of distinctness becomes a contract with the programmer.
-      </p>
-      
-      <p>
-        The time that a Turing Machine takes to copy a symbol to or from tape is considered to be a single machine step. The Turing Machine is defined with a finite alphabet, and a constant number of additional symbols. Then on a real machine, the factory would be used to create the alphabet, and the couple of additional symbols at the time the machine is being defined. Hence the time is not part of the asymptotic behavior of a program. At run time, to copy 1 of N constants there is a constant time that can be defined as the worst case. So the real machine does not introduce a consequential new behavior.
-      </p>
+<p>
+  A <RT-term>symbol</RT-term> is a distinct mathematical object capable of being instantiated. Within a given context, any instance of a specific symbol evaluates as equal to any other instance of that identical symbol, and evaluates as not equal to any instance of a different symbol. (As a matter of convenience in this document, sequences of letters and/or digits are utilized for symbol instances.)
+</p>
 
-      <h2>Distinctness across contexts</h2>
-      <p>
-        If a <RT-term>symbol</RT-term> persists across contexts (such as across scopes or processes), it must remain distinct from all other <RT-term>symbol</RT-term>s in its new context.
-      </p>
+<p>
+  Put more formally, given a set of instantiable objects and a collection of instances created from them, for these objects to be symbols, two structural conditions must be met. First, it must be possible to define an instance comparison operation, denoted <RT-math>=</RT-math>, that acts as an equivalence relation to partition the collection into discrete equivalence classes. Second, this partitioning must result in a strict one-to-one correspondence between the resulting equivalence classes and the original instantiable objects from which the member instances were derived.
+</p>
 
-      <p>
-        This structural boundary creates challenges in computer science across many contexts. One solution is to find a scope encompassing both contexts and to place the symbol factory there. Another solution is to give each context a distinct root symbol and to use an array of symbols in place of the imported symbol. Yet another approach is to associate an imported symbol with a new symbol in the given new context using a correspondence map.
-      </p>
+<p>
+  It follows from this definition that the distinct equivalence classes can be used as a proxy for the instantiable objects themselves. That is, a person can name either the instantiable object or the equivalence class, and then through this correspondence, find the other and definitively know the class members.
+</p>
 
-      <p>
-        When utilizing memory addresses as symbols in a virtual memory environment, the most common approach in computing is to disallow addresses in one process from being used in another. If that isolation is insufficient, it is often adequate to use indexes instead of addresses, taking the address to the base of the data structure. Though the absolute address of the data structure might differ across contexts, the relative offset remains constant. Another approach is to reserve memory address blocks and to guarantee imported pages have the exact same addresses as before, though they might be imported sequentially to reuse the memory block. In architecture, this is generally known as the pointer swizzling problem.
-      </p>
+<h2>The factory interpretation</h2>
 
-      <h2>Alphabet</h2>
-  
-      <p>
-        An alphabet is a finite set of symbols. Because it is simply a set, an infinite number of distinct alphabets can exist. The Turing Machine specification discusses '<em>the</em> alphabet' strictly because a given Turing Machine instance utilizes only one specific alphabet. 
-      </p>
+<p>
+  In the context of real machines, the symbol itself can be defined as a factory that produces symbol instances. A new symbol instance of the given symbol is created by calling the factory's <RT-code>make</RT-code> function. All of the symbol instances created by the factory constitute the members of the corresponding equivalence class.
+</p>
 
-      <h2>Examples</h2>
+<p>
+  A <RT-term>symbol instance</RT-term> newly minted by the factory is said to <RT-neologism>come direct from the factory</RT-neologism>. A symbol instance direct from the factory is also called an <RT-neologism>original</RT-neologism>.
+</p>
 
-      <p>
-        The <RT-code>enum</RT-code> structure of C is an example of a mechanism for creating alphabets of named symbols. Each entry in the enum is a static symbol factory, where instances are distinct integers.
-      </p>
+<h3>Required properties of symbol factories</h3>
 
-      <RT-code>
-      typedef enum {
-          SYMBOL_EMPTY = 0,
-          SYMBOL_ZERO  = 1,
-          SYMBOL_ONE   = 2,
-          SYMBOL_A     = 3,
-          SYMBOL_B     = 4
-      } TapeAlphabet;
-
-      /* The enum definition acts as the factory. */
-      /* 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 */
-      }
-      </RT-code>
+<p>
+  Any two symbol instances returned directly from two distinct factories will always evaluate to <RT-code>False</RT-code> during an equality comparison. In other words, two distinct originals will always be not equal.
+</p>
 
-      <p>
-        While the <RT-code>enum</RT-code> effectively demonstrates a static hardware mapping, a string interning symbol table is a rigorous example of a dynamic runtime factory. This physically demonstrates the <RT-code>make</RT-code> function taking an arbitrary string, checking a correspondence map, and returning a canonical, unique pointer in memory (the <RT-neologism>original</RT-neologism>).
-      </p>
+<p>
+  Given an original, all copies <RT-neologism>stemming from</RT-neologism> it will be equal to each other and to the original. By <RT-neologism-em>stemming from</RT-neologism-em>, this definition includes all direct copies and copies of copies.
+</p>
 
-      <RT-code>
-      #include <string.h>
-
-      #define TABLE_SIZE 100
-      typedef const char* SymbolInstance;
-
-      SymbolInstance symbol_table[TABLE_SIZE];
-      int table_count = 0;
-
-      /* The Factory 'make' function */
-      SymbolInstance make_symbol(const char* name) {
-          /* Search for an existing original */
-          for (int i = 0; i < table_count; i++) {
-              if (strcmp(symbol_table[i], name) == 0) {
-                  return symbol_table[i]; /* Return a copy of the instance */
-              }
-          }
-          
-          /* Mint a new original if one does not exist */
-          symbol_table[table_count] = strdup(name);
-          return symbol_table[table_count++];
-      }
-
-      /* Usage */
-      SymbolInstance x = make_symbol("START");
-      SymbolInstance y = make_symbol("START");
-
-      /* x == y evaluates to True based purely on the physical memory address, 
-         bypassing the need for further string comparisons. */
-      </RT-code>
+<p>
+  Given any two originals, say <var>A</var> and <var>B</var>, it is established that <var>A</var> is not equal to <var>B</var>, as discussed above. Note also that <var>A</var> is not equal to any copy stemming from <var>B</var>, and <var>B</var> is not equal to any copy stemming from <var>A</var>.
+</p>
+
+<p>
+  Though symbol instances are integer-like in that copy and equality comparison operations can be used with them, symbol instances are strictly disallowed from being used with other integer operators. Symbols cannot be compared for greater-than or less-than; they cannot be incremented, added, nor subtracted, etc.
+</p>
+
+<h2>Instance implementation</h2>
+
+<p>
+  Within a process, a reference to the factory can be used as a symbol instance, which will cause the factory to become trivial. Making a new instance will merely require copying the factory reference, and there will be nothing in memory that the base factory reference is pointing to. 
+</p>
+
+<p>
+  In general, memory addresses are built-in symbol instances, hence within the context of a single process run, a program can make use of these symbols. However, this diminishes the size of the address space and leaves the memory at those addresses unused. A common hedge is then to use references into a dictionary, where the data looked up in the dictionary is the <RT-term>name</RT-term> of the symbol.
+</p>
+
+<p>
+  Such symbol names are non-structural strings, so do not need to follow the rules of symbols. For example, a program written where references to strings were used as symbol instances, could give multiple, or all, strings the same name, and the program would function. Conventionally, the names are also required to be distinct to avoid confusion. The hazard here is that a programmer will then conflate the string name with the symbol instance, and perform symbol operations with it.
+</p>
+
+<p>
+  An alternative implementation is to have the factory return an integer value. Each factory has a base integer that is distinct from that of other factories. Calling <RT-code>make</RT-code> then returns the base integer.
+</p>
+
+<p>
+  As another alternative, each factory can be given a base string, and then <RT-code>make</RT-code> returns a copy of the base string. Here we refer literally to the string as the symbol instance. There is no separate name, and the string data, not the reference to the string, becomes the symbol instance. This is however merely an architectural constraint, under the hood an implementation could use string references as long as it always appears to the programmer that the string value is being used.
+</p>
+
+<p> 
+  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). The drawback is that the strings are typically ad hoc so the guarantee of distinctness becomes merely a contract with the programmer. Attempts at strengthening the contract can lead to frustrating errors and add complexity to programs.
+</p>
+
+<h3>Consequentiality</h3>
 
-      <h1>The Turing Machine</h1>
+<p>
+  The time that a Turing Machine takes to copy a symbol to or from tape is considered to be a single machine step. This is a constant time of one step. It will never affect time complexity results.
+</p>
+
+<p>
+  The Turing Machine is defined with a finite alphabet and a couple of additional symbols. As these are part of the machine definition, and thus do not change at run time, the time to construct them is inconsequential.
+</p>
+
+<p>
+  On a real machine, the factory would be used to create the alphabet and the couple of additional symbols, but as the alphabet is finite, and set in advance, its construction is similarly inconsequential.
+</p>
+
+<p>
+  This leaves the question of the time to copy an instance. Such a copy is done when reading and writing a tape on the Turing Machine, and reading and writing memory on a real machine. As the alphabet is finite, each symbol can be encoded in a fixed number of bits. Hence, a copy time is constant. Typically the number of symbols involved is so small, that a single read or write of memory is required for doing a copy, but even if the number of symbols is enormous, it will be a fixed constant time. However, there are extenuating circumstances, such as cache misses and page faults. So generally symbol copy time is inconsequential, but it is possible in memory aliasing conditions with page faults, that they are not.
+</p>
+
+<h2>Distinctness across contexts</h2>
+
+<p>
+  If a symbol persists across contexts (such as across scopes or processes), it must remain distinct from all other symbols in its new context.
+</p>
+
+<p>
+  This structural boundary creates challenges in computer science across many contexts. One solution is to find a scope encompassing both contexts and to place the symbol factory there. Another solution is to give each context a distinct root symbol and to use an array of symbols in place of the imported symbol. Yet another approach is to associate an imported symbol with a new symbol in the given new context using a correspondence map.
+</p>
+
+<p>
+  When utilizing memory addresses as symbols in a virtual memory environment, the most common approach in computing is to disallow addresses in one process from being used in another. If that isolation is insufficient, it is often adequate to use indexes instead of addresses, taking the address to the base of the data structure. Though the absolute address of the data structure might differ across contexts, the relative offset remains constant. Another approach is to reserve memory address blocks and to guarantee imported pages have the exact same addresses as before, though they might be imported sequentially to reuse the memory block. In architecture, this is generally known as the pointer swizzling problem.
+</p>
+
+<h2>Alphabet</h2>
+
+<p>
+  An alphabet is a finite set of symbols. Because it is simply a set, an infinite number of distinct alphabets can exist. The Turing Machine specification discusses '<em>the</em> alphabet' strictly because a given Turing Machine instance utilizes only one specific alphabet. 
+</p>
+
+<h2>Examples</h2>
+
+<p>
+  The <RT-code>enum</RT-code> structure of C is an example of a mechanism for creating alphabets of named symbols. Each entry in the enum is a static symbol factory, where instances are distinct integers.
+</p>
+
+<RT-code>
+typedef enum {
+    SYMBOL_EMPTY = 0,
+    SYMBOL_ZERO  = 1,
+    SYMBOL_ONE   = 2,
+    SYMBOL_A     = 3,
+    SYMBOL_B     = 4
+} TapeAlphabet;
+
+/* The enum definition acts as the factory. */
+/* 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 */
+}
+</RT-code>
+
+<p>
+  While the <RT-code>enum</RT-code> effectively demonstrates a static hardware mapping, a string interning symbol table is a rigorous example of a dynamic runtime factory. This physically demonstrates the <RT-code>make</RT-code> function taking an arbitrary string, checking a correspondence map, and returning a canonical, unique pointer in memory (the <RT-neologism>original</RT-neologism>).
+</p>
+
+<RT-code>
+#include &lt;string.h&gt;
+
+#define TABLE_SIZE 100
+typedef const char* SymbolInstance;
+
+SymbolInstance symbol_table[TABLE_SIZE];
+int table_count = 0;
+
+/* The Factory 'make' function */
+SymbolInstance make_symbol(const char* name) {
+    /* Search for an existing original */
+    for (int i = 0; i < table_count; i++) {
+        if (strcmp(symbol_table[i], name) == 0) {
+            return symbol_table[i]; /* Return a copy of the instance */
+        }
+    }
+    
+    /* Mint a new original if one does not exist */
+    if (table_count < TABLE_SIZE) {
+        symbol_table[table_count] = strdup(name);
+        return symbol_table[table_count++];
+    }
+    return NULL; /* Table capacity reached */
+}
+
+/* Usage */
+SymbolInstance x = make_symbol("START");
+SymbolInstance y = make_symbol("START");
+
+/* x == y evaluates to True based purely on the physical memory address, 
+   bypassing the need for further string comparisons. */
+</RT-code>
+
+      <h1>The Turing Machine as an architecture</h1>
 
       <p>
         In this interpretation of the Turing Machine, the architecture utilizes a single-ended tape, aligning with the foundational model presented by Hopcroft and Ullman <RT-cite ref="John E. Hopcroft and Jeffrey D. Ullman, Introduction to Automata Theory, Languages, and Computation, 1979"></RT-cite>. If a computation strictly requires a two-way infinite tape, the single-ended tape can simulate it by interleaving the addresses: assigning odd-addressed cells to represent the right-going half, and even-addressed cells to represent the left-going half. Structurally, this simulation requires taking two steps instead of one to advance in a given logical direction. When analyzing the time complexity of an algorithm, this structural overhead merely doubles the constant on the linear term, leaving the asymptotic order of complexity entirely unchanged. The outcomes of decider programs are unaffected. Therefore, utilizing a single-ended tape is an <RT-term>inconsequential</RT-term> variation of the two-way tape machine.