doc for now, TM_SR_ND
authorThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Mon, 9 Feb 2026 02:51:20 +0000 (02:51 +0000)
committerThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Mon, 9 Feb 2026 02:51:20 +0000 (02:51 +0000)
12 files changed:
.gitignore
developer/authored/DiscreteFunction.py [new file with mode: 0755]
developer/authored/SymbolSpace.py [new file with mode: 0755]
developer/authored/TM.py
developer/authored/TM_module.c
developer/authored/TM_module.cpython-311-x86_64-linux-gnu.so [deleted file]
developer/authored/build/lib.linux-x86_64-cpython-311/TM_module.cpython-311-x86_64-linux-gnu.so [deleted file]
developer/authored/build/temp.linux-x86_64-cpython-311/TM_module.o [deleted file]
developer/authored/example_features.py [new file with mode: 0755]
developer/authored/example_queries.py [new file with mode: 0755]
developer/authored_2026-02-09.tar [new file with mode: 0644]
document/TM.html

index ff01a07..7bdb193 100644 (file)
@@ -10,3 +10,7 @@ __pycache__/
 *~
 *.bak
 
+# build libraires
+*.so
+*.a
+
diff --git a/developer/authored/DiscreteFunction.py b/developer/authored/DiscreteFunction.py
new file mode 100755 (executable)
index 0000000..f11ad4d
--- /dev/null
@@ -0,0 +1,61 @@
+#!/usr/bin/env python3
+from SymbolSpace import SymbolSpace
+
+# ==========================================
+# THE GRAPH (Discrete Function)
+# ==========================================
+
+class DiscreteFunction:
+  """
+  The Knowledge Store.
+  Supports 'Smart Postings' to Parent Symbols.
+  """
+  def __init__(self):
+    self._rev = {} # reverse map: Symbol -> Set of Objects
+
+  def _add_posting(self ,sym ,obj):
+    if sym not in self._rev: self._rev[sym] = set()
+    self._rev[sym].add(obj)
+
+  def set(self ,obj_sym ,prop_sym):
+    """
+    Assigns a property. Updates indexes for the specific property
+    AND its namespace (Parent).
+    """
+    # 1. Index Specific (e.g., #105 'Red')
+    self._add_posting(prop_sym ,obj_sym)
+
+    # 2. Index General (e.g., #50 'Color')
+    parent = SymbolSpace.get_parent(prop_sym)
+    if parent:
+      self._add_posting(parent ,obj_sym)
+
+  def find(self ,sym):
+    """Returns the set of objects associated with this symbol."""
+    return self._rev.get(sym ,set())
+
+# --- Work Function ---
+
+def verify_graph():
+  print("--- DiscreteFunction Verification ---")
+  # 1. Create Symbols
+  sym_obj = SymbolSpace.alloc()
+  sym_prop = SymbolSpace.alloc()
+  sym_parent = SymbolSpace.alloc()
+  
+  # 2. Setup Hierarchy
+  SymbolSpace.set_parent(sym_prop, sym_parent)
+  
+  # 3. Set Fact
+  df = DiscreteFunction()
+  df.set(sym_obj, sym_prop)
+  
+  # 4. Check Smart Posting
+  print(f"Finding specific property: {len(df.find(sym_prop))} (Expected 1)")
+  print(f"Finding parent category:   {len(df.find(sym_parent))} (Expected 1)")
+
+def CLI():
+  verify_graph()
+
+if __name__ == "__main__":
+  CLI()
diff --git a/developer/authored/SymbolSpace.py b/developer/authored/SymbolSpace.py
new file mode 100755 (executable)
index 0000000..e363e3e
--- /dev/null
@@ -0,0 +1,84 @@
+#!/usr/bin/env python3
+from collections import deque as FIFO
+
+class SymbolSpace:
+  """
+  The manager of the Epimetheus integer namespace.
+  """
+  
+  _counter = 0
+  _dealloc_queue = FIFO()
+  
+  # HIERARCHY SUPPORT (Added)
+  _parents = {} # Map: Child_Sym -> Parent_Sym
+
+  class Instance:
+    """The handle for a symbol."""
+    __slots__ = ('_value' ,)
+
+    def __init__(self ,value):
+      self._value = value
+
+    def __eq__(self ,other):
+      # Compare value, not identity
+      if isinstance(other ,SymbolSpace.Instance): return self._value == other._value
+      return False
+
+    def __hash__(self):
+      return hash(self._value)
+
+    def __repr__(self):
+      return f"<Sym {self._value}>"
+
+  @classmethod
+  def alloc(cls) -> 'SymbolSpace.Instance':
+    val = 0
+    if cls._dealloc_queue:
+      val = cls._dealloc_queue.popleft()
+    else:
+      cls._counter += 1
+      val = cls._counter
+    return cls.Instance(val)
+
+  @classmethod
+  def dealloc(cls ,sym: 'SymbolSpace.Instance'):
+    val = sym._value
+    if val == 0: raise ValueError("Null symbol (0) cannot be deallocated.")
+
+    if val == cls._counter:
+      cls._counter -= 1
+      while cls._counter > 0 and cls._counter in cls._dealloc_queue:
+        cls._dealloc_queue.remove(cls._counter)
+        cls._counter -= 1
+    else:
+      cls._dealloc_queue.append(val)
+
+  @classmethod
+  def get_null(cls) -> 'SymbolSpace.Instance':
+    return cls.Instance(0)
+
+  # --- Hierarchy Methods ---
+
+  @classmethod
+  def set_parent(cls ,child ,parent):
+    cls._parents[child] = parent
+
+  @classmethod
+  def get_parent(cls ,child):
+    return cls._parents.get(child)
+
+def verify():
+  print(f"Allocating 3 symbols...")
+  s1 = SymbolSpace.alloc()
+  s2 = SymbolSpace.alloc()
+  
+  # Test Hierarchy
+  SymbolSpace.set_parent(s2, s1)
+  assert SymbolSpace.get_parent(s2) == s1
+  print("Hierarchy check passed.")
+
+def CLI():
+  verify()
+
+if __name__ == "__main__":
+  CLI()
index 3995622..9af7de4 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python3
 import sys
-from enum import Enum ,auto
+from enum import Enumauto
 
 try:
   import TM_module
@@ -9,11 +9,11 @@ except ImportError:
   sys.exit(1)
 
 # ==========================================
-# 1. Enums
+# 1. Enums & Features
 # ==========================================
 
-LM = "LM"
-RM = "RM"
+class Features:
+  APPEND_RIGHT = "aR"
 
 class Status(Enum):
   ABANDONED = auto()
@@ -28,73 +28,53 @@ class Topology(Enum):
   SEGMENT = auto()
 
 # ==========================================
-# 2. The Machine (Direct Alias)
+# 2. The Machine (Factory)
 # ==========================================
 
-# The Safety Logic is now 100% in C.
-# We just alias the type.
+# TM is now the Factory Function from the C module
 TM = TM_module.FastTM
 
 # ==========================================
-# 3. Status Wrapper
+# 3. Status Wrapper (TMS)
 # ==========================================
 
-class TM2:
-  def __init__(self ,data_obj=None):
+class TMS:
+  def __init__(self, data_obj=None, features=None):
+    """
+    TMS Constructor.
+    Args:
+      data_obj: Initial data container (list).
+      features: List of feature symbols (e.g. [Features.APPEND_RIGHT]).
+    """
     if data_obj:
-      self.tm = TM(data_obj)
+      # Factory Call: C determines the underlying type based on features
+      self.tm = TM(data_obj, features)
       self._stat = Status.ACTIVE
     else:
       self.tm = None
       self._stat = Status.EMPTY
 
+  # --- Base Methods (SR_ND) ---
   def r(self): return self.tm.r()
-  def rn(self ,n_val): return self.tm.rn(n_val)
-  def w(self ,val_obj): return self.tm.w(val_obj)
-  def wn(self ,val_obj): return self.tm.wn(val_obj)
+  def rn(self, n): return self.tm.rn(n)
+  def w(self, v): return self.tm.w(v)
+  def wn(self, v): return self.tm.wn(v)
   def s(self): return self.tm.s()
-  def sn(self ,n_val): return self.tm.sn(n_val)
-  def ls(self): return self.tm.ls()
-  def lsn(self ,n_val): return self.tm.lsn(n_val)
-  def d(self): return self.tm.d()
-  def dn(self ,n_val): return self.tm.dn(n_val)
-  def esd(self): return self.tm.esd()
-  def esdn(self ,n_val): return self.tm.esdn(n_val)
-  def aL(self ,val_obj): return self.tm.aL(val_obj)
-  def aR(self ,val_obj): return self.tm.aR(val_obj)
-  def e(self): return TM2(self.tm.e()) if not self.empty() else TM2(None)
-    
-  def empty(self): return self._stat == Status.EMPTY
-  def rightmost(self): return True if self.empty() else self.tm.rightmost()
-  def leftmost(self): return True if self.empty() else self.tm.leftmost()
+  def sn(self, n): return self.tm.sn(n)
+  
   def address(self): return 0 if self.empty() else self.tm.address()
-  def topology(self): return Topology.NULL if self.empty() else Topology.SEGMENT
-
-# ==========================================
-# 4. Verification
-# ==========================================
+  def len(self): return 0 if self.empty() else self.tm.len()
 
-def CLI():
-  print("--- TM Full C-Entanglement Verification ---")
+  # --- Feature Methods (Delegated) ---
+  # If the C-Type doesn't have these, Python raises AttributeError.
+  def aR(self, v): return self.tm.aR(v)
   
-  # 1. Setup
-  t1 = TM2(['A' ,'B' ,'C'])
-  t2 = t1.e() # Entangle (C handles registration)
-  
-  print(f"T1 Addr: {t1.address()}")
-  print(f"T2 Addr: {t2.address()}")
-  
-  # 2. Move T2 to danger zone
-  t2.s() # T2 on 'B'
-  print(f"T2 Step -> {t2.r()}")
-
-  # 3. Trigger Entanglement Check (in C)
-  print("T1 attempting to delete 'B' (esd)...")
-  try:
-    t1.esd() # Should fail
-  except RuntimeError as e:
-    print(f"Caught C-Level Exception: {e}")
-
-if __name__ == "__main__":
-  CLI()
+  # --- Meta ---
+  def e(self):
+    # Cloning preserves the underlying C-Type (and thus features)
+    return TMS(self.tm.e()) if not self.empty() else TMS(None)
 
+  def empty(self): return self._stat == Status.EMPTY
+  def rightmost(self): return True if self.empty() else self.tm.rightmost()
+  def leftmost(self): return True if self.empty() else (self.tm.head == 0)
+  def topology(self): return Topology.NULL if self.empty() else Topology.SEGMENT
index fefab09..b0e7524 100644 (file)
@@ -1,16 +1,18 @@
 /*
   TM_module.c
-  CPython Extension: Direct List Access + Entanglement Safety
-  RT Code Format Compliant
+  CPython Extension: Tape Machine Factory
+  Implements:
+    - TM_SR_ND (Base: Step Right, Non-Destructive)
+    - TM_SR_ND_AR (Feature: Append Right)
 */
 
 #define PY_SSIZE_T_CLEAN
 #include <Python.h>
 #include "structmember.h"
-#include <stddef.h> /* For offsetof */
+#include <stddef.h> 
 
 /* ========================================================= */
-/* TYPE DEFINITION                                           */
+/* 1. DATA LAYOUT (Shared)                                   */
 /* ========================================================= */
 
 typedef struct {
@@ -21,317 +23,280 @@ typedef struct {
   PyObject* weakreflist;   /* Required for WeakRefs */
 } FastTM;
 
-/* Forward Declaration */
-static PyObject* FastTM_address(FastTM* self);
-
 static void FastTM_dealloc(FastTM* self){
-  /* Clear weak references first! */
   if( self->weakreflist != NULL ){
     PyObject_ClearWeakRefs((PyObject*)self);
   }
-
   Py_XDECREF(self->tape_obj);
   Py_XDECREF(self->peer_list);
   Py_TYPE(self)->tp_free((PyObject*)self);
 }
 
-/* Helper: Register self into the peer_list.
-  Uses WeakRef so dead machines don't keep the list alive.
-*/
-static int register_entanglement(FastTM* self ,PyObject* existing_peer_list){
+/* Helper: Register Entanglement */
+static int register_entanglement(FastTM* self, PyObject* existing_peer_list){
   PyObject* weak_ref = NULL;
-
   if( existing_peer_list ){
-    /* Join existing entanglement */
     self->peer_list = existing_peer_list;
     Py_INCREF(self->peer_list);
   } else {
-    /* Start new entanglement */
     self->peer_list = PyList_New(0);
     if( !self->peer_list ) return -1;
   }
-
-  /* Create WeakRef to self */
-  weak_ref = PyWeakref_NewRef((PyObject*)self ,NULL);
+  weak_ref = PyWeakref_NewRef((PyObject*)self, NULL);
   if( !weak_ref ) return -1;
-
-  /* Add to list */
-  if( PyList_Append(self->peer_list ,weak_ref) < 0 ){
+  if( PyList_Append(self->peer_list, weak_ref) < 0 ){
     Py_DECREF(weak_ref);
     return -1;
   }
-  
   Py_DECREF(weak_ref);
   return 0;
 }
 
-static int FastTM_init(FastTM* self ,PyObject* arg_tuple ,PyObject* kwd_dict){
-  PyObject* input_obj = NULL;
-  
-  /* Initialize weakref list to NULL */
-  self->weakreflist = NULL;
-  
-  if( !PyArg_ParseTuple(arg_tuple ,"O" ,&input_obj) ) return -1;
-
-  if( PyObject_TypeCheck(input_obj ,Py_TYPE(self)) ){
-    /* CLONE MODE: Entangle with existing TM */
-    FastTM* source_tm = (FastTM*)input_obj;
-    
-    /* Share Tape */
-    self->tape_obj = source_tm->tape_obj;
-    Py_INCREF(self->tape_obj);
-    
-    /* Copy Head */
-    self->head = source_tm->head;
-    
-    /* Register in shared peer list */
-    if( register_entanglement(self ,source_tm->peer_list) < 0 ) return -1;
-
-  } else {
-    /* NEW MODE: Create from Container */
-    if( PyList_Check(input_obj) ){
-      self->tape_obj = input_obj;
-      Py_INCREF(self->tape_obj);
-    } else {
-      self->tape_obj = PySequence_List(input_obj);
-      if( !self->tape_obj ) return -1;
-    }
-    
-    self->head = 0;
-    
-    /* Start new peer list */
-    if( register_entanglement(self ,NULL) < 0 ) return -1;
-  }
-
-  return 0;
-}
-
 /* ========================================================= */
-/* ENTANGLEMENT SAFETY CHECK                                 */
+/* 2. THE MIXIN LIBRARY (Static C Functions)                 */
 /* ========================================================= */
 
-/*
-  Checks if any PEER (other than self) is within the forbidden range.
-  Range: [start, start + count)
-  Returns 0 if Safe, -1 if Violation (and sets Exception).
-*/
-static int check_safety(FastTM* self ,Py_ssize_t start_idx ,Py_ssize_t count_val){
-  Py_ssize_t i;
-  Py_ssize_t num_peers;
-  PyObject* ref_item;
-  PyObject* peer_obj;
-  FastTM* peer_tm;
-  Py_ssize_t end_idx = start_idx + count_val;
-
-  num_peers = PyList_Size(self->peer_list);
-  
-  for( i = 0; i < num_peers; i++ ){
-    ref_item = PyList_GetItem(self->peer_list ,i); /* Borrowed */
-    peer_obj = PyWeakref_GetObject(ref_item);     /* Borrowed */
-
-    /* Skip dead objects or self */
-    if( peer_obj == Py_None || peer_obj == (PyObject*)self ) continue;
-    
-    peer_tm = (FastTM*)peer_obj;
-    
-    /* Collision Check */
-    if( peer_tm->head >= start_idx && peer_tm->head < end_idx ){
-      PyErr_SetString(PyExc_RuntimeError ,"Entanglement Violation: Peer is on target cell");
-      return -1;
-    }
-  }
-  return 0;
+/* --- Navigation --- */
+static PyObject* mixin_s(FastTM* self){
+  self->head++;
+  Py_RETURN_NONE;
 }
 
-/* ========================================================= */
-/* METHODS                                                   */
-/* ========================================================= */
+static PyObject* mixin_sn(FastTM* self, PyObject* arg_tuple){
+  Py_ssize_t n_val;
+  if( !PyArg_ParseTuple(arg_tuple, "n", &n_val) ) return NULL;
+  if (n_val < 0) {
+      PyErr_SetString(PyExc_ValueError, "Machine supports positive steps only.");
+      return NULL;
+  }
+  self->head += n_val;
+  Py_RETURN_NONE;
+}
 
-/* --- Read --- */
-static PyObject* FastTM_r(FastTM* self){
-  PyObject* item_obj = PyList_GetItem(self->tape_obj ,self->head);
+/* --- I/O --- */
+static PyObject* mixin_r(FastTM* self){
+  PyObject* item_obj = PyList_GetItem(self->tape_objself->head);
   if( !item_obj ) return NULL; 
   Py_INCREF(item_obj);
   return item_obj;
 }
 
-static PyObject* FastTM_rn(FastTM* self ,PyObject* arg_tuple){
+static PyObject* mixin_rn(FastTM* self, PyObject* arg_tuple){
   Py_ssize_t n_val;
-  if( !PyArg_ParseTuple(arg_tuple ,"n" ,&n_val) ) return NULL;
-  return PyList_GetSlice(self->tape_obj ,self->head ,self->head + n_val);
+  if( !PyArg_ParseTuple(arg_tuple, "n", &n_val) ) return NULL;
+  return PyList_GetSlice(self->tape_obj, self->head, self->head + n_val);
 }
 
-/* --- Write --- */
-static PyObject* FastTM_w(FastTM* self ,PyObject* val_obj){
+static PyObject* mixin_w(FastTM* self, PyObject* val_obj){
   Py_INCREF(val_obj);
-  if( PyList_SetItem(self->tape_obj ,self->head ,val_obj) < 0 ) return NULL;
+  if( PyList_SetItem(self->tape_obj, self->head, val_obj) < 0 ) return NULL;
   Py_RETURN_NONE;
 }
 
-static PyObject* FastTM_wn(FastTM* self ,PyObject* arg_tuple){
+static PyObject* mixin_wn(FastTM* self, PyObject* arg_tuple){
   PyObject* val_list;
-  if( !PyArg_ParseTuple(arg_tuple ,"O" ,&val_list) ) return NULL;
+  if( !PyArg_ParseTuple(arg_tuple, "O", &val_list) ) return NULL;
   Py_ssize_t len_val = PySequence_Size(val_list);
-  if( PyList_SetSlice(self->tape_obj ,self->head ,self->head + len_val ,val_list) < 0 ) return NULL;
+  if( PyList_SetSlice(self->tape_obj, self->head, self->head + len_val, val_list) < 0 ) return NULL;
   Py_RETURN_NONE;
 }
 
-/* --- Step --- */
-static PyObject* FastTM_s(FastTM* self){
-  self->head++;
-  Py_RETURN_NONE;
-}
+/* --- Features --- */
 
-static PyObject* FastTM_sn(FastTM* self ,PyObject* arg_tuple){
-  Py_ssize_t n_val;
-  if( !PyArg_ParseTuple(arg_tuple ,"n" ,&n_val) ) return NULL;
-  self->head += n_val;
+/* Feature: aR (Append Right) */
+static PyObject* mixin_aR(FastTM* self, PyObject* val_obj){
+  /* aR typically appends to the END of the tape, 
+     regardless of head position, in non-destructive contexts? 
+     Or at the head? 
+     Standard definition: Append to end of container. */
+  if( PyList_Append(self->tape_obj, val_obj) < 0 ) return NULL;
   Py_RETURN_NONE;
 }
 
-static PyObject* FastTM_ls(FastTM* self){
-  self->head--;
-  Py_RETURN_NONE;
+/* --- Meta --- */
+static PyObject* mixin_e(FastTM* self){
+  /* Factory-aware Entanglement:
+     We call the type's constructor. Since Py_TYPE(self) is the specific 
+     machine type (e.g. TM_SR_ND_AR), the clone will inherit the same features. */
+  PyObject* arg_tuple = PyTuple_Pack(1, self);
+  PyObject* new_obj = PyObject_CallObject((PyObject*)Py_TYPE(self), arg_tuple);
+  Py_DECREF(arg_tuple);
+  return new_obj;
 }
 
-static PyObject* FastTM_lsn(FastTM* self ,PyObject* arg_tuple){
-  Py_ssize_t n_val;
-  if( !PyArg_ParseTuple(arg_tuple ,"n" ,&n_val) ) return NULL;
-  self->head -= n_val;
-  Py_RETURN_NONE;
+static PyObject* mixin_address(FastTM* self){
+  return PyLong_FromSsize_t(self->head);
 }
 
-/* --- Allocate --- */
-static PyObject* FastTM_aL(FastTM* self ,PyObject* val_obj){
-  if( PyList_Insert(self->tape_obj ,0 ,val_obj) < 0 ) return NULL;
-  self->head++; 
-  Py_RETURN_NONE;
+static PyObject* mixin_len(FastTM* self){
+  return PyLong_FromSsize_t(PyList_Size(self->tape_obj));
 }
 
-static PyObject* FastTM_aR(FastTM* self ,PyObject* val_obj){
-  if( PyList_Append(self->tape_obj ,val_obj) < 0 ) return NULL;
-  Py_RETURN_NONE;
+static PyObject* mixin_rightmost(FastTM* self){
+  Py_ssize_t len = PyList_Size(self->tape_obj);
+  if( self->head >= len - 1 ) Py_RETURN_TRUE;
+  Py_RETURN_FALSE;
 }
 
-/* --- Delete (Safe) --- */
-
-static PyObject* FastTM_d(FastTM* self){
-  if( check_safety(self ,self->head ,1) < 0 ) return NULL;
-  if( PyList_SetSlice(self->tape_obj ,self->head ,self->head + 1 ,NULL) < 0 ) return NULL;
-  Py_RETURN_NONE;
-}
+/* ========================================================= */
+/* 3. TYPE DEFINITIONS                                       */
+/* ========================================================= */
 
-static PyObject* FastTM_dn(FastTM* self ,PyObject* arg_tuple){
-  Py_ssize_t n_val;
-  if( !PyArg_ParseTuple(arg_tuple ,"n" ,&n_val) ) return NULL;
+/* Generic Init (Used by all types) */
+static int GenericTM_init(FastTM* self, PyObject* args, PyObject* kwds){
+  PyObject* input_obj = NULL;
+  PyObject* features_obj = NULL; /* Ignored here, consumed by Factory */
   
-  if( check_safety(self ,self->head ,n_val) < 0 ) return NULL;
-  if( PyList_SetSlice(self->tape_obj ,self->head ,self->head + n_val ,NULL) < 0 ) return NULL;
-  Py_RETURN_NONE;
+  if( !PyArg_ParseTuple(args, "O|O", &input_obj, &features_obj) ) return -1;
+  
+  if( PyObject_TypeCheck(input_obj, Py_TYPE(self)) ){
+    /* Clone/Entangle */
+    FastTM* source_tm = (FastTM*)input_obj;
+    self->tape_obj = source_tm->tape_obj;
+    Py_INCREF(self->tape_obj);
+    self->head = source_tm->head;
+    if( register_entanglement(self, source_tm->peer_list) < 0 ) return -1;
+  } else {
+    /* New */
+    if( PyList_Check(input_obj) ){
+      self->tape_obj = input_obj;
+      Py_INCREF(self->tape_obj);
+    } else {
+      self->tape_obj = PySequence_List(input_obj);
+      if( !self->tape_obj ) return -1;
+    }
+    if (PyList_Size(self->tape_obj) == 0) {
+        PyErr_SetString(PyExc_ValueError, "First Order TM cannot be empty.");
+        return -1;
+    }
+    self->head = 0;
+    if( register_entanglement(self, NULL) < 0 ) return -1;
+  }
+  return 0;
 }
 
-static PyObject* FastTM_esd(FastTM* self){
-  Py_ssize_t victim = self->head + 1;
-  if( check_safety(self ,victim ,1) < 0 ) return NULL;
-  if( PyList_SetSlice(self->tape_obj ,victim ,victim + 1 ,NULL) < 0 ) return NULL;
-  Py_RETURN_NONE;
-}
+/* --- Type 1: TM_SR_ND (Base) --- */
+static PyMethodDef TM_SR_ND_methods[] = {
+  {"r", (PyCFunction)mixin_r, METH_NOARGS, ""},
+  {"rn", (PyCFunction)mixin_rn, METH_VARARGS, ""},
+  {"w", (PyCFunction)mixin_w, METH_O, ""},
+  {"wn", (PyCFunction)mixin_wn, METH_VARARGS, ""},
+  {"s", (PyCFunction)mixin_s, METH_NOARGS, ""},
+  {"sn", (PyCFunction)mixin_sn, METH_VARARGS, ""},
+  {"e", (PyCFunction)mixin_e, METH_NOARGS, ""},
+  {"address", (PyCFunction)mixin_address, METH_NOARGS, ""},
+  {"len", (PyCFunction)mixin_len, METH_NOARGS, ""},
+  {"rightmost", (PyCFunction)mixin_rightmost, METH_NOARGS, ""},
+  {NULL}
+};
 
-static PyObject* FastTM_esdn(FastTM* self ,PyObject* arg_tuple){
-  Py_ssize_t n_val;
-  Py_ssize_t start_val;
-  if( !PyArg_ParseTuple(arg_tuple ,"n" ,&n_val) ) return NULL;
-  
-  start_val = self->head + 1;
-  if( check_safety(self ,start_val ,n_val) < 0 ) return NULL;
-  if( PyList_SetSlice(self->tape_obj ,start_val ,start_val + n_val ,NULL) < 0 ) return NULL;
-  Py_RETURN_NONE;
-}
+static PyTypeObject TM_SR_ND_Type = {
+  PyVarObject_HEAD_INIT(NULL, 0)
+  .tp_name = "TM_module.TM_SR_ND",
+  .tp_doc = "Step Right, Non-Destructive",
+  .tp_basicsize = sizeof(FastTM),
+  .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+  .tp_new = PyType_GenericNew,
+  .tp_init = (initproc)GenericTM_init,
+  .tp_dealloc = (destructor)FastTM_dealloc,
+  .tp_methods = TM_SR_ND_methods,
+  .tp_weaklistoffset = offsetof(FastTM, weakreflist)
+};
 
-/* --- Meta --- */
-static PyObject* FastTM_e(FastTM* self){
-  PyObject* arg_tuple = PyTuple_Pack(1 ,self);
-  PyObject* new_obj = PyObject_CallObject((PyObject*)Py_TYPE(self) ,arg_tuple);
-  Py_DECREF(arg_tuple);
-  return new_obj;
-}
+/* --- Type 2: TM_SR_ND_AR (Base + aR) --- */
+static PyMethodDef TM_SR_ND_AR_methods[] = {
+  /* Copy Base Methods */
+  {"r", (PyCFunction)mixin_r, METH_NOARGS, ""},
+  {"rn", (PyCFunction)mixin_rn, METH_VARARGS, ""},
+  {"w", (PyCFunction)mixin_w, METH_O, ""},
+  {"wn", (PyCFunction)mixin_wn, METH_VARARGS, ""},
+  {"s", (PyCFunction)mixin_s, METH_NOARGS, ""},
+  {"sn", (PyCFunction)mixin_sn, METH_VARARGS, ""},
+  {"e", (PyCFunction)mixin_e, METH_NOARGS, ""},
+  {"address", (PyCFunction)mixin_address, METH_NOARGS, ""},
+  {"len", (PyCFunction)mixin_len, METH_NOARGS, ""},
+  {"rightmost", (PyCFunction)mixin_rightmost, METH_NOARGS, ""},
+  /* Add Feature */
+  {"aR", (PyCFunction)mixin_aR, METH_O, "Append Right"},
+  {NULL}
+};
 
-static PyObject* FastTM_address(FastTM* self){
-  return PyLong_FromSsize_t(self->head);
-}
+static PyTypeObject TM_SR_ND_AR_Type = {
+  PyVarObject_HEAD_INIT(NULL, 0)
+  .tp_name = "TM_module.TM_SR_ND_AR",
+  .tp_doc = "Step Right, Non-Destructive, Append Right",
+  .tp_basicsize = sizeof(FastTM),
+  .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+  .tp_new = PyType_GenericNew,
+  .tp_init = (initproc)GenericTM_init,
+  .tp_dealloc = (destructor)FastTM_dealloc,
+  .tp_methods = TM_SR_ND_AR_methods,
+  .tp_weaklistoffset = offsetof(FastTM, weakreflist)
+};
 
-static PyObject* FastTM_len(FastTM* self){
-  return PyLong_FromSsize_t(PyList_Size(self->tape_obj));
-}
+/* ========================================================= */
+/* 4. THE FACTORY                                            */
+/* ========================================================= */
 
-static PyObject* FastTM_rightmost(FastTM* self){
-  Py_ssize_t len = PyList_Size(self->tape_obj);
-  if( self->head >= len - 1 ) Py_RETURN_TRUE;
-  Py_RETURN_FALSE;
-}
+static PyObject* FastTM_Factory(PyObject* self, PyObject* args, PyObject* kwds){
+  PyObject* input_obj = NULL;
+  PyObject* features_obj = NULL;
+  
+  if( !PyArg_ParseTuple(args, "O|O", &input_obj, &features_obj) ) return NULL;
+
+  /* Check for "aR" in features */
+  int has_aR = 0;
+  if( features_obj && PyList_Check(features_obj) ){
+    Py_ssize_t size = PyList_Size(features_obj);
+    for( Py_ssize_t i=0; i<size; i++ ){
+      PyObject* item = PyList_GetItem(features_obj, i); /* Borrowed */
+      if( PyUnicode_Check(item) ){
+        const char* s = PyUnicode_AsUTF8(item);
+        if( s && strcmp(s, "aR") == 0 ) has_aR = 1;
+      }
+    }
+  }
 
-static PyObject* FastTM_leftmost(FastTM* self){
-  if( self->head <= 0 ) Py_RETURN_TRUE;
-  Py_RETURN_FALSE;
+  /* Select Type */
+  PyTypeObject* target_type = has_aR ? &TM_SR_ND_AR_Type : &TM_SR_ND_Type;
+
+  /* Create Instance */
+  PyObject* arg_tuple = PyTuple_Pack(2, input_obj, features_obj ? features_obj : Py_None);
+  PyObject* obj = PyObject_CallObject((PyObject*)target_type, arg_tuple);
+  Py_DECREF(arg_tuple);
+  
+  return obj;
 }
 
 /* ========================================================= */
-/* REGISTRATION                                              */
+/* 5. MODULE INIT                                            */
 /* ========================================================= */
 
-static PyMethodDef FastTM_methods[] = {
-  {"r" ,(PyCFunction)FastTM_r ,METH_NOARGS ,""}
-  ,{"rn" ,(PyCFunction)FastTM_rn ,METH_VARARGS ,""}
-  ,{"w" ,(PyCFunction)FastTM_w ,METH_O ,""}
-  ,{"wn" ,(PyCFunction)FastTM_wn ,METH_VARARGS ,""}
-  ,{"s" ,(PyCFunction)FastTM_s ,METH_NOARGS ,""}
-  ,{"sn" ,(PyCFunction)FastTM_sn ,METH_VARARGS ,""}
-  ,{"ls" ,(PyCFunction)FastTM_ls ,METH_NOARGS ,""}
-  ,{"lsn" ,(PyCFunction)FastTM_lsn ,METH_VARARGS ,""}
-  ,{"aL" ,(PyCFunction)FastTM_aL ,METH_O ,""}
-  ,{"aR" ,(PyCFunction)FastTM_aR ,METH_O ,""}
-  ,{"d" ,(PyCFunction)FastTM_d ,METH_NOARGS ,""}
-  ,{"dn" ,(PyCFunction)FastTM_dn ,METH_VARARGS ,""}
-  ,{"esd" ,(PyCFunction)FastTM_esd ,METH_NOARGS ,""}
-  ,{"esdn" ,(PyCFunction)FastTM_esdn ,METH_VARARGS ,""}
-  ,{"e" ,(PyCFunction)FastTM_e ,METH_NOARGS ,""}
-  ,{"address" ,(PyCFunction)FastTM_address ,METH_NOARGS ,""}
-  ,{"len" ,(PyCFunction)FastTM_len ,METH_NOARGS ,""}
-  ,{"rightmost" ,(PyCFunction)FastTM_rightmost ,METH_NOARGS ,""}
-  ,{"leftmost" ,(PyCFunction)FastTM_leftmost ,METH_NOARGS ,""}
-  ,{NULL}
-};
-
-static PyTypeObject FastTMType = {
-  PyVarObject_HEAD_INIT(NULL ,0)
-  .tp_name = "TM_module.FastTM"
-  ,.tp_doc = "Safe Entangled Tape Machine"
-  ,.tp_basicsize = sizeof(FastTM)
-  ,.tp_itemsize = 0
-  ,.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
-  ,.tp_new = PyType_GenericNew
-  ,.tp_init = (initproc)FastTM_init
-  ,.tp_dealloc = (destructor)FastTM_dealloc
-  ,.tp_methods = FastTM_methods
-  ,.tp_weaklistoffset = offsetof(FastTM ,weakreflist) /* CRITICAL FIX */
+static PyMethodDef module_methods[] = {
+    {"FastTM", (PyCFunction)FastTM_Factory, METH_VARARGS | METH_KEYWORDS, "TM Factory"},
+    {NULL, NULL, 0, NULL}
 };
 
 static PyModuleDef TM_module = {
-  PyModuleDef_HEAD_INIT
-  ,"TM_module"
-  ,"Fast TM Extension"
-  ,-1
-  ,NULL
+  PyModuleDef_HEAD_INIT, "TM_module", "Fast TM Extension", -1, module_methods
 };
 
 PyMODINIT_FUNC PyInit_TM_module(void){
   PyObject* m_obj;
-  if( PyType_Ready(&FastTMType) < 0 ) return NULL;
+  
+  if( PyType_Ready(&TM_SR_ND_Type) < 0 ) return NULL;
+  if( PyType_Ready(&TM_SR_ND_AR_Type) < 0 ) return NULL;
 
   m_obj = PyModule_Create(&TM_module);
   if( !m_obj ) return NULL;
 
-  Py_INCREF(&FastTMType);
-  PyModule_AddObject(m_obj ,"FastTM" ,(PyObject*)&FastTMType);
+  Py_INCREF(&TM_SR_ND_Type);
+  Py_INCREF(&TM_SR_ND_AR_Type);
+  
+  /* We export the Types if user wants to inspect them, 
+     but primarily they use the FastTM factory. */
+  PyModule_AddObject(m_obj, "TM_SR_ND", (PyObject*)&TM_SR_ND_Type);
+  PyModule_AddObject(m_obj, "TM_SR_ND_AR", (PyObject*)&TM_SR_ND_AR_Type);
+  
   return m_obj;
 }
diff --git a/developer/authored/TM_module.cpython-311-x86_64-linux-gnu.so b/developer/authored/TM_module.cpython-311-x86_64-linux-gnu.so
deleted file mode 100755 (executable)
index a19ec17..0000000
Binary files a/developer/authored/TM_module.cpython-311-x86_64-linux-gnu.so and /dev/null differ
diff --git a/developer/authored/build/lib.linux-x86_64-cpython-311/TM_module.cpython-311-x86_64-linux-gnu.so b/developer/authored/build/lib.linux-x86_64-cpython-311/TM_module.cpython-311-x86_64-linux-gnu.so
deleted file mode 100755 (executable)
index a19ec17..0000000
Binary files a/developer/authored/build/lib.linux-x86_64-cpython-311/TM_module.cpython-311-x86_64-linux-gnu.so and /dev/null differ
diff --git a/developer/authored/build/temp.linux-x86_64-cpython-311/TM_module.o b/developer/authored/build/temp.linux-x86_64-cpython-311/TM_module.o
deleted file mode 100644 (file)
index 86ce839..0000000
Binary files a/developer/authored/build/temp.linux-x86_64-cpython-311/TM_module.o and /dev/null differ
diff --git a/developer/authored/example_features.py b/developer/authored/example_features.py
new file mode 100755 (executable)
index 0000000..7233dc6
--- /dev/null
@@ -0,0 +1,59 @@
+#!/usr/bin/env python3
+from TM import TM, TMS, Features
+
+def test_base_machine():
+  print("\n--- Test 1: Base Machine (TM_SR_ND) ---")
+  data = [10, 20, 30]
+  
+  # No features requested
+  t = TMS(data) 
+  print(f"Created Base Machine: {t.len()} items.")
+  
+  # 1. Step & Read (Should work)
+  t.s()
+  print(f"Step -> Val: {t.r()} (Expected: 20)")
+  
+  # 2. Try Append (Should FAIL)
+  print("Attempting aR()...")
+  try:
+    t.aR(99)
+    print("!! FAIL: aR() succeeded on Base Machine")
+  except AttributeError:
+    print(">> SUCCESS: Caught expected AttributeError (Feature missing)")
+
+def test_ar_machine():
+  print("\n--- Test 2: Feature Machine (TM_SR_ND_AR) ---")
+  data = [10, 20, 30]
+  
+  # Feature requested
+  t = TMS(data, features=[Features.APPEND_RIGHT])
+  print(f"Created Feature Machine: {t.len()} items.")
+  
+  # 1. Step
+  t.s()
+  
+  # 2. Append (Should WORK)
+  print("Attempting aR(99)...")
+  try:
+    t.aR(99)
+    print(f">> SUCCESS: aR() completed. New Len: {t.len()}")
+    
+    # Verify data
+    print(f"Tape content (from head): {t.rn(5)}")
+  except AttributeError as e:
+    print(f"!! FAIL: {e}")
+
+  # 3. Entanglement Check
+  print("Entangling...")
+  t2 = t.e()
+  print("Attempting aR(100) on Clone...")
+  try:
+    t2.aR(100)
+    print(f">> SUCCESS: Clone inherited aR feature. Len: {t2.len()}")
+  except AttributeError:
+    print("!! FAIL: Clone lost the feature!")
+
+if __name__ == "__main__":
+  test_base_machine()
+  test_ar_machine()
+
diff --git a/developer/authored/example_queries.py b/developer/authored/example_queries.py
new file mode 100755 (executable)
index 0000000..3801579
--- /dev/null
@@ -0,0 +1,88 @@
+#!/usr/bin/env python3
+from SymbolSpace import SymbolSpace
+from Binder import Binder
+from DiscreteFunction import DiscreteFunction
+from Namespace import DifferentiatedSymbol ,OrderedNamespace
+
+def example_queries():
+  print("--- Epimetheus Architecture Example ---")
+
+  # 1. System Initialization
+  binder = Binder()
+  graph = DiscreteFunction()
+
+  # 2. Ontology Definition (The Factories)
+  Frame = DifferentiatedSymbol("FrameMaterial")
+  Price = OrderedNamespace("Price")
+
+  # 3. Data Ingestion (Transient Objects)
+  data_source = [
+    ("Bike_A" ,"Carbon" ,3500),
+    ("Bike_B" ,"Steel"  ,800),
+    ("Bike_C" ,"Alum"   ,1200),
+    ("Bike_D" ,"Carbon" ,1500),
+  ]
+
+  print(f"Ingesting {len(data_source)} items...")
+  
+  # Keep references to prevent GC during ingestion for this example
+  start_objects = [] 
+
+  for label, material, cost in data_source:
+    # A. Create the Python Object
+    obj = type("Bike", (), {"label": label})()
+    start_objects.append(obj)
+    
+    # B. Bind: Object -> Symbol
+    sym_bike = binder.get_symbol(obj)
+    
+    # C. Describe: Symbol -> Properties
+    graph.set(sym_bike ,Frame(material))
+    graph.set(sym_bike ,Price(cost))
+
+  # ---------------------------------------------------------
+  # Example 1: Exact Query ("Find Carbon Frames")
+  # ---------------------------------------------------------
+  print("\n[Example 1] Exact Match: Frame('Carbon')")
+  
+  # We ask the Factory for the symbol representing 'Carbon'
+  sym_carbon = Frame("Carbon")
+  
+  # We ask the Graph for entities with that symbol
+  results = graph.find(sym_carbon)
+  print(f" -> Found {len(results)} bikes with Carbon frames.")
+
+  # ---------------------------------------------------------
+  # Example 2: Range Query ("Find Price 1000..2000")
+  # ---------------------------------------------------------
+  print("\n[Example 2] Range Match: Price(1000..2000)")
+
+  # Step A: Ask Namespace for symbols in range
+  # The OrderedNamespace uses bisect to find symbols efficiently
+  price_symbols = Price.find_range(1000 ,2000)
+  print(f" -> Namespace identified {len(price_symbols)} relevant price points.")
+
+  # Step B: Ask Graph for objects having ANY of those symbols
+  matches = set()
+  for p_sym in price_symbols:
+    found = graph.find(p_sym)
+    matches.update(found)
+
+  print(f" -> Graph resolved {len(matches)} bikes in price range.")
+
+  # ---------------------------------------------------------
+  # Example 3: Hierarchy Query ("Find Priced Things")
+  # ---------------------------------------------------------
+  print("\n[Example 3] Hierarchy Match: Has Price")
+  
+  # We query the Root Symbol of the Price namespace.
+  # This works because the Graph automatically 'posts' up to the parent.
+  # FIXED: Changed .root to .root_symbol to match Namespace.py
+  all_priced = graph.find(Price.root_symbol)
+  print(f" -> Found {len(all_priced)} objects that have a price.")
+
+def CLI():
+  example_queries()
+
+if __name__ == "__main__":
+  CLI()
diff --git a/developer/authored_2026-02-09.tar b/developer/authored_2026-02-09.tar
new file mode 100644 (file)
index 0000000..91a53ef
Binary files /dev/null and b/developer/authored_2026-02-09.tar differ
index abeead4..ebe8d5b 100644 (file)
       </p>
 
       <p>
-        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 <RT-term>second order</RT-term> tape machine.
+        If an operation were permitted to remove the last remaining cell of a tape, 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 <RT-term>second order</RT-term> tape machine.
       </p>
 
       <p>
-        Tape machines that share a tape are said to be <RT-neologism>entangled</RT-neologism>. 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 <em>a tape machine head is always on a valid cell</em>. We leave the data hazard management to the programmer; however, we provide specific features for preventing control hazards.
+        Tape machines that share a tape are said to be <RT-neologism>entangled</RT-neologism>. There will be both data and structure hazards among entangled machines. Data hazards have to do with the misuse of locks or other mistakes in cooperation between machines that cause a machine to read the wrong data. Data hazards can lead to incorrectly computed results, but they will not break the machines. In contrast, structure hazards lead to broken machines. The principle structure hazard is that of one entangled TM deleting a cell that another TM has its head on. That orphans the head of that other machine and leads to a violation of the <em>a tape machine head is always on a valid cell</em> invariant. 
       </p>
 
       <p>
-        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 <RT-term>non-destructive</RT-term>. 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 <RT-neologism>solitary machine</RT-neologism> 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 <RT-neologism>entanglement accounting</RT-neologism>. 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.
+        We leave the data hazard management to the programmer; however, we provide specific features for avoiding  structure hazards.
+        These are selected at TM 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 <RT-term>non-destructive</RT-term>. 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 <RT-neologism>solitary machine</RT-neologism> 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 <RT-neologism>entanglement accounting</RT-neologism>. 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. An alternative is to use a compiler that only produces correct code in the first place.  This is the approach of <RT-term>correct by construction</RT-term>.
       </p>
 
       <h1>Command language</h1>
 
       <p>
-        The command language is not used directly. It describes the letter patterns used to form TM interface function names.
-        This approach began with LISP, and its extension is described in the paper "Towards a Better Understanding of CAR, CDR, CADR and the Others".
+        The command language is not used directly, rather it describes the letter patterns used to form TM interface function names.
+        Such an approach can be found in LISP language list access function names, and its extension is described in the paper "Towards a Better Understanding of CAR, CDR, CADR and the Others".
       </p>
 
       <p>
-        The actual function names found on TM interfaces are listed in later sections of this guide. Reading the source code can also help.
-        Later we can add a compiler for creating new functions based on this language. Such a compiler would be a function that adds functions to a TM interface.
+        The actual function names found on TM interfaces are listed in later sections of this guide. The ultimate authority is the source code itself. Later we can add a compiler for creating new functions based on this language. Such a compiler would be a function that adds functions to a TM interface.
       </p>
 
       <p>
       <p>
         The query command, <RT-code>q</RT-code>, reports head state.
         With no <RT-code>arg</RT-code> descriptor it returns a boolean value.
-        With an <RT-code>R</RT-code> <RT-code>arg</RT-code> descriptor it returns true iff the head is on the rightmost cell.
+        With an <RT-code>R</RT-code> <RT-code>arg</RT-code> descriptor it returns true iff the head is on the rightmost cell. With an <RT-code>I</RT-code> <RT-code>arg</RT-code> descriptor it returns an index.
       </p>
 
       <p>
       <h3>Examples</h3>
 
       <p>
-        The example descriptions state effects in the base view.
-        Effects in the mirror view match the same command without the <RT-code>L</RT-code> prefix.
+        In these examples, the comments discuss what happens on the base machine. Effects in the mirror view match the same command without the <RT-code>L</RT-code> prefix.
       </p>
 
       <h4>Relative head movement</h4>
         <RT-code>LsI(k)</RT-code> and <RT-code>sI(k)</RT-code> cue the head to the same indexed cell.
         <RT-code>L</RT-code> flips direction and the meaning of <RT-code>R</RT-code>, not the index to cell correspondence.
         Thus <RT-code>LsI(0)</RT-code> cues the cell with index zero, which is rightmost in the mirror view and leftmost in the base view.
-        For that reason there is no primitive family for <RT-code>LsI</RT-code> distinct from <RT-code>sI</RT-code>.
       </p>
 
       <h4>Absolute head movement</h4>
       </RT-code>
 
       <p>
-        In <RT-code>q</RT-code>, the <RT-code>I</RT-code> <RT-code>arg</RT-code> descriptor selects an index valued result.
+        The <RT-code>I</RT-code> <RT-code>arg</RT-code> descriptor causes <RT-code>q</RT-code> to return an index.
         By default <RT-code>q</RT-code> returns a boolean value.
         In other commands, an <RT-code>I</RT-code> <RT-code>arg</RT-code> descriptor indicates that an index argument is supplied.
       </p>
       <h2>Query primitives</h2>
 
       <p>
-        Query primitives expose the <RT-code>q</RT-code> command.
+        Query primitives are built from the <RT-code>q</RT-code> command.
         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.
       </p>
 
       <p>
         If indexing is enabled, the API also exposes index query primitives.
-        These correspond to the <RT-code>A</RT-code> arg descriptor in the command language.
-        (If you later rename <RT-code>A</RT-code> to <RT-code>I</RT-code>, this section becomes <RT-code>qI</RT-code> and <RT-code>qIR</RT-code> accordingly.)
+        These correspond to the <RT-code>I</RT-code> arg descriptor in the command language.
       </p>
 
       <ul>
-        <li><RT-code>qA()</RT-code> returns the current head index. (Command form: <RT-code>qA</RT-code>.)</li>
-        <li><RT-code>qAR()</RT-code> returns the index of the selected view rightmost cell. (Command form: <RT-code>qAR</RT-code>.)</li>
+        <li><RT-code>qI()</RT-code> returns the current head index. (Command form: <RT-code>qI</RT-code>.)</li>
+        <li><RT-code>qIR()</RT-code> returns the index of the selected view rightmost cell. (Command form: <RT-code>qIR</RT-code>.)</li>
       </ul>
 
       <p>
         Mirror view query forms follow the same rule in the command language.
-        For example, <RT-code>LqR</RT-code> tests the leftmost of the underlying tape, and <RT-code>LqAR</RT-code> returns its index, typically zero.
-        In the API, that effect is obtained either by left primitives (for <RT-code>LqR</RT-code> this is <RT-code>lsqR()</RT-code> 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.
+        For example, <RT-code>LqR</RT-code> tests the leftmost of the underlying tape, and <RT-code>LqIR</RT-code> returns its index, typically zero.
       </p>
 
       <h2>Entanglement primitives</h2>
 
       <p>
         Entanglement primitives implement the <RT-code>e</RT-code> command.
-        The entangled machine shares the tape with the original and starts on the same cell.
+        The entangled machine shares the tape with the original machine and and initially have their head on the same cell.
         In entanglement accounting configurations, entangled machines also share the group catalog used by guard predicates.
       </p>
 
       </ol>
 
       <p>
-        In order to maintain these properties, a TM uses inclusive bounds for intervals.
-        An interval is marked by placing a head on the leftmost cell of the interval, and placing an entangled head on the rightmost cell of the interval.
+        In order to maintain these properties, a TM uses inclusive bounds for intervals, including intervals of cells, and intervals of indexes.
       </p>
 
       <h2>Contract with the programmer</h2>
       </p>
 
       <ol>
-        <li>When there is a right bound, the caller guarantees they will never command the machine to step beyond the rightmost cell.</li>
-        <li>When there is a left bound, the caller guarantees they will never command the machine to step left of the leftmost cell.</li>
+        <li>When there is a right bound, the caller guarantees that he will never command the machine to step beyond the rightmost cell.</li>
+        <li>When there is a left bound, the caller guarantees that he will never command the machine to step left of the leftmost cell.</li>
       </ol>
 
       <p>