From: Thomas Walker Lynch Date: Sun, 31 May 2026 16:22:19 +0000 (+0000) Subject: pulling Python TM over from Epimetheus X-Git-Url: https://git.reasoningtechnology.com/figure_5.png?a=commitdiff_plain;h=3cbbb727ce28ab772ed712e81862f5e537625c94;p=TM-2026 pulling Python TM over from Epimetheus --- diff --git a/administrator/tool/install_Python b/administrator/tool/install_Python new file mode 100755 index 0000000..8b38cbe --- /dev/null +++ b/administrator/tool/install_Python @@ -0,0 +1,107 @@ +#!/usr/bin/env bash +script_afp=$(realpath "${BASH_SOURCE[0]}") + +# Enforce execution for this administrative tool +if [[ "${BASH_SOURCE[0]}" != "$0" ]]; then + echo "$script_afp:: This script must be executed, not sourced." + return 1 +fi + +# without this bash takes non-matching globs literally +shopt -s nullglob + +# does not presume sharing or world permissions +umask 0077 + +# Ensure required environment variables exist +if [[ -z "$REPO_HOME" || -z "$PROJECT" ]]; then + echo "$script_afp:: REPO_HOME or PROJECT variables are undefined. Please source the setup administrator first." + exit 1 +fi + +echo "Repository Home: $REPO_HOME" +echo "Project Name: $PROJECT" + +# The scratchpad must exist at the top level of the project for scanning clarity +scratchpad="$REPO_HOME"/scratchpad +if [[ ! -d "$scratchpad" ]]; then + echo "$script_afp:: scratchpad directory missing at $scratchpad" + exit 1 +fi + +#-------------------------------------------------------------------------------- +# Python name/version +# + +version=3.12.3 +Python_dn=Python-"$version" +tarf="$Python_dn".tgz + +# Python install directory, sibling to this project +Python_da="$(realpath "$REPO_HOME"/../)"/"$Python_dn" + +#-------------------------------------------------------------------------------- + +# Verify if the requested Python version is already built +if [[ -x "$Python_da/bin/python3" ]]; then + echo "Python $version is already built and installed at $Python_da." +else + # Download only if the archive is absent + wget -nc -P "$scratchpad" https://www.python.org/ftp/python/"$version"/"$tarf" + + # Extract into the scratchpad to prevent source and installation collisions + source_dn="$scratchpad"/Python-src-"$version" + mkdir -p "$source_dn" + tar xzf "$scratchpad"/"$tarf" -C "$source_dn" --strip-components=1 + + # Explicit error reporting prevents silent administrative failures + cd "$source_dn" || { + echo "$script_afp:: Failed to change directory to $source_dn. Extraction likely failed." + exit 1 + } + + # Configure with developer baseline (--enable-shared) required for C extensions + LDFLAGS="-Wl,-rpath=$Python_da/lib" ./configure --prefix="$Python_da" --enable-optimizations --enable-shared + + make -j8 + make install +fi + +# Establish the versioned executable link +link_dir="$REPO_HOME"/shared/linked-project +mkdir -p "$link_dir" +cd "$link_dir" || { + echo "$script_afp:: Failed to navigate to linked-project directory at $link_dir" + exit 1 +} + +if [[ ! -L "$Python_dn" ]]; then + # The depth accurately escapes linked-project, shared, and REPO_HOME + ln -s ../../../"$Python_dn"/ "$Python_dn" + echo "Successfully created symlink for $Python_dn" +else + echo "The symlink for $Python_dn already exists." +fi + +# -------------------------------------------------------------------------------- +# Path & Environment Configuration Plugin +# -------------------------------------------------------------------------------- +path_sh="$REPO_HOME"/shared/tool/PATH.sh +touch "$path_sh" + +# Define the cluster of variables required by the python plugin environment +line_env="export VIRTUAL_ENV=\"\$REPO_HOME/shared/linked-project/$Python_dn\"" +line_home="export PYTHON_HOME=\"\$VIRTUAL_ENV\"" +line_unset="unset PYTHONHOME" +line_path="PATH=\"\$VIRTUAL_ENV/bin:\$PATH\"" + +# Append the variables sequentially if they are missing from the configuration file +for line in "$line_env" "$line_home" "$line_unset" "$line_path"; do + if ! grep -Fq "$line" "$path_sh"; then + echo "$line" >> "$path_sh" + echo "Appended plugin configuration line to PATH.sh." + else + echo "Configuration line already present in PATH.sh." + fi +done + diff --git a/developer/authored/C/.gitkeep b/developer/authored/C/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/developer/authored/ExampleGreet/Greeter.lib.c b/developer/authored/ExampleGreet/Greeter.lib.c deleted file mode 100644 index 1d23879..0000000 --- a/developer/authored/ExampleGreet/Greeter.lib.c +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef ExampleGreet·Greeter·ONCE -#define ExampleGreet·Greeter·ONCE - -#include "Math.lib.c" - -void ExampleGreet·Greeter·hello_loop(int count); - -#ifdef ExampleGreet·Greeter - #include - - void ExampleGreet·Greeter·hello_loop(int count){ - for(int TM = 0; TM < count; ++TM){ - int current_count = ExampleGreet·Math·add(TM ,1); - printf("Hello iteration: %d\n" ,current_count); - } - } - -#endif // ExampleGreet·Greeter - -#endif // ExampleGreet·Greeter·ONCE diff --git a/developer/authored/ExampleGreet/Math.lib.c b/developer/authored/ExampleGreet/Math.lib.c deleted file mode 100644 index 6f1880e..0000000 --- a/developer/authored/ExampleGreet/Math.lib.c +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef ExampleGreet·Math·ONCE -#define ExampleGreet·Math·ONCE - -int ExampleGreet·Math·add(int a ,int b); - -#ifdef ExampleGreet·Math - int ExampleGreet·Math·add(int a ,int b){ - return a + b; - } -#endif // ExampleGreet·Math - -#endif // ExampleGreet·Math·ONCE diff --git a/developer/authored/ExampleGreet/hello.CLI.c b/developer/authored/ExampleGreet/hello.CLI.c deleted file mode 100644 index 684e2a7..0000000 --- a/developer/authored/ExampleGreet/hello.CLI.c +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include - -#include "Math.lib.c" -#include "Greeter.lib.c" - -void CLI(void){ - int base_count = ExampleGreet·Math·add(1 ,2); - printf("Calculated base loop count: %d\n" ,base_count); - ExampleGreet·Greeter·hello_loop(base_count); -} - -int main(int argc ,char **argv){ - (void)argc; - (void)argv; - - CLI(); - - return EXIT_SUCCESS; -} diff --git a/developer/authored/Java/.gitkeep b/developer/authored/Java/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/developer/authored/JavaScript/.gitkeep b/developer/authored/JavaScript/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/developer/authored/Python/TM/TM.py b/developer/authored/Python/TM/TM.py new file mode 100755 index 0000000..693b77b --- /dev/null +++ b/developer/authored/Python/TM/TM.py @@ -0,0 +1,120 @@ +""" +TM.py +Wrapper for the C extension TM_module. +""" +import TM_module + +# ----------------------------------------------------------------------------- +# 1. Arr (Fixed Array) +# ----------------------------------------------------------------------------- +TM_Arr_CR_ND = TM_module.TM_Arr_CR_ND +TM_Arr_CR_SO = TM_module.TM_Arr_CR_SO +TM_Arr_CR_EA = TM_module.TM_Arr_CR_EA + +TM_Arr_CLR_ND = TM_module.TM_Arr_CLR_ND +TM_Arr_CLR_SO = TM_module.TM_Arr_CLR_SO +TM_Arr_CLR_EA = TM_module.TM_Arr_CLR_EA + +# ----------------------------------------------------------------------------- +# 2. ArrV (Variable Array / Vector) +# ----------------------------------------------------------------------------- +TM_ArrV_CR_ND = TM_module.TM_ArrV_CR_ND +TM_ArrV_CR_SO = TM_module.TM_ArrV_CR_SO +TM_ArrV_CR_EA = TM_module.TM_ArrV_CR_EA + +TM_ArrV_CLR_ND = TM_module.TM_ArrV_CLR_ND +TM_ArrV_CLR_SO = TM_module.TM_ArrV_CLR_SO +TM_ArrV_CLR_EA = TM_module.TM_ArrV_CLR_EA + +# ----------------------------------------------------------------------------- +# 3. Gr (Graph Right / Linked List) +# ----------------------------------------------------------------------------- +TM_Gr_CR_ND = TM_module.TM_Gr_CR_ND +TM_Gr_CR_SO = TM_module.TM_Gr_CR_SO +TM_Gr_CR_EA = TM_module.TM_Gr_CR_EA + +TM_Gr_CLR_ND = TM_module.TM_Gr_CLR_ND +TM_Gr_CLR_SO = TM_module.TM_Gr_CLR_SO +TM_Gr_CLR_EA = TM_module.TM_Gr_CLR_EA + +# ----------------------------------------------------------------------------- +# 4. Glr (Graph Left Right / Doubly Linked List) +# ----------------------------------------------------------------------------- +TM_Glr_CR_ND = TM_module.TM_Glr_CR_ND +TM_Glr_CR_SO = TM_module.TM_Glr_CR_SO +TM_Glr_CR_EA = TM_module.TM_Glr_CR_EA + +TM_Glr_CLR_ND = TM_module.TM_Glr_CLR_ND +TM_Glr_CLR_SO = TM_module.TM_Glr_CLR_SO +TM_Glr_CLR_EA = TM_module.TM_Glr_CLR_EA + +# ----------------------------------------------------------------------------- +# 5. Set (Unordered) +# ----------------------------------------------------------------------------- +TM_Set_CR_ND = TM_module.TM_Set_CR_ND +TM_Set_CR_SO = TM_module.TM_Set_CR_SO +TM_Set_CR_EA = TM_module.TM_Set_CR_EA + +TM_Set_CLR_ND = TM_module.TM_Set_CLR_ND +TM_Set_CLR_SO = TM_module.TM_Set_CLR_SO +TM_Set_CLR_EA = TM_module.TM_Set_CLR_EA + +# ----------------------------------------------------------------------------- +# 6. Map (Items) +# ----------------------------------------------------------------------------- +TM_Map_CR_ND = TM_module.TM_Map_CR_ND +TM_Map_CR_SO = TM_module.TM_Map_CR_SO +TM_Map_CR_EA = TM_module.TM_Map_CR_EA + +TM_Map_CLR_ND = TM_module.TM_Map_CLR_ND +TM_Map_CLR_SO = TM_module.TM_Map_CLR_SO +TM_Map_CLR_EA = TM_module.TM_Map_CLR_EA + +# ----------------------------------------------------------------------------- +# 7. MapK (Keys) +# ----------------------------------------------------------------------------- +TM_MapK_CR_ND = TM_module.TM_MapK_CR_ND +TM_MapK_CR_SO = TM_module.TM_MapK_CR_SO +TM_MapK_CR_EA = TM_module.TM_MapK_CR_EA + +TM_MapK_CLR_ND = TM_module.TM_MapK_CLR_ND +TM_MapK_CLR_SO = TM_module.TM_MapK_CLR_SO +TM_MapK_CLR_EA = TM_module.TM_MapK_CLR_EA + +# ----------------------------------------------------------------------------- +# 8. MapV (Values) +# ----------------------------------------------------------------------------- +TM_MapV_CR_ND = TM_module.TM_MapV_CR_ND +TM_MapV_CR_SO = TM_module.TM_MapV_CR_SO +TM_MapV_CR_EA = TM_module.TM_MapV_CR_EA + +TM_MapV_CLR_ND = TM_module.TM_MapV_CLR_ND +TM_MapV_CLR_SO = TM_module.TM_MapV_CLR_SO +TM_MapV_CLR_EA = TM_module.TM_MapV_CLR_EA + +# ----------------------------------------------------------------------------- +# 9. ASCII (String) +# ----------------------------------------------------------------------------- +TM_ASCII_CR_ND = TM_module.TM_ASCII_CR_ND +TM_ASCII_CR_SO = TM_module.TM_ASCII_CR_SO +TM_ASCII_CR_EA = TM_module.TM_ASCII_CR_EA + +TM_ASCII_CLR_ND = TM_module.TM_ASCII_CLR_ND +TM_ASCII_CLR_SO = TM_module.TM_ASCII_CLR_SO +TM_ASCII_CLR_EA = TM_module.TM_ASCII_CLR_EA + +# ----------------------------------------------------------------------------- +# 10. UTF8 (String) +# ----------------------------------------------------------------------------- +TM_UTF8_CR_ND = TM_module.TM_UTF8_CR_ND +TM_UTF8_CR_SO = TM_module.TM_UTF8_CR_SO +TM_UTF8_CR_EA = TM_module.TM_UTF8_CR_EA + +TM_UTF8_CLR_ND = TM_module.TM_UTF8_CLR_ND +TM_UTF8_CLR_SO = TM_module.TM_UTF8_CLR_SO +TM_UTF8_CLR_EA = TM_module.TM_UTF8_CLR_EA + +# ----------------------------------------------------------------------------- +# 11. Abstract +# ----------------------------------------------------------------------------- +TMA_NaturalNumber = TM_module.TMA_NaturalNumber diff --git a/developer/authored/Python/TM/TMS.py b/developer/authored/Python/TM/TMS.py new file mode 100644 index 0000000..c0a18d7 --- /dev/null +++ b/developer/authored/Python/TM/TMS.py @@ -0,0 +1,278 @@ +# TMS.py +# RT format: 2-space indent, PascalCase type names, snake_case identifiers. + +from enum import Enum, auto + +class Status(Enum): + EMPTY_TYPED = auto() # No instance, knows type. + EMPTY_STASHED = auto() # Instance exists (1 zombie cell), logically empty. + PARKED = auto() # Instance exists, head virtual -1. + SINGLETON = auto() # Instance exists, size 1, Head at 0. + ACTIVE = auto() # Instance exists, size > 1 OR Head > 0. + + +class TMS: + """ + Turing Machine with Status (Second Order Machine). + - Projective Parked State (Connects to both ends). + - Late Binding & Zombie Cell optimization. + - Partial Direct Binding for performance. + """ + __slots__ = ( + "tm" + ,"tm_type" + ,"_status" + # VTable Methods + ,"s" + ,"Ls" + ,"r" + ,"w" + ,"d" + ,"append" + ,"cue_leftmost" + ,"cue_rightmost" + ,"park" + ,"dealloc" + ,"is_empty" + ) + + def __init__(self ,tm=None ,tm_type=None): + self.tm = None + self.tm_type = None + + if(tm is not None): + self.tm = tm + self.tm_type = type(tm) + self._change_state(Status.PARKED) + elif(tm_type is not None): + self.tm_type = tm_type + self._change_state(Status.EMPTY_TYPED) + else: + self._change_state(Status.EMPTY_TYPED) + + @property + def status(self): + return self._status + + def _change_state(self ,new_status): + self._status = new_status + + # --------------------------------------------------------- + # STATE: ACTIVE + # --------------------------------------------------------- + if(new_status == Status.ACTIVE): + # Direct Binding (Max Performance) + self.r = self.tm.r + self.w = self.tm.w + self.append = self._active_append + + # Navigation: Wrapped Binding (Guarded) + self.s = self._active_s + self.Ls = self._active_Ls + + self.d = self._active_d + self.cue_leftmost = self._active_cue_leftmost + self.cue_rightmost = self._active_cue_rightmost + self.park = self._active_park + self.dealloc = self._generic_dealloc + self.is_empty = self._return_false + + # --------------------------------------------------------- + # STATE: SINGLETON (Size == 1, Head == 0) + # --------------------------------------------------------- + elif(new_status == Status.SINGLETON): + self.r = self.tm.r + self.w = self.tm.w + + # Navigation + self.s = self._singleton_s # Falls off 0 -> Active + self.Ls = self._singleton_Ls # Falls off 0 -> Parked + + self.d = self._singleton_d # Becomes Stashed + self.append = self._singleton_append + + self.cue_leftmost = self._noop # Already at 0 + self.cue_rightmost = self._noop # Already at 0 (Rightmost=Leftmost) + self.park = self._active_park + self.dealloc = self._generic_dealloc + self.is_empty = self._return_false + + # --------------------------------------------------------- + # STATE: PARKED (Projective, Head Virtual) + # --------------------------------------------------------- + elif(new_status == Status.PARKED): + self.s = self._parked_s # Enter Left + self.Ls = self._parked_Ls # Enter Right (Projective) + + self.r = self._error_io + self.w = self._error_io + self.d = self._parked_d + self.append = self._error_append + + self.cue_leftmost = self._parked_cue_leftmost + self.cue_rightmost = self._parked_cue_rightmost + self.park = self._noop + self.dealloc = self._generic_dealloc + self.is_empty = self._return_false + + # --------------------------------------------------------- + # STATE: EMPTY STASHED + # --------------------------------------------------------- + elif(new_status == Status.EMPTY_STASHED): + self.s = self._error_step + self.Ls = self._error_step + self.r = self._error_io + self.w = self._error_io + self.d = self._error_op + + self.append = self._stashed_append + + self.cue_leftmost = self._noop + self.cue_rightmost = self._noop + self.park = self._noop + self.dealloc = self._generic_dealloc + self.is_empty = self._return_true + + # --------------------------------------------------------- + # STATE: EMPTY TYPED + # --------------------------------------------------------- + elif(new_status == Status.EMPTY_TYPED): + self.s = self._error_step + self.Ls = self._error_step + self.r = self._error_io + self.w = self._error_io + self.d = self._error_op + + self.append = self._typed_append + + self.cue_leftmost = self._noop + self.cue_rightmost = self._noop + self.park = self._noop + self.dealloc = self._noop + self.is_empty = self._return_true + + # --- ACTIVE wrappers --- + + def _active_s(self): + # Guard against stepping off the right end + if(self.tm.qR()): + raise RuntimeError("Cannot step right: At Rightmost cell.") + self.tm.s() + + def _active_Ls(self): + # Guard: If at Leftmost, transition to Parked + if(self.tm.Lq()): + self._change_state(Status.PARKED) + else: + self.tm.Ls() + + def _active_d(self): + self.tm.d() + if(self.tm.is_singleton()): + self._change_state(Status.SINGLETON) + + def _active_append(self ,val): + self.tm.append(val) + + def _active_cue_leftmost(self): + self.tm.cue_leftmost() + + def _active_cue_rightmost(self): + self.tm.cue_rightmost() + + def _active_park(self): + self.tm.cue_leftmost() + self._change_state(Status.PARKED) + + # --- SINGLETON wrappers --- + + def _singleton_s(self): + # Step Right from Singleton(0). + # If successful, we are no longer at 0 (or size > 1). + # Thus, we must transition to ACTIVE. + self.tm.s() + self._change_state(Status.ACTIVE) + + def _singleton_Ls(self): + # Left of Singleton(0) is Parked + self._change_state(Status.PARKED) + + def _singleton_d(self): + # Stash zombie + self._change_state(Status.EMPTY_STASHED) + + def _singleton_append(self ,val): + self.tm.append(val) + self._change_state(Status.ACTIVE) + + # --- PARKED wrappers --- + + def _parked_s(self): + # Enter tape at Leftmost (0) + self.tm.cue_leftmost() + if(self.tm.is_singleton()): + self._change_state(Status.SINGLETON) + else: + self._change_state(Status.ACTIVE) + + def _parked_Ls(self): + # Enter tape at Rightmost (Projective) + self.tm.cue_rightmost() + if(self.tm.is_singleton()): + self._change_state(Status.SINGLETON) + else: + self._change_state(Status.ACTIVE) + + def _parked_d(self): + # Delete Leftmost (right neighbor) + self.tm.cue_leftmost() + if(self.tm.is_singleton()): + self._change_state(Status.EMPTY_STASHED) + else: + self.tm.d() + if(self.tm.is_singleton()): + self._change_state(Status.SINGLETON) + else: + self._change_state(Status.ACTIVE) + + def _parked_cue_leftmost(self): + self._parked_s() + + def _parked_cue_rightmost(self): + self._parked_Ls() + + # --- SPECIAL APPENDS --- + + def _stashed_append(self ,val): + self.tm.w(val) + self._change_state(Status.SINGLETON) + + def _typed_append(self ,val): + if(self.tm_type is None): + raise RuntimeError("No TM type known.") + self.tm = self.tm_type(val) + self._change_state(Status.SINGLETON) + + # --- GENERIC --- + + def _generic_dealloc(self): + if(self.tm is not None): + self.tm_type = type(self.tm) + self.tm = None + self._change_state(Status.EMPTY_TYPED) + + def _return_true(self): return True + def _return_false(self): return False + def _noop(self): pass + + def _error_io(self ,*args): + raise RuntimeError(f"I/O illegal in {self._status.name} state.") + + def _error_step(self): + raise RuntimeError(f"Stepping illegal in {self._status.name} state.") + + def _error_op(self): + raise RuntimeError(f"Operation illegal in {self._status.name} state.") + + def _error_append(self ,val): + raise RuntimeError(f"Cannot append in {self._status.name} state.") diff --git a/developer/authored/Python/TM/TMS_refactored.py b/developer/authored/Python/TM/TMS_refactored.py new file mode 100644 index 0000000..b2f2b88 --- /dev/null +++ b/developer/authored/Python/TM/TMS_refactored.py @@ -0,0 +1,336 @@ +# TMS.py +# RT format: 2-space indent, PascalCase type names, snake_case identifiers. + +from enum import Enum, auto + + +class Status(Enum): + EMPTY_TYPED = auto() # No instance, knows type or factory. + EMPTY_STASHED = auto() # Instance exists (1 zombie cell), logically empty. + PARKED = auto() # Instance exists, head is conceptually off tape. + SINGLETON = auto() # Instance exists, size 1, head at 0. + ACTIVE = auto() # Instance exists, size > 1 OR head > 0. + + +class TMS: + """ + Tape Machine with Status (Second Order Machine). + + Design + 1. First order invariants live inside the wrapped TM. + 2. Second order status tracks lifecycle and head validity outside the tape. + 3. Active state binds hot path calls directly to the wrapped TM. + """ + + __slots__ = ( + "tm" + ,"tm_type" + ,"tm_factory" + ,"_status" + # VTable Methods + ,"s" + ,"Ls" + ,"r" + ,"w" + ,"d" + ,"append" + ,"park" + ,"dealloc" + ,"is_empty" + ) + + def __init__(self ,tm=None ,tm_type=None ,tm_factory=None): + self.tm = None + self.tm_type = tm_type + self.tm_factory = tm_factory + + if(tm is not None): + self.tm = tm + if(self.tm_type is None): + self.tm_type = type(tm) + self._change_state(Status.PARKED) + return + + if(self.tm_type is not None or self.tm_factory is not None): + self._change_state(Status.EMPTY_TYPED) + return + + self._change_state(Status.EMPTY_TYPED) + + @property + def status(self): + return self._status + + # --------------------------------------------------------- + # Wrapped TM compatibility helpers + # --------------------------------------------------------- + + def _tm_LqR(self): + if(hasattr(self.tm ,"LqR")): + return self.tm.LqR() + if(hasattr(self.tm ,"Lq")): + return self.tm.Lq() + raise RuntimeError("Wrapped TM lacks LqR/Lq.") + + def _tm_qR(self): + if(hasattr(self.tm ,"qR")): + return self.tm.qR() + if(hasattr(self.tm ,"q")): + return self.tm.q() + raise RuntimeError("Wrapped TM lacks qR/q.") + + def _tm_LsR(self): + if(hasattr(self.tm ,"LsR")): + return self.tm.LsR() + if(hasattr(self.tm ,"cue_leftmost")): + return self.tm.cue_leftmost() + raise RuntimeError("Wrapped TM lacks LsR/cue_leftmost.") + + def _tm_sR(self): + if(hasattr(self.tm ,"sR")): + return self.tm.sR() + if(hasattr(self.tm ,"cue_rightmost")): + return self.tm.cue_rightmost() + raise RuntimeError("Wrapped TM lacks sR/cue_rightmost.") + + def _tm_is_singleton(self): + return self._tm_LqR() and self._tm_qR() + + # --------------------------------------------------------- + # State machine + # --------------------------------------------------------- + + def _change_state(self ,new_status): + self._status = new_status + + # --------------------------------------------------------- + # STATE: ACTIVE + # --------------------------------------------------------- + if(new_status == Status.ACTIVE): + # Direct Binding + self.r = self.tm.r + self.w = self.tm.w + self.append = self._active_append + + # Wrapped Binding + self.s = self._active_s + self.Ls = self._active_Ls + self.d = self._active_d + self.park = self._active_park + self.dealloc = self._generic_dealloc + self.is_empty = self._return_false + return + + # --------------------------------------------------------- + # STATE: SINGLETON + # --------------------------------------------------------- + if(new_status == Status.SINGLETON): + self.r = self.tm.r + self.w = self.tm.w + + self.s = self._singleton_s + self.Ls = self._singleton_Ls + self.d = self._singleton_d + self.append = self._singleton_append + + self.park = self._singleton_park + self.dealloc = self._generic_dealloc + self.is_empty = self._return_false + return + + # --------------------------------------------------------- + # STATE: PARKED + # --------------------------------------------------------- + if(new_status == Status.PARKED): + self.s = self._parked_s + self.Ls = self._parked_Ls + + self.r = self._error_io + self.w = self._error_io + self.d = self._parked_d + self.append = self._error_append + + self.park = self._noop + self.dealloc = self._generic_dealloc + self.is_empty = self._return_false + return + + # --------------------------------------------------------- + # STATE: EMPTY STASHED + # --------------------------------------------------------- + if(new_status == Status.EMPTY_STASHED): + self.s = self._error_step + self.Ls = self._error_step + self.r = self._error_io + self.w = self._error_io + self.d = self._error_op + + self.append = self._stashed_append + + self.park = self._noop + self.dealloc = self._generic_dealloc + self.is_empty = self._return_true + return + + # --------------------------------------------------------- + # STATE: EMPTY TYPED + # --------------------------------------------------------- + if(new_status == Status.EMPTY_TYPED): + self.s = self._error_step + self.Ls = self._error_step + self.r = self._error_io + self.w = self._error_io + self.d = self._error_op + + self.append = self._typed_append + + self.park = self._noop + self.dealloc = self._noop + self.is_empty = self._return_true + return + + raise RuntimeError(f"Unknown state: {new_status!r}") + + # --------------------------------------------------------- + # ACTIVE wrappers + # --------------------------------------------------------- + + def _active_s(self): + if(self._tm_qR()): + raise RuntimeError("Cannot step right: At Rightmost cell.") + self.tm.s() + + def _active_Ls(self): + if(self._tm_LqR()): + self._change_state(Status.PARKED) + return + self.tm.Ls() + + def _active_d(self): + self.tm.d() + if(self._tm_is_singleton()): + self._change_state(Status.SINGLETON) + + def _active_append(self ,val): + self.tm.append(val) + + def _active_park(self): + self._tm_LsR() + self._change_state(Status.PARKED) + + # --------------------------------------------------------- + # SINGLETON wrappers + # --------------------------------------------------------- + + def _singleton_s(self): + # Open issue: semantics depend on the wrapped TM. + # Some containers can grow on step right. Some are bounded and raise. + self.tm.s() + self._change_state(Status.ACTIVE) + + def _singleton_Ls(self): + self._change_state(Status.PARKED) + + def _singleton_d(self): + # Preserve a zombie cell for reuse. + self._change_state(Status.EMPTY_STASHED) + + def _singleton_append(self ,val): + self.tm.append(val) + self._change_state(Status.ACTIVE) + + def _singleton_park(self): + self._change_state(Status.PARKED) + + # --------------------------------------------------------- + # PARKED wrappers + # --------------------------------------------------------- + + def _parked_s(self): + # Enter tape at Leftmost. + self._tm_LsR() + if(self._tm_is_singleton()): + self._change_state(Status.SINGLETON) + else: + self._change_state(Status.ACTIVE) + + def _parked_Ls(self): + # Enter tape at Rightmost (projective). + self._tm_sR() + if(self._tm_is_singleton()): + self._change_state(Status.SINGLETON) + else: + self._change_state(Status.ACTIVE) + + def _parked_d(self): + # Delete the Leftmost cell while remaining Parked. + self._tm_LsR() + + if(self._tm_is_singleton()): + self._change_state(Status.EMPTY_STASHED) + return + + self.tm.d() + + # Prepare for next entry, then remain Parked. + self._tm_LsR() + self._change_state(Status.PARKED) + + # --------------------------------------------------------- + # SPECIAL APPENDS + # --------------------------------------------------------- + + def _stashed_append(self ,val): + self.tm.w(val) + self._change_state(Status.SINGLETON) + + def _typed_append(self ,val): + if(self.tm_factory is not None): + self.tm = self.tm_factory(val) + if(self.tm_type is None): + self.tm_type = type(self.tm) + self._change_state(Status.SINGLETON) + return + + if(self.tm_type is None): + raise RuntimeError("No TM type or factory known.") + + # Default: most concrete TM constructors accept a sequence. + try: + self.tm = self.tm_type([val]) + except TypeError: + self.tm = self.tm_type(val) + + self._change_state(Status.SINGLETON) + + # --------------------------------------------------------- + # GENERIC + # --------------------------------------------------------- + + def _generic_dealloc(self): + if(self.tm is not None): + if(self.tm_type is None): + self.tm_type = type(self.tm) + self.tm = None + self._change_state(Status.EMPTY_TYPED) + + def _return_true(self): + return True + + def _return_false(self): + return False + + def _noop(self): + pass + + def _error_io(self ,*args): + raise RuntimeError(f"I/O illegal in {self._status.name} state.") + + def _error_step(self): + raise RuntimeError(f"Stepping illegal in {self._status.name} state.") + + def _error_op(self): + raise RuntimeError(f"Operation illegal in {self._status.name} state.") + + def _error_append(self ,val): + raise RuntimeError(f"Cannot append in {self._status.name} state.") diff --git a/developer/authored/Python/TM/TM_Array.c b/developer/authored/Python/TM/TM_Array.c new file mode 100644 index 0000000..471f805 --- /dev/null +++ b/developer/authored/Python/TM/TM_Array.c @@ -0,0 +1,331 @@ +/* + TM_Array.c + Topology: Contiguous Memory (Linear) + Backing: PyListObject +*/ + +#define PY_SSIZE_T_CLEAN +#include +#include "structmember.h" + +/* --- 1. HEAD STRUCT --- */ + +typedef struct { + PyObject_HEAD + PyObject* tape_obj; /* Variable: Container */ + PyObject** head_ptr; /* Variable: Current Cell */ + PyObject** leftmost_ptr; /* Variable: Left Bound */ + PyObject** right_sentinel;/* Variable: Right Bound */ +} TM·Arr·Head; + +static void TM·Arr·dealloc(TM·Arr·Head* self){ + Py_XDECREF(self->tape_obj); + Py_TYPE(self)->tp_free((PyObject*)self); +} + +static int TM·Arr·init(TM·Arr·Head* self, PyObject* args, PyObject* kwds){ + PyObject* input_obj = NULL; + if( !PyArg_ParseTuple(args, "O", &input_obj) ) return -1; + + if( !PyList_Check(input_obj) ){ + PyErr_SetString(PyExc_TypeError, "TM_Array requires a Python List."); + return -1; + } + if (PyList_Size(input_obj) == 0) { + PyErr_SetString(PyExc_ValueError, "TM cannot be empty."); + return -1; + } + + self->tape_obj = input_obj; + Py_INCREF(self->tape_obj); + + Py_ssize_t len = PyList_GET_SIZE(self->tape_obj); + PyObject** items = ((PyListObject*)self->tape_obj)->ob_item; + + self->leftmost_ptr = items; + self->right_sentinel = items + len; + self->head_ptr = items; + + return 0; +} + +/* --- 2. HELPERS --- */ + +static void TM·Arr·sync(TM·Arr·Head* self){ + Py_ssize_t offset = self->head_ptr - self->leftmost_ptr; + Py_ssize_t len = PyList_GET_SIZE(self->tape_obj); + PyObject** new_items = ((PyListObject*)self->tape_obj)->ob_item; + + self->leftmost_ptr = new_items; + self->right_sentinel = new_items + len; + self->head_ptr = self->leftmost_ptr + offset; +} + +static inline void TM·Arr·lazysync(TM·Arr·Head* self){ + Py_ssize_t known_len = self->right_sentinel - self->leftmost_ptr; + Py_ssize_t actual_len = PyList_GET_SIZE(self->tape_obj); + if (known_len != actual_len) { + TM·Arr·sync(self); + } +} + +/* --- 3. PRIMITIVES: NAVIGATION --- */ + +static PyObject* TM·Arr·s(TM·Arr·Head* self){ + TM·Arr·lazysync(self); + self->head_ptr++; + Py_RETURN_NONE; +} + +static PyObject* TM·Arr·Ls(TM·Arr·Head* self){ + TM·Arr·lazysync(self); + self->head_ptr--; + Py_RETURN_NONE; +} + +static PyObject* TM·Arr·sn(TM·Arr·Head* self, PyObject* args){ + TM·Arr·lazysync(self); + Py_ssize_t n; if(!PyArg_ParseTuple(args, "n", &n)) return NULL; + self->head_ptr += n; + Py_RETURN_NONE; +} + +static PyObject* TM·Arr·Lsn(TM·Arr·Head* self, PyObject* args){ + TM·Arr·lazysync(self); + Py_ssize_t n; if(!PyArg_ParseTuple(args, "n", &n)) return NULL; + self->head_ptr -= n; + Py_RETURN_NONE; +} + +static PyObject* TM·Arr·sR(TM·Arr·Head* self){ + TM·Arr·lazysync(self); + self->head_ptr = self->right_sentinel - 1; + Py_RETURN_NONE; +} + +static PyObject* TM·Arr·LsR(TM·Arr·Head* self){ + TM·Arr·lazysync(self); + self->head_ptr = self->leftmost_ptr; + Py_RETURN_NONE; +} + +/* --- 4. PRIMITIVES: ENTANGLEMENT --- */ + +static PyObject* TM·Arr·e(TM·Arr·Head* self){ + TM·Arr·lazysync(self); + PyTypeObject* type = Py_TYPE(self); + TM·Arr·Head* new_tm = (TM·Arr·Head*)type->tp_alloc(type, 0); + if (!new_tm) return NULL; + + new_tm->tape_obj = self->tape_obj; + Py_INCREF(new_tm->tape_obj); + + new_tm->leftmost_ptr = self->leftmost_ptr; + new_tm->right_sentinel = self->right_sentinel; + new_tm->head_ptr = self->head_ptr; + + return (PyObject*)new_tm; +} + +/* --- 5. PRIMITIVES: I/O --- */ + +static PyObject* TM·Arr·r(TM·Arr·Head* self){ + TM·Arr·lazysync(self); + PyObject* item = *self->head_ptr; + Py_INCREF(item); + return item; +} + +static PyObject* TM·Arr·w(TM·Arr·Head* self, PyObject* val){ + TM·Arr·lazysync(self); + PyObject* old = *self->head_ptr; + Py_INCREF(val); + *self->head_ptr = val; + Py_DECREF(old); + Py_RETURN_NONE; +} + +/* --- 6. PRIMITIVES: QUERY --- */ + +static PyObject* TM·Arr·qR(TM·Arr·Head* self){ + TM·Arr·lazysync(self); + if(self->head_ptr >= self->right_sentinel - 1) Py_RETURN_TRUE; + Py_RETURN_FALSE; +} + +static PyObject* TM·Arr·LqR(TM·Arr·Head* self){ + TM·Arr·lazysync(self); + if(self->head_ptr <= self->leftmost_ptr) Py_RETURN_TRUE; + Py_RETURN_FALSE; +} + +static PyObject* TM·Arr·qnR(TM·Arr·Head* self){ + TM·Arr·lazysync(self); + Py_ssize_t count = (self->right_sentinel - self->head_ptr) - 1; + return PyLong_FromSsize_t(count); +} + +static PyObject* TM·Arr·LqnR(TM·Arr·Head* self){ + TM·Arr·lazysync(self); + Py_ssize_t count = self->head_ptr - self->leftmost_ptr; + return PyLong_FromSsize_t(count); +} + +/* --- 7. DESTRUCTIVE (SO Only) --- */ + +static PyObject* TM·Arr·dR(TM·Arr·Head* self){ + TM·Arr·lazysync(self); + if (self->head_ptr <= self->leftmost_ptr) { + PyErr_SetString(PyExc_RuntimeError, "Invariant Violation: Cannot dR from leftmost cell."); + return NULL; + } + Py_ssize_t idx = self->head_ptr - self->leftmost_ptr; + Py_ssize_t len = PyList_GET_SIZE(self->tape_obj); + + if (PyList_SetSlice(self->tape_obj, idx, len, NULL) < 0) return NULL; + + self->head_ptr--; + TM·Arr·sync(self); + Py_RETURN_NONE; +} + +static PyObject* TM·Arr·LdR(TM·Arr·Head* self){ + TM·Arr·lazysync(self); + if (self->head_ptr >= self->right_sentinel - 1) { + PyErr_SetString(PyExc_RuntimeError, "Invariant Violation: Cannot LdR from rightmost cell."); + return NULL; + } + Py_ssize_t idx = self->head_ptr - self->leftmost_ptr; + + if (PyList_SetSlice(self->tape_obj, 0, idx+1, NULL) < 0) return NULL; + + self->head_ptr = self->leftmost_ptr; + TM·Arr·sync(self); + Py_RETURN_NONE; +} + +static PyObject* TM·Arr·esd(TM·Arr·Head* self){ + TM·Arr·lazysync(self); + if (self->head_ptr >= self->right_sentinel - 1) { + PyErr_SetString(PyExc_IndexError, "esd: No right neighbor."); + return NULL; + } + Py_ssize_t idx = self->head_ptr - self->leftmost_ptr; + if (PyList_SetSlice(self->tape_obj, idx+1, idx+2, NULL) < 0) return NULL; + TM·Arr·sync(self); + Py_RETURN_NONE; +} + +static PyObject* TM·Arr·eLsd(TM·Arr·Head* self){ + TM·Arr·lazysync(self); + if (self->head_ptr <= self->leftmost_ptr) { + PyErr_SetString(PyExc_IndexError, "eLsd: No left neighbor."); + return NULL; + } + Py_ssize_t idx = self->head_ptr - self->leftmost_ptr; + if (PyList_SetSlice(self->tape_obj, idx-1, idx, NULL) < 0) return NULL; + + self->head_ptr--; + TM·Arr·sync(self); + Py_RETURN_NONE; +} + +static PyObject* TM·Arr·esa(TM·Arr·Head* self, PyObject* val){ + TM·Arr·lazysync(self); + Py_ssize_t idx = self->head_ptr - self->leftmost_ptr; + if (PyList_Insert(self->tape_obj, idx+1, val) < 0) return NULL; + TM·Arr·sync(self); + Py_RETURN_NONE; +} + +static PyObject* TM·Arr·eLsa(TM·Arr·Head* self, PyObject* val){ + TM·Arr·lazysync(self); + Py_ssize_t idx = self->head_ptr - self->leftmost_ptr; + if (PyList_Insert(self->tape_obj, idx, val) < 0) return NULL; + self->head_ptr++; + TM·Arr·sync(self); + Py_RETURN_NONE; +} + +static PyObject* TM·Arr·aR(TM·Arr·Head* self, PyObject* val){ + if (PyList_Append(self->tape_obj, val) < 0) return NULL; + TM·Arr·sync(self); + Py_RETURN_NONE; +} + +static PyObject* TM·Arr·LaR(TM·Arr·Head* self, PyObject* val){ + if (PyList_Insert(self->tape_obj, 0, val) < 0) return NULL; + self->head_ptr++; + TM·Arr·sync(self); + Py_RETURN_NONE; +} + +/* --- 8. METHOD TABLES --- */ + +static PyMethodDef Table·Arr·CR·ND[] = { + {"s", (PyCFunction)TM·Arr·s, METH_NOARGS, ""}, + {"sn",(PyCFunction)TM·Arr·sn,METH_VARARGS,""}, + {"e", (PyCFunction)TM·Arr·e, METH_NOARGS, ""}, + {"r", (PyCFunction)TM·Arr·r, METH_NOARGS, ""}, + {"w", (PyCFunction)TM·Arr·w, METH_O, ""}, + {"qR",(PyCFunction)TM·Arr·qR,METH_NOARGS, ""}, + {"qnR",(PyCFunction)TM·Arr·qnR,METH_NOARGS,""}, + {"LqnR",(PyCFunction)TM·Arr·LqnR,METH_NOARGS,""}, + {"LsR",(PyCFunction)TM·Arr·LsR,METH_NOARGS,""}, + {NULL} +}; + +static PyMethodDef Table·Arr·CLR·ND[] = { + {"s", (PyCFunction)TM·Arr·s, METH_NOARGS, ""}, + {"sn",(PyCFunction)TM·Arr·sn,METH_VARARGS,""}, + {"e", (PyCFunction)TM·Arr·e, METH_NOARGS, ""}, + {"Ls",(PyCFunction)TM·Arr·Ls,METH_NOARGS, ""}, + {"Lsn",(PyCFunction)TM·Arr·Lsn,METH_VARARGS,""}, + {"r", (PyCFunction)TM·Arr·r, METH_NOARGS, ""}, + {"w", (PyCFunction)TM·Arr·w, METH_O, ""}, + {"qR",(PyCFunction)TM·Arr·qR,METH_NOARGS, ""}, + {"LqR",(PyCFunction)TM·Arr·LqR,METH_NOARGS, ""}, + {"qnR",(PyCFunction)TM·Arr·qnR,METH_NOARGS,""}, + {"LqnR",(PyCFunction)TM·Arr·LqnR,METH_NOARGS,""}, + {"sR",(PyCFunction)TM·Arr·sR,METH_NOARGS, ""}, + {"LsR",(PyCFunction)TM·Arr·LsR,METH_NOARGS,""}, + {NULL} +}; + +static PyMethodDef Table·Arr·CR·SO[] = { + {"s", (PyCFunction)TM·Arr·s, METH_NOARGS, ""}, + {"sn",(PyCFunction)TM·Arr·sn,METH_VARARGS,""}, + {"r", (PyCFunction)TM·Arr·r, METH_NOARGS, ""}, + {"w", (PyCFunction)TM·Arr·w, METH_O, ""}, + {"dR",(PyCFunction)TM·Arr·dR,METH_NOARGS, ""}, + {"esd",(PyCFunction)TM·Arr·esd,METH_NOARGS,""}, + {"esa",(PyCFunction)TM·Arr·esa,METH_O, ""}, + {"aR",(PyCFunction)TM·Arr·aR,METH_O, ""}, + {"qR",(PyCFunction)TM·Arr·qR,METH_NOARGS, ""}, + {"qnR",(PyCFunction)TM·Arr·qnR,METH_NOARGS,""}, + {"LqnR",(PyCFunction)TM·Arr·LqnR,METH_NOARGS,""}, + {"LsR",(PyCFunction)TM·Arr·LsR,METH_NOARGS,""}, + {NULL} +}; + +static PyMethodDef Table·Arr·CLR·SO[] = { + {"s", (PyCFunction)TM·Arr·s, METH_NOARGS, ""}, + {"Ls",(PyCFunction)TM·Arr·Ls,METH_NOARGS, ""}, + {"r", (PyCFunction)TM·Arr·r, METH_NOARGS, ""}, + {"w", (PyCFunction)TM·Arr·w, METH_O, ""}, + {"dR",(PyCFunction)TM·Arr·dR,METH_NOARGS, ""}, + {"LdR",(PyCFunction)TM·Arr·LdR,METH_NOARGS,""}, + {"esd",(PyCFunction)TM·Arr·esd,METH_NOARGS,""}, + {"eLsd",(PyCFunction)TM·Arr·eLsd,METH_NOARGS,""}, + {"esa",(PyCFunction)TM·Arr·esa,METH_O, ""}, + {"eLsa",(PyCFunction)TM·Arr·eLsa,METH_O, ""}, + {"aR",(PyCFunction)TM·Arr·aR,METH_O, ""}, + {"LaR",(PyCFunction)TM·Arr·LaR,METH_O, ""}, + {"qR",(PyCFunction)TM·Arr·qR,METH_NOARGS, ""}, + {"LqR",(PyCFunction)TM·Arr·LqR,METH_NOARGS, ""}, + {"qnR",(PyCFunction)TM·Arr·qnR,METH_NOARGS,""}, + {"LqnR",(PyCFunction)TM·Arr·LqnR,METH_NOARGS,""}, + {"sR",(PyCFunction)TM·Arr·sR,METH_NOARGS, ""}, + {"LsR",(PyCFunction)TM·Arr·LsR,METH_NOARGS,""}, + {NULL} +}; diff --git a/developer/authored/Python/TM/TM_GR.c b/developer/authored/Python/TM/TM_GR.c new file mode 100644 index 0000000..3134744 --- /dev/null +++ b/developer/authored/Python/TM/TM_GR.c @@ -0,0 +1,142 @@ +/* + TM_GR.c + Topology: Graph / Linear Linked Nodes + Backing: Generic Python Object with "right" and "left" attributes. +*/ + +#define PY_SSIZE_T_CLEAN +#include +#include "structmember.h" + +typedef struct { + PyObject_HEAD + PyObject* leftmost_node; + PyObject* head_node; +} TM·Gr·Head; + +static void TM·Gr·dealloc(TM·Gr·Head* self){ + Py_XDECREF(self->leftmost_node); + Py_XDECREF(self->head_node); + Py_TYPE(self)->tp_free((PyObject*)self); +} + +static int TM·Gr·init(TM·Gr·Head* self, PyObject* args, PyObject* kwds){ + PyObject* input_obj = NULL; + if( !PyArg_ParseTuple(args, "O", &input_obj) ) return -1; + + if (input_obj == Py_None) { + PyErr_SetString(PyExc_ValueError, "TM cannot be empty."); + return -1; + } + + self->leftmost_node = input_obj; + Py_INCREF(self->leftmost_node); + + self->head_node = input_obj; + Py_INCREF(self->head_node); + + return 0; +} + +/* --- PRIMITIVES --- */ + +static PyObject* TM·Gr·s(TM·Gr·Head* self){ + PyObject* right = PyObject_GetAttrString(self->head_node, "right"); + if (!right) return NULL; + if (right == Py_None) { + Py_DECREF(right); + PyErr_SetString(PyExc_RuntimeError, "Stepped off tape (right is None)."); + return NULL; + } + Py_DECREF(self->head_node); + self->head_node = right; + Py_RETURN_NONE; +} + +static PyObject* TM·Gr·Ls(TM·Gr·Head* self){ + PyObject* left = PyObject_GetAttrString(self->head_node, "left"); + if (!left) return NULL; + if (left == Py_None) { + Py_DECREF(left); + PyErr_SetString(PyExc_RuntimeError, "Stepped off tape (left is None)."); + return NULL; + } + Py_DECREF(self->head_node); + self->head_node = left; + Py_RETURN_NONE; +} + +static PyObject* TM·Gr·e(TM·Gr·Head* self){ + PyTypeObject* type = Py_TYPE(self); + TM·Gr·Head* new_tm = (TM·Gr·Head*)type->tp_alloc(type, 0); + if (!new_tm) return NULL; + + new_tm->leftmost_node = self->leftmost_node; + Py_INCREF(new_tm->leftmost_node); + + new_tm->head_node = self->head_node; + Py_INCREF(new_tm->head_node); + + return (PyObject*)new_tm; +} + +static PyObject* TM·Gr·r(TM·Gr·Head* self){ + Py_INCREF(self->head_node); + return self->head_node; +} + +static PyObject* TM·Gr·w(TM·Gr·Head* self, PyObject* val){ + if (PyObject_SetAttrString(self->head_node, "val", val) < 0) return NULL; + Py_RETURN_NONE; +} + +static PyObject* TM·Gr·qR(TM·Gr·Head* self){ + PyObject* right = PyObject_GetAttrString(self->head_node, "right"); + if (!right || right == Py_None) { + Py_XDECREF(right); + Py_RETURN_TRUE; + } + Py_DECREF(right); + Py_RETURN_FALSE; +} + +static PyObject* TM·Gr·LqR(TM·Gr·Head* self){ + PyObject* left = PyObject_GetAttrString(self->head_node, "left"); + if (!left || left == Py_None) { + Py_XDECREF(left); + Py_RETURN_TRUE; + } + Py_DECREF(left); + Py_RETURN_FALSE; +} + +static PyObject* TM·Gr·LsR(TM·Gr·Head* self){ + Py_DECREF(self->head_node); + self->head_node = self->leftmost_node; + Py_INCREF(self->head_node); + Py_RETURN_NONE; +} + +/* --- METHOD TABLES --- */ + +static PyMethodDef Table·Gr·CR·ND[] = { + {"s", (PyCFunction)TM·Gr·s, METH_NOARGS, ""}, + {"e", (PyCFunction)TM·Gr·e, METH_NOARGS, ""}, + {"r", (PyCFunction)TM·Gr·r, METH_NOARGS, ""}, + {"w", (PyCFunction)TM·Gr·w, METH_O, ""}, + {"qR",(PyCFunction)TM·Gr·qR,METH_NOARGS, ""}, + {"LsR",(PyCFunction)TM·Gr·LsR,METH_NOARGS,""}, + {NULL} +}; + +static PyMethodDef Table·Gr·CLR·ND[] = { + {"s", (PyCFunction)TM·Gr·s, METH_NOARGS, ""}, + {"e", (PyCFunction)TM·Gr·e, METH_NOARGS, ""}, + {"Ls",(PyCFunction)TM·Gr·Ls,METH_NOARGS, ""}, + {"r", (PyCFunction)TM·Gr·r, METH_NOARGS, ""}, + {"w", (PyCFunction)TM·Gr·w, METH_O, ""}, + {"qR",(PyCFunction)TM·Gr·qR,METH_NOARGS, ""}, + {"LqR",(PyCFunction)TM·Gr·LqR,METH_NOARGS, ""}, + {"LsR",(PyCFunction)TM·Gr·LsR,METH_NOARGS,""}, + {NULL} +}; diff --git a/developer/authored/Python/TM/TM_NaturalNumber.c b/developer/authored/Python/TM/TM_NaturalNumber.c new file mode 100644 index 0000000..c782b7d --- /dev/null +++ b/developer/authored/Python/TM/TM_NaturalNumber.c @@ -0,0 +1,99 @@ +/* + TM_NaturalNumber.c + Topology: Infinite Line +*/ + +#define PY_SSIZE_T_CLEAN +#include +#include "structmember.h" + +typedef struct { + PyObject_HEAD + unsigned long long state; +} TM·Nat·Head; + +static int TM·Nat·init(TM·Nat·Head* self, PyObject* args, PyObject* kwds){ + self->state = 0; + return 0; +} + +static void TM·Nat·dealloc(TM·Nat·Head* self){ + Py_TYPE(self)->tp_free((PyObject*)self); +} + +static PyObject* TM·Nat·s(TM·Nat·Head* self){ + self->state++; + Py_RETURN_NONE; +} + +static PyObject* TM·Nat·sn(TM·Nat·Head* self, PyObject* args){ + unsigned long long n; + if(!PyArg_ParseTuple(args, "K", &n)) return NULL; + self->state += n; + Py_RETURN_NONE; +} + +static PyObject* TM·Nat·Ls(TM·Nat·Head* self){ + if(self->state > 0) self->state--; + Py_RETURN_NONE; +} + +static PyObject* TM·Nat·LsR(TM·Nat·Head* self){ + self->state = 0; + Py_RETURN_NONE; +} + +static PyObject* TM·Nat·r(TM·Nat·Head* self){ + return PyLong_FromUnsignedLongLong(self->state); +} + +static PyObject* TM·Nat·w(TM·Nat·Head* self, PyObject* val){ + PyErr_SetString(PyExc_TypeError, "Cannot write to Abstract Natural Number tape (Immutable)."); + return NULL; +} + +static PyObject* TM·Nat·qR(TM·Nat·Head* self){ + Py_RETURN_FALSE; +} + +static PyObject* TM·Nat·LqR(TM·Nat·Head* self){ + if(self->state == 0){ + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; +} + +static PyObject* TM·Nat·qnR(TM·Nat·Head* self){ + PyErr_SetString(PyExc_RuntimeError, "Natural Number tape is infinite to the right."); + return NULL; +} + +static PyObject* TM·Nat·LqnR(TM·Nat·Head* self){ + return PyLong_FromUnsignedLongLong(self->state); +} + +static PyMethodDef TM·Nat·methods[] = { + {"s", (PyCFunction)TM·Nat·s, METH_NOARGS, ""}, + {"sn",(PyCFunction)TM·Nat·sn,METH_VARARGS,""}, + {"Ls",(PyCFunction)TM·Nat·Ls,METH_NOARGS, ""}, + {"r", (PyCFunction)TM·Nat·r, METH_NOARGS, ""}, + {"w", (PyCFunction)TM·Nat·w, METH_O, ""}, + {"qR",(PyCFunction)TM·Nat·qR,METH_NOARGS, ""}, + {"LqR",(PyCFunction)TM·Nat·LqR,METH_NOARGS, ""}, + {"qnR",(PyCFunction)TM·Nat·qnR,METH_NOARGS, ""}, + {"LqnR",(PyCFunction)TM·Nat·LqnR,METH_NOARGS, ""}, + {"LsR",(PyCFunction)TM·Nat·LsR,METH_NOARGS, ""}, + {NULL} +}; + +static PyTypeObject TMA_NaturalNumber·Type = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "TM_module.TMA_NaturalNumber", + .tp_doc = "Abstract TM: Natural Numbers", + .tp_basicsize = sizeof(TM·Nat·Head), + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_new = PyType_GenericNew, + .tp_init = (initproc)TM·Nat·init, + .tp_dealloc = (destructor)TM·Nat·dealloc, + .tp_methods = TM·Nat·methods, +}; diff --git a/developer/authored/Python/TM/TM_module.c b/developer/authored/Python/TM/TM_module.c new file mode 100644 index 0000000..8d56b74 --- /dev/null +++ b/developer/authored/Python/TM/TM_module.c @@ -0,0 +1,179 @@ +/* + TM_module.c + CPython Extension: Tape Machine Factory + Aggregates implementations for Array, Graph, and Abstract topologies. +*/ + +#include + +/* Include Implementations */ +#include "TM_Array.c" +#include "TM_GR.c" +#include "TM_NaturalNumber.c" + +/* --- TYPE MACROS --- */ + +#define DEFINE_ARRAY_TYPE(NAME, METHODS) \ +static PyTypeObject NAME##·Type = { \ + PyVarObject_HEAD_INIT(NULL, 0) \ + .tp_name = "TM_module." #NAME, \ + .tp_basicsize = sizeof(TM·Arr·Head), \ + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, \ + .tp_new = PyType_GenericNew, \ + .tp_init = (initproc)TM·Arr·init, \ + .tp_dealloc = (destructor)TM·Arr·dealloc, \ + .tp_methods = METHODS, \ +}; + +#define DEFINE_GR_TYPE(NAME, METHODS) \ +static PyTypeObject NAME##·Type = { \ + PyVarObject_HEAD_INIT(NULL, 0) \ + .tp_name = "TM_module." #NAME, \ + .tp_basicsize = sizeof(TM·Gr·Head), \ + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, \ + .tp_new = PyType_GenericNew, \ + .tp_init = (initproc)TM·Gr·init, \ + .tp_dealloc = (destructor)TM·Gr·dealloc, \ + .tp_methods = METHODS, \ +}; + +/* --- TYPE DEFINITIONS --- */ + +/* 1. Array Types */ +DEFINE_ARRAY_TYPE(TM_Arr_CR_ND, Table·Arr·CR·ND) +DEFINE_ARRAY_TYPE(TM_Arr_CR_SO, Table·Arr·CR·SO) +DEFINE_ARRAY_TYPE(TM_Arr_CR_EA, Table·Arr·CR·ND) + +DEFINE_ARRAY_TYPE(TM_Arr_CLR_ND, Table·Arr·CLR·ND) +DEFINE_ARRAY_TYPE(TM_Arr_CLR_SO, Table·Arr·CLR·SO) +DEFINE_ARRAY_TYPE(TM_Arr_CLR_EA, Table·Arr·CLR·ND) + +DEFINE_ARRAY_TYPE(TM_ArrV_CR_ND, Table·Arr·CR·ND) +DEFINE_ARRAY_TYPE(TM_ArrV_CR_SO, Table·Arr·CR·SO) +DEFINE_ARRAY_TYPE(TM_ArrV_CR_EA, Table·Arr·CR·ND) + +DEFINE_ARRAY_TYPE(TM_ArrV_CLR_ND, Table·Arr·CLR·ND) +DEFINE_ARRAY_TYPE(TM_ArrV_CLR_SO, Table·Arr·CLR·SO) +DEFINE_ARRAY_TYPE(TM_ArrV_CLR_EA, Table·Arr·CLR·ND) + +/* ... ASCII/UTF8 ... */ +DEFINE_ARRAY_TYPE(TM_ASCII_CR_ND, Table·Arr·CR·ND) +DEFINE_ARRAY_TYPE(TM_ASCII_CR_SO, Table·Arr·CR·SO) +DEFINE_ARRAY_TYPE(TM_ASCII_CR_EA, Table·Arr·CR·ND) +DEFINE_ARRAY_TYPE(TM_ASCII_CLR_ND, Table·Arr·CLR·ND) +DEFINE_ARRAY_TYPE(TM_ASCII_CLR_SO, Table·Arr·CLR·SO) +DEFINE_ARRAY_TYPE(TM_ASCII_CLR_EA, Table·Arr·CLR·ND) + +DEFINE_ARRAY_TYPE(TM_UTF8_CR_ND, Table·Arr·CR·ND) +DEFINE_ARRAY_TYPE(TM_UTF8_CR_SO, Table·Arr·CR·SO) +DEFINE_ARRAY_TYPE(TM_UTF8_CR_EA, Table·Arr·CR·ND) +DEFINE_ARRAY_TYPE(TM_UTF8_CLR_ND, Table·Arr·CLR·ND) +DEFINE_ARRAY_TYPE(TM_UTF8_CLR_SO, Table·Arr·CLR·SO) +DEFINE_ARRAY_TYPE(TM_UTF8_CLR_EA, Table·Arr·CLR·ND) + +/* 2. Graph Types */ +DEFINE_GR_TYPE(TM_Gr_CR_ND, Table·Gr·CR·ND) +DEFINE_GR_TYPE(TM_Gr_CR_SO, Table·Gr·CR·ND) +DEFINE_GR_TYPE(TM_Gr_CR_EA, Table·Gr·CR·ND) + +DEFINE_GR_TYPE(TM_Gr_CLR_ND, Table·Gr·CLR·ND) +DEFINE_GR_TYPE(TM_Gr_CLR_SO, Table·Gr·CLR·ND) +DEFINE_GR_TYPE(TM_Gr_CLR_EA, Table·Gr·CLR·ND) + +DEFINE_GR_TYPE(TM_Glr_CR_ND, Table·Gr·CR·ND) +DEFINE_GR_TYPE(TM_Glr_CR_SO, Table·Gr·CR·ND) +DEFINE_GR_TYPE(TM_Glr_CR_EA, Table·Gr·CR·ND) +DEFINE_GR_TYPE(TM_Glr_CLR_ND, Table·Gr·CLR·ND) +DEFINE_GR_TYPE(TM_Glr_CLR_SO, Table·Gr·CLR·ND) +DEFINE_GR_TYPE(TM_Glr_CLR_EA, Table·Gr·CLR·ND) + +/* ... Maps and Sets ... */ +DEFINE_GR_TYPE(TM_Set_CR_ND, Table·Gr·CR·ND) +DEFINE_GR_TYPE(TM_Set_CR_SO, Table·Gr·CR·ND) +DEFINE_GR_TYPE(TM_Set_CR_EA, Table·Gr·CR·ND) +DEFINE_GR_TYPE(TM_Set_CLR_ND, Table·Gr·CLR·ND) +DEFINE_GR_TYPE(TM_Set_CLR_SO, Table·Gr·CLR·ND) +DEFINE_GR_TYPE(TM_Set_CLR_EA, Table·Gr·CLR·ND) + +DEFINE_GR_TYPE(TM_Map_CR_ND, Table·Gr·CR·ND) +DEFINE_GR_TYPE(TM_Map_CR_SO, Table·Gr·CR·ND) +DEFINE_GR_TYPE(TM_Map_CR_EA, Table·Gr·CR·ND) +DEFINE_GR_TYPE(TM_Map_CLR_ND, Table·Gr·CLR·ND) +DEFINE_GR_TYPE(TM_Map_CLR_SO, Table·Gr·CLR·ND) +DEFINE_GR_TYPE(TM_Map_CLR_EA, Table·Gr·CLR·ND) + +DEFINE_GR_TYPE(TM_MapK_CR_ND, Table·Gr·CR·ND) +DEFINE_GR_TYPE(TM_MapK_CR_SO, Table·Gr·CR·ND) +DEFINE_GR_TYPE(TM_MapK_CR_EA, Table·Gr·CR·ND) +DEFINE_GR_TYPE(TM_MapK_CLR_ND, Table·Gr·CLR·ND) +DEFINE_GR_TYPE(TM_MapK_CLR_SO, Table·Gr·CLR·ND) +DEFINE_GR_TYPE(TM_MapK_CLR_EA, Table·Gr·CLR·ND) + +DEFINE_GR_TYPE(TM_MapV_CR_ND, Table·Gr·CR·ND) +DEFINE_GR_TYPE(TM_MapV_CR_SO, Table·Gr·CR·ND) +DEFINE_GR_TYPE(TM_MapV_CR_EA, Table·Gr·CR·ND) +DEFINE_GR_TYPE(TM_MapV_CLR_ND, Table·Gr·CLR·ND) +DEFINE_GR_TYPE(TM_MapV_CLR_SO, Table·Gr·CLR·ND) +DEFINE_GR_TYPE(TM_MapV_CLR_EA, Table·Gr·CLR·ND) + + +/* --- MODULE INIT --- */ + +static PyModuleDef TM_module = { + PyModuleDef_HEAD_INIT, "TM_module", "Tape Machine Factory", -1, NULL +}; + +#define ADD_TYPE(NAME) \ + if (PyType_Ready(&NAME##·Type) < 0) return NULL; \ + Py_INCREF(&NAME##·Type); \ + PyModule_AddObject(m, #NAME, (PyObject*)&NAME##·Type); + +PyMODINIT_FUNC PyInit_TM_module(void){ + PyObject* m = PyModule_Create(&TM_module); + if(!m) return NULL; + + /* Arr */ + ADD_TYPE(TM_Arr_CR_ND) ADD_TYPE(TM_Arr_CR_SO) ADD_TYPE(TM_Arr_CR_EA) + ADD_TYPE(TM_Arr_CLR_ND) ADD_TYPE(TM_Arr_CLR_SO) ADD_TYPE(TM_Arr_CLR_EA) + + /* ArrV */ + ADD_TYPE(TM_ArrV_CR_ND) ADD_TYPE(TM_ArrV_CR_SO) ADD_TYPE(TM_ArrV_CR_EA) + ADD_TYPE(TM_ArrV_CLR_ND) ADD_TYPE(TM_ArrV_CLR_SO) ADD_TYPE(TM_ArrV_CLR_EA) + + /* Gr */ + ADD_TYPE(TM_Gr_CR_ND) ADD_TYPE(TM_Gr_CR_SO) ADD_TYPE(TM_Gr_CR_EA) + ADD_TYPE(TM_Gr_CLR_ND) ADD_TYPE(TM_Gr_CLR_SO) ADD_TYPE(TM_Gr_CLR_EA) + + /* Glr */ + ADD_TYPE(TM_Glr_CR_ND) ADD_TYPE(TM_Glr_CR_SO) ADD_TYPE(TM_Glr_CR_EA) + ADD_TYPE(TM_Glr_CLR_ND) ADD_TYPE(TM_Glr_CLR_SO) ADD_TYPE(TM_Glr_CLR_EA) + + /* Set */ + ADD_TYPE(TM_Set_CR_ND) ADD_TYPE(TM_Set_CR_SO) ADD_TYPE(TM_Set_CR_EA) + ADD_TYPE(TM_Set_CLR_ND) ADD_TYPE(TM_Set_CLR_SO) ADD_TYPE(TM_Set_CLR_EA) + + /* Map */ + ADD_TYPE(TM_Map_CR_ND) ADD_TYPE(TM_Map_CR_SO) ADD_TYPE(TM_Map_CR_EA) + ADD_TYPE(TM_Map_CLR_ND) ADD_TYPE(TM_Map_CLR_SO) ADD_TYPE(TM_Map_CLR_EA) + + /* MapK */ + ADD_TYPE(TM_MapK_CR_ND) ADD_TYPE(TM_MapK_CR_SO) ADD_TYPE(TM_MapK_CR_EA) + ADD_TYPE(TM_MapK_CLR_ND) ADD_TYPE(TM_MapK_CLR_SO) ADD_TYPE(TM_MapK_CLR_EA) + + /* MapV */ + ADD_TYPE(TM_MapV_CR_ND) ADD_TYPE(TM_MapV_CR_SO) ADD_TYPE(TM_MapV_CR_EA) + ADD_TYPE(TM_MapV_CLR_ND) ADD_TYPE(TM_MapV_CLR_SO) ADD_TYPE(TM_MapV_CLR_EA) + + /* ASCII */ + ADD_TYPE(TM_ASCII_CR_ND) ADD_TYPE(TM_ASCII_CR_SO) ADD_TYPE(TM_ASCII_CR_EA) + ADD_TYPE(TM_ASCII_CLR_ND) ADD_TYPE(TM_ASCII_CLR_SO) ADD_TYPE(TM_ASCII_CLR_EA) + + /* UTF8 */ + ADD_TYPE(TM_UTF8_CR_ND) ADD_TYPE(TM_UTF8_CR_SO) ADD_TYPE(TM_UTF8_CR_EA) + ADD_TYPE(TM_UTF8_CLR_ND) ADD_TYPE(TM_UTF8_CLR_SO) ADD_TYPE(TM_UTF8_CLR_EA) + + /* Abstract */ + ADD_TYPE(TMA_NaturalNumber) + + return m; +} diff --git a/developer/authored/Python/TM/__init__.py b/developer/authored/Python/TM/__init__.py new file mode 100644 index 0000000..bf8ea64 --- /dev/null +++ b/developer/authored/Python/TM/__init__.py @@ -0,0 +1,2 @@ +from .TM import TM + diff --git a/developer/authored/Python/TM/build.sh b/developer/authored/Python/TM/build.sh new file mode 100755 index 0000000..7ccef3c --- /dev/null +++ b/developer/authored/Python/TM/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/Python/TM/install.sh b/developer/authored/Python/TM/install.sh new file mode 100644 index 0000000..86cec75 --- /dev/null +++ b/developer/authored/Python/TM/install.sh @@ -0,0 +1,2 @@ +apt-get update +apt-get install python3-dev diff --git a/developer/authored/Python/TM/setup.py b/developer/authored/Python/TM/setup.py new file mode 100644 index 0000000..1beccd2 --- /dev/null +++ b/developer/authored/Python/TM/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/Python/TM/try.c b/developer/authored/Python/TM/try.c new file mode 100644 index 0000000..a3af1d1 --- /dev/null +++ b/developer/authored/Python/TM/try.c @@ -0,0 +1,11 @@ + +#include + +int main(){ + int x[3] = {100, 101, 102}; + void *p = &x; + printf("x[0] == %d\n" ,*(int *)p); + (char *)p += sizeof(x[0]); // <---- note this line + printf("x[0] == %d\n" ,*(int *)p); +} + diff --git a/developer/authored/Python/example/example_TMS.py b/developer/authored/Python/example/example_TMS.py new file mode 100755 index 0000000..158be59 --- /dev/null +++ b/developer/authored/Python/example/example_TMS.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 +# example_TMS.py +# Demonstration of the Tape Machine with Status (Second Order) + +import TM +from TMS import TMS, Status + +def assert_status(tms, expected): + print(f" Status: {tms.status.name} (Expected: {expected.name})") + if tms.status != expected: + raise AssertionError(f"Status mismatch! Got {tms.status}, want {expected}") + +def demo_late_binding(): + print("\n--- 1. Late Binding & Lifecycle ---") + + # Create a TMS without a machine, just the type. + # State: EMPTY_TYPED + tms = TMS(tm_type=TM.TM) + assert_status(tms, Status.EMPTY_TYPED) + + print(" Appending 10...") + tms.append(10) + # State: SINGLETON (Size 1) + assert_status(tms, Status.SINGLETON) + print(f" Read: {tms.r()}") + + print(" Appending 20...") + tms.append(20) + # State: ACTIVE (Size > 1) + assert_status(tms, Status.ACTIVE) + + print(" Deleting current...") + tms.d() + # Should degrade back to SINGLETON + assert_status(tms, Status.SINGLETON) + + print(" Deleting last element...") + tms.d() + # Should go to EMPTY_STASHED (Zombie state), preserving the cell for reuse + assert_status(tms, Status.EMPTY_STASHED) + + print(" Appending 99 (Reuse Zombie)...") + tms.append(99) + assert_status(tms, Status.SINGLETON) + print(f" Read: {tms.r()} (Exp: 99)") + +def demo_projective_parking(): + print("\n--- 2. Projective Parking (The Loop) ---") + data = [10, 20, 30] + tm = TM.TM(data) + tms = TMS(tm=tm) # Starts PARKED by default when instance provided + + assert_status(tms, Status.PARKED) + + # Step Right from Parked -> Leftmost (10) + print(" [Parked] s() -> Enter Left") + tms.s() + assert_status(tms, Status.ACTIVE) + print(f" Value: {tms.r()} (Exp: 10)") + + # Park again + print(" Parking...") + tms.park() + assert_status(tms, Status.PARKED) + + # Step Left from Parked -> Rightmost (30) - PROJECTIVE BEHAVIOR + print(" [Parked] Ls() -> Enter Right (Projective)") + tms.Ls() + assert_status(tms, Status.ACTIVE) + print(f" Value: {tms.r()} (Exp: 30)") + + # Step Right from Rightmost -> Error (Bounded Tape) + print(" [Rightmost] s() -> Expect Error") + try: + tms.s() + except RuntimeError as e: + print(f" Caught expected error: {e}") + + # Step Left from Rightmost -> Middle + tms.Ls() + print(f" [Middle] Value: {tms.r()} (Exp: 20)") + + # Step Left from Leftmost -> Parked + tms.Ls() # At 10 + print(" [Leftmost] Ls() -> Exit to Parked") + tms.Ls() + assert_status(tms, Status.PARKED) + +def main(): + demo_late_binding() + demo_projective_parking() + +if __name__ == "__main__": + main() + + diff --git a/developer/authored/Python/example/example_TM_loop.py b/developer/authored/Python/example/example_TM_loop.py new file mode 100755 index 0000000..6227826 --- /dev/null +++ b/developer/authored/Python/example/example_TM_loop.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python3 +import TM_module as TM +import sys + + +# rest unchanged + +#!/usr/bin/env python3 +import TM +import sys + +def print_tape(tm): + tm.LsR() + sys.stdout.write(f"{tm.r()}") + while not tm.qR(): + tm.s() + sys.stdout.write(f" ,{tm.r()}") + print("") + +def tm_loops_tutorial(): + print("--- 1. The Standard Traversal (Read -> Process -> Step) ---") + data = [10, 20, 30, 40, 50] + tm = TM.TM_Arr_CR_ND(data) + + while True: + val = tm.r() + print(f"Processing: {val}") + if tm.qR(): break + tm.s() + + print("\n--- 2. The Accumulator (Initialized First) ---") + tm = TM.TM_Arr_CR_ND([1, 2, 3, 4, 5]) + + total = tm.r() # Process First + while not tm.qR(): # Guard + tm.s() # Step + total += tm.r() # Process Next + + print(f"Total: {total}") + + print("\n--- 3. Destructive Filter (Variable Tape) ---") + # We use TM_ArrV_CLR_SO (Chiral Left Right, Solitary). + # We need CLR to support 'eLsd' (Delete Left Neighbor). + original_data = [1, 2, 3, 4, 5, 6, 7] + tm = TM.TM_ArrV_CLR_SO(original_data) + + # 1. Process First (Index 0) - Special Case + # We check the start. If odd, we must delete it. + # Since we are at the start, we cannot use eLsd (no left neighbor). + # We must Step then eLsd? No, that deletes 0. + # If we Step, 0 becomes the left neighbor. + + tm.LsR() # Ensure start + + first_val = tm.r() + if first_val % 2 != 0: + print(f"Deleting odd start: {first_val}") + if tm.qR(): + # Single element list. Cannot step. + print("(Cannot delete last remaining element)") + else: + tm.s() # Step to 1 + tm.eLsd() # Delete Left Neighbor (Index 0) + # Head is now at Index 0 (the element that shifted down). + # We must NOT step in the loop immediately, or we skip the new First. + # To handle this cleanly in a loop, we align the head to "Previous" logic? + # Easier: Just restart logic from the new current. + + # Since we deleted 0, the loop below starts at the *new* 0. + # We just need to make sure we don't double step. + # The simplest way is to handle the deletion, then let the loop + # run normally from the current head position. + + # Main Loop + # Invariant: Head is on a valid cell we want to inspect. + while True: + val = tm.r() + if val % 2 != 0: + # Found odd. Delete it. + print(f"Deleting odd: {val}") + + if not tm.qR(): + # Case: Not at end. + # Step Right, then delete the item to our Left (which is 'val'). + tm.s() + tm.eLsd() + # Head is now on the next item (shifted left into current slot). + # We continue loop to inspect *this* item. + else: + # Case: At End (Tail). + # Cannot use eLsd strategy because we can't step right. + # Must use esd strategy: Step Left, delete Right Neighbor. + if tm.LqR(): + print("(Last item, cannot empty tape)") + break + + tm.Ls() # Step Left + tm.esd() # Delete Right Neighbor (Tail) + # Tail deleted. We are at new tail. + # We inspected this even number already (presumably), so we break? + # Actually, if we stepped left, we are on a number we already kept. + break + else: + print(f"Keeping even: {val}") + if tm.qR(): break + tm.s() + + print("Final Tape Content:") + # Pass the SO machine directly. + # This will consume/rewind the head, but that is acceptable here. + print_tape(tm) + +if __name__ == "__main__": + tm_loops_tutorial() diff --git a/developer/authored/Python/example/example_TM_machine.py b/developer/authored/Python/example/example_TM_machine.py new file mode 100755 index 0000000..a9a804e --- /dev/null +++ b/developer/authored/Python/example/example_TM_machine.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 +# example_TM_machines.py + +import TM_module as TM + +def example_machine_grammar(): + print("--- TM Machine Grammar Example ---") + + data = [10 ,20 ,30 ,40 ,50] + + t_arr = TM.TM_Arr_CR_ND(data) + print(f"\n[Array CR ND] {type(t_arr).__name__}") + print(f" Read: {t_arr.r()}") + t_arr.s() + print(f" Step, Read: {t_arr.r()}") + + t_var = TM.TM_ArrV_CLR_ND(data) + print(f"\n[Vector CLR ND] {type(t_var).__name__}") + t_var.sR() + print(f" Cue Rightmost, Read: {t_var.r()} (Exp: 50)") + t_var.Ls() + print(f" Left Step, Read: {t_var.r()} (Exp: 40)") + + ascii_data = [65 ,66 ,67] + t_asc = TM.TM_ASCII_CR_SO(ascii_data) + print(f"\n[ASCII CR SO] {type(t_asc).__name__}") + print(f" Read: {t_asc.r()} (Exp: 65/A)") + + # Map example removed until a dict linearization adaptor exists. + + t_nat = TM.TMA_NaturalNumber() + print(f"\n[Abstract] {type(t_nat).__name__}") + print(f" Read: {t_nat.r()} (Exp: 0)") + t_nat.sn(1000) + print(f" Step 1000, Read: {t_nat.r()} (Exp: 1000)") + +if __name__ == "__main__": + example_machine_grammar() diff --git a/developer/authored/Scheme/.gitkeep b/developer/authored/Scheme/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/developer/authored/example-greet/Greeter.lib.c b/developer/authored/example-greet/Greeter.lib.c new file mode 100644 index 0000000..1d23879 --- /dev/null +++ b/developer/authored/example-greet/Greeter.lib.c @@ -0,0 +1,20 @@ +#ifndef ExampleGreet·Greeter·ONCE +#define ExampleGreet·Greeter·ONCE + +#include "Math.lib.c" + +void ExampleGreet·Greeter·hello_loop(int count); + +#ifdef ExampleGreet·Greeter + #include + + void ExampleGreet·Greeter·hello_loop(int count){ + for(int TM = 0; TM < count; ++TM){ + int current_count = ExampleGreet·Math·add(TM ,1); + printf("Hello iteration: %d\n" ,current_count); + } + } + +#endif // ExampleGreet·Greeter + +#endif // ExampleGreet·Greeter·ONCE diff --git a/developer/authored/example-greet/Math.lib.c b/developer/authored/example-greet/Math.lib.c new file mode 100644 index 0000000..6f1880e --- /dev/null +++ b/developer/authored/example-greet/Math.lib.c @@ -0,0 +1,12 @@ +#ifndef ExampleGreet·Math·ONCE +#define ExampleGreet·Math·ONCE + +int ExampleGreet·Math·add(int a ,int b); + +#ifdef ExampleGreet·Math + int ExampleGreet·Math·add(int a ,int b){ + return a + b; + } +#endif // ExampleGreet·Math + +#endif // ExampleGreet·Math·ONCE diff --git a/developer/authored/example-greet/hello.CLI.c b/developer/authored/example-greet/hello.CLI.c new file mode 100644 index 0000000..684e2a7 --- /dev/null +++ b/developer/authored/example-greet/hello.CLI.c @@ -0,0 +1,20 @@ +#include +#include + +#include "Math.lib.c" +#include "Greeter.lib.c" + +void CLI(void){ + int base_count = ExampleGreet·Math·add(1 ,2); + printf("Calculated base loop count: %d\n" ,base_count); + ExampleGreet·Greeter·hello_loop(base_count); +} + +int main(int argc ,char **argv){ + (void)argc; + (void)argv; + + CLI(); + + return EXIT_SUCCESS; +} diff --git a/developer/document/AI-memory_DeepSeek.txt b/developer/document/AI-memory_DeepSeek.txt new file mode 100644 index 0000000..1d3acd1 --- /dev/null +++ b/developer/document/AI-memory_DeepSeek.txt @@ -0,0 +1,5 @@ +Hello DeepSeek, I am Thomas. + +Here is a summary of our past interactions + + 2026-05-31 08:56:03 Z diff --git a/document/TM.html b/document/TM.html new file mode 100644 index 0000000..d400aa3 --- /dev/null +++ b/document/TM.html @@ -0,0 +1,594 @@ + + + + + Tape Machine + + + + + + + + + + + + +

Introduction

+ +

+ A Tape Machine (TM) is an abstract mechanism for manipulating data found in sequences. Such sequences include lists, arrays, sets (given an ordering function), and maps (also given an ordering function). Also included are linear traversals of more complex structures. The theory underpinning the TM is discussed in the TTCA book. +

+ +

+ Unlike standard arrays (which are stateless) or iterators (which are transient), a TM combines a data substrate with a persistent head. The head maintains positional state, allowing the programmer to navigate, read, and write tape cells. +

+ +

+ Thus a TM packages both data, and all pointers into that data, within one structure. +

+ +

+ A TM can have a concrete tape or a virtual tape. A concrete tape is backed by a container. A virtual tape presents the same TM interface, but its cells and motion are implemented by functions over some internal state. For example, an abstract Counting Number tape machine can use a big integer as its state and implement stepping and reading over that state, instead of traversing an array of numbers. +

+ +

+ A defining invariant of all Tape Machines is that cell contents are cargo. The TM reads and writes cell payload, but it does not interpret that payload as control. The decisions are made above the TM, by the programmer’s algorithm. +

+ +

+ A first order TM is defined by a single invariant: the head is always on a valid cell. This invariant makes the primitive interface total: every move, read, write, and query has a clean, well defined meaning, and caller code stays free of scattered end case tests. +

+ +

+ If an operation were permitted to remove the last remaining cell 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 second order tape machine. +

+ +

+ Tape machines that share a tape are said to be entangled. 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 a tape machine head is always on a valid cell invariant. +

+ +

+ 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 non-destructive. Without destructive operations, entangled machines simply do not have the ability to break each other. In a second approach, the interface is configured so there are no functions for entangling machines in the first place. Each solitary machine can safely perform destructive operations because no other machine shares its tape. As a third approach, each group of entangled machines shares a catalog listing all machines in the group. Caller code can guard operations by querying whether a planned operation is safe before attempting it. This third strategy is called entanglement accounting. During the time of execution of the guard and operation, each tape machine must be able to lockout others from access to the catalog. Yet another approach is for the programmer, compiler, or external function to prove code is safe, which is the same as proving that guard code is not needed. An alternative is to use a compiler that only produces correct code in the first place. This is the approach of correct by construction. +

+ +

Machine Naming Convention

+ +

+ Concrete Tape Machine classes follow a strict naming grammar. This grammar acts as a feature descriptor, allowing the programmer to select a machine by constructing its name. +

+ +

+ The name is composed of three feature segments: the Container Type, the Chirality, and the Entanglement Approach. +

+ +

grammar

+ + class_name :: TM [ _container ] [ _chirality ] [ _entanglement ] + container :: Arr | ArrV | GR | GLR | Set | Map | MapK | MapV + | ASCII | UTF8 + chirality :: CR | CLR + entanglement :: ND | SO | EA + + +

+ Segments are separated by underscores. The default configuration for a segment is used if that segment is omitted. + The default machine is TM_Arr_CR_ND (Fixed Array, Chiral Right, Non-Destructive). +

+ +

container

+
    +
  • Arr Array Fixed (Default). A contiguous sequence of fixed length (e.g., Python List, C Array).
  • +
  • ArrV Array Variable. A contiguous sequence that may resize (e.g., Vector).
  • +
  • GR Graph Right. A node-based sequence with a single right neighbor (Singly Linked List).
  • +
  • GLR Graph Left Right. A node-based sequence with left and right neighbors (Doubly Linked List).
  • +
  • Set Set. Iteration over the elements of a Set.
  • +
  • Map Map. Iteration over the items (Key-Value pairs) of a Map.
  • +
  • MapK Map Keys. Iteration over the keys of a Map.
  • +
  • MapV Map Values. Iteration over the values of a Map.
  • +
  • ASCII Ascii. A sequence of 1-byte characters.
  • +
  • UTF8 Utf8. A sequence of variable-width Unicode characters.
  • +
+ +

chirality

+
    +
  • CR Chiral Right (Default). The machine head can only be moved to the right.
  • +
  • CLR Chiral Left Right. The machine is bidirectional, supports stepping either right or left.
  • +
+ +

entanglement

+
    +
  • ND Non-Destructive (Default). Safe for entanglement.
  • +
  • SO Solitary. Exclusive ownership; supports destructive ops.
  • +
  • EA Entanglement Accounting. Shared access guarded by a catalog.
  • +
+ +

Abstract and Traversal Machines

+

+ The naming convention extends to Abstract and Traversal machines using specific prefixes. +

+
    +
  • TMA TM Abstract. Virtual tapes computed over state. +
    Example: TMA_NaturalNumber (Iterates 0, 1, 2...).
  • +
  • TMT TM Traversal. Algorithmic traversals over non-linear structures. +
    Example: TMT_Tree_DepthFirst (Linearizes a tree via stack/recursion).
  • +
+ +

Command language

+ +

+ 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". +

+ +

+ 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. +

+ +

+ The grammar selects which parts of the language are available based on the machine's configuration (CR or CLR). +

+ +

For the non-destructive step right machine

+ +

grammar

+ + statement :: ( command [arg]* )+ + command :: e | q | r | s | w + arg :: R | n + + +

statement

+

+ A statement is parsed left to right. Each command letter begins a new command group. All following arg descriptors attach to that command until the next command letter appears. There are no spaces. Arguments are given to the resulting function in the order that the command and its descriptors require them. +

+ +

+ Accordingly, a function name such as snr(i) denotes two command groups: + sn(i) steps right i times, then r copies out the current cell. +

+ +

command

+
    +
  • e entangle
  • +
  • q query
  • +
  • r read
  • +
  • s step
  • +
  • w write
  • +
+ +

+ Two or more machines are entangled when they share one tape. + Entangle differs from clone because the tape is shared rather than copied. + What is duplicated is the head state, so entangled heads move independently. + A machine produced by e begins with its head on the same cell as the machine it was created from. +

+ +

+ The query command, q, reports head state. + With no arg descriptor it returns a boolean value. + With an R arg descriptor it returns true iff the head is on the rightmost cell. +

+ +

+ TM uses a guard approach for end cases. Query commands appear in control flow so caller code can select the guards it needs and handle end cases explicitly. + When guards are unnecessary, caller code can omit them. +

+ +

+ The r and w commands copy values to and from the current cell. + As of the time of this writing they are cell local operations, so direction does not enter. +

+ +

+ The s step command moves the head to the right neighbor cell. + When s is given an n arg descriptor, it performs n right steps. + On a step right only machine, n must be positive. +

+ +

arg

+
    +
  • n n
  • +
  • R Rightmost
  • +
+ +

+ The n arg descriptor supplies a repetition count or implies a distance query. +

+ +

+ The R arg descriptor focuses the command on the rightmost cell. + For qR, the result is true iff the head is on rightmost. + For sR, the effect is to cue the head to rightmost. +

+ +

Examples

+ +

Relative head movement

+ + s ; step to right neighbor + sn(1) ; step to right neighbor + sn(2) ; step to right neighbor twice + + +

Absolute head movement

+ + sR ; cue the head to rightmost + + +

Query

+ + qR ; true iff head is on rightmost + qnR ; returns number of steps to rightmost + + +

Copying to and from tape cells and python variables

+ + r ; copies cell contents to the LHS of an assignment + w(v) ; copies v into the cell + + + +

For the non-destructive machine that has step left

+ +

+ The step right grammar extends to left going behavior by introducing a mirror view of a machine. + In the mirror view, every rightward operation corresponds to the base machine’s leftward operation, so new command letters are unnecessary. + What is rightmost in the base view becomes leftmost in the mirror view, and vice versa. +

+ +

+ In this extended grammar, the L prefix selects the mirror view for the command group that follows it. + L affects direction sensitive operations such as stepping, moving to rightmost, and scans. + Today r and w are cell local, so L does not change their behavior. +

+ +

+ When L is available, n can also be negative, with the sign selecting the direction in the base view. +

+ +

grammar

+ + statement :: ( [machine] command [arg]* )+ + machine :: L + command :: e | q | r | s | w + arg :: R | n + + +

+ Consider a tape with cells [c_0 ,c_1 ,c_2 ,c_3 ,c_4], where c_4 is rightmost. + In the mirror view we write the same cells as [c_4 ,c_3 ,c_2 ,c_1 ,c_0]. + In the mirror view c_4 sits at the left edge. + A right step from c_4 in the mirror view lands on c_3, which matches a left step from c_4 in the base view. +

+ +

Examples

+ +

+ In these examples, the comments discuss what happens on the base machine. Effects in the mirror view match the same command without the L prefix. +

+ +

Relative head movement

+ + Ls ; step to left neighbor + Lsn(2) ; step to left neighbor twice + sn(-2) ; step to left neighbor twice + sn(2) ; step to right neighbor twice + + +

Absolute head movement

+ + LsR ; cue the head to leftmost + sR ; cue the head to rightmost + + +

Query

+ + LqR ; head is on leftmost + qR ; head is on rightmost + qnR ; steps to rightmost + LqnR ; steps to leftmost + + +

+ The R arg descriptor focuses the command on the selected view rightmost cell. + For qR, the result is true iff the head is on rightmost. + Under L, that rightmost cell is the base view leftmost cell, so LqR returns true iff the head is on the leftmost cell. +

+ +

Copying to and from tape cells and python variables

+ + r ; copies cell contents to the LHS of an assignment + w(v) ; copies v into the cell + + +

+ The current r and w are cell local and are unaffected by L. + If we later support list forms or repetition forms for copy, L will affect the scan direction for those operations. +

+ +

TM interface functions

+ +

+ This section lists the concrete methods exposed by the Python/C implementation. + These methods implement a selected subset of the command grammar. + The grammar defines a command language, while the primitive set defines the operations the library exposes directly. + Later sections can introduce a compile layer that accepts additional command combinations. +

+ +

+ The L prefix is not implemented as a distinct family of primitives. + In the command language it selects the mirror view. + In the API the same effect is provided by explicit left primitives such as Ls() and Lsn(n), or by allowing a signed n on machines that support step left. +

+ +

Navigation primitives

+ +

+ Navigation primitives implement the s command with the argument forms ε, n, and R. + On a step right only machine, n is constrained to positive values. + On a machine that supports step left, n can be negative, with the sign selecting direction in the base view. +

+ +
    +
  • s() steps to the right neighbor. (Command form: s.)
  • +
  • sn(n) steps by n cells. On a step right only machine, n must be positive. (Command form: sn(n).)
  • +
  • sR() cues the head to the selected view rightmost cell. (Command form: sR.)
  • +
+ +

+ If step left is enabled, left motion is available either as explicit primitives, or via negative n on sn(n), depending on the configured interface. + When explicit left primitives exist, they correspond to the mirror view command forms. +

+ +
    +
  • Ls() steps to the left neighbor. (Command form: Ls.)
  • +
  • Lsn(n) steps left n times. (Command form: Lsn(n).)
  • +
  • LsR() cues the head to leftmost. (Command form: LsR.)
  • +
+ +

+ Note the correspondence: sR cues rightmost in the base view, and LsR cues leftmost of that same underlying tape. + The primitives sR() and LsR() are optimized cues. +

+ +

Input and output primitives

+ +

+ The I/O primitives implement r and w(value). + In the command language, r reads the current cell payload, and w(v) writes a payload to the current cell. + As of the time of this writing, these operations are cell local, so mirror view does not change their behavior. +

+ +
    +
  • r() reads the current cell.
  • +
  • w(v) writes v to the current cell.
  • +
+ +

+ Bulk forms can exist in the API, but they are not represented in the current command grammar. + They are library level conveniences built on top of repeated primitive behavior. + If bulk copy forms become part of the command grammar later, mirror view will affect scan direction for those operations. +

+ +
    +
  • rn(n) reads n cells.
  • +
  • wn(list) writes a list of values.
  • +
+ +

Destructive Primitives

+ +

+ Machines configured with the SO (Solitary) entanglement approach may expose primitives that modify the tape structure. + These are distinct from w (which modifies cell content) because they change the cell count or sequence. +

+ +

+ Note: Not all container types support all destructive operations. For example, Arr (Fixed Array) does not support deletion or insertion, whereas ArrV (Variable Array) does. +

+ +

Delete Neighbor (esd)

+

+ A compound-style primitive that deletes a neighbor without moving the active head. + Mnemonic: Entangle-Step-Delete (conceptually acts on the neighbor). +

+
    +
  • esd(): Deletes the immediate right neighbor. Guard: Requires not qR().
  • +
  • eLsd(): Deletes the immediate left neighbor. Guard: Requires not LqR().
  • +
+ +

Delete to Bound (dR)

+
    +
  • dR(): Deletes from current to Rightmost (inclusive). Head steps left. Guard: Requires not LqR().
  • +
  • LdR(): Deletes from current to Leftmost (inclusive). Head lands on right neighbor. Guard: Requires not qR().
  • +
+ +

Insert/Append (esa)

+
    +
  • esa(v): Appends value v after the current head position.
  • +
  • eLsa(v): Appends value v before the current head position.
  • +
  • aR(v): Appends value v to the Rightmost end of the tape.
  • +
  • LaR(v): Appends value v to the Leftmost end of the tape.
  • +
+ +

Query primitives

+ +

+ Query primitives are built from the q command. + On the step right only machine, the primitive set covers the boolean query forms. +

+ +
    +
  • qR() returns whether the head is on the selected view rightmost cell. (Command form: qR.)
  • +
  • qnR() returns number of steps to rightmost cell. (Command form: qnR.)
  • +
+ +

+ Mirror view query forms follow the same rule in the command language. + For example, LqR tests the leftmost of the underlying tape. +

+ +
    +
  • LqR() returns whether the head is on the leftmost cell. (Command form: LqR.)
  • +
  • LqnR() returns number of steps to leftmost cell. (Command form: LqnR.)
  • +
+ +

Entanglement primitives

+ +

+ Entanglement primitives implement the e command. + 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. +

+ +
    +
  • e() returns a new entangled machine sharing the same tape. (Command form: e.)
  • +
+ +

+ Combined command forms such as es are legal in the grammar, but they are not required as primitives. + The library can expose such combinations as convenience calls, or generate them through a compile layer. + The core model remains that a statement is a sequence of commands applied to a selected view. +

+ +

Usage

+ +

First order TM properties

+ +

+ For a first order TM these properties are always true. +

+ +
    +
  1. The head is always on a valid cell.
  2. +
  3. All cells return a value when read.
  4. +
+ +

+ In order to maintain these properties, a TM uses inclusive bounds for intervals, including intervals of cells. +

+ +

Contract with the programmer

+ +

+ Some first order TM types rely upon the caller to maintain a contract. + Such machines typically have debug variants that add contract checks. + For some machines, breaking the contract limits compiler optimization. + For other machines, breaking the contract causes program bugs. +

+ +

+ Contract: +

+ +
    +
  1. When there is a right bound, the caller guarantees that he will never command the machine to step beyond the rightmost cell.
  2. +
  3. When there is a left bound, the caller guarantees that he will never command the machine to step left of the leftmost cell.
  4. +
+ +

+ When traversing a tape, the contract is fulfilled by a First Rest pattern. +

+ +

First Rest pattern with initialization

+ + + # Pattern 1: First Rest (Initialize with First) + # Useful when the accumulator starts with the first value. + total = tm.r() # Process First + while not tm.qR(): # Guard: Is there a Rest? + tm.s() # Step (Protected) + total += tm.r() # Process Next + + +

+ Here tm.qR() queries whether the head is on the selected view rightmost cell. + It guards the step in the loop. + No redundant tests are done, and the loop ends without stepping off the tape. +

+ +

First Rest pattern without initialization

+ +

+ Sometimes the accumulator is initialized to an identity value (such as zero) before the loop starts. + In that form, the loop and a half structure is natural. +

+ + + # Conceptual "do" loop + do: + total += tm.r() # Always process the current cell + if tm.qR() break # protects increment from spilling over + tm.s() # Step only when not at the end + + +

+ Python has no do statement, so the same logic is written explicitly: +

+ + + # Python implementation + while True: + total += tm.r() + if tm.qR(): break + tm.s() + + +

+ The middle test tm.qR() guards tm.s(), so the machine never steps beyond rightmost. +

+ +

Region Machine

+ +

A Region Machine is a composite structure built from three entangled tape machines. It enforces the invariant that the active head remains within a specified closed interval of the tape.

+ +

Structure

+ +

The Region Machine consists of:

  • Left Boundary Machine: A TM marking the leftmost valid cell of the region.
  • Right Boundary Machine: A TM marking the rightmost valid cell of the region.
  • Active Machine: The TM interface exposed to the user for navigation and I/O.
+ +

Because the Region Machine relies on the First Order invariant (head always on a valid cell), a region cannot be empty. The minimum region size is one cell, where the Left Boundary, Right Boundary, and Active Head all occupy the same cell.

+ +

Behavior

+ +

The Region Machine implements the standard TM interface but constrains movement based on the boundary heads.

+ +
  • Step (s): The Active Head performs a step only if it is not currently on the Right Boundary cell.
    • s() requires not qR().
  • Step Left (Ls): The Active Head performs a left step only if it is not currently on the Left Boundary cell.
    • Ls() requires not LqR().
  • Query Bounds (qR, LqR):
    • qR() returns true if the Active Head is on the same cell as the Right Boundary Head.
    • LqR() returns true if the Active Head is on the same cell as the Left Boundary Head.
  • Cue Bounds (sR, LsR):
    • sR() moves the Active Head to the cell occupied by the Right Boundary Head.
    • LsR() moves the Active Head to the cell occupied by the Left Boundary Head.
+ +

Boundary Management

+ +

The boundaries of a region are themselves Tape Machines. This allows the region to expand or contract dynamically. Moving a boundary head changes the effective range of the Active Machine immediately.

+ +

Safety Constraint: A boundary head cannot step past the other boundary head. The Left Boundary must always be to the left of or on the same cell as the Right Boundary. Furthermore, the Active Head must not be orphaned by boundary movement. If the Right Boundary steps left past the Active Head, the Active Head is no longer valid. Therefore, boundary contraction requires checking or moving the Active Head to maintain the invariant.

+ +

TM Workspace functions

+ +

The TM_workspace namespace contains higher-level functions that coordinate multiple machines. These functions are not part of the core TM interface but operate on TMs to implement common algorithms.

+ +

Tandem operations

+ +

Tandem operations drive multiple machines simultaneously. They are useful for copying, comparing, or parallel processing.

+ +
  • step_tandem(tm1, tm2): Steps both machines to their respective right neighbors. Requires that neither machine is at its rightmost bound.
  • zip_apply(f, tm1, tm2): Applies function f to the values read from tm1 and tm2, then steps both.
+ +

Predicates

+ +

Predicates test relationships between entangled machines.

+ +
  • head_on_same_cell(tm1, tm2): Returns true if the heads of two entangled machines are on the same cell. This is the fundamental primitive used to implement qR in Region Machines.
+ + + + + +
+ + diff --git a/document/TMS.html b/document/TMS.html new file mode 100644 index 0000000..7a5c064 --- /dev/null +++ b/document/TMS.html @@ -0,0 +1,160 @@ + + + + + Tape Machine with Status + + + + + + + + + + + + +

Introduction

+ +

+ The Tape Machine with Status (TMS) is a Second Order Machine. It wraps a standard First Order Tape Machine (TM) to provide state management and advanced lifecycle features. +

+ +

+ While a First Order TM must always reside on a valid cell (the Head must be at a valid address), the TMS allows the machine to be: +

    +
  • Empty (containing no data)
  • +
  • Parked (the head is conceptually "off tape")
  • +
  • Active (functioning as a standard TM)
  • +
+

+ +

+ The TMS implementation uses the State Pattern (vtable swapping) to ensure that the Active state incurs zero overhead. Method calls in the active state are directly bound to the underlying First Order TM's methods. +

+ +

States

+ +

+ The TMS manages five distinct states to handle lifecycle, late binding, and memory optimization. +

+ +

1. EmptyTyped

+

+ The machine is logically empty and has no underlying TM instance allocated. It holds a reference to a TM class type. This supports Late Binding, allowing the TMS to be created before data is available. +

+

+ Transitions: +

    +
  • append(v) → Instantiates the TM with value v, transitions to Singleton.
  • +
+

+ +

2. EmptyStashed

+

+ The machine is logically empty, but the underlying TM instance is preserved with exactly one "zombie" cell. This is a performance optimization to avoid deallocation and reallocation costs when a machine is cleared and immediately reused. +

+

+ Transitions: +

    +
  • append(v) → Overwrites the zombie cell with v, transitions to Singleton.
  • +
  • dealloc() → Destroys the TM instance, transitions to EmptyTyped.
  • +
+

+ +

3. Parked

+

+ The underlying TM exists, but the TMS Head is conceptually located "outside" the tape. This state is projective, meaning it connects to both ends of the tape. +

+

+ Transitions: +

    +
  • s() (Step Right) → Enters the tape at the Leftmost cell. Transitions to Singleton or Active.
  • +
  • Ls() (Step Left) → Enters the tape at the Rightmost cell. Transitions to Singleton or Active.
  • +
  • d() → Deletes the "right neighbor" (the Leftmost cell). Logic handles degradation to Empty or Singleton.
  • +
+

+ +

4. Singleton

+

+ The underlying TM has exactly one cell. The Head is at Address 0. In this state, the underlying TM reports both Lq (Left Query) and qR (Query Right) as true. +

+

+ Transitions: +

    +
  • Ls() → Transitions to Parked (exits left).
  • +
  • s() → Transitions to Active (extends right) or raises error if bounded.
  • +
  • d() → Does not physically delete the cell. Transitions to EmptyStashed (preserving the zombie cell).
  • +
+

+ +

5. Active

+

+ The underlying TM has more than one cell. Methods are directly bound to the underlying TM for maximum performance. +

+

+ Transitions: +

    +
  • Ls() → If Lq is true (at Leftmost), transitions to Parked. Otherwise, steps left.
  • +
  • d() → If the size degrades to 1, transitions to Singleton.
  • +
+

+ +

Interface

+ +

Navigation

+

+ s(): Step Right. +

    +
  • In Parked: Lands on Leftmost cell.
  • +
  • In Active: Steps right (guarded by qR).
  • +
+

+

+ Ls(): Step Left. +

    +
  • In Parked: Lands on Rightmost cell.
  • +
  • In Active: Steps left. If at Leftmost, exits to Parked.
  • +
+

+

+ park(): Explicitly moves the machine to the Parked state and cues the underlying TM to the leftmost cell. +

+ +

I/O

+

+ r() and w(val): Read and Write operations are passed directly to the underlying TM. These are valid only in Active or Singleton states. +

+ +

Lifecycle

+

+ append(val): Adds data to the end of the tape. Handles the transition from Empty states to Singleton. +

+

+ d(): Delete. Removes the current cell. +

    +
  • In Active: Removes current cell.
  • +
  • In Parked: Removes the Leftmost cell.
  • +
+

+

+ dealloc(): Forces the release of the underlying TM instance, returning the TMS to the EmptyTyped state. +

+ +
+ + + + + + + + diff --git a/document/TMS_revised.html b/document/TMS_revised.html new file mode 100644 index 0000000..198f54c --- /dev/null +++ b/document/TMS_revised.html @@ -0,0 +1,195 @@ + + + + + Tape Machine with Status + + + + + + + + + + + + +

Introduction

+ +

+ The Tape Machine with Status (TMS) is a Second Order Machine. It wraps a standard First Order Tape Machine (TM) to provide state management and advanced lifecycle features. +

+ +

+ While a First Order TM must always reside on a valid cell (the Head must be at a valid address), the TMS allows the machine to be: +

    +
  • Empty (containing no data)
  • +
  • Parked (the head is conceptually "off tape")
  • +
  • Active (functioning as a standard TM)
  • +
+

+ +

+ The TMS implementation uses the State Pattern (vtable swapping) to ensure that the Active state incurs zero overhead. Method calls in the active state are directly bound to the underlying First Order TM's methods. +

+ + +

Second Order definition and motivation

+ +

+ A First Order Tape Machine maintains one invariant: + the head is always on a valid cell. + That invariant keeps r() and w(v) simple, and it keeps traversal code clean. + End cases live in the caller through explicit guards such as qR(). +

+ +

+ A Second Order Machine adds structure for cases where the First Order invariant does not hold. + In TMS, those cases are represented as explicit status values, including Empty and Parked. + The status wrapper keeps First Order algorithms unchanged while still supporting empty tapes, head off tape states, and lifecycle actions such as deallocation. +

+ +
    +
  • + Projective parking. + One parked state connects to both ends. + s() enters at Leftmost and Ls() enters at Rightmost. +
  • +
  • + Late binding. + A TMS can exist before the first cell exists, and then be promoted by insertion. +
  • +
  • + Reuse. + EmptyStashed preserves a single cell to avoid allocate free churn. +
  • +
  • + Fast active path. + In Active, method calls bind directly to the wrapped TM methods. +
  • +
+

States

+ +

+ The TMS manages five distinct states to handle lifecycle, late binding, and memory optimization. +

+ +

1. EmptyTyped

+

+ The machine is logically empty and has no underlying TM instance allocated. It holds a reference to a TM class type. This supports Late Binding, allowing the TMS to be created before data is available. +

+

+ Transitions: +

    +
  • append(v) → Instantiates the TM with value v, transitions to Singleton.
  • +
+

+ +

2. EmptyStashed

+

+ The machine is logically empty, but the underlying TM instance is preserved with exactly one "zombie" cell. This is a performance optimization to avoid deallocation and reallocation costs when a machine is cleared and immediately reused. +

+

+ Transitions: +

    +
  • append(v) → Overwrites the zombie cell with v, transitions to Singleton.
  • +
  • dealloc() → Destroys the TM instance, transitions to EmptyTyped.
  • +
+

+ +

3. Parked

+

+ The underlying TM exists, but the TMS Head is conceptually located "outside" the tape. This state is projective, meaning it connects to both ends of the tape. +

+

+ Transitions: +

    +
  • s() (Step Right) → Enters the tape at the Leftmost cell. Transitions to Singleton or Active.
  • +
  • Ls() (Step Left) → Enters the tape at the Rightmost cell. Transitions to Singleton or Active.
  • +
  • d() → Deletes the "right neighbor" (the Leftmost cell). Logic handles degradation to Empty or Singleton.
  • +
+

+ +

4. Singleton

+

+ The underlying TM has exactly one cell. The Head is at Address 0. In this state, the underlying TM reports both Lq (Left Query) and qR (Query Right) as true. +

+

+ Transitions: +

    +
  • Ls() → Transitions to Parked (exits left).
  • +
  • s() → Transitions to Active (extends right) or raises error if bounded.
  • +
  • d() → Does not physically delete the cell. Transitions to EmptyStashed (preserving the zombie cell).
  • +
+

+ +

5. Active

+

+ The underlying TM has more than one cell. Methods are directly bound to the underlying TM for maximum performance. +

+

+ Transitions: +

    +
  • Ls() → If Lq is true (at Leftmost), transitions to Parked. Otherwise, steps left.
  • +
  • d() → If the size degrades to 1, transitions to Singleton.
  • +
+

+ +

Interface

+ +

Navigation

+

+ s(): Step Right. +

    +
  • In Parked: Lands on Leftmost cell.
  • +
  • In Active: Steps right (guarded by qR).
  • +
+

+

+ Ls(): Step Left. +

    +
  • In Parked: Lands on Rightmost cell.
  • +
  • In Active: Steps left. If at Leftmost, exits to Parked.
  • +
+

+

+ park(): Explicitly moves the machine to the Parked state and cues the underlying TM to the leftmost cell. +

+ +

I/O

+

+ r() and w(val): Read and Write operations are passed directly to the underlying TM. These are valid only in Active or Singleton states. +

+ +

Lifecycle

+

+ append(val): Adds data to the end of the tape. Handles the transition from Empty states to Singleton. +

+

+ d(): Delete. Removes the current cell. +

    +
  • In Active: Removes current cell.
  • +
  • In Parked: Removes the Leftmost cell.
  • +
+

+

+ dealloc(): Forces the release of the underlying TM instance, returning the TMS to the EmptyTyped state. +

+ +
+ + + + + + + + diff --git a/document/TMS_updated.html b/document/TMS_updated.html new file mode 100644 index 0000000..930f324 --- /dev/null +++ b/document/TMS_updated.html @@ -0,0 +1,170 @@ + + + + + Tape Machine with Status + + + + + + + + + + + + +

Introduction

+ +
    +
  • + Clean algorithms. + Traversal code stays First Order. + Empty and parked behavior lives in one wrapper. +
  • +
  • + Projective parked state. + One off tape state connects to both ends. + s() enters at Leftmost. + Ls() enters at Rightmost. +
  • +
  • + Late binding. + Construct a TMS with a TM type or factory before data exists. +
  • +
  • + Zombie cell reuse. + Clear to EmptyStashed, then refill without allocating. +
  • +
  • + Hot path speed. + In Active, r() and w() bind directly to the wrapped TM. +
  • +
+

What TMS buys

+

+ A Second Order Machine handles the cases where the First Order invariant does not apply. + The tape can be empty. + The head can be conceptually off tape. + The machine can keep a stashed cell for reuse. +

+

+ A First Order TM runs under one central invariant. + The head always names a valid cell. + That invariant makes r() and w(v) simple and predictable. + Motion stays simple too. + Caller code guards motion with queries such as LqR() and qR(). +

+

+ The Tape Machine with Status (TMS) is a Second Order Machine. + It wraps a First Order Tape Machine (TM) and adds explicit lifecycle state. +

+

States

+

+ The TMS manages five distinct states to handle lifecycle, late binding, and memory optimization. +

+

1. EmptyTyped

+

+ The machine is logically empty and has no underlying TM instance allocated. It holds a reference to a TM class type. This supports Late Binding, allowing the TMS to be created before data is available. +

+

+ Transitions: +

    +
  • append(v) → Instantiates the TM with value v, transitions to Singleton.
  • +
+

+

2. EmptyStashed

+

+ The machine is logically empty, but the underlying TM instance is preserved with exactly one "zombie" cell. This is a performance optimization to avoid deallocation and reallocation costs when a machine is cleared and immediately reused. +

+

+ Transitions: +

    +
  • append(v) → Overwrites the zombie cell with v, transitions to Singleton.
  • +
  • dealloc() → Destroys the TM instance, transitions to EmptyTyped.
  • +
+

+

3. Parked

+

+ The underlying TM exists, but the TMS Head is conceptually located "outside" the tape. This state is projective, meaning it connects to both ends of the tape. +

+

+ Transitions: +

    +
  • s() (Step Right) → Enters the tape at the Leftmost cell. Transitions to Singleton or Active.
  • +
  • Ls() (Step Left) → Enters the tape at the Rightmost cell. Transitions to Singleton or Active.
  • +
  • d() → Deletes the "right neighbor" (the Leftmost cell). Logic handles degradation to Empty or Singleton.
  • +
+

+

4. Singleton

+

+ The underlying TM has exactly one cell. The Head is at Address 0. In this state, the underlying TM reports both Lq (Left Query) and qR (Query Right) as true. +

+

+ Transitions: +

    +
  • Ls() → Transitions to Parked (exits left).
  • +
  • s() → Transitions to Active (extends right) or raises error if bounded.
  • +
  • d() → Does not physically delete the cell. Transitions to EmptyStashed (preserving the zombie cell).
  • +
+

+

5. Active

+

+ The underlying TM has more than one cell. Methods are directly bound to the underlying TM for maximum performance. +

+

+ Transitions: +

    +
  • Ls() → If Lq is true (at Leftmost), transitions to Parked. Otherwise, steps left.
  • +
  • d() → If the size degrades to 1, transitions to Singleton.
  • +
+

+

Interface

+

Navigation

+

+ s(): Step Right. +

    +
  • In Parked: Lands on Leftmost cell.
  • +
  • In Active: Steps right (guarded by qR).
  • +
+

+

+ Ls(): Step Left. +

    +
  • In Parked: Lands on Rightmost cell.
  • +
  • In Active: Steps left. If at Leftmost, exits to Parked.
  • +
+

+

+ park(): Explicitly moves the machine to the Parked state and calls LsR() on the underlying TM. +

+

I/O

+

+ r() and w(val): Read and Write operations are passed directly to the underlying TM. These are valid only in Active or Singleton states. +

+

Lifecycle

+

+ append(val): Adds data to the end of the tape. Handles the transition from Empty states to Singleton. +

+

+ d(): Delete. Removes the current cell. +

    +
  • In Active: Removes current cell.
  • +
  • In Parked: Removes the Leftmost cell.
  • +
+

+

+ dealloc(): Forces the release of the underlying TM instance, returning the TMS to the EmptyTyped state. +

+
+ + + + + + diff --git a/document/TM_total_updated.html b/document/TM_total_updated.html new file mode 100644 index 0000000..1f74580 --- /dev/null +++ b/document/TM_total_updated.html @@ -0,0 +1,634 @@ + + + + + Tape Machine + + + + + + + + + + + + +

Introduction

+ +

+ A Tape Machine (TM) is an abstract mechanism for manipulating data found in sequences. Such sequences include lists, arrays, sets (given an ordering function), and maps (also given an ordering function). Also included are linear traversals of more complex structures. The theory underpinning the TM is discussed in the TTCA book. +

+ +

+ Unlike standard arrays (which are stateless) or iterators (which are transient), a TM combines a data substrate with a persistent head. The head maintains positional state, allowing the programmer to navigate, read, and write tape cells. +

+ +

+ Thus a TM packages both data, and all pointers into that data, within one structure. +

+ +

+ A TM can have a concrete tape or a virtual tape. A concrete tape is backed by a container. A virtual tape presents the same TM interface, but its cells and motion are implemented by functions over some internal state. For example, an abstract Counting Number tape machine can use a big integer as its state and implement stepping and reading over that state, instead of traversing an array of numbers. +

+ +

+ A defining invariant of all Tape Machines is that cell contents are cargo. The TM reads and writes cell payload, but it does not interpret that payload as control. The decisions are made above the TM, by the programmer’s algorithm. +

+ +

+ A first order TM is defined by a single invariant: the head is always on a valid cell. + Under this contract, cell I O is simple. + r() returns the cargo of the current cell, and w(v) overwrites that cargo. + Motion is simple too. + s() steps to the right neighbor and Ls() steps to the left neighbor. + Caller code uses query forms such as qR() and LqR() to guard motion, so end cases stay in control flow, not scattered through the primitives. +

+ +

+ If an operation were permitted to remove the last remaining cell of a tape, the first order invariant would be broken. + A machine that supports that deletion needs explicit empty state logic. + That logic either lives inside each primitive as edge handling, or it lives above the TM as a status wrapper. + Either choice shifts the level of analysis, and leads to a distinct second order tape machine. +

+ +

+ Tape machines that share a tape are said to be entangled. 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 a tape machine head is always on a valid cell invariant. +

+ +

+ 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 non-destructive. Without destructive operations, entangled machines simply do not have the ability to break each other. In a second approach, the interface is configured so there are no functions for entangling machines in the first place. Each solitary machine can safely perform destructive operations because no other machine shares its tape. As a third approach, each group of entangled machines shares a catalog listing all machines in the group. Caller code can guard operations by querying whether a planned operation is safe before attempting it. This third strategy is called entanglement accounting. During the time of execution of the guard and operation, each tape machine must be able to lockout others from access to the catalog. Yet another approach is for the programmer, compiler, or external function to prove code is safe, which is the same as proving that guard code is not needed. An alternative is to use a compiler that only produces correct code in the first place. This is the approach of correct by construction. +

+ +

Machine Naming Convention

+ +

+ Concrete Tape Machine classes follow a strict naming grammar. This grammar acts as a feature descriptor, allowing the programmer to select a machine by constructing its name. +

+ +

+ The name is composed of three feature segments: the Container Type, the Chirality, and the Entanglement Approach. +

+ +

grammar

+ + class_name :: TM [ _container ] [ _chirality ] [ _entanglement ] + container :: Arr | ArrV | GR | GLR | Set | Map | MapK | MapV + | ASCII | UTF8 + chirality :: CR | CLR + entanglement :: ND | SO | EA + + +

+ Segments are separated by underscores. The default configuration for a segment is used if that segment is omitted. + The default machine is TM_Arr_CR_ND (Fixed Array, Chiral Right, Non-Destructive). +

+ +

container

+
    +
  • Arr Array Fixed (Default). A contiguous sequence of fixed length (e.g., Python List, C Array).
  • +
  • ArrV Array Variable. A contiguous sequence that may resize (e.g., Vector).
  • +
  • GR Graph Right. A node-based sequence with a single right neighbor (Singly Linked List).
  • +
  • GLR Graph Left Right. A node-based sequence with left and right neighbors (Doubly Linked List).
  • +
  • Set Set. Iteration over the elements of a Set.
  • +
  • Map Map. Iteration over the items (Key-Value pairs) of a Map.
  • +
  • MapK Map Keys. Iteration over the keys of a Map.
  • +
  • MapV Map Values. Iteration over the values of a Map.
  • +
  • ASCII Ascii. A sequence of 1-byte characters.
  • +
  • UTF8 Utf8. A sequence of variable-width Unicode characters.
  • +
+ +

chirality

+
    +
  • CR Chiral Right (Default). The machine head can only be moved to the right.
  • +
  • CLR Chiral Left Right. The machine is bidirectional, supports stepping either right or left.
  • +
+ +

entanglement

+
    +
  • ND Non-Destructive (Default). Safe for entanglement.
  • +
  • SO Solitary. Exclusive ownership; supports destructive ops.
  • +
  • EA Entanglement Accounting. Shared access guarded by a catalog.
  • +
+ +

Abstract and Traversal Machines

+

+ The naming convention extends to Abstract and Traversal machines using specific prefixes. +

+
    +
  • TMA TM Abstract. Virtual tapes computed over state. +
    Example: TMA_NaturalNumber (Iterates 0, 1, 2...).
  • +
  • TMT TM Traversal. Algorithmic traversals over non-linear structures. +
    Example: TMT_Tree_DepthFirst (Linearizes a tree via stack/recursion).
  • +
+ +

Command language

+ +

+ 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". +

+ +

+ 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. +

+ +

+ The grammar selects which parts of the language are available based on the machine's configuration (CR or CLR). +

+ +

For the non-destructive step right machine

+ +

grammar

+ + statement :: ( command [arg]* )+ + command :: e | q | r | s | w + arg :: R | n + + +

statement

+

+ A statement is parsed left to right. Each command letter begins a new command group. All following arg descriptors attach to that command until the next command letter appears. There are no spaces. Arguments are given to the resulting function in the order that the command and its descriptors require them. +

+ +

+ Accordingly, a function name such as snr(i) denotes two command groups: + sn(i) steps right i times, then r copies out the current cell. +

+ +

command

+
    +
  • e entangle
  • +
  • q query
  • +
  • r read
  • +
  • s step
  • +
  • w write
  • +
+ +

+ Two or more machines are entangled when they share one tape. + Entangle differs from clone because the tape is shared rather than copied. + What is duplicated is the head state, so entangled heads move independently. + A machine produced by e begins with its head on the same cell as the machine it was created from. +

+ +

+ The query command, q, reports head state. + With no arg descriptor it returns a boolean value. + With an R arg descriptor it returns true iff the head is on the rightmost cell. +

+ +

+ TM uses a guard approach for end cases. Query commands appear in control flow so caller code can select the guards it needs and handle end cases explicitly. + When guards are unnecessary, caller code can omit them. +

+ +

+ The r and w commands copy values to and from the current cell. + As of the time of this writing they are cell local operations, so direction does not enter. +

+ +

+ The s step command moves the head to the right neighbor cell. + When s is given an n arg descriptor, it performs n right steps. + On a step right only machine, n must be positive. +

+ +

arg

+
    +
  • n n
  • +
  • R Rightmost
  • +
+ +

+ The n arg descriptor supplies a repetition count or implies a distance query. +

+ +

+ The R arg descriptor focuses the command on the rightmost cell. + For qR, the result is true iff the head is on rightmost. + For sR, the effect is to cue the head to rightmost. +

+ +

Examples

+ +

Relative head movement

+ + s ; step to right neighbor + sn(1) ; step to right neighbor + sn(2) ; step to right neighbor twice + + +

Absolute head movement

+ + sR ; cue the head to rightmost + + +

Query

+ + qR ; true iff head is on rightmost + qnR ; returns number of steps to rightmost + + +

Copying to and from tape cells and python variables

+ + r ; copies cell contents to the LHS of an assignment + w(v) ; copies v into the cell + + + +

For the non-destructive machine that has step left

+ +

+ The step right grammar extends to left going behavior by introducing a mirror view of a machine. + In the mirror view, every rightward operation corresponds to the base machine’s leftward operation, so new command letters are unnecessary. + What is rightmost in the base view becomes leftmost in the mirror view, and vice versa. +

+ +

+ In this extended grammar, the L prefix selects the mirror view for the command group that follows it. + L affects direction sensitive operations such as stepping, moving to rightmost, and scans. + Today r and w are cell local, so L does not change their behavior. +

+ +

+ When L is available, n can also be negative, with the sign selecting the direction in the base view. +

+ +

grammar

+ + statement :: ( [machine] command [arg]* )+ + machine :: L + command :: e | q | r | s | w + arg :: R | n + + +

+ Consider a tape with cells [c_0 ,c_1 ,c_2 ,c_3 ,c_4], where c_4 is rightmost. + In the mirror view we write the same cells as [c_4 ,c_3 ,c_2 ,c_1 ,c_0]. + In the mirror view c_4 sits at the left edge. + A right step from c_4 in the mirror view lands on c_3, which matches a left step from c_4 in the base view. +

+ +

Examples

+ +

+ In these examples, the comments discuss what happens on the base machine. Effects in the mirror view match the same command without the L prefix. +

+ +

Relative head movement

+ + Ls ; step to left neighbor + Lsn(2) ; step to left neighbor twice + sn(-2) ; step to left neighbor twice + sn(2) ; step to right neighbor twice + + +

Absolute head movement

+ + LsR ; cue the head to leftmost + sR ; cue the head to rightmost + + +

Query

+ + LqR ; head is on leftmost + qR ; head is on rightmost + qnR ; steps to rightmost + LqnR ; steps to leftmost + + +

+ The R arg descriptor focuses the command on the selected view rightmost cell. + For qR, the result is true iff the head is on rightmost. + Under L, that rightmost cell is the base view leftmost cell, so LqR returns true iff the head is on the leftmost cell. +

+ +

Copying to and from tape cells and python variables

+ + r ; copies cell contents to the LHS of an assignment + w(v) ; copies v into the cell + + +

+ The current r and w are cell local and are unaffected by L. + If we later support list forms or repetition forms for copy, L will affect the scan direction for those operations. +

+ +

TM interface functions

+ +

+ This section lists the concrete methods exposed by the Python/C implementation. + These methods implement a selected subset of the command grammar. + The grammar defines a command language, while the primitive set defines the operations the library exposes directly. + Later sections can introduce a compile layer that accepts additional command combinations. +

+ +

+ The L prefix is not implemented as a distinct family of primitives. + In the command language it selects the mirror view. + In the API the same effect is provided by explicit left primitives such as Ls() and Lsn(n), or by allowing a signed n on machines that support step left. +

+ +

Navigation primitives

+ +

+ Navigation primitives implement the s command with the argument forms ε, n, and R. + On a step right only machine, n is constrained to positive values. + On a machine that supports step left, n can be negative, with the sign selecting direction in the base view. +

+ +
    +
  • s() steps to the right neighbor. (Command form: s.)
  • +
  • sn(n) steps by n cells. On a step right only machine, n must be positive. (Command form: sn(n).)
  • +
  • sR() cues the head to the selected view rightmost cell. (Command form: sR.)
  • +
+ +

+ If step left is enabled, left motion is available either as explicit primitives, or via negative n on sn(n), depending on the configured interface. + When explicit left primitives exist, they correspond to the mirror view command forms. +

+ +
    +
  • Ls() steps to the left neighbor. (Command form: Ls.)
  • +
  • Lsn(n) steps left n times. (Command form: Lsn(n).)
  • +
  • LsR() cues the head to leftmost. (Command form: LsR.)
  • +
+ +

+ Note the correspondence: sR cues rightmost in the base view, and LsR cues leftmost of that same underlying tape. + The primitives sR() and LsR() are optimized cues. +

+ +

Input and output primitives

+ +

+ The I/O primitives implement r and w(value). + In the command language, r reads the current cell payload, and w(v) writes a payload to the current cell. + As of the time of this writing, these operations are cell local, so mirror view does not change their behavior. +

+ +
    +
  • r() reads the current cell.
  • +
  • w(v) writes v to the current cell.
  • +
+ +

+ Bulk forms can exist in the API, but they are not represented in the current command grammar. + They are library level conveniences built on top of repeated primitive behavior. + If bulk copy forms become part of the command grammar later, mirror view will affect scan direction for those operations. +

+ +
    +
  • rn(n) reads n cells.
  • +
  • wn(list) writes a list of values.
  • +
+ +

Destructive Primitives

+ +

+ Machines configured with the SO (Solitary) entanglement approach may expose primitives that modify the tape structure. + These are distinct from w (which modifies cell content) because they change the cell count or sequence. +

+ +

+ Note: Not all container types support all destructive operations. For example, Arr (Fixed Array) does not support deletion or insertion, whereas ArrV (Variable Array) does. +

+ +

Delete Neighbor (esd)

+

+ A compound-style primitive that deletes a neighbor without moving the active head. + Mnemonic: Entangle-Step-Delete (conceptually acts on the neighbor). +

+
    +
  • esd(): Deletes the immediate right neighbor. Guard: Requires not qR().
  • +
  • eLsd(): Deletes the immediate left neighbor. Guard: Requires not LqR().
  • +
+ +

Delete to Bound (dR)

+
    +
  • dR(): Deletes from current to Rightmost (inclusive). Head steps left. Guard: Requires not LqR().
  • +
  • LdR(): Deletes from current to Leftmost (inclusive). Head lands on right neighbor. Guard: Requires not qR().
  • +
+ +

Insert/Append (esa)

+
    +
  • esa(v): Appends value v after the current head position.
  • +
  • eLsa(v): Appends value v before the current head position.
  • +
  • aR(v): Appends value v to the Rightmost end of the tape.
  • +
  • LaR(v): Appends value v to the Leftmost end of the tape.
  • +
+ +

Query primitives

+ +

+ Query primitives are built from the q command. + On the step right only machine, the primitive set covers the boolean query forms. +

+ +
    +
  • qR() returns whether the head is on the selected view rightmost cell. (Command form: qR.)
  • +
  • qnR() returns number of steps to rightmost cell. (Command form: qnR.)
  • +
+ +

+ Mirror view query forms follow the same rule in the command language. + For example, LqR tests the leftmost of the underlying tape. +

+ +
    +
  • LqR() returns whether the head is on the leftmost cell. (Command form: LqR.)
  • +
  • LqnR() returns number of steps to leftmost cell. (Command form: LqnR.)
  • +
+ +

Entanglement primitives

+ +

+ Entanglement primitives implement the e command. + 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. +

+ +
    +
  • e() returns a new entangled machine sharing the same tape. (Command form: e.)
  • +
+ +

+ Combined command forms such as es are legal in the grammar, but they are not required as primitives. + The library can expose such combinations as convenience calls, or generate them through a compile layer. + The core model remains that a statement is a sequence of commands applied to a selected view. +

+ +

Usage

+ +

First order TM properties

+ +

+ For a first order TM these properties are always true. +

+ +
    +
  1. The head is always on a valid cell.
  2. +
  3. All cells return a value when read.
  4. +
+ +

+ In order to maintain these properties, a TM uses inclusive bounds for intervals, including intervals of cells. +

+ +

Contract with the programmer

+ +

+ Some first order TM types rely upon the caller to maintain a contract. + Such machines typically have debug variants that add contract checks. + For some machines, breaking the contract limits compiler optimization. + For other machines, breaking the contract causes program bugs. +

+ +

+ Contract: +

+ +
    +
  1. When there is a right bound, the caller guarantees that he will never command the machine to step beyond the rightmost cell.
  2. +
  3. When there is a left bound, the caller guarantees that he will never command the machine to step left of the leftmost cell.
  4. +
+ +

+ When traversing a tape, the contract is fulfilled by a First Rest pattern. +

+ +

First Rest pattern with initialization

+ + + # Pattern 1: First Rest (Initialize with First) + # Useful when the accumulator starts with the first value. + total = tm.r() # Process First + while not tm.qR(): # Guard: Is there a Rest? + tm.s() # Step (Protected) + total += tm.r() # Process Next + + +

+ Here tm.qR() queries whether the head is on the selected view rightmost cell. + It guards the step in the loop. + No redundant tests are done, and the loop ends without stepping off the tape. +

+ +

First Rest pattern without initialization

+ +

+ Sometimes the accumulator is initialized to an identity value (such as zero) before the loop starts. + In that form, the loop and a half structure is natural. +

+ + + # Conceptual "do" loop + do: + total += tm.r() # Always process the current cell + if tm.qR() break # protects increment from spilling over + tm.s() # Step only when not at the end + + +

+ Python has no do statement, so the same logic is written explicitly: +

+ + + # Python implementation + while True: + total += tm.r() + if tm.qR(): break + tm.s() + + +

+ The middle test tm.qR() guards tm.s(), so the machine never steps beyond rightmost. +

+ +

Region Machine

+ +

A Region Machine is a composite structure built from three entangled tape machines. It enforces the invariant that the active head remains within a specified closed interval of the tape.

+ +

Structure

+ +

The Region Machine consists of:

  • Left Boundary Machine: A TM marking the leftmost valid cell of the region.
  • Right Boundary Machine: A TM marking the rightmost valid cell of the region.
  • Active Machine: The TM interface exposed to the user for navigation and I/O.
+ +

Because the Region Machine relies on the First Order invariant (head always on a valid cell), a region cannot be empty. The minimum region size is one cell, where the Left Boundary, Right Boundary, and Active Head all occupy the same cell.

+ +

Behavior

+ +

The Region Machine implements the standard TM interface but constrains movement based on the boundary heads.

+ +
  • Step (s): The Active Head performs a step only if it is not currently on the Right Boundary cell.
    • s() requires not qR().
  • Step Left (Ls): The Active Head performs a left step only if it is not currently on the Left Boundary cell.
    • Ls() requires not LqR().
  • Query Bounds (qR, LqR):
    • qR() returns true if the Active Head is on the same cell as the Right Boundary Head.
    • LqR() returns true if the Active Head is on the same cell as the Left Boundary Head.
  • Cue Bounds (sR, LsR):
    • sR() moves the Active Head to the cell occupied by the Right Boundary Head.
    • LsR() moves the Active Head to the cell occupied by the Left Boundary Head.
+ +

Boundary Management

+ +

The boundaries of a region are themselves Tape Machines. This allows the region to expand or contract dynamically. Moving a boundary head changes the effective range of the Active Machine immediately.

+ +

Safety Constraint: A boundary head cannot step past the other boundary head. The Left Boundary must always be to the left of or on the same cell as the Right Boundary. Furthermore, the Active Head must not be orphaned by boundary movement. If the Right Boundary steps left past the Active Head, the Active Head is no longer valid. Therefore, boundary contraction requires checking or moving the Active Head to maintain the invariant.

+ +

TM Workspace functions

+ +

The TM_workspace namespace contains higher-level functions that coordinate multiple machines. These functions are not part of the core TM interface but operate on TMs to implement common algorithms.

+ +

Tandem operations

+ +

Tandem operations drive multiple machines simultaneously. They are useful for copying, comparing, or parallel processing.

+ +
  • step_tandem(tm1, tm2): Steps both machines to their respective right neighbors. Requires that neither machine is at its rightmost bound.
  • zip_apply(f, tm1, tm2): Applies function f to the values read from tm1 and tm2, then steps both.
+ +

Predicates

+ +

Predicates test relationships between entangled machines.

+ +
  • head_on_same_cell(tm1, tm2): Returns true if the heads of two entangled machines are on the same cell. This is the fundamental primitive used to implement qR in Region Machines.
+ + + + + +

Second Order Machine (TMS)

+ +

A Second Order Machine, or TMS (Tape Machine Status), is a wrapper that manages the lifecycle of a First Order Tape Machine. It introduces the concept of status to handle conditions that violate First Order invariants, specifically the absence of valid cells (emptiness).

+ +

Status definitions

+ +

The TMS manages a state machine where the states are called statuses to distinguish them from the internal state of the tape or head. The current status determines which interface functions are available to the programmer.

+ +
  • Active: The machine contains cells. The underlying First Order TM is valid. All standard TM navigation and I/O commands function normally.
  • Empty: The machine contains no cells. There is no tape and no head position. First Order operations like r or s are invalid and will raise errors if called. Only status-query and insertion operations are available.
  • Parked: The machine contains cells, but the head is effectively "lifted" from the tape. The head is not on any valid cell. This status is often used during initialization or after a search fails to find a target.
+ +

Dynamic interface dispatch

+ +

The TMS implementation uses dynamic dispatch (or mixin replacement) to enforce status constraints. When the status changes, the interface functions are swapped.

+ +

For example, in the Empty status, the r() function is mapped to an error handler: Error: Attempted to read from an empty machine. This prevents the programmer from accidentally running First Order logic on a machine that does not satisfy the First Order invariant.

+ +

Transitions

+ +

Status changes occur when operations alter the cell count to or from zero, or when the head is explicitly parked or unparked.

+ +

Promotion (Empty to Active)

When a TMS is Empty, calling an insertion function (e.g., append(v)) creates the first cell. The status transitions to Active. The interface is updated to expose standard TM behaviors. The head is placed on the newly created cell.

+ +

Demotion (Active to Empty)

If a deletion operation removes the last remaining cell of an Active machine, the First Order invariant is broken. The TMS detects this event, destroys the underlying First Order TM, and transitions the status to Empty. The interface is updated to the restricted Empty set.

+ +

Usage with algorithms

+ +

Algorithms requiring a First Order TM (such as foreach loops or First Rest patterns) must effectively be guarded by a status check.

+ + if tms.is_active(): # Safe to treat as a First Order TM run_algorithm(tms) else: # Handle empty case pass + +

Because the TMS implements the TM interface, it can be passed directly to these algorithms. However, if the status is Empty, the first operation attempted by the algorithm (usually r()) will trigger a "second order" error, alerting the programmer that they neglected the guard.

+ +
+ + diff --git a/setup b/setup index ebc1244..7603f3e 100644 --- a/setup +++ b/setup @@ -41,18 +41,6 @@ fi source shared/authored/setup fi -# setup tools -# - export PYTHON_HOME="${REPO_HOME}/shared/linked-project/Python" - if [[ ":${PATH}:" != *":${PYTHON_HOME}/bin:"* ]]; then - export PATH="${PYTHON_HOME}/bin:${PATH}" - fi - - RT_gcc="${REPO_HOME}/shared/linked-project/RT_gcc/release" - if [[ ":${PATH}:" != *":${RT_gcc}:"* ]]; then - export PATH="${RT_gcc}:${PATH}" - fi - # setup the role # export ROLE="${1}" diff --git a/shared/document/installation_Python.org b/shared/document/installation_Python.org index 06155b7..bd37a3a 100644 --- a/shared/document/installation_Python.org +++ b/shared/document/installation_Python.org @@ -1,73 +1,71 @@ -#+TITLE: Installing Python in Harmony -#+AUTHOR: Thomas Walker Lynch -#+OPTIONS: toc:2 num:nil - -* Overview - -This document describes how to install a project-local Python environment under: - -#+begin_src bash -shared/linked-project/Python -#+end_src - -* Precondition - -Ensure the following: - -- You are in a POSIX shell with =python3= installed. -- The =python3-venv= package is available (on Debian: =sudo apt install python3-venv=). -- You have sourced the Harmony environment via =env_toolsmith= to initialize =REPO_HOME= and related variables. - -* Step-by-Step Installation - -1. Source the Harmony environment: - #+begin_src bash - source env_toolsmith - #+end_src - -2. Create the virtual environment: - #+begin_src bash - python3 -m venv "$REPO_HOME/shared/linked-project/Python" - #+end_src - -3. Activate it temporarily to install required packages: - #+begin_src bash - source "$REPO_HOME/shared/linked-project/Python/bin/activate" - pip install --upgrade pip - pip install pytest # Add any shared packages here - deactivate - #+end_src - -4. Rename Python's default activate and deactivate: - Harmony provides its own role-aware environment management. Using Python’s default activation scripts may interfere with prompt logic, PATH order, and role-specific behavior. - - Disable the default scripts by renaming them: - #+begin_src bash - mv "$REPO_HOME/shared/linked-project/Python/bin/activate" \ - "$REPO_HOME/shared/linked-project/Python/bin/activate_deprecated" - #+end_src - - This ensures that accidental sourcing of Python’s =activate= script won't override Harmony's environment setup. - -5. Verify installation: - #+begin_src bash - ls "$REPO_HOME/shared/linked-project/Python/bin/python3" - #+end_src - - The binary should exist and report a working Python interpreter when run. - -* Notes - -- The virtual environment is deliberately named =Python=, not =venv=, to reflect its role as a shared system component. -- Harmony environment scripts define and control =VIRTUAL_ENV=, =PYTHON_HOME=, and =PATH=, making Python activation seamless and uniform. -- There is no need to use Python’s =bin/activate= directly — it is fully replaced by Harmony’s environment logic. - -* Related Files - -- =shared/authored/env= -- =shared/authored/env_source= -- =env_developer=, =env_tester=, =env_toolsmith= - -* Last Verified - -2025-05-19 :: Activate/deactivate renamed post-install. Requires Harmony environment sourcing prior to execution. +#!/usr/bin/env bash +script_afp=$(realpath "${BASH_SOURCE[0]}") + +# Enforce execution for this administrative tool +if [[ "${BASH_SOURCE[0]}" != "$0" ]]; then + echo "$script_afp:: This script must be executed, not sourced." + return 1 +fi + +# without this bash takes non-matching globs literally +shopt -s nullglob + +# does not presume sharing or world permissions +umask 0077 + +# Ensure required environment variables exist +if [[ -z "$REPO_HOME" || -z "$PROJECT" ]]; then + echo "Error: REPO_HOME or PROJECT variables are undefined. Please source the setup administrator first." + exit 1 +fi + +echo "Repository Home: $REPO_HOME" +echo "Project Name: $PROJECT" + +# The scratchpad must exist at the top level of the project +scratchpad="$REPO_HOME"/scratchpad +if [[ ! -d "$scratchpad" ]]; then + echo "Error: scratchpad directory missing at $scratchpad" + exit 1 +fi + +version=3.12.3 +tarf=Python-"$version".tgz +Python_dn=Python-"$version" + +# Python installation target located at the sibling level +Python_da="$(realpath "$REPO_HOME"/../)"/"$Python_dn" + +# Verify if the requested Python version is already built +if [[ -x "$Python_da/bin/python3" ]]; then + echo "Python $version is already built and installed at $Python_da." +else + # Download only if the archive is absent + wget -nc -P "$scratchpad" https://www.python.org/ftp/python/"$version"/"$tarf" + + # Extract into the scratchpad to prevent source and installation collisions + Source_dn="$scratchpad"/Python-src-"$version" + mkdir -p "$Source_dn" + tar xzf "$scratchpad"/"$tarf" -C "$Source_dn" --strip-components=1 + + cd "$Source_dn" || exit 1 + + # Configure with developer baseline (--enable-shared) required for C extensions + LDFLAGS="-Wl,-rpath=$Python_da/lib" ./configure --prefix="$Python_da" --enable-optimizations --enable-shared + + make -j8 + make install +fi + +# Establish the executable link +link_dir="$REPO_HOME"/shared/linked-project +mkdir -p "$link_dir" +cd "$link_dir" || exit 1 + +if [[ ! -L "$Python_dn" ]]; then + # The depth accurately escapes linked-project, shared, and REPO_HOME + ln -s ../../../"$Python_dn"/ "$Python_dn" + echo "Successfully created symlink for $Python_dn" +else + echo "The symlink for $Python_dn already exists." +fi diff --git a/shared/linked-project/Python-3.12.3 b/shared/linked-project/Python-3.12.3 new file mode 120000 index 0000000..e0f747b --- /dev/null +++ b/shared/linked-project/Python-3.12.3 @@ -0,0 +1 @@ +../../../Python-3.12.3/ \ No newline at end of file diff --git a/shared/tool/PATH.sh b/shared/tool/PATH.sh new file mode 100644 index 0000000..01d9da6 --- /dev/null +++ b/shared/tool/PATH.sh @@ -0,0 +1,4 @@ +export VIRTUAL_ENV="$REPO_HOME/shared/linked-project/Python-3.12.3" +export PYTHON_HOME="$VIRTUAL_ENV" +unset PYTHONHOME +PATH="$VIRTUAL_ENV/bin:$PATH" diff --git a/shared/tool/setup b/shared/tool/setup index 58af6d9..6cfc738 100644 --- a/shared/tool/setup +++ b/shared/tool/setup @@ -14,15 +14,13 @@ umask 0077 # -------------------------------------------------------------------------------- # project definition -# actual absolute director path for this script file - +# actual absolute directory path for this script file script_adp(){ dirname "$script_afp" } -# assume this script is located $REPO_HOME/tools_shared/authored and work backwards -# to get $REPO_HOME, etc. - +# This script is located at $REPO_HOME/shared/tool/setup. +# Ascend two directories to discover the absolute $REPO_HOME path. REPO_HOME=$(dirname "$(dirname "$(script_adp)")") echo REPO_HOME "$REPO_HOME" @@ -34,30 +32,6 @@ umask 0077 export REPO_HOME PROJECT PROMPT_DECOR -# -------------------------------------------------------------------------------- -# Project wide Tool setup -# - -export VIRTUAL_ENV="$REPO_HOME/shared/linked-project/Python" -export PYTHON_HOME="$VIRTUAL_ENV" -unset PYTHONHOME - - -# -------------------------------------------------------------------------------- -# PATH -# precedence: last defined, first discovered - - PATH="$REPO_HOME/shared/authored:$PATH" - PATH="$REPO_HOME/shared/made:$PATH" - PATH="$REPO_HOME/shared/tool:$PATH" - - # Remove duplicates - clean_path() { - PATH=$(echo ":$PATH" | awk -v RS=: -v ORS=: '!seen[$0]++' | sed 's/^://; s/:$//') - } - clean_path - export PATH - # -------------------------------------------------------------------------------- # the following functions are provided for other scripts to use. # at the top of files that make use of these functions put the following line: @@ -69,7 +43,7 @@ unset PYTHONHOME basename "$script_afp" } - ## script's dirpath relative to $REPO_HOME + ## script's file path relative to $REPO_HOME script_fp(){ realpath --relative-to="${REPO_HOME}" "$script_afp" } @@ -81,10 +55,31 @@ unset PYTHONHOME export -f script_adp script_fn script_dp script_fp +# -------------------------------------------------------------------------------- +# PATH & Plugin Sourcing +# precedence: last defined, first discovered + + PATH="$REPO_HOME/shared/authored:$PATH" + PATH="$REPO_HOME/shared/made:$PATH" + PATH="$REPO_HOME/shared/tool:$PATH" + + # Remove duplicates + clean_path() { + PATH=$(echo ":$PATH" | awk -v RS=: -v ORS=: '!seen[$0]++' | sed 's/^://; s/:$//') + } + clean_path + + # Sourcing is wrapped in a conditional guard to prevent failure on initial bootstrapping + installed_tool_sh="$REPO_HOME/$(script_dp)/PATH.sh" + if [[ -f "$installed_tool_sh" ]]; then + source "$installed_tool_sh" + fi + + export PATH + #-------------------------------------------------------------------------------- # used by release scripts # - install_file() { if [ "$#" -lt 3 ]; then echo "env::install_file usage: install_file ... " @@ -111,8 +106,6 @@ unset PYTHONHOME if ! install -m "$perms" "$source_fp" "$target_file"; then echo "env::install_file: Failed to install $(basename "$source_fp") to $target_dp" return 1 - else - echo "env::install_file: installed $(basename "$source_fp") to $target_dp with permissions $perms" fi done } @@ -125,4 +118,3 @@ unset PYTHONHOME if [[ -z "$ENV" ]]; then export ENV=$(script_fp) fi - diff --git a/shared/tool/version b/shared/tool/version index f4f7d38..4e16589 100755 --- a/shared/tool/version +++ b/shared/tool/version @@ -1,4 +1,4 @@ -echo "Harmony v3.0 2026-05-10" +echo "Harmony v3.2 2026-05-31"