From fdeeb913c94205eb5cbe08aa46680d1f787c58df Mon Sep 17 00:00:00 2001 From: Thomas Walker Lynch Date: Tue, 3 Feb 2026 14:44:35 +0000 Subject: [PATCH] TM moved to C --- developer/authored/RT_code_format_notes.txt | 8 + developer/authored/TM.py | 100 ++++++ developer/authored/TM_module.c | 338 ++++++++++++++++++ .../TM_module.cpython-311-x86_64-linux-gnu.so | Bin 0 -> 33280 bytes developer/authored/TapeMachine.py | 165 --------- developer/authored/build.sh | 6 + .../TM_module.cpython-311-x86_64-linux-gnu.so | Bin 0 -> 33280 bytes .../temp.linux-x86_64-cpython-311/TM_module.o | Bin 0 -> 37792 bytes developer/authored/install.sh | 2 + developer/authored/setup.py | 13 + developer/authored/tape_machine.py | 276 -------------- developer/authored/tm.py | 301 ---------------- 12 files changed, 467 insertions(+), 742 deletions(-) create mode 100644 developer/authored/RT_code_format_notes.txt create mode 100755 developer/authored/TM.py create mode 100644 developer/authored/TM_module.c create mode 100755 developer/authored/TM_module.cpython-311-x86_64-linux-gnu.so delete mode 100644 developer/authored/TapeMachine.py create mode 100755 developer/authored/build.sh create mode 100755 developer/authored/build/lib.linux-x86_64-cpython-311/TM_module.cpython-311-x86_64-linux-gnu.so create mode 100644 developer/authored/build/temp.linux-x86_64-cpython-311/TM_module.o create mode 100644 developer/authored/install.sh create mode 100644 developer/authored/setup.py delete mode 100755 developer/authored/tape_machine.py delete mode 100644 developer/authored/tm.py 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 0000000000000000000000000000000000000000..aa2b237b94907cffaea9739dd1470bc8cbb7558d GIT binary patch literal 33280 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 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 0000000000000000000000000000000000000000..aa2b237b94907cffaea9739dd1470bc8cbb7558d GIT binary patch literal 33280 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 literal 0 HcmV?d00001 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() -- 2.20.1