From: Thomas Walker Lynch Date: Tue, 3 Feb 2026 14:44:35 +0000 (+0000) Subject: TM moved to C X-Git-Url: https://git.reasoningtechnology.com/%5B%5E?a=commitdiff_plain;h=fdeeb913c94205eb5cbe08aa46680d1f787c58df;p=Epimetheus%2F.git TM moved to C --- diff --git a/developer/authored/RT_code_format_notes.txt b/developer/authored/RT_code_format_notes.txt new file mode 100644 index 0000000..a613f61 --- /dev/null +++ b/developer/authored/RT_code_format_notes.txt @@ -0,0 +1,8 @@ + +**RT Code Format Enforcement:** +1. **Format:** Pre-space commas `(a ,b)`. 2-space indent. +2. **Enclosures:** Space padding ONLY for nested/multi-level enclosures (e.g., `if( (a) )` or `if( func() )`, but `if( a )`). +3. **Naming:** `PascalCase` for Types/Modules. `snake_case` for Functions/Vars. +4. **Acronyms:** MUST be capitalized in `snake_case` (e.g., `TM_module`, `JSON_parser`, `CLI_func`). +5. **Plurals:** Forbidden in identifiers. Use container suffixes (e.g., `item_list`, `arg_tuple`, `peer_set`). + diff --git a/developer/authored/TM.py b/developer/authored/TM.py new file mode 100755 index 0000000..3995622 --- /dev/null +++ b/developer/authored/TM.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 +import sys +from enum import Enum ,auto + +try: + import TM_module +except ImportError: + print("Error: Import failed. Run 'python3 setup.py build_ext --inplace'") + sys.exit(1) + +# ========================================== +# 1. Enums +# ========================================== + +LM = "LM" +RM = "RM" + +class Status(Enum): + ABANDONED = auto() + ACTIVE = auto() + EMPTY = auto() + +class Topology(Enum): + CIRCLE = auto() + LINEAR_RIGHT = auto() + LINEAR_OPEN = auto() + NULL = auto() + SEGMENT = auto() + +# ========================================== +# 2. The Machine (Direct Alias) +# ========================================== + +# The Safety Logic is now 100% in C. +# We just alias the type. +TM = TM_module.FastTM + +# ========================================== +# 3. Status Wrapper +# ========================================== + +class TM2: + def __init__(self ,data_obj=None): + if data_obj: + self.tm = TM(data_obj) + self._stat = Status.ACTIVE + else: + self.tm = None + self._stat = Status.EMPTY + + 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 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 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 CLI(): + print("--- TM Full C-Entanglement Verification ---") + + # 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() + diff --git a/developer/authored/TM_module.c b/developer/authored/TM_module.c new file mode 100644 index 0000000..d72789f --- /dev/null +++ b/developer/authored/TM_module.c @@ -0,0 +1,338 @@ +/* + TM_module.c + CPython Extension: Direct List Access + Entanglement Safety + RT Code Format Compliant +*/ + +#define PY_SSIZE_T_CLEAN +#include +#include "structmember.h" + +/* ========================================================= */ +/* TYPE DEFINITION */ +/* ========================================================= */ + +typedef struct { + PyObject_HEAD + PyObject* tape_obj; /* The Python List (Shared) */ + PyObject* peer_list; /* List of WeakRefs (Shared) */ + Py_ssize_t head; /* Raw Instruction Pointer */ +} FastTM; + +/* Forward Declaration */ +static PyObject* FastTM_address(FastTM* self); + +static void FastTM_dealloc(FastTM* 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){ + 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); + if( !weak_ref ) return -1; + + /* Add to list */ + 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; + + 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 */ +/* ========================================================= */ + +/* + 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; +} + +/* ========================================================= */ +/* METHODS */ +/* ========================================================= */ + +/* --- Read --- */ +static PyObject* FastTM_r(FastTM* self){ + PyObject* item_obj = PyList_GetItem(self->tape_obj ,self->head); + if( !item_obj ) return NULL; + Py_INCREF(item_obj); + return item_obj; +} + +static PyObject* FastTM_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); +} + +/* --- Write --- */ +static PyObject* FastTM_w(FastTM* self ,PyObject* val_obj){ + Py_INCREF(val_obj); + 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){ + PyObject* val_list; + 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; + Py_RETURN_NONE; +} + +/* --- Step --- */ +static PyObject* FastTM_s(FastTM* self){ + self->head++; + Py_RETURN_NONE; +} + +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; + Py_RETURN_NONE; +} + +static PyObject* FastTM_ls(FastTM* self){ + self->head--; + Py_RETURN_NONE; +} + +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; +} + +/* --- Allocate --- */ +static PyObject* FastTM_aL(FastTM* self ,PyObject* val_obj){ + /* Insert Left: Does this shift heads? + For 'Address Stability', inserting at 0 shifts data indices up. + Heads pointing to index I will now point to OLD(I-1). + To stay on the SAME data, we must increment head. + */ + if( PyList_Insert(self->tape_obj ,0 ,val_obj) < 0 ) return NULL; + + /* We must update OUR head. What about PEERS? + True entanglement requires updating ALL peers if indexes shift. + But keeping it simple: We update self. Peers might drift. + (Addressing drift is complex without Double Linked Nodes). + */ + self->head++; + Py_RETURN_NONE; +} + +static PyObject* FastTM_aR(FastTM* self ,PyObject* val_obj){ + if( PyList_Append(self->tape_obj ,val_obj) < 0 ) return NULL; + Py_RETURN_NONE; +} + +/* --- 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; +} + +static PyObject* FastTM_dn(FastTM* self ,PyObject* arg_tuple){ + Py_ssize_t n_val; + if( !PyArg_ParseTuple(arg_tuple ,"n" ,&n_val) ) return NULL; + + 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; +} + +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; +} + +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; +} + +/* --- Meta --- */ +static PyObject* FastTM_e(FastTM* self){ + /* Create new instance using 'self' as template (Clone Constructor) */ + 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_address(FastTM* self){ + return PyLong_FromSsize_t(self->head); +} + +static PyObject* FastTM_len(FastTM* self){ + return PyLong_FromSsize_t(PyList_Size(self->tape_obj)); +} + +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_leftmost(FastTM* self){ + if( self->head <= 0 ) Py_RETURN_TRUE; + Py_RETURN_FALSE; +} + +/* ========================================================= */ +/* REGISTRATION */ +/* ========================================================= */ + +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 +}; + +static PyModuleDef TM_module = { + PyModuleDef_HEAD_INIT + ,"TM_module" + ,"Fast TM Extension" + ,-1 + ,NULL +}; + +PyMODINIT_FUNC PyInit_TM_module(void){ + PyObject* m_obj; + if( PyType_Ready(&FastTMType) < 0 ) return NULL; + + m_obj = PyModule_Create(&TM_module); + if( !m_obj ) return NULL; + + Py_INCREF(&FastTMType); + PyModule_AddObject(m_obj ,"FastTM" ,(PyObject*)&FastTMType); + 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 new file mode 100755 index 0000000..aa2b237 Binary files /dev/null and b/developer/authored/TM_module.cpython-311-x86_64-linux-gnu.so differ diff --git a/developer/authored/TapeMachine.py b/developer/authored/TapeMachine.py deleted file mode 100644 index 187b283..0000000 --- a/developer/authored/TapeMachine.py +++ /dev/null @@ -1,165 +0,0 @@ -#!/usr/bin/env python3 -import copy - -class TapeMachine: - """ - TTCA Tape Machine Implementation. - Adapts List, Map, and Set to a common Tape Interface. - """ - def __init__(self, tape_ref, path=None, point=0, iterator=None): - self.tape = tape_ref # The 'Memory' (Shared) - self.path = path or [] # The 'Stack' (Hierarchy context) - - # 'point' is the Address. - # For Lists: Integer Index - # For Maps: Key (Symbol) - # For Sets: The Item itself - self.point = point - - # For Maps/Sets, we need an iterator to support 'Step' (s) - self._iter = iterator - - # --- (e) Entangle --- - def e(self): - """ - Entangled Copy. - Returns a new head sharing the same tape memory. - """ - # We must clone the iterator state if possible, - # though Python iterators are hard to clone. - # We usually restart iteration or assume random access. - return TapeMachine(self.tape, self.path, self.point) - - # --- (r) Read --- - def r(self): - """Reads the cell under the head.""" - container = self._resolve_container() - - if isinstance(container, list): - if 0 <= self.point < len(container): - return container[self.point] - - elif isinstance(container, dict): - return container.get(self.point, None) - - elif isinstance(container, set): - # In a set, if we are 'at' a point, the value IS the point. - # But we must verify it still exists. - return self.point if self.point in container else None - - return None - - # --- (w) Write --- - def w(self, value): - """Writes to the cell under the head.""" - container = self._resolve_container() - - if isinstance(container, list): - container[self.point] = value - - elif isinstance(container, dict): - container[self.point] = value - - elif isinstance(container, set): - raise TypeError("Cannot 'Write' to a Set cell. Use 'd' (Delete) and 'a' (Add).") - - # --- (s) Step --- - def s(self, direction=1): - """ - Move relative to current position. - Direction +1 = Next, -1 = Previous. - """ - container = self._resolve_container() - - if isinstance(container, list): - self.point += direction - - elif isinstance(container, (dict, set)): - # Maps/Sets require iteration to step. - # This is expensive (O(N)) unless we maintain an active iterator. - # Simplified Logic: - try: - # In a real engine, we'd cache the list of keys - keys = list(container.keys()) if isinstance(container, dict) else list(container) - - # Find current index - try: - current_idx = keys.index(self.point) - next_idx = current_idx + direction - if 0 <= next_idx < len(keys): - self.point = keys[next_idx] - except ValueError: - # Current point no longer in set/map, reset to start - if keys: self.point = keys[0] - except: - pass - return self - - # --- (m) Move --- - def m(self, address): - """ - Absolute jump to an address. - List: index (int), Map: key (symbol), Set: member (symbol). - """ - self.point = address - return self - - # --- (a) Allocate / Add --- - def a(self, value, key=None): - """ - Appends or Inserts. - List: Append value. - Map: Insert key:value. - Set: Add value. - """ - container = self._resolve_container() - - if isinstance(container, list): - container.append(value) - - elif isinstance(container, dict): - if key is None: raise ValueError("Map allocation requires key") - container[key] = value - - elif isinstance(container, set): - container.add(value) - - # --- Hierarchy Navigation (Enter/Exit) --- - def enter(self): - """Descends into the current cell.""" - current_val = self.r() - - # Valid container? - if isinstance(current_val, (list, dict, set)): - # Push context - new_path = self.path + [(self._resolve_container(), self.point)] - - # Determine starting point for new container - start_point = 0 - if isinstance(current_val, (dict, set)) and len(current_val) > 0: - # Start at the first key/member - start_point = next(iter(current_val)) - - return TapeMachine(self.tape, new_path, start_point) - return None - - def exit(self): - """Ascends to parent.""" - if not self.path: return None - - # Pop context - parent_container, parent_point = self.path[-1] - new_path = self.path[:-1] - - return TapeMachine(self.tape, new_path, parent_point) - - # --- Internal --- - def _resolve_container(self): - """Drills down the path stack to find current container.""" - curr = self.tape - for container, index in self.path: - if isinstance(container, list): curr = container[index] - elif isinstance(container, dict): curr = container[index] - # Set traversal in path stack implies we 'entered' a member - # (which must be a container itself) - return curr diff --git a/developer/authored/build.sh b/developer/authored/build.sh new file mode 100755 index 0000000..7ccef3c --- /dev/null +++ b/developer/authored/build.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Compile with FACE and IMPL defined to generate the full library +python3 setup.py build_ext --inplace + 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 new file mode 100755 index 0000000..aa2b237 Binary files /dev/null and b/developer/authored/build/lib.linux-x86_64-cpython-311/TM_module.cpython-311-x86_64-linux-gnu.so 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 new file mode 100644 index 0000000..3b0d312 Binary files /dev/null and b/developer/authored/build/temp.linux-x86_64-cpython-311/TM_module.o differ diff --git a/developer/authored/install.sh b/developer/authored/install.sh new file mode 100644 index 0000000..86cec75 --- /dev/null +++ b/developer/authored/install.sh @@ -0,0 +1,2 @@ +apt-get update +apt-get install python3-dev diff --git a/developer/authored/setup.py b/developer/authored/setup.py new file mode 100644 index 0000000..1beccd2 --- /dev/null +++ b/developer/authored/setup.py @@ -0,0 +1,13 @@ +from setuptools import setup ,Extension + +module_obj = Extension( + "TM_module" + ,sources=["TM_module.c"] +) + +setup( + name="TM_module" + ,version="1.0" + ,description="Fast Tape Machine C Extension" + ,ext_modules=[module_obj] +) diff --git a/developer/authored/tape_machine.py b/developer/authored/tape_machine.py deleted file mode 100755 index d7cb1fe..0000000 --- a/developer/authored/tape_machine.py +++ /dev/null @@ -1,276 +0,0 @@ -#!/usr/bin/env python3 -import abc -from enum import Enum ,auto - -# ========================================== -# 1. Enums and Constants -# ========================================== - -class Topology(Enum): - NULL = auto() - ,SEGMENT - ,LINEAR_RIGHT - ,CIRCLE - ,LOOP_AND_TAIL - -class Status(Enum): - ABANDONED = auto() - ,EMPTY - ,ACTIVE - -# ========================================== -# 2. Handler Registry (The Method Tape) -# ========================================== - -def handler_hard_error(tm ,*args): - """The default 'Mean' behavior: Hard Stop.""" - raise RuntimeError(f"Operation not permitted on {type(tm).__name__}") - -def handler_ignore(tm ,*args): - """The 'Black Hole' behavior: Do nothing, return None.""" - return None - -def handler_write_list(tm ,val): - """Standard Write for Python List backing.""" - tm.tape[tm.head] = val - -def handler_delete_right_neighbor(tm): - """ - Primitive 'd' command: Deletes the RIGHT neighbor. - Appropriate for Singly Linked Tapes where looking back is hard. - """ - if tm.head + 1 < len(tm.tape): - del tm.tape[tm.head + 1] - else: - # Default behavior when no neighbor exists - pass - -# ========================================== -# 3. Interfaces and Machines -# ========================================== - -class TMInterface(abc.ABC): - """ - The shared interface for First and Second Order machines. - """ - @abc.abstractmethod - def r(self): pass - - @abc.abstractmethod - def w(self ,v): pass - - @abc.abstractmethod - def s(self ,n=1): pass - - @abc.abstractmethod - def d(self): pass - - @abc.abstractmethod - def e(self): pass - - @abc.abstractmethod - def rightmost(self): pass - -class NullTM(TMInterface): - """ - The 'Mean Machine'. - Represents a machine with NO tape. - All operations throw hard errors by default. - """ - def __init__(self): - self._write_handler = handler_hard_error - self._delete_handler = handler_hard_error - self._read_handler = handler_hard_error - self._step_handler = handler_hard_error - - def r(self): return self._read_handler(self) - def w(self ,v): return self._write_handler(self ,v) - def s(self ,n=1): return self._step_handler(self ,n) - def d(self): return self._delete_handler(self) - - def topology(self): return Topology.NULL - def status(self): return Status.EMPTY - - def rightmost(self): return self._read_handler(self) - def e(self): return self._read_handler(self) - -class VanillaTM(TMInterface): - """ - The Plain Vanilla Finite Tape Machine. - Topology: SEGMENT (Finite List). - """ - def __init__(self ,data): - self.tape = data - self.head = 0 - - # Registered Handlers (The Method Tape) - self._write_handler = handler_write_list - self._delete_handler = handler_delete_right_neighbor - - def r(self): - # Critical Loop Speed: No error checking. - return self.tape[self.head] - - def w(self ,v): - return self._write_handler(self ,v) - - def d(self): - return self._delete_handler(self) - - def s(self ,n=1): - # Standard Segment Step - self.head += n - return self - - def e(self): - # Entangle: Create new machine, same tape, same handlers - new_tm = VanillaTM(self.tape) - new_tm.head = self.head - new_tm._write_handler = self._write_handler - new_tm._delete_handler = self._delete_handler - return new_tm - - def rightmost(self): - return self.head >= len(self.tape) - 1 - - def topology(self): - return Topology.SEGMENT - - def set_readonly(self): - """Configuration Helper: Swaps the write handler.""" - self._write_handler = handler_hard_error - -class StatusTM(TMInterface): - """ - Second Order Machine. - Wraps a First Order Machine to handle Lifecycle (Empty/Active). - """ - def __init__(self ,data=None): - if data and len(data) > 0: - self.tm = VanillaTM(data) - self._stat = Status.ACTIVE - else: - self.tm = NullTM() - self._stat = Status.EMPTY - - def empty(self): - return self._stat == Status.EMPTY - - # --- Delegation --- - - def r(self): return self.tm.r() - def w(self ,v): return self.tm.w(v) - def s(self ,n=1): return self.tm.s(n) - def d(self): return self.tm.d() - - def e(self): - if self.empty(): return StatusTM(None) - - # Create new wrapper around entangled inner - new_wrapper = StatusTM.__new__(StatusTM) - new_wrapper.tm = self.tm.e() - new_wrapper._stat = Status.ACTIVE - return new_wrapper - - def rightmost(self): - if self.empty(): return True - return self.tm.rightmost() - -# ========================================== -# 4. Compiler -# ========================================== - -def compile_compound(tm ,command_str): - """ - Compiles a string like 'wsr' or 's-d' into a callable function. - """ - steps = [] - i = 0 - while i < len(command_str): - char = command_str[i] - - if char == 'w': - steps.append(lambda t ,v=None: t.w(v)) - elif char == 'r': - steps.append(lambda t: t.r()) - elif char == 'd': - steps.append(lambda t: t.d()) - elif char == 's': - steps.append(lambda t: t.s(1)) - elif char == '-': - # Lookahead for modifier - if i + 1 < len(command_str): - next_char = command_str[i+1] - if next_char == 's': - steps.append(lambda t: t.s(-1)) - i += 1 - i += 1 - - def compiled_func(value_for_write=None): - res = None - for step in steps: - try: - res = step(tm ,value_for_write) - except TypeError: - res = step(tm) - return res - - return compiled_func - -# ========================================== -# 5. CLI / Verification -# ========================================== - -def CLI(): - print("--- TTCA Tape Machine Verification ---") - - # 1. Setup Data - data = [ - 'A' - ,'B' - ,'C' - ] - stm = StatusTM(data) - - # 2. Config: Make it Read-Only (Runtime Handler Swap) - if not stm.empty(): - stm.tm.set_readonly() - - # 3. The Loop (First-Rest Pattern) - if not stm.empty(): - # First - print(f"First: {stm.r()}") - - # Try Illegal Write - try: - stm.w('Z') - except RuntimeError as e: - print(f"Caught Expected Error: {e}") - - # Rest - while not stm.rightmost(): - stm.s() - print(f"Rest: {stm.r()}") - - # 4. The Null Case - empty_stm = StatusTM([]) - if not empty_stm.empty(): - pass - else: - print("Empty machine handled correctly (skipped).") - - # 5. Delete (The 'd' command) - d_list = [ - '1' - ,'2' - ,'3' - ] - dtm = StatusTM(d_list) - if not dtm.empty(): - print(f"Before Delete: {d_list}") - dtm.d() - print(f"After Delete: {d_list}") - -if __name__ == "__main__": - CLI() - diff --git a/developer/authored/tm.py b/developer/authored/tm.py deleted file mode 100644 index a798a51..0000000 --- a/developer/authored/tm.py +++ /dev/null @@ -1,301 +0,0 @@ -#!/usr/bin/env python3 -import abc -from enum import Enum ,auto - -# ========================================== -# 1. Enums and Constants -# ========================================== - -class Topology(Enum): - NULL = auto() - SEGMENT = auto() - LINEAR_RIGHT = auto() - CIRCLE = auto() - LOOP_AND_TAIL = auto() - -class Status(Enum): - ABANDONED = auto() - EMPTY = auto() - ACTIVE = auto() - -# ========================================== -# 2. Handler Registry (The Method Tape) -# ========================================== - -def handler_hard_error(tm ,*args): - """The default 'Mean' behavior: Hard Stop.""" - raise RuntimeError(f"Operation not permitted on {type(tm).__name__}") - -def handler_ignore(tm ,*args): - """The 'Black Hole' behavior: Do nothing.""" - return None - -def handler_write_list(tm ,val): - """Standard Write for List backing.""" - # Entanglement Accounting Check - if tm.tape_ref.count > 1: - raise RuntimeError("Cannot Write: Tape is Entangled (Shared)") - tm.tape_ref.data[tm.head] = val - -def handler_delete_right_neighbor_list(tm): - """Delete right neighbor in a list.""" - if tm.tape_ref.count > 1: - raise RuntimeError("Cannot Delete: Tape is Entangled (Shared)") - - # Check neighbor existence - if tm.head + 1 < len(tm.tape_ref.data): - del tm.tape_ref.data[tm.head + 1] - -def handler_write_map(tm ,val): - """Standard Write for Map backing (updates value for current key).""" - if tm.tape_ref.count > 1: - raise RuntimeError("Cannot Write: Tape is Entangled") - - key = tm.address() - tm.tape_ref.data[key] = val - -# ========================================== -# 3. Tape Reference (Entanglement Accounting) -# ========================================== - -class Tape: - """ - Holds the actual data and the entanglement reference count. - """ - def __init__(self ,data): - self.data = data - self.count = 1 # Start with 1 owner - - # For Maps, we might need a stable key view for stepping - self.keys_view = None - if isinstance(data ,dict): - self.keys_view = list(data.keys()) - - def checkout(self): - self.count += 1 - - def checkin(self): - if( self.count > 0 ): - self.count -= 1 - -# ========================================== -# 4. The Machines -# ========================================== - -class TM_Interface(abc.ABC): - @abc.abstractmethod - def r(self): pass - @abc.abstractmethod - def w(self ,v): pass - @abc.abstractmethod - def s(self ,n=1): pass - @abc.abstractmethod - def d(self): pass - @abc.abstractmethod - def e(self): pass - @abc.abstractmethod - def rightmost(self): pass - @abc.abstractmethod - def address(self): pass - @abc.abstractmethod - def dismount(self): pass - -class TM(TM_Interface): - """ - The General Entanglement Accounting Machine. - Specialized for LIST (Sequence) tapes. - """ - def __init__(self ,data): - # If data is already a Tape object (from entanglement), use it. - # Otherwise create new. - if( isinstance(data ,Tape) ): - self.tape_ref = data - else: - self.tape_ref = Tape(data) - - self.head = 0 - - # Registered Handlers - self._write_handler = handler_write_list - self._delete_handler = handler_delete_right_neighbor_list - - def r(self): - return self.tape_ref.data[self.head] - - def w(self ,v): - return self._write_handler(self ,v) - - def d(self): - return self._delete_handler(self) - - def s(self ,n=1): - self.head += n - return self - - def e(self): - # Entangle: Checkout the tape - self.tape_ref.checkout() - - # Create new machine sharing the Tape ref - new_tm = TM(self.tape_ref) - new_tm.head = self.head - - # Copy handlers - new_tm._write_handler = self._write_handler - new_tm._delete_handler = self._delete_handler - return new_tm - - def dismount(self): - self.tape_ref.checkin() - - def rightmost(self): - return self.head >= len(self.tape_ref.data) - 1 - - def address(self): - """For List, address is the integer index.""" - return self.head - - def topology(self): - return Topology.SEGMENT - - -class TM_Map(TM): - """ - Entanglement Accounting Machine specialized for MAPS. - """ - def __init__(self ,data): - super().__init__(data) - self._write_handler = handler_write_map - # Delete on map is complex (removing key affects order), - # disabling default delete for now or need custom handler. - self._delete_handler = handler_hard_error - - def r(self): - # Read Value - key = self.tape_ref.keys_view[self.head] - return self.tape_ref.data[key] - - def address(self): - # Address is the Key - return self.tape_ref.keys_view[self.head] - - def rightmost(self): - return self.head >= len(self.tape_ref.keys_view) - 1 - - def e(self): - self.tape_ref.checkout() - new_tm = TM_Map(self.tape_ref) - new_tm.head = self.head - return new_tm - - -class TM_Null(TM_Interface): - """ - The Mean Machine (No Tape). - """ - def __init__(self): - pass - - def r(self): handler_hard_error(self) - def w(self ,v): handler_hard_error(self) - def s(self ,n=1): handler_hard_error(self) - def d(self): handler_hard_error(self) - def e(self): handler_hard_error(self) - def address(self): handler_hard_error(self) - def dismount(self): pass # No tape to checkin - - def rightmost(self): handler_hard_error(self) - def topology(self): return Topology.NULL - def status(self): return Status.EMPTY - - -class TM2(TM_Interface): - """ - Second Order (Status) Machine. - Wraps a First Order Machine. - """ - def __init__(self ,data=None ,tm_class=TM): - if( data and len(data) > 0 ): - self.tm = tm_class(data) - self._stat = Status.ACTIVE - else: - self.tm = TM_Null() - self._stat = Status.EMPTY - - # Store class for entanglement factories - self._tm_class = tm_class - - def empty(self): - return self._stat == Status.EMPTY - - # --- Delegation --- - - def r(self): return self.tm.r() - def w(self ,v): return self.tm.w(v) - def s(self ,n=1): return self.tm.s(n) - def d(self): return self.tm.d() - def address(self): return self.tm.address() - def dismount(self): self.tm.dismount() - - def e(self): - if( self.empty() ): return TM2(None) - - # Create new wrapper around entangled inner - new_wrapper = TM2.__new__(TM2) - new_wrapper.tm = self.tm.e() - new_wrapper._stat = Status.ACTIVE - new_wrapper._tm_class = self._tm_class - return new_wrapper - - def rightmost(self): - if( self.empty() ): return True - return self.tm.rightmost() - -# ========================================== -# 5. CLI Verification -# ========================================== - -def CLI(): - print("--- TTCA Tape Machine Verification ---") - - # 1. List Machine (TM) - print("\n[Test 1] List Machine (EA)") - data = ['A' ,'B' ,'C'] - tm2 = TM2(data ,TM) - - if( not tm2.empty() ): - # Address check - print(f"Addr {tm2.address()}: {tm2.r()}") - - # Entanglement - tm2_copy = tm2.e() - tm2.s() - print(f"Original Moved -> Addr {tm2.address()}: {tm2.r()}") - print(f"Copy Stayed -> Addr {tm2_copy.address()}: {tm2_copy.r()}") - - # Destructive Check (Should Fail due to 2 owners) - try: - tm2.d() - except RuntimeError as e: - print(f"Caught Expected EA Error: {e}") - - # Dismount copy to allow delete - tm2_copy.dismount() - print("Copy dismounted.") - - # Now delete should work (deletes right neighbor 'C') - tm2.d() - print(f"After Delete: {data}") - - # 2. Map Machine (TM_Map) - print("\n[Test 2] Map Machine") - map_data = {'x': 10 ,'y': 20 ,'z': 30} - tm_map = TM2(map_data ,TM_Map) - - if( not tm_map.empty() ): - print(f"Key {tm_map.address()}: Val {tm_map.r()}") - tm_map.s() - print(f"Key {tm_map.address()}: Val {tm_map.r()}") - -if __name__ == "__main__": - CLI()