From 3082f160dddadaef76f1dfa0bd1ca79ac9621aae Mon Sep 17 00:00:00 2001
From: Thomas Walker Lynch
Date: Fri, 6 Feb 2026 16:20:28 +0000
Subject: [PATCH] sketching out more of the user manual
---
document/TM.html | 210 +++++++++++++++++++++++++++++++++--------------
1 file changed, 148 insertions(+), 62 deletions(-)
diff --git a/document/TM.html b/document/TM.html
index 3634c02..abeead4 100644
--- a/document/TM.html
+++ b/document/TM.html
@@ -23,15 +23,11 @@
Introduction
- A Tape Machine (TM) is an abstract mechanism for manipulating data found in sequences.
- Such sequences include lists, arrays, sets (given an ordering function), and maps (also given an ordering function).
- Also included are linear traversals of more complex structures.
- The theory underpinning the TM is discussed in the TTCA book.
+ A Tape Machine (TM) is an abstract mechanism for manipulating data found in sequences. Such sequences include lists, arrays, sets (given an ordering function), and maps (also given an ordering function). Also included are linear traversals of more complex structures. The theory underpinning the TM is discussed in the TTCA book.
- Unlike standard arrays (which are stateless) or iterators (which are transient), a TM combines a data substrate with a persistent head.
- The head maintains positional state, allowing the programmer to navigate, read, and write tape cells.
+ Unlike standard arrays (which are stateless) or iterators (which are transient), a TM combines a data substrate with a persistent head. The head maintains positional state, allowing the programmer to navigate, read, and write tape cells.
@@ -39,44 +35,32 @@
- A TM can have a concrete tape or a virtual tape.
- A concrete tape is backed by a container.
- A virtual tape presents the same TM interface, but its cells and motion are implemented by functions over some internal state.
- For example, an abstract Counting Number tape machine can use a big integer as its state and implement stepping and reading over that state, instead of traversing an array of numbers.
+ A TM can have a concrete tape or a virtual tape. A concrete tape is backed by a container. A virtual tape presents the same TM interface, but its cells and motion are implemented by functions over some internal state. For example, an abstract Counting Number tape machine can use a big integer as its state and implement stepping and reading over that state, instead of traversing an array of numbers.
- A defining invariant of all Tape Machines is that cell contents are cargo.
- The TM reads and writes cell payload, but it does not interpret that payload as control.
- The decisions are made above the TM, by the programmerâs algorithm.
+ A defining invariant of all Tape Machines is that cell contents are cargo. The TM reads and writes cell payload, but it does not interpret that payload as control. The decisions are made above the TM, by the programmerâs algorithm.
- A TM is constructed with a set of feature symbols that select which parts of the interface are available.
- When no feature symbols are supplied, the result is a non-destructive step right machine with no indexing.
- Feature symbols can enable step left behavior (via the mirror view), and can independently enable indexing commands.
+ A TM is constructed with a set of feature symbols that select which parts of the interface are available. When no feature symbols are supplied, the result is a non-destructive step right machine with no indexing. Feature symbols can enable step left behavior (via the mirror view), enable random access indexing functions, and accounting for a shared tape, among other things.
- A first order TM is defined by a single invariant: the head is always on a valid cell.
- This invariant makes the primitive interface total: every move, read, write, and query has a clean, well defined meaning, and caller code stays free of scattered end case tests.
+ A first order TM is defined by a single invariant: the head is always on a valid cell. This invariant makes the primitive interface total: every move, read, write, and query has a clean, well defined meaning, and caller code stays free of scattered end case tests.
- If an operation were permitted to remove the last remaining cell, said first order invariant would be broken and the interface would stop being total.
- A working TM that supported such a deletion would need status logic that represents the empty state.
- That status logic would either be embedded inside the TM operations as edge handling, or be represented explicitly as a separate status machine layered above the base TM.
- Either choice represents a shift in level of analysis being done, and therefore would lead to the construction of a distinct second order tape machine.
+ If an operation were permitted to remove the last remaining cell, said first order invariant would be broken and the interface would stop being total. A working TM that supported such a deletion would need status logic that represents the empty state. That status logic would either be embedded inside the TM operations as edge handling, or be represented explicitly as a separate status machine layered above the base TM. Either choice represents a shift in level of analysis being done, and therefore would lead to the construction of a distinct second order tape machine.
- TM machines incorporate various approaches for controlling entanglement, depending on which interface features are selected at construction time.
- In one approach, no methods are placed on the interface that can destroy tape cells. This supports a non-destructive programming paradigm, so such machines are said to be non-destructive. Without destructive operations, one machine cannot break another by changing its tape structure.
- In a second approach, the interface is configured so there are no functions for entangling machines in the first place. Each solitary machine can safely perform destructive operations because no other machine shares its tape.
- As a third approach, each group of entangled machines shares a catalog listing all machines in the group. Caller code can guard operations by querying whether a planned operation is safe before attempting it. This third strategy is called entanglement accounting.
- Yet another approach is for the programmer, compiler, or external function to prove code is safe, which is the same as proving that guard code is not needed.
+ Tape machines that share a tape are said to be entangled. There will be both data and control hazards among entangled machines. Data hazards have to do with one machine writing data being read by another, either unexpectedly, or in the wrong temporal order. Data hazards can lead to incorrectly computed results, but they will not break the machines. In contrast, control hazards lead to broken machines. The principle control hazard is that of one entangled TM deleting a cell that another TM is visiting. That orphans the head of that other machine and leads to a violation of the a tape machine head is always on a valid cell. We leave the data hazard management to the programmer; however, we provide specific features for preventing control hazards.
+
+ TM machines incorporate various approaches for managing entanglement and avoiding control hazards. These are chosen as features at construction time. In one approach, no methods are placed on the interface that can destroy tape cells. This supports a non-destructive programming paradigm, so such machines are said to be non-destructive. Without destructive operations, entangled machines simply do not have the ability to break each other. In a second approach, the interface is configured so there are no functions for entangling machines in the first place. Each solitary machine can safely perform destructive operations because no other machine shares its tape. As a third approach, each group of entangled machines shares a catalog listing all machines in the group. Caller code can guard operations by querying whether a planned operation is safe before attempting it. This third strategy is called entanglement accounting. During the time of execution of the guard and operation, each tape machine must be able to lockout others from access to the catalog. Yet another approach is for the programmer, compiler, or external function to prove code is safe, which is the same as proving that guard code is not needed.
+
Command language
@@ -305,8 +289,7 @@
If we later support list forms or repetition forms for copy, L will affect the scan direction for those operations.
-
- Primitive method reference
+ TM interface functions
This section lists the concrete methods exposed by the Python/C implementation.
@@ -317,29 +300,47 @@
The L prefix is not implemented as a distinct family of primitives.
- It selects the mirror view in the command language.
- In the API, the same effect is provided by explicit left variants such as ls() and lsn(n).
+ In the command language it selects the mirror view.
+ In the API the same effect is provided by explicit left primitives such as ls() and lsn(n), or by allowing a signed n on machines that support step left.
+
+
+ Feature symbols and primitive availability
+
+
+ A TM is constructed with feature symbols that select which primitive families are present.
+ With no feature symbols, the result is a non-destructive step right machine with no indexing.
+ Enabling step left adds left motion primitives (or signed n support) and mirror view semantics in the command language.
+ Indexing is an independent feature: when enabled, index based query and cue forms become legal and corresponding primitives become available.
Navigation primitives
- The navigation primitives implement the s command with the argument forms ε and n(int).
- The left variants implement the mirror view behavior directly.
+ Navigation primitives implement the s command with the argument forms ε, n, and R.
+ On a step right only machine, n is constrained to positive values.
+ On a machine that supports step left, n can be negative, with the sign selecting direction in the base view.
- s() steps to the right neighbor. (Command form: s.)
- - sn(n) steps right n times. (Command form: sn(n).)
+ - sn(n) steps by n cells. On a step right only machine, n must be positive. (Command form: sn(n).)
+ - sR() cues the head to the selected view rightmost cell. (Command form: sR.)
+
+
+
+ If step left is enabled, left motion is available either as explicit primitives, or via negative n on sn(n), depending on the configured interface.
+ When explicit left primitives exist, they correspond to the mirror view command forms.
+
+
+
- ls() steps to the left neighbor. (Command form: Ls.)
- lsn(n) steps left n times. (Command form: Lsn(n).)
- - Rs() cues the selected machine rightmost. (Command form: sR.)
- - Ls() cues the selected machine leftmost. (Command form: LsR.)
+ - lsR() cues the head to leftmost. (Command form: LsR.)
- Note the correspondence: sR cues rightmost in the right going view, and LsR cues leftmost in that same underlying tape.
- The primitives Rs() and Ls() are optimized forms of those cues.
+ Note the correspondence: sR cues rightmost in the base view, and LsR cues leftmost of that same underlying tape.
+ The primitives sR() and lsR() are optimized cues.
Input and output primitives
@@ -347,6 +348,7 @@
The I/O primitives implement r and w(value).
In the command language, r reads the current cell payload, and w(v) writes a payload to the current cell.
+ As of the time of this writing, these operations are cell local, so mirror view does not change their behavior.
- Bulk forms exist in the API, but they are not represented in the current command grammar.
+ Bulk forms can exist in the API, but they are not represented in the current command grammar.
They are library level conveniences built on top of repeated primitive behavior.
+ If bulk copy forms become part of the command grammar later, mirror view will affect scan direction for those operations.
@@ -368,18 +371,30 @@
Query primitives expose the q command.
- In the command language, query arguments refine what is being queried.
+ On the step right only machine, the primitive set covers the boolean query forms.
+ When indexing is enabled as an additional feature, index valued query forms become available.
- - qI() returns the current head index. (Command form: qI.)
- qR() returns whether the head is on the selected view rightmost cell. (Command form: qR.)
- - qIR() returns the index of the selected view rightmost cell. (Command form: qIR.)
- The mirror view query forms follow the same rule.
- For example, LqR tests the leftmost of the underlying tape, and LqIR returns its index, which is zero.
+ If indexing is enabled, the API also exposes index query primitives.
+ These correspond to the A arg descriptor in the command language.
+ (If you later rename A to I, this section becomes qI and qIR accordingly.)
+
+
+
+ - qA() returns the current head index. (Command form: qA.)
+ - qAR() returns the index of the selected view rightmost cell. (Command form: qAR.)
+
+
+
+ Mirror view query forms follow the same rule in the command language.
+ For example, LqR tests the leftmost of the underlying tape, and LqAR returns its index, typically zero.
+ In the API, that effect is obtained either by left primitives (for LqR this is lsqR() if such a helper exists), or by explicit equivalences such as âleftmost testâ implemented via the leftmost cue or by comparing to a known bound head.
+ The primitive set stays small, and higher level forms live in friend or workspace layers.
Entanglement primitives
@@ -387,14 +402,15 @@
Entanglement primitives implement the e command.
The entangled machine shares the tape with the original and starts on the same cell.
+ In entanglement accounting configurations, entangled machines also share the group catalog used by guard predicates.
- - e() returns a new entangled machine sharing the same tape and safety catalog. (Command form: e.)
+ - e() returns a new entangled machine sharing the same tape. (Command form: e.)
- Combined command forms such as es or els are legal in the grammar, but they are not required as primitives.
+ Combined command forms such as es are legal in the grammar, but they are not required as primitives.
The library can expose such combinations as convenience calls, or generate them through a compile layer.
The core model remains that a statement is a sequence of commands applied to a selected view.
@@ -442,12 +458,12 @@
First Rest pattern with initialization
-# Pattern 1: First Rest (Initialize with First)
-# Useful when the accumulator starts with the first value.
-total = tm.r() # Process First
-while not tm.qR(): # Guard: Is there a Rest?
- tm.s() # Step (Protected)
- total += tm.r() # Process Next
+ # Pattern 1: First Rest (Initialize with First)
+ # Useful when the accumulator starts with the first value.
+ total = tm.r() # Process First
+ while not tm.qR(): # Guard: Is there a Rest?
+ tm.s() # Step (Protected)
+ total += tm.r() # Process Next
@@ -464,11 +480,11 @@ while not tm.qR(): # Guard: Is there a Rest?
-# Conceptual "do" loop
-do:
- total += tm.r() # Always process the current cell
- if tm.qR() break # Middle break: if at rightmost, stop
- tm.s() # Step only when not at the end
+ # Conceptual "do" loop
+ do:
+ total += tm.r() # Always process the current cell
+ if tm.qR() break # protects increment from spilling over
+ tm.s() # Step only when not at the end
@@ -476,17 +492,54 @@ do:
-# Python implementation
-while True:
- total += tm.r()
- if tm.qR(): break
- tm.s()
+ # Python implementation
+ while True:
+ total += tm.r()
+ if tm.qR(): break
+ tm.s()
The middle test tm.qR() guards tm.s(), so the machine never steps beyond rightmost.
+ Region Machine
+
+ A Region Machine is a composite structure built from three entangled tape machines. It enforces the invariant that the active head remains within a specified closed interval of the tape.
+
+ Structure
+
+ The Region Machine consists of:
- Left Boundary Machine: A TM marking the leftmost valid cell of the region.
- Right Boundary Machine: A TM marking the rightmost valid cell of the region.
- Active Machine: The TM interface exposed to the user for navigation and I/O.
+
+ Because the Region Machine relies on the First Order invariant (head always on a valid cell), a region cannot be empty. The minimum region size is one cell, where the Left Boundary, Right Boundary, and Active Head all occupy the same cell.
+
+ Behavior
+
+ The Region Machine implements the standard TM interface but constrains movement based on the boundary heads.
+
+ - Step (s): The Active Head performs a step only if it is not currently on the Right Boundary cell.
- Step Left (ls): The Active Head performs a left step only if it is not currently on the Left Boundary cell.
- Query Bounds (qR, qL):
- qR() returns true if the Active Head is on the same cell as the Right Boundary Head.
- qL() returns true if the Active Head is on the same cell as the Left Boundary Head.
- Cue Bounds (sR, lsR):
- sR() moves the Active Head to the cell occupied by the Right Boundary Head.
- lsR() moves the Active Head to the cell occupied by the Left Boundary Head.
+
+ Boundary Management
+
+ The boundaries of a region are themselves Tape Machines. This allows the region to expand or contract dynamically. Moving a boundary head changes the effective range of the Active Machine immediately.
+
+ Safety Constraint: A boundary head cannot step past the other boundary head. The Left Boundary must always be to the left of or on the same cell as the Right Boundary. Furthermore, the Active Head must not be orphaned by boundary movement. If the Right Boundary steps left past the Active Head, the Active Head is no longer valid. Therefore, boundary contraction requires checking or moving the Active Head to maintain the invariant.
+
+ TM Workspace functions
+
+ The TM_workspace namespace contains higher-level functions that coordinate multiple machines. These functions are not part of the core TM interface but operate on TMs to implement common algorithms.
+
+ Tandem operations
+
+ Tandem operations drive multiple machines simultaneously. They are useful for copying, comparing, or parallel processing.
+
+ - step_tandem(tm1, tm2): Steps both machines to their respective right neighbors. Requires that neither machine is at its rightmost bound.
- zip_apply(f, tm1, tm2): Applies function f to the values read from tm1 and tm2, then steps both.
+
+ Predicates
+
+ Predicates test relationships between entangled machines.
+
+ - head_on_same_cell(tm1, tm2): Returns true if the heads of two entangled machines are on the same cell. This is the fundamental primitive used to implement qR in Region Machines.
@@ -494,6 +547,39 @@ while True:
window.StyleRT.style_orchestrator();
+ Second Order Machine (TMS)
+
+ A Second Order Machine, or TMS (Tape Machine Status), is a wrapper that manages the lifecycle of a First Order Tape Machine. It introduces the concept of status to handle conditions that violate First Order invariants, specifically the absence of valid cells (emptiness).
+
+ Status definitions
+
+ The TMS manages a state machine where the states are called statuses to distinguish them from the internal state of the tape or head. The current status determines which interface functions are available to the programmer.
+
+ - Active: The machine contains cells. The underlying First Order TM is valid. All standard TM navigation and I/O commands function normally.
- Empty: The machine contains no cells. There is no tape and no head position. First Order operations like r or s are invalid and will raise errors if called. Only status-query and insertion operations are available.
- Parked: The machine contains cells, but the head is effectively "lifted" from the tape. The head is not on any valid cell. This status is often used during initialization or after a search fails to find a target.
+
+ Dynamic interface dispatch
+
+ The TMS implementation uses dynamic dispatch (or mixin replacement) to enforce status constraints. When the status changes, the interface functions are swapped.
+
+ For example, in the Empty status, the r() function is mapped to an error handler: Error: Attempted to read from an empty machine. This prevents the programmer from accidentally running First Order logic on a machine that does not satisfy the First Order invariant.
+
+ Transitions
+
+ Status changes occur when operations alter the cell count to or from zero, or when the head is explicitly parked or unparked.
+
+ Promotion (Empty to Active)
When a TMS is Empty, calling an insertion function (e.g., append(v)) creates the first cell. The status transitions to Active. The interface is updated to expose standard TM behaviors. The head is placed on the newly created cell.
+
+ Demotion (Active to Empty)
If a deletion operation removes the last remaining cell of an Active machine, the First Order invariant is broken. The TMS detects this event, destroys the underlying First Order TM, and transitions the status to Empty. The interface is updated to the restricted Empty set.
+
+ Usage with algorithms
+
+ Algorithms requiring a First Order TM (such as foreach loops or First Rest patterns) must effectively be guarded by a status check.
+
+ if tms.is_active(): # Safe to treat as a First Order TM run_algorithm(tms) else: # Handle empty case pass
+
+ Because the TMS implements the TM interface, it can be passed directly to these algorithms. However, if the status is Empty, the first operation attempted by the algorithm (usually r()) will trigger a "second order" error, alerting the programmer that they neglected the guard.
+
+