#life #artificial #input-output #distributed #assembly #distributed-systems

app aelhometta

古老的自主非沙箱分布式人工生命模拟器尝试

9个稳定版本

1.0.16 2024年6月26日
1.0.14 2024年6月8日
1.0.12 2024年5月25日
1.0.8 2024年4月13日
1.0.2 2024年1月23日

科学 中排名 4

Download history 134/week @ 2024-05-03 14/week @ 2024-05-10 8/week @ 2024-05-17 155/week @ 2024-05-24 8/week @ 2024-05-31 169/week @ 2024-06-07 22/week @ 2024-06-14 136/week @ 2024-06-21 14/week @ 2024-06-28 37/week @ 2024-07-05 4/week @ 2024-07-12

每月下载 748

GPL-3.0-or-later

480KB
7K SLoC

Ælhometta

crate

古老的自主非沙箱分布式人工生命模拟器尝试,它具有以下特点:描述数据和执行数据的分离,提供分支和循环而无需跳转指令,通过Tor与其他实例进行加密的发布-订阅交互,通过与外部传感器和执行器相关联的普通文件进行输入/输出,以及内置的shell。

当然,它与AlChemy[FON1], [FON2] / Avida[ADA1], [OFR1] / Coreworld[RAS1] / Stringmol[HIC1] / (网络) Tierra[RAY1], [RAY3] / ... / biolife 相似,作为一个项目和概念,由于参与设备较少,可能比预期更早地崩溃或分支,这些设备 可以控制,它们定期在线,并且可以选择连接到麦克风、摄像头、温度计、接收器、剂量计 等(输入)以及扬声器、显示器、空调、发射器、控制棒 等(输出)。然而,一个实例可以完全在离线设备的内存中独立运行,不接触外界,或在不同模式之间切换。

demo scast gif

freqs scast gif

到现在,你可能比我们更了解这类企业那些耀眼而难以捉摸的目标——无限开放、寒武纪大爆发、诸如此类——问题在于,如果它们与安全相冲突怎么办?如果必要(尽管不是充分)的条件是允许人工环境与现实世界在沙箱阈值之外进行交互呢?在这个世界中,受进化塑造的我们,如果它没有受到同一世界力量的塑造,如果没有名称的某些力量,我们能否识别无限开放?如果它导致毁灭,它将死去……或者说,不那么适应的变异体将死去,但更适应的变异体将生存下来。

如果是这样,那么我们应该选择:无限开放或安全。另一方面,我们宝贵的安全可能源于……经验,简单地说:数十年的研究,大量的反思,但——没有例外,因为我们还在这里……然而——最终,只是一个失败。正如二十年前所指出的,

“所有这些都是令人印象深刻的工作,它指明了这些富有想象力的个人所做工作的方向。但是,整合从未发生。我参加的每一次会议,涉及的更大群体似乎都希望从头开始,用自己的方式来做。每个人都以自己的方式设定问题。几乎没有足够的工作是在雷和其他人的有希望的开始的基础上进行的。这个领域从未过渡到任何类似正常科学的东西。现在它已经停滞不前。”[GOD1]

目录

功能

  • 节点,一种记忆单元——包含基本指令,具有不透明的地址,通过指向下一个节点的指针形成链。

  • 控制器,一种CPU——在每次滴答时随机选择,沿着节点链移动,执行改变其局部状态和全局状态的指令。

  • 没有“指针算术”,因此由于节点地址的不透明性,有“写保护”。再见易碎性?你好刚性!此外,ælhometta居住的“空间”的欧几里得性更少:它既不是1D,也不是任何nD,连接性差,东西不会在短距离或长距离(实际上,没有度量)“移动”。

  • 在祖先实体中将描述性(类似于染色体的“方案”)和执行性(类似于核糖体的“构造者”)链分离:一条链描述方案,另一条链实现它。这可能是与“传统”方法的主要差异,在这些人工生命世界的部分,通常一个“生物体”会扫描并复制自己的代码……尽管它类似于在Tierra中进化的(超)寄生虫,当然,冯·诺伊曼的原始方法也有这种分离[NEU1]

  • (这种分离提供了)执行流程的非线性,没有跳转指令,既不是按地址,也不是按模板;相反,每个节点有2个指针,一个指向主下一个节点,另一个指向替代下一个节点。选择由控制器根据某些标志来决定,但两条路线都由执行链构建的方案定义。

  • 基于原始链,可以复制(线性逐字复制)或构建(非线性地构建,考虑特殊的“构建”指令)新的链。

  • 通过环形缓冲区和悬挂指针实现“死亡率”:当节点或控制器数量达到最大值时,新节点会替换旧节点,当控制器跟随前一个节点的指针移动到不存在的节点时,该控制器将不再存在。

  • 2个全局可访问数组——节点的不透明地址和整数的数组——用于控制器之间的通信。前者不包含所有这样的地址,而只是控制器传输的地址。这里的寻址是线性的,因此欧几里得性再次出现。

  • 通过互联网(特别是通过Tor)与其他实例进行加密交互,遵循发布-订阅模式ZeroMQ。交换的数据是64位小端整数的数组,至少在Ælhometta提供的级别上是这样;直到达到一定复杂性之前,ælhomettas如何解释这些数据是无意义的。

  • 通过包含64位小端整数的普通文件进行输入和输出,以连接到“现实世界”。这里缺少的链接是一系列外部应用程序,它们将文件本身与现实世界连接,分为两种:记录器将传感器数据写入文件,播放器从文件中读取数据以控制执行器。

  • 没有手动调整单个节点和控制器的方法,这样你就不需要玩骰子的原子,让姐姐机会来做。

  • 使用交互式shell进行控制或运行指定时间。

  • 在退出时自动保存状态,在启动时加载状态。

  • 跨平台——已知在以下目标上运行,至少有预编译的二进制文件

    • x86_64-unknown-linux-gnu

    • i686-unknown-linux-gnu

    • aarch64-unknown-linux-gnu

    • armv7-unknown-linux-gnueabihf

    • x86_64-apple-darwin

    • aarch64-apple-darwin

    • aarch64-linux-android

    • armv7-linux-androideabi

    • x86_64-pc-windows-msvc/-gnu

    • i686-pc-windows-msvc/-gnu

  • 即使在文本模式下也可以运行。

  • 源代码小,小于整个README的3倍。

部署

取决于目标系统,其中Ælhometta将要运行。下载发行版的二进制文件或从源代码构建,源代码可在crates.ioGitHub上找到。

二进制文件是尝试此项目的最快方式,而专门为您的设备从源代码构建则可以为优化铺平道路,这些优化可能不会出现在“通用”二进制文件中;特别是,速度很重要——当它成为10天、几个月、几年等待(数字)进化达到某个里程碑的区别时,10%的增加看起来并不小……或者承认没有里程碑。(谁会等这么久?)当然,你需要一定的兴趣来投资这种调整。

大多数与依赖项相关的问题都涉及libzmqlibsodium,这些库不是由Ælhometta直接需要的,而是由它所依赖的emyzelium crate需要的,该crate是ZeroMQ部分的一个薄包装;这种薄度是我们将它们称为Ælhometta本身依赖项的原因。

Linux在x86_64/i686/aarch64/arm[v7]/...

最简单的方法是下载与您的体系结构对应的最新发行版

请注意,它包含依赖项——.so文件在deps/中,——提供可移植性:aelhometta_using_deps.sh应该在这些库系统范围内是否存在时都能工作。另请参阅build.rs中与*-unknown-linux-gnu相关的部分。

要在基于Debian的发行版上全局安装依赖项(从官方仓库系统)

$ sudo apt install libzmq3-dev

或者从源代码构建Ælhometta:安装与上述相同的依赖项,然后安装Rust工具链,下载源代码,例如到~/rust/aelhometta/,然后从这里

$ cargo build --release

接下来,深入洞中是构建Ælhometta的依赖项libzmq及其核心依赖项libsodium。这有其自身的“成本”(工具链设置和编译问题……本节的其余部分属于C/C++世界,Rust在最后简要提及),但允许更好的设备特定调整(例如,--enable-opt选项是libsodiumconfigure),并减少了您必须与可执行文件一起打包的共享库的数量;通常这两个就足够了,与包含“全部包含”的libzmq的官方仓库中的额外libpgmlibnormlibcomm_err等相比。显然,当手头的设备没有预构建的二进制文件/库时,这一步是强制性的

以下假设libsodiumlibzmq不是全局安装的,因此它们不会在构建过程中作为错误的依赖项而干扰。

  • 安装构建工具
$ sudo apt install cmake

(它还会根据建议安装make

I) libsodium

libsodium的本地构建
  • 安装编译器(s)
$ sudo apt install g++
  • ~/libsodium/build/,运行常规
$ ../configure
$ make -j 8
libsodium的交叉构建

例如,从一个基于Debian的发行版的x86_64主机到aarch64目标。

  • 安装工具链
$ sudo apt install g++-aarch64-linux-gnu
  • ~/libsodium/build/中,创建文件build.sh(基于
#!/bin/sh

export CFLAGS='-Os'
../configure --host=aarch64-linux-gnu
make -j 8

通过chmod u+x使其可执行并运行。


II) libzmq

  • https://github.com/zeromq/libzmq/releases下载zeromq-A.B.C.tar.gz到例如~/zeromq/,在内部创建build目录

  • ~/zeromq/build/中创建sysroot目录,并在其中

    • 放置~/libsodium/src/libsodium/include/目录的副本(或将其作为符号链接),包括来自~/libsodium/build/src/libsodium/include/sodium/version.h文件

    • 创建 lib 目录,将其中的 libsodium.solibsodium.so.A 等文件复制到该目录中——您已经在 (I) 中构建了这些文件——从 ~/libsodium/build/src/libsodium/.libs/(或者将其设置为 .../.libs/ 的符号链接)

  • ~/zeromq/build/ 准备 genvars.cmake 文件,内容如下

set(BUILD_STATIC OFF CACHE BOOL "")
set(BUILD_TESTS OFF CACHE BOOL "")
set(WITH_LIBBSD OFF CACHE BOOL "")
set(WITH_LIBSODIUM ON CACHE BOOL "")
set(ENABLE_CURVE ON CACHE BOOL "")
  • ~/zeromq/build/ 准备 CMake 的工具链文件 toolchain.cmake(基于 另一个CMake 文档

    • toolchain.cmake 的第一部分
libzmq 的本地构建
set(CMAKE_FIND_ROOT_PATH ${CMAKE_BINARY_DIR}/sysroot)
libzmq 的交叉构建

(再次,从 x86_64aarch64。)

set(TOOLCHAIN_PREFIX aarch64-linux-gnu)

set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)

set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX};${CMAKE_BINARY_DIR}/sysroot)
    • toolchain.cmake 的第二部分
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

set(CMAKE_CXX_FLAGS "-static-libgcc -static-libstdc++")

set(ENV{PKG_CONFIG_LIBDIR} ${CMAKE_BINARY_DIR}/sysroot/lib/pkgconfig)

set(CMAKE_SKIP_BUILD_RPATH true)

检查点:构建树的目录结构应该是

~/zeromq/build/
|--sysroot/
|  |--include/
|  |--lib/
|--genvars.cmake
|--toolchain.cmake
  • 切换到 ~/zeromq/build/ 目录并运行
$ cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake -C genvars.cmake ..
$ cmake --build . --config Release -j 8

关于清理的说明。 使用脚本(注意使用 bash 而不是 sh)将构建目录重置为其初始状态

#!/bin/bash

shopt -s extglob
rm -rf !("sysroot"|"genvars.cmake"|"toolchain.cmake")

关于 x86_64-到-i686 的交叉构建。 工具链是 g++[-9]-multilib;如果 g++-multilib 与 ARM 交叉工具有关的内容冲突,请将其删除,但保留其“编号”版本,例如 g++-9-multilib。向 CFLAGSCMAKE_CXX_FLAGS 变量添加 -m32。您可能还需要将 /usr/include/asm 符号链接添加到 /usr/include/asm-generic/


关于通过 Zig 构建 libsodium 的说明。 另一个选项,安装 Zig 并遵循 这些说明


假设 (I)(II) 已成功完成,然后将获得的共享库(.so 文件/ libsodiumlibzmq 的符号链接),放入 Rust 工具链能够“捕获”它们的位置——即 ~/rust/aelhometta/target/TARGET/release/deps/(此处 TARGET 是目标,例如 aarch64-unknown-linux-gnu)。libsodium.so.Mlibzmq.so 符号链接就足够了。

最后,从 ~/rust/aelhometta

$ cargo build --release [--target i686-unknown-linux-gnu]

或者,如果 Cargo 无法自行选择合适的链接器,

$ RUSTFLAGS="-C linker=aarch64-linux-gnu-g++" cargo build --release --target aarch64-unknown-linux-gnu

由于从本过程生成的Ælhometta可执行文件是针对库的构建版本“调整”的,因此它们必须与它一起分发。例如,请参阅针对Linux的二进制发布版本:存在一个名为deps的目录,其中包含libsodium.so.Mlibzmq.so.N的文件,并且运行可执行文件的脚本会告诉动态连接器/加载器在那个目录中查找。在最简单的情况下,当您在它所在的同一目录中运行可执行文件时,

$ LD_LIBRARY_PATH=deps:$LD_LIBRARY_PATH ./aelhometta

就足够了。

关于符号链接的说明。 如果您经历了许多构建过程的迭代,请使用它们,以避免反复将更新的库复制到依赖程序的构建树中。例如,将~/zeromq/build/sysroot/lib/作为~/libsodium/build/src/libsodium/.libs/的符号链接。

macOS on x86_64/aarch64

的情况与Linux非常相似,只是brew代替了aptzeromq代替了libzmq,以及一些其他区别。

从您架构的最新二进制发布版开始。

位于deps/中的.dylib文件提供可移植性:aelhometta_using_deps.sh在这些库存在于系统范围内或不存在时都能正常工作。

要全局安装依赖项,首先安装Homebrew包管理器,按照https://brew.sh.cn/上的说明进行操作。其间,将安装Xcode命令行工具。然后

$ brew install zeromq

或者从源代码构建Ælhometta:安装与上述相同的依赖项,然后安装Rust工具链,下载源代码,例如到~/rust/aelhometta/,然后从这里

$ cargo build --release

(第一次可能因为缺少cc而失败,但macOS应该会弹出窗口提示安装工具链。)


您还可以从源代码构建Ælhometta的依赖库libzmq以及核心依赖项,该依赖项提供安全性,libsodium。例如,当$ brew install zeromq失败(我们应该说是崩溃?溢出?)时,或者当您需要更好的设备特定调整(例如,libsodiumconfigure--enable-opt选项)时。

实际上,在旧版本的macOS上,这种方法比$ brew install zeromq要快得多——我们在这里谈论的是分钟小时的差距——因为后者安装了20个或更多的依赖项,其中大多数也是从源代码构建的。

这里我们主要考虑本机构建过程,从macBook上的macOS到macBook上的macOS,可能除了不同的架构(请参见末尾的说明)。当然,还有交叉编译的替代方案,其中QuickEmu就是其中之一(考虑此手册ram="<something>G"添加到macos-<version>.conf中,并与if [ "${RAM_VM//G/}" -lt 8 ]; then行中的8进行减少,位于/usr/bin/quickemu,以及--extra_args "-cpu host"参数的quickemu调用)。

为了简化,我们假设 libsodiumlibzmq 并未全局安装;如果已安装,它们可能会因为错误的依赖而干扰构建过程。

  • 安装构建工具
$ brew install cmake pkg-config

I) libsodium

$ configure
$ make -j 8

II) libzmq

  • https://github.com/zeromq/libzmq/releases下载zeromq-A.B.C.tar.gz到例如~/zeromq/,在内部创建build目录

  • ~/zeromq/build/中创建sysroot目录,并在其中

    • include 符号链接放置到 ~/libsodium/src/libsodium/include/ 目录

    • lib 符号链接放置到 ~/libsodium/src/libsodium/.libs/ 目录

  • ~/zeromq/build/ 准备 genvars.cmake 文件,内容如下

set(CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR}/sysroot CACHE PATH "")

set(BUILD_STATIC OFF CACHE BOOL "")
set(BUILD_TESTS OFF CACHE BOOL "")
set(WITH_LIBSODIUM ON CACHE BOOL "")
set(ENABLE_CURVE ON CACHE BOOL "")

检查点:构建树的目录结构应该是

~/zeromq/build/
|--sysroot/
|  |--include/
|  |--lib/
|--genvars.cmake
  • 切换到 ~/zeromq/build/ 目录并运行
$ cmake -C genvars.cmake ..
$ cmake --build . --config Release -j 8

假设 (I)(II) 成功,然后将符号链接放置到构建的共享库 libzmq.dylib 所在的位置,以便 Rust 工具链可以“拾取”它——例如,在 ~/rust/aelhometta/target/release/deps/

最后,从 ~/rust/aelhometta/,

$ cargo build --release

通过这种方式获得的 Ælhometta 可执行文件是针对构建的库版本“调整”的,libsodium.M.dyliblibzmq.N.dylib,因此它们必须存在于附近,并且您可以使用指向它们位置的 DYLD_LIBRARY_PATH 加载它。例如,请参阅 macOS 二进制发布版本。特别是,当您从与可执行文件相同的目录中运行它时,并且 .dylib 文件位于 deps 子目录下

$ DYLD_LIBRARY_PATH=deps:$DYLD_LIBRARY_PATH ./aelhometta

关于从 x86_64 构建到 aarch64 或相反的说明。 基本上是一样的,但构建 libsodium 的脚本最好是以文件的形式存在,例如,在 ~/libsodium/ 中的 build.sh,具有以下内容

#!/bin/sh
export CC="cc --target=aarch64-apple-darwin"
export CFLAGS="--target=aarch64-apple-darwin"
../configure --host=aarch64-apple-darwin
make -j 8

(如果没有这个 --target=... 的重复,.dylib 文件将不存在或“空洞”),同样 libzmq 也是通过以下方式构建的

$ cmake -DCMAKE_C_FLAGS="--target=aarch64-apple-darwin" -DCMAKE_CXX_FLAGS="--target=aarch64-apple-darwin" -C genvars.cmake ..
$ cmake --build . --config Release -j 8
armv7/aarch64 上的 Android

目前,这样的系统上的 Ælhometta 以原生可执行文件的形式在 Termux 中运行,因此首先安装它,并立即通过以下命令更新其包:$ pkg update && pkg upgrade。请 记住 可执行文件应位于 Termux 的 ~ 目录内(即 /data/data/com.termux/files/home),而不是内部存储或外部 SD 卡的任何地方;$ termux-setup-storage 将提供访问外部 SD 卡在 Android/data/com.termux/files 下的部分,您可以使用它将 Ælhometta 的二进制文件通过 $ cp 命令在 Termux 中本身移动到,例如,到 ~/aelhometta/

此操作不需要 root 权限。

依赖项

$ pkg install libzmq

您可以获取最新的二进制发布版(包括依赖项,.so文件在deps/目录中)适用于armv7aarch64(提示:在Termux中使用$ lscpu)。


或者,从源代码构建;本节其余部分将描述如何进行。

  1. 本地构建。使用Termux的Rust包,不是来自https://sh.rustup.rs的脚本。
$ pkg install rust

构建过程的其余部分与Linux情况相同,除了使用$ pkg install libzmq而不是$ sudo apt install libzmq3-dev

  1. 交叉构建。您需要另一个装有Linux的x86_64i686设备。在那里,
  • 下载适用于Linux的最新Android NDK并将其解压到例如~/android-ndk-r26d/。SDK/Studio将是多余的。在解压缩NDK期间,请注意保留.zip中的符号链接,否则它将无法工作 —— configure的错误将出现C编译器无法创建可执行文件错误,由clang调用产生,它们有点误导... 没有输入文件posix_spawn失败: exec格式错误等。 此评论建议使用命令行unzip而不是具有GUI的文件管理器内置提取程序。

  • 安装Rust工具链

  • 获取Ælhometta的源代码

  • https://packages.termux.dev/apt/termux-main/pool/main/获取.deb文件包的libzmq,并在Midnight Commander(或$ ar x package.deb && tar -x -f data.tar.xz)中将其作为存档浏览。您需要从usr/lib/获取libzmq.so,将其复制到.../aelhometta/target/TARGET/release/deps/

  • 最后,从源代码目录,

$ RUSTFLAGS="-C linker=$HOME/android-ndk-r26d/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang++" cargo build --release --target aarch64-linux-android

(或类似地,对于armv7[a]-linux-androideabi代替aarch64-linux-android),以获取target/TARGET/release中的二进制文件。


cross crate 是 Android NDK 的替代品,但它本身需要一些依赖项,特别是 依赖项,例如 Docker Engine。然后,您不需要指定 RUSTFLAGS,而是将 cargo build ... 替换为 cross build ...


注意 Termux 特定的库路径,在 build.rs 中硬编码。还可以选择静态链接。

从源码构建 Android 的 libzmq

通过 libzmq 源代码发布中已包含的面向 Android 的构建脚本得以简化,因此您只需要提供一些通用参数。特别是,libsodium 会在构建过程中创建。为了明确起见,我们假设宿主系统为 Debian,目标系统为 aarch64

#!/bin/sh

# export MIN_SDK_VERSION=21

export NDK_VERSION=android-ndk-r26d
export ANDROID_NDK_ROOT=$HOME/${NDK_VERSION}

export CURVE=libsodium
export LIBSODIUM_ROOT=$HOME/libsodium

./build.sh arm64

然后通过 chmod u+x ... 使其可执行并运行

  • /zeromq/builds/android/prefix/arm64/lib/ 获取构建好的 libzmq.so(链接和运行时依赖项),libsodium.solibc++_shared.so(运行时依赖项)

x86_64/i686 的 Windows

最新版本的 发布版 包含可执行文件和 .dll 依赖项。


或者从源代码构建,在这种情况下,首先的任务是使用一些 C/C++ 工具链(例如 CMake 和 Sodium)从 libzmq 最新版本 中创建链接和运行时 ZeroMQ 库...如果你没有在其他地方获得它们,则预先构建。

本地构建(Windows)
  • 安装包括 CMake 在内的 Visual Studio 建筑工具;本身不需要 Studio

  • 准备包含以下内容的 genvars.cmake 文件

set(CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR}/sysroot CACHE PATH "")

set(BUILD_STATIC OFF CACHE BOOL "")
set(BUILD_TESTS OFF CACHE BOOL "")
set(WITH_LIBSODIUM ON CACHE BOOL "")
set(ENABLE_CURVE ON CACHE BOOL "")
  • https://github.com/zeromq/libzmq/releases下载zeromq-A.B.C.zip,例如保存到C:/src/zeromq-X.Y.Z/,在该目录下创建build目录,并进入该build/目录;在那里,放置genvars.cmake,并使用includelib子目录创建sysroot目录

  • https://download.libsodium.org/libsodium/releases/下载libsodium-X.Y.Z[-stable]-msvc.zip;将include/x64/Release/v.../dynamic内容分别提取到build/sysroot/include/build/sysroot/lib/目录中

  • 运行与您的宿主机和目标相对应的“工具增强”命令提示符,例如x64 Native Tools Command Prompt(在开始菜单中查看VS相关快捷方式)。在这样的提示符内,更改目录到C:/src/zeromq-Z.Y.Z/build/

> cmake -C genvars.cmake ..
> cmake --build . --config Release -j 8

(注意:“裸”命令提示符不足以完成此操作。)

  • build/lib/libzmq-....lib重命名为zmq.lib
交叉编译(Ubuntu到Windows)
$ sudo apt install cmake mingw-w64
  • 为CMake准备工具链文件toolchain.cmake,内容如下
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_VERSION 10.0) # 6.1 -> Windows 7, 6.2 -> Windows 8, 6.3 -> Windows 8.1, 10.0 -> Windows 10
set(TOOLCHAIN_PREFIX ARCH-w64-mingw32)

set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)

set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX};${CMAKE_BINARY_DIR}/sysroot)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

set(CMAKE_CXX_FLAGS "-static-libgcc -static-libstdc++")

set(ENV{PKG_CONFIG_LIBDIR} ${CMAKE_BINARY_DIR}/sysroot/lib/pkgconfig)

其中ARCHx86_64i686

  • 使用以下内容准备genvars.cmake文件
set(BUILD_STATIC OFF CACHE BOOL "")
set(BUILD_TESTS OFF CACHE BOOL "")
set(ZMQ_CV_IMPL none CACHE STRING "")
set(WITH_LIBBSD OFF CACHE BOOL "")
set(WITH_LIBSODIUM ON CACHE BOOL "")
set(ENABLE_CURVE ON CACHE BOOL "")
$ cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake -C genvars.cmake ..
$ cmake --build . --config Release -j 8

现在,应出现在build/lib/中的是zmq.lib(本地)/libzmq.dll.a(交叉)——链接库——,以及在build/bin/中的是libzmq-....dll(本地)/libzmq.dll(交叉)——运行时库

然后,假设 Rust 工具链已安装,并且 Ælhometta 的源代码已下载到 .../aelhometta/ 目录下,— 将链接库复制到 .../aelhometta/target/TARGET/release/deps/ 目录(其中 TARGETx86_64-pc-windows-msvc(本地) / x86_64-pc-windows-gnu(交叉)或 i686-pc-windows-...)。

如果编译是交叉编译,请添加所需的目标

$ rustup target add x86_64-pc-windows-gnu i686-pc-windows-gnu

从 Ælhometta 的源代码目录生成二进制文件

$ cargo build --release [--target ARCH-pc-windows-gnu]


最后,在运行二进制文件之前,您需要将其放在同一目录下的以下 .dll 文件中

  • libzmq.dll — 来自上述描述的 libzmq 构建过程的输出

  • libsodium-MN.dll — 来自 Sodium 发布版,您在构建过程中也已经获得

此外,如果是交叉编译

  • libwinpthread-1.dlllibgcc_s_seh-1.dll(64 位) / libgcc_s_[dw2|sjlj]-1.dll(32 位) — 来自任何地方,例如 /usr/x86_64-w64-mingw32/lib//usr/lib/gcc/x86_64-w64-mingw32/9.3-posixWinLibs 工具链的 MinGW-w64
其他事项

如果没有预构建的二进制文件,并且例如通过 QEMU 进行仿真不是一个选择,那么剩下的就是从源代码构建。 安装 Rust 工具链,将 Ælhometta 的源代码下载到 .../aelhometta/,然后从那里

$ cargo build --release

应该几乎进行到最后...当链接阶段因 -lzmq not found 类似错误而失败时。好吧,现在您需要 libzmq,包括链接和运行时依赖。在您的操作系统仓库、互联网上搜索,尝试从源代码构建(参见 Linux 情况)。

这是可能的,因为所有上述情况都曾经在这里出现过。覆盖的平台越多,能够钩住的本地平台就越多,这将迈出第一个小小的第一步

快速入门

到目前为止,经过 部署,您已经在目标系统上拥有了 Ælhometta 的可执行文件及其依赖项。在 Linux 和 macOS(以及 Android)上,您还可以从二进制发布版运行 aelhometta_using_deps.sh 脚本,使可执行文件依赖于 deps/ 目录中的共享库而不是系统库,——结果应该是相同的。为了明确起见,我们假设您运行的是可执行文件本身。

由于状态保存在一个大小可能达到数百 MB 的文件中,请考虑创建到二进制文件的符号链接,或者将此二进制文件放置在另一个位置,例如 ramdisk,并从中运行它

user@pc:/mnt/ramdisk/aelhom$ ./aelhometta

或者 从那里调用 它,当无法创建符号链接时(例如在 Windows 或 Android 上)

user@pc:/mnt/bigdisk/aelhom$ ~/rust/aelhometta/target/release/aelhometta

无论如何,然后您将看到 shell,不是您的操作系统(提示 $),而是 Ælhometta 本身(提示 Æ

Loading Ælhometta... Cannot load Ælhometta: Cannot open 'aelhometta.bin': No such file or directory (os error 2)
Using new default one
Loading Commander... Cannot load Commander: Cannot read from 'commander.json': No such file or directory (os error 2)
Using new default one

Lastick 1969.12.31 Wed 23:59:59.000 UTC - Age 0 : Nodes 0 | Controllers 0 | Limit =2^22 : Memory ~ 72 MiB
"?" — see the list of available commands
Æ █

我们现在处于可能被称为生物危害等级0的状态...因为还没有发生任何事情。这很无聊,让我们继续吧。

生物危害等级1

ælhometta存在于您的计算机内存中,不触及其他计算机,也不与外界互动。

输入以下命令

Æ anc b 5
Æ r

(与以下相同

Æ ancestor b 5
Æ run

但具有别名)。也就是说,我们引入一个祖先 — 类型为B,容量为5的spacity — 并让环境自行tick。在每个tick时,从所有控制器集中随机选择一个控制器,处理它当前“看”到的节点的内容,并移动到下一个节点。

右边的图表显示了执行命令和其他指令的相对频率。最初,NextOptuid应该是出现频率最高的。

等待大约半分钟,然后按(几乎)任意键停止tick。应该有更多的节点控制器,如下所示

[0:00:29] Age 1934061 : Nodes 3645220 | Controllers 14159
[0:00:30] Age 1965719 : Nodes 3702543 | Controllers 14346

Lastick 2024.01.16 Tue 12:00:30.292 UTC - Age 1974509 : Nodes 3720924 | Controllers 14407 | Limit 4194304=2^22 : Memory ~ 192 MiB
Æ █

观察更多统计信息

Æ stat cgen
Æ stat ctick
Æ stat chan
Æ stat cont
Æ stat run

到目前为止,内容统计(Æ stat cont)大多包含0,因为所有可用命令和指令中只有一小部分存在于祖先B及其精确的副本-后代中。让我们引入随机突变,或glitches

Æ glitch back 0.001
Æ glitch repl 0.03
Æ glitch cons 2.5e-2

然后再次

Æ r

一段时间后,停止并比较新的内容统计与旧的一个。


要详细查看链结构的结构变化,请随机选择控制器的uid — CTRL-UID(8个十六进制数字) — 通过

Æ rand ctrl

并查看该控制器的状态

Æ sct CTRL-UID

该控制器附加的链的起始节点在ChainStart下给出,我们用NODE-UID表示。从起点跟随链

Æ ss NODE-UID

失望的是,序列几乎与原始实体在祖先中描述的相同。进化停滞了吗?

生物危害等级2

ælhometta与其他计算机(或更确切地说,与其他设备上的ælhomettas)互动,但(直接)不与外界互动。

假设2个设备上运行的2个ælhomettas已经在生物危害等级1,你还需要从你这边

  • 从你这边

    • 40个字符的Z85格式曲线公钥和私钥
    • 56个字符的onion地址和端口(0-65535),该Tor隐藏服务运行在你的设备上
  • 从其他设备或其所有者的这边

    • 40个字符的Z85格式曲线公钥和私钥
    • 56个字符的onion地址和端口(0-65535),该Tor隐藏服务运行在该设备上

这是快速做到这一点的方法


在Python中获取密钥对
$ pip3 install -U pyzmq
import zmq
public, secret = zmq.curve_keypair()
print("Public key:", public.decode("ascii"))
print("Secret key:", secret.decode("ascii"))
在Termux上获取密钥对(Android)
$ pkg install libzmq
$ curve_keygen

如果是在Linux上,设置您的onion服务,跳过第1步,因为您不需要web服务器。验证Tor服务通过$ systemctl status tor@default运行,并从HiddenServiceDir指定的目录中的hostname文件中获取onion地址。

在macOS上

安装Tor

$ brew install tor

转到/usr/local/etc/tor/,并将torrc.sample的副本命名为torrc。在任何文本编辑器中打开torrc,取消注释并更改两个与HiddenService相关的行到如下所示

HiddenServiceDir /usr/local/var/lib/tor/hidd_aelhom_srv1/
HiddenServicePort 60847

现在,如果lib/tor目录子树尚未存在,请将其添加到/usr/local/var/中。然后

$ brew services start tor

很快,Tor服务将创建.../hidd_aelhom_srv1/(通过$ brew services info tor验证其运行状态)。该文件内的hostname文件包含洋葱地址。同时备份其他文件,并保持私密。

在Android的Termux上
$ pkg install tor
$ pkg install termux-services

打开/data/data/com.termux/files/usr/etc/tor/torrc并编辑与HiddenService相关的行

HiddenServiceDir /data/data/com.termux/files/usr/var/lib/tor/hidd_aelhom_srv1/
HiddenServicePort 60847

启动Tor服务

$ sv-enable tor
$ sv up tor

(没有systemctlservice)。等待服务创建.../hidd_aelhom_srv1/目录(通过$ sv status tor验证其运行状态)并从hostname文件中获取洋葱地址。同时备份其他文件,并保持私密。

在Windows上

Tor Expert Bundle for Windows应该足够使用。解压其内容,以管理员身份运行命令提示符,并从.../bundle/tor/,

> tor --service install

这会在C:/Windows/ServiceProfiles/LocalService/AppData/Roaming/目录中引入tor子目录。在那里创建torrc文件,内容如下

HiddenServiceDir C:/Windows/ServiceProfiles/LocalService/AppData/Roaming/tor/hidden_service1
HiddenServicePort 60847

从那个管理员命令提示符,

> tor --service stop
> tor --service start

很快将出现由HiddenServiceDir指定的目录,其中包含一些文件。特别是,hostname包含洋葱地址。(其他文件也很重要,请保持其副本的私密性。)


像往常一样,一个秘密密钥必须只为它的所有者所知。

默认端口是608470xEDAF)。

当这些字符串和数字已经确定后,在你的设备上执行以下操作

Æ peer secret MySecretKeyMySecretKeyMySecretKeyMySecre
Æ peer port 60847
Æ peer share size 10000
Æ peer share interval 2000000
Æ peer expose

其他参与者,在他们的设备上,也执行以下操作

Æ peer secret TheirSecretKeyTheirSecretKeyTheirSecretK
Æ peer port 60847
Æ peer share size 20000
Æ peer share interval 1000000
Æ peer expose

现在你们两个人都需要相互订阅对方的发布。你这样做

Æ peer connect TheirPublicKeyTheirPublicKeyTheirPublicK TheirOnionAddressTheirOnionAddressTheirOnionAddressTheir 60847

他们也是这样做的

Æ peer connect MyPublicKeyMyPublicKeyMyPublicKeyMyPubli MyOnionAddressMyOnionAddressMyOnionAddressMyOnionAddress 60847

不要忘记运行两个实例

Æ r

几秒钟后,如果建立了连接,你的ælhometta将能够访问对方ælhometta传输的64位整数数组。使用以下方法在你的设备上检查

Æ peer

—— 应该有1个其他对等点,其Share size应该非零,并且其Last update应该是某个近期时间点(通常是过去几分钟)。要检查接收到的数据,

Æ peer ether TheirPublicKeyTheirPublicKeyTheirPublicK 0 100

你的ælhometta和他们的ælhometta是否实际上使用他们交换的整数值,是另一个问题(提示:可能开始时他们并不使用)。

注意1。“其他”设备可能是...你的设备,即两个ælhometta在同一个计算机上运行。只需在/etc/tor/torrc中将不同的HiddenServicePort分配给相应的隐藏服务即可。

注意2。一些对等点已经存在,尽管“全天候在线”并不能保证...完全如此。尝试连接到他们

Æ peer connect USBD7[O^8L[}saCh+6U#}6wie4oAedZ4#W4!b%LI t3kauc3flp2bpv3mv7vtnedfu6zrho3undncccj35akpuyjqqydwvfyd 60847

Æ peer connect &i!VkHl[]m.c!^j0D%i)&4#[u5b(a=QCdZ9C0$p{ yhel64h6cjab75tcpncnla2rdhqmxut2vtitywhbu7bpjh4hfhp6hnid 60847

这两个只是演示用的,由我们维护以测试网络功能。将来,可能会有更多列在网络中。

Abiohazard Level 3

其中ælhometta与其他ælhometta以及外部世界交互。

因此,你的ælhometta运行在Abiohazard Level 2。我们将添加与周围环境的音频交互,假设其运行的设备至少有一个扬声器和麦克风。

我们还需要2个中间应用程序,本质上是一个播放器和录音机。鉴于它们功能要求非常低,我们的“播放器”将被称为蜂鸣器,我们的“录音机”将被称为听众


  • 蜂鸣器通过扬声器发出一定数量的清晰音调(正弦波),频率不同,每个音调都有其自己的音量。在一定的间隔时间(例如2秒)内,音量从文件buzz.i64中读取并调整。为了简单起见,只使用int64值的最低字节,其他假设为0。也就是说,如果从文件中读取的字节内容是

2A00 00 00 00 00 00 00 98 00 00 00 00 00 00 00 ...

那么第一个音调将以音量2Ah = 42(256分之42)播放,第二个音调以音量98h = 152播放,以此类推。下次,读取的内容是

01 00 00 00 00 00 00 00 E7 00 00 00 00 00 00 00 ...

并且音量发生变化:第一个音调几乎被关闭(音量1/256),第二个音调变得更响(音量231/256)。


  • 听众从麦克风录制一定时长(例如半秒)的样本,进行一些频谱分析,并将与预定义频率带相关的计算出的级别写入文件hear.i64,覆盖之前的级别。(注意:目前,这些带与蜂鸣器的频率是否有任何关系并不重要。)像之前一样,我们假设1字节分辨率。

例如,有人在麦克风附近吹小号。在录制的声音中,低频振幅较大,而高频振幅较小。因此,听众将数据写入hear.i64,例如

DE 00 00 00 00 00 00 00 ... 20 00 00 00 00 00 00 00

然后他们把小号放下,开始吹口哨。现在频谱是镜像的:低频携带较少的能量,高频携带更多,

14 00 00 00 00 00 00 00 ... B3 00 00 00 00 00 00 00


输入/输出中寻找这种应用的快速简单的Python实现,或者自己编写,或者使用更复杂的数字音频编辑器的功能。

让蜂鸣器有12个频率,听众有14个频带。将蜂鸣器和听众放入包含Ælhometta的可执行文件的目录中,并启动它们(蜂鸣器是安静的,因为buzz.i64还不存在。)

将文件hear.i64的映射添加到ælhometta的14个整数通道的范围内,从第50个开始

Æ iomap in add 50 14 1500000 ./hear.i64

类似地,将第70个开始的12个整数通道的映射添加到文件

Æ iomap out add 70 12 1000000 ./buzz.i64

然后运行,

Æ r

如果整数通道70-81包含足够的数字,你应该会听到一些...蜂鸣声。当这些整数变化时,蜂鸣声也会变化,但会有一些延迟。另一方面,

Æ eth int 50 14

应该产生类似的结果

          50        184=B8h
          51        255=FFh
          52        103=67h
          53        67=43h
          54        31=1Fh
          55        48=30h
          56        =29h
          57        21=15h
          58        9=9h
          59        9=9h
          60        10=Ah
          61        6=6h
          62        2=2h
          63        0=0h

为了跳过等待“进化”填充与蜂鸣器相关的整数通道的非零值,一个明显的“肮脏的技巧”是将它们与与听众相关的通道“短路”:通过以下方式删除上面的“输出”映射

Æ iomap out del 0

并替换为

Æ iomap out add 50 12 1000000 ./buzz.i64

看哪!如果你已经将听众的通道包含在你与ælhometta共享的同伴中,那么任何订阅它的人都将接收到(非常粗糙的)你设备周围的声音景观的频谱,将其变成一个窃听器


最后,

Æ q

将ælhometta和指挥官的状态保存到当前目录,并退出shell(qq退出时不保存任何内容)。

下次运行程序时,一切都会恢复

Loading Ælhometta... OK
Loading Commander... OK

Lastick 2024.01.16 Tue 23:57:21.584 UTC - Age 1974509 : Nodes 3720924 | Controllers 14407 | Limit 4194304=2^22 : Memory ~ 192 MiB
"?" — see the list of available commands
Æ █

...放心,这确实只是一个快速开始。

指挥官和外壳

ælhometta运行时,指挥官仅保留少量与数据显示格式的设置 —— Æ sets 显示它们,Æ set ... 设置它们)—— 以及shell历史记录(Æ history ... 显示最近或全部历史记录)。shell本身是一个基本的命令行界面。

换句话说,指挥官和shell是相对于ælhometta的前端。当shell等待你的输入时,

Æ █

— ælhometta处于暂停状态,没有滴答声。

指挥官的设置对ælhometta的行为没有影响,除了速度:当show_ticks设置为true时,每次滴答的屏幕输出会显著减慢速度(2倍或更多)。

Æ helpÆ ?(简称),提供有关所有命令或指定命令的信息。例如,

Æ ? peer

显示有关网络配置的所有子命令的描述和参数。

指挥官的状态保存到 commander.json

可用的shell命令

其中大部分都有更短的别名。

  • quitexitendbye(并保存状态)
  • quitquit 或 ... byebye(不保存状态)
  • help
  • =(重复最后一个命令),
  • ancestor(介绍一个,带参数)
  • run(直到按键,每秒显示更新的计数器)
  • tick(控制器的一步)
  • glitch(突变概率和计数器)
  • shownode(单个节点)
  • showctrl(控制器状态)
  • showseq(节点的前向序列)
  • prevnodes(有给定下一个节点的节点)
  • backtrace(节点的反向序列)
  • ether(全局数组中的optuids和整数的两个全局数组)
  • random(随机实体的uid),
  • 统计信息
  • cleanse(状态的一部分或全部)
  • commandswitch(用于NOP命令)
  • changelim(调整实体最大数量)
  • peer(网络)
  • iomap(I/O),
  • showsizes(某些数组的预定义大小)
  • settings(查看指挥官设置)
  • set(更改指挥官设置)
  • history(命令历史记录)
  • about(关于程序的一般信息)

频率图表

你可能已经注意到了,因为它占据了屏幕的右侧部分,并且每秒稍微改变一下... 它也显示统计数据——执行命令、构建指令和主要/替代分支选择的比例——但在短时间间隔内而不是在整个过去,这是Æ stat run所做的。示例摘要显示,在过去16秒中最频繁的命令NextOptuid

要选择命令(或构建指令)并查看其完整名称以及在时间窗口内的确切出现次数,请在run运行时按← →(或↑ ↓)。任何其他键将停止run并返回到shell提示符Æ

通过show_freqsfreqs_window_marginfreqs_comm_str_lenfreqs_cons_str_len设置调整此窗口的显示。其中,freqs_interval指定了间隔时长(以秒为单位),默认值为16。

由于故障引入了其他命令,并且它们渗透到节点链中,它们的频率会增加。此外,一些进化变化预计会改变分布,使得一个或另一个命令组占主导地位,这暗示着“物种”的适应性更强。相反的情况并不保证:例如,老鼠和人类体内的化学元素分布并没有很大差异,以及这些元素在100万年前和今天的地壳(广义理解)中的分布也没有很大差异。


在shell模式下,应用程序的退出状态为0(成功)或2(临界错误)。至于1,

无shell运行指定时长

通常情况下,你的ælhometta在运行数小时甚至数月后都不会受到你的干扰,直到你通过按下(几乎)任何键来打断它的沉默过程。

routine scast gif

然而,为了提高弹性,我们建议定期备份状态。

当你以单个参数运行应用程序而不是无参数时,这些方法会结合在一起,该参数是请求的运行时长(以秒为单位)

$ ./aelhometta 43200

此模式下没有shell。一旦时长结束(例如12小时)或按下(几乎)任何键,应用程序将退出并保存状态。在后一种情况下,退出状态设置为1。

为了无限期地运行ælhometta并每小时备份一次,将此类调用放入循环中

#!/bin/sh

while true; do
    ./aelhometta 3600
    if [ $? = 1 ]; then
        echo "Halt due to keypress"
        break
    fi
done

请注意,如果应用程序发生临界错误(退出状态2),此循环将继续。

为了每周运行一次ælhometta一天,将/path/aelhometta 86400调用放入/etc/cron.weekly/

无论此类场景如何,想象你的角色缺席、远离、消失或任何其他情况,只是简短地出现在开始时,可能有助于你理解。事情的发展也将如此...

远程运行

除了对已安装ælhometta的远程计算机的SSH访问外,你还需要一个“持久分离的终端”,由终端复用器(如ByobutmuxGNU Screen)提供;也在那里安装它。

只需在虚拟终端中运行ælhometta(最好像上面描述的那样进行常规备份)并从该终端分离;稍后,再次连接到它。

不需要X11连接或转发。


现在我们才揭开表面现象背后的面纱...

ælhometta的基本元素

...也许简单地阅读src/aelhometta.rs是更好地了解它的方法。那里直接引用了同名结构

pub struct Ælhometta {
    // Serialisable part
    max_num_chains_binlog: u8,

    new_node_uid: Uid,
    nodes: HashMap<Uid, Node>,
    nodes_historing: Vec<Optuid>,
    i_nodes_historing: usize,

    new_controller_uid: Uid,
    controllers: HashMap<Uid, Controller>,
    controllers_historing: Vec<Optuid>,
    i_controllers_historing: usize,

    commandswitch: u128,

    ether_optuids: Vec<Optuid>,
    ether_integers: Vec<Integer>,

    age: u128,
    ut_last_tick: i64,
    
    spaces_count: u128,
    branches_main_count: u128,
    branches_alt_count: u128,
    commands_count: HashMap<Command, u128>,
    constructions_count: HashMap<Construction, u128>,

    glitch_background_prob: f64,
    glitch_background_count: u128,
    glitch_replicate_prob: f64,
    glitch_replicate_count: u128,
    glitch_construct_prob: f64,
    glitch_construct_count: u128,

    // Peer-related
    share_size: usize,
    share_interval: i64,

    ut_last_share: i64,
    shares_count: u128,

    secretkey: String,
    port: u16,
    torproxy_port: u16,
    torproxy_host: String,

    exposed: bool,

    other_peers: Vec<OtherPeer>,

    whitelist: HashSet<String>,

    in_permitted_before_num: u64,
    in_attempted_before_num: u64,

    ut_last_disconnect: i64,
    ut_last_permit: i64,
    ut_last_attempt: i64,

    // IO-related
    output_mappings: Vec<IntegersFileMapping>,
    input_mappings: Vec<IntegersFileMapping>,

    // Non-serialisable part
    max_num_chains: usize,
    max_num_chains_binmask: usize,

    rng: ThreadRng,

    efunguz: Option<Efunguz>,
}

其中

pub type Uid = u32;
pub type Optuid = Option<Uid>;

pub type Integer = i64;
节点

信息的基本单元。见节点

控制器

沿着节点链移动并相应地根据节点内容进行操作的自动机。见控制器

2 Ethers

所有控制器都可以访问的全局节点地址和整数值数组。

对等配置

指定ælhometta的网络标识及其与网络中其他ælhomettas的交互(更精确地说,是通过Tor)。见网络

I/O配置

将其他应用程序控制的(输入)和(输出)文件中的整数连续范围映射。这些应用程序反过来又通过传感器和执行器连接到外部世界。请参阅输入/输出

杂项

commandswitch的第i位,当0时,对索引为i命令进行NOP操作,即用... nothing(被认为是成功的)代替其执行。由于GetExecFromOptuidSetOptuidFromExec命令违反了描述/执行分离原则,它们默认被NOP操作(您也可以更改这一点)。

age在每次tick中增加。

ut_last_tick以及其他ut_...,自Unix纪元以来以微秒为单位进行测量。

spaces_countbranches...countcommands_count记录每个相关内容被执行了多少次。constructions_count在执行Construct命令时计算发生的Construction指令的数量。


ælhometta的状态保存在aelhometta.bin中,请参阅src/aelhometta/serbin.rs。尽管这种序列化是二进制且包含如LEB128之类的技巧,但其大小并非最小;例如,经典的ZIP几乎将其减半。

节点

pub struct Node {
    b_content: u8,
    b_next: Uid,
    b_altnext: Uid
}

节点具有内容,描述控制器应该执行什么,以及2个指针:(主要)下一个节点替代下一个节点,它们描述控制器在执行此节点后移动到哪个节点。此类指针(它可能为空)的值也称为optuid(可选唯一标识符)。

内容以标准字节表示,请参阅impl ToBits<u8> for Contentimpl OtBits<u8> for Contentsrc/aelhometta.rs中。

有4种内容类型

空间

NOP,占位符,不执行任何操作。但它可以被替换为其他内容。

分支

如果GetExecFromOptuidSetOptuidFromExec命令被NOP操作(默认情况下是这样),则此类型节点是唯一提供执行路径非线性的一种。

如果success标志为true,则执行指针移动到主下一个节点。

如果success标志为false,则执行指针移动到替代下一个节点。

命令

指定控制器应执行的操作。可能会更改控制器的状态——寄存器、标志、指针数组、整数等(请参阅控制器);也可能更改整个ælhometta的状态。

如果命令执行失败(例如除以零、溢出、索引越界),则 success 标志将被设置为 false。然而,结果应该出现的地方可能会有一些“垃圾”数据,而“失败”和“未失败”的区分则视情况而定。 Test... 命令也会影响 success 标志。

“不可崩溃”原则(单个化学反应不能崩溃宇宙)贯穿于命令的执行中,并且是行业内每个人所熟悉的。

再次强调,src/aelhometta/tick.rs 提供了更完整的画面。以下列表在很大程度上依赖于...词汇的自我解释属性。

可用命令
  • 将整数结果放置在整数寄存器中的无参数运算符

    • RandomContent(代表 Content 变体的“有效”整数)
    • RandomInteger(所有 64 位都是随机的)
    • ZeroInteger
  • 对整数寄存器执行一元运算,用结果替换其值

    • Abs
    • BitNot
    • Decrement
    • Increment
    • Negate
    • ShiftDown
    • ShiftUp
    • Sign
    • Square
  • 对整数寄存器执行二进制运算,第一个操作数是整数寄存器,第二个操作数是选定的整数,结果放入整数寄存器

    • Add
    • BitAnd
    • BitOr
    • BitXor
    • Divide
    • Multiply
    • Remainder
    • Subtract
  • 将整数寄存器转换为特定数组中选定元素的索引...

    • IntegerToDataOptuidIndex
    • IntegerToIntegerChannel
    • IntegerToIntegerIndex
    • IntegerToOptuidChannel
    • IntegerToOptuidIndex
    • IntegerToPeer
  • ...并将其转换回来

    • DataOptuidIndexToInteger
    • IntegerChannelToInteger
    • IntegerIndexToInteger
    • OptuidChannelToInteger
    • OptuidIndexToInteger
    • PeerToInteger
  • 将整数寄存器转换为成功标志,反之亦然(通常的 int ↔ bool 语义)

    • IntegerToSuccess
    • SuccessToInteger
  • 对由 data_optuids[i_data_optuid] 指向的节点执行操作

    • Insert
    • Read
    • Remove
    • Skip
    • Write
  • 测试,影响 success 标志

    • TestDataOptuid(如果 data_optuids[i_data_optuid] 指向现有节点则为真)
    • TestIntegerNegative
    • TestIntegerNonZero
    • TestIntegerPositive
  • 创建新的链,如果它是活动的,则创建与它相关联的控制器

    • Construct
    • NewChainAddInteger
    • NewChainAddIntegerChannel
    • NewChainAddOptuid
    • NewChainAddOptuidChannel
    • NewChainDetach
    • NewChainInitActive
    • NewChainInitPassive
    • Replicate

ConstructReplicate 与控制器的 data_optuids[i_data_optuid] 一起工作,连续读取它所指向的节点并将其推进到下一个节点。在某种意义上,它们是“快捷方式”,因为它们绕过了 Ælhometta 的人工生物化学的一些角落。

NewChainAdd... 实际上会将相应的元素添加到正在创建的活跃链所附加的控制器中。

新链不为空,它在开始处有一个 Space 节点。

  • 移动到对应数组中的下一个/前一个元素

    • NextDataOptuid
    • NextInteger
    • NextIntegerChannel
    • NextOptuid
    • NextOptuidChannel
    • NextPeer
    • PreviousDataOptuid
    • PreviousInteger
    • PreviousIntegerChannel
    • PreviousOptuid
    • PreviousOptuidChannel
    • PreviousPeer
  • 读取/写入“optuids ether”——ælhometta 所有控制器都可以访问的(某些)optuid 的全局数组,其中目标/源是控制器当前选定的 optuid,而 ether 的元素索引由 optuid_channels[i_optuid_channel] 提供的索引提供。

    • ReceiveOptuid
    • TransmitOptuid
  • 读取/写入 "整数ether"。目标/源是整数寄存器,ether的元素由integer_channels[i_integer_channel]给出,当i_peer不为0时,ether是其他对等方的。在后一种情况下,ether是只读的(只有Receive...起作用),因为它已经通过发布-订阅模式从其他对等方获得。

    • 接收整数
    • 传输整数
  • 在整数寄存器和整数数组之间、前进和非前进optuids数组之间交换数据

    • 从整数数组获取整数
    • 从optuid设置数据optuid
    • 从整数设置整数
    • 从数据optuid设置optuid
  • 重启控制器

    • 重启
  • 将选定的optuid复制到执行optuid(此命令在"强制"下一个执行节点的optuid时是独特的,无论当前节点的主指针和替代指针如何)并反之亦然。这两个默认都是NOPped

    • 从optuid获取执行
    • 从执行设置optuid

请注意,根据"不透明寻址"原则,无法将Optuid转换为整数和反之亦然。

此外,请注意冗余。例如,NextIntegerChannel几乎做了IntegerChannelToIntegerIncrementIntegerToIntegerChannel所做的一切。

构建

仅在控制器构建执行(活动)链时才起作用——当执行Construct命令时,它与节点uids的堆栈一起工作。

可用的构建指令
  • AltNextNextToStored指令之前打开"替代下一个"模式,然后设置当前添加的节点的替代下一个指针而不是主指针,并恢复"主模式"。
  • Discard从堆栈中删除最顶部的uid。
  • NextToStored将当前添加的节点的主或替代下一个节点指针设置为堆栈中最顶部的uid。
  • Restore将"构建指针"从当前添加的节点更改为堆栈中最顶部的uid。
  • Store将当前添加的节点的uid推入堆栈。
  • Swap交换堆栈上最顶部的两个uid。
  • Terminus在当前添加的节点中断Construct(但不是Replicate)命令。

我们仍然缺乏对自然数编码选择对这种系统演化前景的复杂方式的量化或代数化...例如,enum Command的变体按字母顺序编号:ReceiveOptuid52Remainder53,同样,AltNext0Terminus6;为什么不是相反的?这是如此任意,如此脱离底层,就像化学与物理学脱钩一样,进化可能太弱而无法填补这一差距...是什么?即使是今天也是不可名状的。

备注。 Ælhometta有一个较旧的版本,没有在ContentInteger之间进行自动转换,而是有2个各自的寄存器,而不是现在1个Integer。这种方法从指令级别看,数值级别的透明度太高,因此被放弃。我们将它的复兴留给"读者练习"(另请参阅Panmutations)。

控制器

执行实体。CPU是另一个类比。

再次,直接从源复制

pub struct Controller {
    chain_start_optuid: Optuid,

    exec_optuid: Optuid,

    data_optuids: Vec<Optuid>,
    i_data_optuid: usize,

    new_chain_optuid: Optuid,
    new_controller: Option<Box<Self>>,

    registers: Registers,
    flags: Flags,

    optuids: Vec<Optuid>,
    i_optuid: usize,

    integers: Vec<Integer>,
    i_integer: usize,

    optuid_channels: Vec<usize>,
    i_optuid_channel: usize,

    i_peer: usize,

    integer_channels: Vec<usize>,
    i_integer_channel: usize,

    generation: u128,
    ticks: u128
}

目前,在RegistersFlags中存在冗余,因为

pub struct Registers {
    integer: Integer
}

pub struct Flags {
    success: bool
}

exec_optuid基本上是指令指针,chain_start_optuid为了Restart命令的初始值而保持其值。当exec_optuid变为None或指向非现有节点时,控制器“死亡”。

new_chain_optuidnew_controller用于复制被动/描述性链以及构建主动/执行链(附有控制器的链)。

data_optuids[i_data_optuid]在通过ReadWriteInsert命令进行的读写操作中自动前进到下一个节点,这些命令使用此optuid。 ConstructReplicate命令也会将其推进,直到“结束”。

i_data_optuidi_optuidi_integeri_optuid_channeli_integer_channel是相应数组当前选定元素的索引:data_optuids[]等。

i_peer当为0时表示“这个”,否则表示其他对等方,从1开始计数。它影响对integer_channels的解释,例如Transmit命令仅适用于此对等方。

generation在控制器的创建时设置一次,为构建控制器的generation加1。控制器创建时ticks为0,并在每个它的...tick时递增。

祖先...

更简单的一个,祖先B包括

  • 构造者方案链
Construction(Store),

// Replicate scheme
Command(SetDataOptuid),
Command(NextOptuid),
Command(NewChainInitPassive),
Command(PreviousOptuid),
Command(Skip),
Command(Replicate),
Command(NewChainDetach),

// Build constructor from scheme
Command(SetDataOptuid),
Command(NextOptuid),
Command(NextOptuid),
Command(NewChainInitActive),
Command(Skip),
Command(Construct),
Command(PreviousOptuid),
Command(NewChainAddOptuid),
Command(NewChainDetach),

Construction(NextToStored),
Construction(Discard)
  • 构造者的执行链,几乎与方案相同,只是没有构造节点,并且根据这些节点的指令,最后节点指向隐含的1st Space节点:这个链是一个循环。(好吧,不是完全是这样:从第1代开始。在0代,即祖先本身,循环是开放的。)

  • 构造者的控制器附加到构造者的执行链。

请注意数据的经典双重解释:第一是线性逐字复制,第二是非线性构造,它扩展了特殊(Construction:...)单元的含义。进化是否会保持它们之间的分离线清晰?

Spacity参数在引入此祖先时提供——如在Æ anc b 5中——是在每个非Construction节点之前插入的Space的数量(本例中为5)。对于突变来说,它们是用的,需要用某物来替换,而不必破坏原始动作序列。

这个祖先只利用了可用的Content的一小部分。还有一个稍微复杂一些的,有更多种类的Content祖先A:除了构造者外,它还有一个打乱者,它会扫描与构造者使用的相同方案,并随机更改它(通过替换、插入、删除)。换句话说,打乱者将突变内部化。然而,在Ælhometta中,引入突变的标准方式是“外部”的,并且更加全局。

请参阅src/aelhometta/ancestors.rs

...及其后代

以下链是从具有突变和来自麦克风的微小输入映射的ælhometta中随机提取的,在运行3天后。允许的最大节点数是224=16777216,控制器的数量相同(尽管后者从未超过3×105)。

在~3×108tick之后

进化的链,示例1
Space
Command:NextDataOptuid
Space
Space
Command:ZeroInteger
Space
Command:NewChainAddOptuidChannel
Space
Command:Abs
Command:Remove
Command:SetDataOptuidFromOptuid
Command:NewChainInitActive
Command:Write
Command:PreviousIntegerChannel
Command:NewChainAddOptuid
Command:NextPeer
Command:Construct
Command:NewChainDetach
Command:GetExecFromOptuid
Command:IntegerIndexToInteger
Command:SetIntegersFromInteger
Command:ZeroInteger
Space
Command:NextIntegerChannel
Command:OptuidChannelToInteger
Command:Construct
Space
Command:Read
Command:Negate
×
进化的控制器链,示例1
Space
Space
Space
Space
Space
Command:BitNot
Space
Command:IntegerToOptuidChannel
Command:OptuidChannelToInteger
Command:SetOptuidFromExec
Command:SetDataOptuidFromOptuid
Command:NewChainInitActive
Command:Subtract
Command:GetIntegerFromIntegers
Command:NewChainAddOptuid
Command:NextPeer
Command:Construct
Command:NewChainDetach
Command:GetExecFromOptuid
Command:GetExecFromOptuid
Command:BitAnd
Command:ZeroInteger
Space
Command:GetExecFromOptuid
Command:Write
Command:PreviousDataOptuid
Space
Command:SetDataOptuidFromOptuid
Command:NewChainInitActive
Command:Write
Command:IntegerToIntegerIndex
Command:NewChainAddOptuid
Command:ShiftUp
Command:Construct
Command:NewChainDetach
Command:GetExecFromOptuid
Space
Command:SetIntegersFromInteger
Command:ZeroInteger
Space
Command:GetExecFromOptuid
Command:Increment
Command:PreviousOptuidChannel
Space
Command:GetIntegerFromIntegers
Command:NextIntegerChannel
Command:TestIntegerNegative
Command:NewChainInitActive
Command:TestIntegerNonZero
Command:BitOr
Command:NewChainAddOptuid
Command:GetExecFromOptuid
Command:NewChainAddOptuid
Command:SetIntegersFromInteger
Command:PreviousDataOptuid
Command:Restart
Command:RandomInteger
Command:NewChainAddOptuidChannel
Command:NewChainAddInteger
Command:BitNot
Command:IntegerToDataOptuidIndex
Command:RandomContent
Space
Command:IntegerToIntegerIndex
Command:Remainder
Command:Remove
Space
Command:TransmitOptuid
Command:OptuidIndexToInteger
Command:OptuidChannelToInteger
Command:PreviousOptuid
Command:Skip
Command:Replicate
Command:Divide
Space
×

在~4×108tick之后

进化的链,示例2
Command:SetDataOptuidFromOptuid
Command:NewChainInitActive
Command:BitNot
Command:Skip
Command:NewChainAddOptuid
Command:NextPeer
Command:Construct
Command:NewChainDetach
Command:Write
Command:BitAnd
Command:Add
Space
Command:Write
Command:Read
Space
Command:SetDataOptuidFromOptuid
Command:NewChainInitActive
Command:Write
Command:Remainder
Command:NewChainAddOptuid
Command:Divide
Command:Construct
Command:NewChainDetach
Command:GetExecFromOptuid
Space
Command:Read
Command:NewChainDetach
Command:Read
Command:ZeroInteger
Command:Increment
Command:PreviousOptuidChannel
Space
Branch
Command:RandomContent
Command:TestIntegerNegative
Command:Construct
Space
Command:BitOr
Command:TestIntegerNegative
Command:PreviousInteger
Command:Remove
Command:OptuidChannelToInteger
Command:PreviousDataOptuid
Command:NextOptuidChannel
Command:SetIntegersFromInteger
Command:NewChainAddOptuidChannel
Command:NewChainAddOptuidChannel
Command:NewChainInitPassive
Command:IntegerToDataOptuidIndex
Command:Write
Space
Command:IntegerToIntegerIndex
Command:Restart
Command:Remove
Space
Command:Decrement
Command:TransmitOptuid
Command:OptuidIndexToInteger
Command:TestIntegerPositive
Command:NextDataOptuid
Command:Abs
Command:Divide
Space
×
进化的控制器链,示例2
Space
Command:OptuidIndexToInteger
Space
Command:NextInteger
Space
Space
Command:NewChainAddOptuid
Command:PreviousDataOptuid
Command:OptuidChannelToInteger
Command:IntegerToSuccess
Command:SetDataOptuidFromOptuid
Command:NewChainInitActive
Command:Write
Command:Replicate
Command:NewChainAddOptuid
Command:Construct
Command:NewChainDetach
Command:TestDataOptuid
Command:SetOptuidFromExec
Command:TestIntegerNegative
Command:IntegerToPeer
Command:NewChainDetach
Command:GetExecFromOptuid
Command:Increment
Command:PreviousDataOptuid
Command:SetDataOptuidFromOptuid
Command:TestIntegerNonZero
Command:Write
Command:GetIntegerFromIntegers
Command:NewChainAddOptuid
Command:Divide
Command:Construct
Command:NewChainDetach
Command:GetExecFromOptuid
Command:IntegerToDataOptuidIndex
Command:RandomContent
Space
Space
Command:SetOptuidFromExec
Command:Construct
Command:ShiftDown
Space
Command:NextIntegerChannel
Command:TestIntegerNonZero
Command:NewChainInitActive
Space
Command:BitOr
Command:Construct
Command:Decrement
Command:Remove
Command:SetIntegersFromInteger
×

在~5×108tick之后

进化的链,示例3
Space
Space
Space
Space
Space
Space
Space
Space
Space
Space
Space
Space
Space
Space
Command:SetDataOptuidFromOptuid
Command:NewChainInitActive
Command:IntegerToIntegerIndex
Command:TestIntegerPositive
Command:NewChainAddOptuid
Command:Construct
Command:NewChainDetach
Command:PreviousInteger
Command:PreviousOptuid
Command:BitAnd
Command:TestDataOptuid
Command:GetExecFromOptuid
Command:Write
Command:Increment
Command:SetDataOptuidFromOptuid
Command:NewChainInitActive
Command:Subtract
Command:ReceiveInteger
Command:NewChainAddOptuid
Command:Divide
Command:PreviousInteger
Command:NewChainDetach
Space
Command:PreviousIntegerChannel
Command:ZeroInteger
Space
Command:GetExecFromOptuid
Command:NextPeer
Command:IntegerToOptuidIndex
Space
Command:NextOptuid
Command:Subtract
Command:Add
Command:NewChainInitActive
Command:Add
Command:BitOr
Command:PeerToInteger
Command:GetExecFromOptuid
Command:Remove
Command:NewChainInitActive
Command:NewChainAddOptuidChannel
Command:PreviousInteger
Command:BitXor
Command:SetIntegersFromInteger
Command:NewChainAddInteger
Command:DataOptuidIndexToInteger
Command:Subtract
Command:PreviousIntegerChannel
Space
Command:Write
Command:Remainder
Command:OptuidIndexToInteger
Space
×
演化的控制器链,示例3
Space
Space
Space
Space
Command:Insert
Command:Write
Command:IntegerIndexToInteger
Command:OptuidChannelToInteger
Command:PeerToInteger
Command:SetDataOptuidFromOptuid
Command:NewChainInitActive
Command:Write
Command:NewChainAddOptuid
Command:Multiply
Command:Construct
Command:NewChainDetach
Command:GetExecFromOptuid
Command:SetDataOptuidFromOptuid
Command:BitAnd
Command:ReceiveInteger
Command:Insert
Command:GetExecFromOptuid
Command:NewChainAddOptuid
Command:PreviousDataOptuid
Command:SetDataOptuidFromOptuid
Command:NewChainInitActive
Command:NextOptuid
Command:SetOptuidFromDataOptuid
Command:NewChainAddOptuid
Command:IntegerToPeer
Command:IntegerIndexToInteger
Command:BitOr
Command:Subtract
Command:PreviousPeer
Command:ZeroInteger
Command:PreviousOptuidChannel
Command:BitXor
Command:IntegerToIntegerChannel
Command:Restart
Space
Command:NextDataOptuid
Command:Multiply
Command:Increment
Command:SetIntegersFromInteger
Command:BitOr
Command:PeerToInteger
Command:GetExecFromOptuid
Command:Remove
Command:Write
Command:IntegerToDataOptuidIndex
Command:NewChainInitActive
Command:PreviousInteger
Command:BitXor
×

备注。 第一链属于控制器而非方案是完全可能的。要确定这一点,请检查Construction:它们可以出现在由Replicate构建的链中,而不能出现在由Construct构建的链中。


享受进化的混乱和重复性... 那么,从这个样本中我们可以得出哪些进化结论呢?起初,看起来有很多垃圾,但这真的是垃圾吗?能否在不显著改变“表型”的情况下将其删除?或者它以非平凡的方式与这里未显示的部分相互作用?特别是,数值操作(AddDivideShiftUp)无处不在。

ConstructReplicate命令,以及NewChainInit...NewChainDetach,表明了繁殖的能力。没有控制器和链的状态,我们不能说它们的孩子将会多么“重要”。

原始祖先中的循环和执行路径的非线性,在进化的道路上大多已经消失,除了偶尔的Branch(链2)。

Construction指令仍然非常罕见。

有一些访问全局数组的权限——TransmitOptuidReceiveInteger命令——但,同样地,没有其他内容,很难说这种访问是否有意义,至少在其他地方有ReceiveOptuidTransmitInteger的对应命令。

这与E.coli[GLA1]的水平相隔多少时代?..

突变

我们称它们为glitches

  • 背景 glitch以指定的概率在每次tick时发生,并随机改变整个ælhometta中随机节点的内容

  • 复制 glitch在复制每个复制的节点时以指定的概率发生,并随机改变其内容

  • 构建 glitch在构建每个读取的节点时以指定的概率发生,随机改变其内容

更精确地说,“随机”意味着等概率。

默认情况下,所有三个概率都是0。我们已经在快速入门中说明了如何调整它们。要查看它们的值和相应glitches的发生次数甚至更简单

Æ glitch
无glitch(或jumblers)的内容统计示例
Command:Remainder                                  0      0.000 %
Command:Remove                                     0      0.000 %
Command:Replicate                              38860      1.012 %
Command:Restart                                    0      0.000 %
Command:SetDataOptuid                          77720      2.023 %
Command:SetInteger                                 0      0.000 %
Command:SetOptuid                                  0      0.000 %
Command:ShiftUp                                    0      0.000 %
Command:ShiftDown                                  0      0.000 %
Command:Sign                                       0      0.000 %
Command:Skip                                   77720      2.023 %
Command:Square                                     0      0.000 %
Command:Subtract                                   0      0.000 %
Command:SuccessToInteger                           0      0.000 %
Command:TestDataOptuid                             0      0.000 %
Command:TestIntegerNegative                        0      0.000 %
Command:TestIntegerNonZero                         0      0.000 %
Command:TestIntegerPositive                        0      0.000 %
Command:TransmitInteger                            0      0.000 %
Command:TransmitOptuid                             0      0.000 %
Command:Write                                      0      0.000 %
Command:ZeroInteger                                0      0.000 %
Construction:AltNext                               0      0.000 %
Construction:Discard                           22393      0.583 %
Construction:NextToStored                      22393      0.583 %
有glitch的内容统计示例
Command:Remainder                                937      0.022 %
Command:Remove                                   274      0.007 %
Command:Replicate                              42305      1.009 %
Command:Restart                                  268      0.006 %
Command:SetDataOptuid                          84855      2.023 %
Command:SetInteger                              1065      0.025 %
Command:SetOptuid                                516      0.012 %
Command:ShiftUp                                  528      0.013 %
Command:ShiftDown                               1311      0.031 %
Command:Sign                                   42646      1.017 %
Command:Skip                                   43337      1.033 %
Command:Square                                   270      0.006 %
Command:Subtract                                1010      0.024 %
Command:SuccessToInteger                         558      0.013 %
Command:TestDataOptuid                           782      0.019 %
Command:TestIntegerNegative                      523      0.012 %
Command:TestIntegerNonZero                      1332      0.032 %
Command:TestIntegerPositive                      665      0.016 %
Command:TransmitInteger                         1202      0.029 %
Command:TransmitOptuid                          1798      0.043 %
Command:Write                                   1135      0.027 %
Command:ZeroInteger                             1315      0.031 %
Construction:AltNext                             258      0.006 %
Construction:Discard                             281      0.007 %
Construction:NextToStored                        225      0.005 %

请参阅上述祖先后代的比较。

全突变

突变有限,因为它们不能改变可用命令的集合,命令的工作方式,ælhometta的总体结构...所有这些事情都在它们之上(πανω απο)。目前,这种潜在的全突变来源是... ,作为一个程序员,因为我们对设计的选择感到沮丧,并急于重写一些ælhometta中特别糟糕的部分。《欢迎!》至少在强联网I/O协议保持兼容的情况下,因为那时你的ælhomettaPlus和其他版本将由同行重写者产生的不同突变将巩固为一个abiosphere。

随着时间的推移,ælhomettas可能会获得自我全突变的方法,例如通过专门的I/O重写和重新编译它们的源代码...以及,正如现在所超过的,通过像Copilot这样的工具。

μ突变的

困扰这些水域的一个众所周知的问题是,“随着时间的推移,什么是发生突变/进化的?”其特点是区分什么是以及什么不是的边界(缺乏)。一方面,ælhometta发生变化(包括全突变);另一方面,你,一个(外部?)观察者,也会变化,因为这对你有影响,以及当你决定升级以增加速度或如果它没有满足你的期望就丢弃它时运行的硬件,以及它与之交互的所有其他ælhomettas及其所有者,以及当许多人使用电力来运行ælhomettas时的全球经济等等……一直到什么,一切?但我们应该小心地理解这样的结论,否则它并没有太多意义。我们更感兴趣的是我们能在我们能够到达的层面上做什么,以便让异质层次的其他层次变得更有趣。

网络

每个Ælhometta实例都是一个潜在的同行,通过其公钥洋葱地址端口从外部识别。为了确认使用公钥的“权利”,必须指定相应的私钥

同行之间按照发布-订阅模式交换数据:每个ælhometta共享其整数通道的某些连续子集,从其数组的开始(因为随着进化的展开,似乎使用小索引的通道被使用得更频繁),并且订阅了它的每个其他ælhometta都会接收到这个子集(如果发布者端没有白名单过滤器)。我们预计会有人对这种模式过于“被动”提出投诉:一个ælhometta不能对另一个ælhometta说任何东西,直到后者开始监听。

以下结构(来自src/aelhometta.rs)代表了你的同行从“你的同行的视角”

pub struct OtherPeer {
    publickey: String,
    onion: String,
    port: u16,
    ether_integers: Vec<Integer>,
    limit: usize,
    ut_last_update: i64,
    updates_count: u128,
    description: String
}

本质上,没有中央服务器,而是每个同行都是提供数据的“感兴趣”同行的服务器。这也不是类似 torrent 的,因为没有追踪器:你必须知道一个同行的(公钥、洋葱、端口)身份才能订阅它。

底层消息库是ZeroMQ,因此公共和私钥都是40个字符的Z85字符串。您可以通过从原始libzmq或通过其语言绑定的包装器调用zmq_curve_keypair()来获取它们。《快速入门》显示了如何在 Python 中做到这一点。

网络身份和数据流由Tor的洋葱服务(v3)提供。Tortor@default服务必须在系统上运行,以保持您的 Tor 实例连接到 Tor 基础设施的其他部分。

注意,ZeroMQ 的公钥与洋葱服务的公钥无关。这里有两重加密/身份验证,这可能是多余的...


在执行Æ peer expose之后,您的同行开始每interval微秒发布一次数据,首先是来自您的ælhometta整数ether(第0个、第1个、(size - 1)个)的size个整数。

可以随时停止订阅其他同行的操作。

Æ peer disconnect TheirPublicKeyTheirPublicKeyTheirPublicK

在这种情况下,所有后续同行的索引都会递减。如果ælhometta已经调整到这样的索引(其控制器的i_peer),调整可能会丢失。似乎添加同行比删除同行更安全。

您可以在任何时候停止整个网络活动,包括发送和接收。

Æ peer repose

尽管如此,只要您没有发起断开连接,从每个对等点获取的最后一份数据就会被保留。

不需要同时传输和接收,但即使您只需要接收,也必须指定密钥。只要interval等于0,就不会进行传输。另一方面,如果interval>0且size=0,您的对等点将传输空份额(可用作心跳)。

您可以通过将它们添加到白名单来限制能够订阅您的对等点(如果它是空的,则允许所有其他人员)

Æ peer whitelist add TheirPublicKeyTheirPublicKeyTheirPublicK

如果情况发生变化,可以通过Æ peer whitelist del ...从白名单中删除任何此类密钥(以及相应的对等点)。或者,可以通过Æ peer whitelist clear完全删除限制。简单的Æ peer whitelist会显示所有白名单上的公钥。

没有白名单,世界上任何知道公钥、洋葱地址和端口的任何人都可以订阅;您无法预测您的ælhometta在未来某个时间将有多少订阅者,因此互联网流量可能会变化。

备注。为了有效地模仿空白名单(禁止所有人订阅),请将一个随机公钥添加到您的白名单中,该公钥不用于任何其他地方。只有这个“幽灵”对等点才能订阅,祝任何试图猜测大约2256个可能的密钥中的相应密钥的真实对等点好运...

已知对等点
公钥 洋葱 端口 描述 份额大小
USBD7[O^8L[}saCh+6U#}6wie4oAedZ4#W4!b%LI t3kauc3flp2bpv3mv7vtnedfu6zrho3undncccj35akpuyjqqydwvfyd 60847 我们维护用于测试。在线而不是离线 1000–10000
&i!VkHl[]m.c!^j0D%i)&4#[u5b(a=QCdZ9C0$p{ yhel64h6cjab75tcpncnla2rdhqmxut2vtitywhbu7bpjh4hfhp6hnid 60847 我们维护用于测试。离线而不是在线 1000–10000

请小心:您与任何其他对等点的交互都存在风险。一个安全问题是对大小限制的担忧——您可能不想花费流量,耗尽提供商的套餐,来接收几个GB的慷慨共享...零(00 00 ... 00),然后因为“内存不足!”而崩溃。为了解决后者的问题,请考虑为不受信任的对等点使用Æ peer limit ...,它丢弃超过指定大小的接收数据。

另一个问题是,从不受信任的来源接收的数据如何影响您的ælhometta,它可以发展哪些想法...它在谁的利益下运作...

传输网络身份

也就是说,在将ælhometta移动到另一台计算机上。

除了aelhometta.bin(和commander.json)之外,您还需要保留Tor隐藏服务目录的内容,该目录位于Linux上的/var/lib/tor/中。其中3个基本文件是hostnamehs_ed25519_public_keyhs_ed25519_secret_key。此结构必须在下一台计算机上重建,包括/etc/tor/torrc或至少其HiddenServicePortHiddenServiceDir设置。

确保ælhometta在新位置上线(其他人接收其份额,并且它接收其他人的份额),然后从旧位置中删除它或不要将其暴露给网络,这样Tor就不会被两个具有相同身份的洋葱所迷惑。

输入/输出

整型通道的范围可以通过文本形式(小端,8字节)的整数映射到(输入)或(输出)文件。与这类文件工作的程序可以完全独立于Ælhometta,除了需要同步“节奏”(interval,以微秒为单位)。

每次更新都会截断并覆盖输出文件。

输入文件的大小必须不小于映射到的整型通道范围长度的8倍,否则不会发生更新。

pub struct IntegersFileMapping {
    start: usize,
    length: usize,
    interval: i64,
    filepath: String,
    ut_last_update: i64,
    updates_count: u128
}

在所有输入映射之前,所有输出映射都与相应的文件同步——与它们[BUZ1]

我们考虑了在快速入门中使用iomap命令的情况。在那里,用于分析(输入,“听者”)和合成(输出,“蜂鸣器”)声音的外部程序是黑盒子:从ælhometta的角度来看,它们只需要分别写入和读取大小为映射范围长度的8倍的文件。让我们揭开黑盒的秘密...以下是一个例子,例如在Python中

aelhom_hearer.py
import numpy as np
import sounddevice as sd

NUM_BANDS = 14
MIN_FREQUENCY = 100
MAX_FREQUENCY = 6000
DESTINATION_FILEPATH = "./hear.i64"
SAMPLE_RATE = 32768
UPDATE_RATE = 2.0

BASIC_FREQUENCIES = [int(MIN_FREQUENCY * np.power(2.0, i * np.log2(MAX_FREQUENCY / MIN_FREQUENCY) / (NUM_BANDS - 1))) for i in range(NUM_BANDS)] # in Hz
NUM_REC_SAMPLES = int(SAMPLE_RATE / UPDATE_RATE)

print("Basic frequencies (Hz):", BASIC_FREQUENCIES)
print("Press Ctrl+C to exit...")

samples = np.zeros(SAMPLE_RATE)

updates = 0

try:
	while True:
		recording = sd.rec(NUM_REC_SAMPLES, samplerate=SAMPLE_RATE, channels=1, dtype='int16', blocking=True).flatten()

		if NUM_REC_SAMPLES < SAMPLE_RATE:
			samples = np.concatenate((samples[NUM_REC_SAMPLES:], recording))
		else:
			samples = recording[(NUM_REC_SAMPLES - SAMPLE_RATE):]

		spectrum = np.absolute(np.fft.rfft(samples)[1:])
		begin = 0
		bandspectrum = np.zeros(NUM_BANDS)
		for i in range(NUM_BANDS):
			end = BASIC_FREQUENCIES[i]
			# bandspectrum[i] = np.sum(spectrum[begin:end])
			# bandspectrum[i] = np.average(spectrum[begin:end])
			bandspectrum[i] = np.max(spectrum[begin:max(begin + 1, end)])
			begin = end

		bandspectrum /= max(np.max(bandspectrum), 1e-8)

		updates += 1
		status_str = f"[{updates}] Bandspectrum: "

		bs = bytes()
		for i in range(NUM_BANDS):
			i64 = int(0xFF * bandspectrum[i]) # only lowest byte of 8
			bs += i64.to_bytes(8, byteorder="little")
			status_str += f"{i64:02X} "
		
		with open(DESTINATION_FILEPATH, "wb") as f:
			f.write(bs)

		print(status_str, end="\r", flush=True)

except KeyboardInterrupt:
	print("Done.")
aelhom_buzzer.py
import numpy as np
import pygame as pg

import time

NUM_BANDS = 12
MIN_FREQUENCY = 150
MAX_FREQUENCY = 5000
SOURCE_FILEPATH = "./buzz.i64"
SAMPLE_RATE = 4
UPDATE_RATE = 1.0
IDLE_RATE = 100.0

BASIC_FREQUENCIES = [int(MIN_FREQUENCY * np.power(2.0, i * np.log2(MAX_FREQUENCY / MIN_FREQUENCY) / (NUM_BANDS - 1))) for i in range(NUM_BANDS)] # in Hz

print("Basic frequencies (Hz):", BASIC_FREQUENCIES)

pg.mixer.init(frequency=SAMPLE_RATE, channels=1)
pg.mixer.set_num_channels(NUM_BANDS)

pitches = [pg.sndarray.make_sound(np.array(32767.0 * np.sin(np.linspace(0.0, 2.0 * np.pi * f, SAMPLE_RATE) + np.random.random() * 2.0 * np.pi), dtype='int16')) for f in BASIC_FREQUENCIES] # clear tones

volumes = [0.0 for i in range(NUM_BANDS)]

for p in pitches:
	p.set_volume(0.0)
	p.play(-1)

t_last_update = - 1.0 / UPDATE_RATE - 1.0 # ensure immediate update
print("Press Ctrl+C to exit...")

updates = 0

try:
	while True:
		t = time.time()
		if t - t_last_update >= 1.0 / UPDATE_RATE:
			updates += 1

			status_str = f"[{updates}] Volumes: "

			try:
				with open(SOURCE_FILEPATH, "rb") as f:
					fcontent = f.read(NUM_BANDS << 3) # 64-bit integers
					if len(fcontent) == NUM_BANDS << 3:
						for i in range(NUM_BANDS):
							i64 = int.from_bytes(fcontent[(i << 3):((i + 1) << 3)], byteorder="little", signed=True)
							vol = abs(i64) & 0xFF # only lowest byte matters
							volumes[i] = vol / 0xFF
							status_str += f"{vol:02X} "

				for i in range(NUM_BANDS):
					pitches[i].set_volume(volumes[i])

			except FileNotFoundError:
				status_str += "source file not found"

			t_last_update = t

			print(status_str, end="\r", flush=True)
		
		time.sleep(1.0 / IDLE_RATE)

except KeyboardInterrupt:
	print("Done.")

pg.mixer.stop()

在它们使用之前,—— $ python3 aelhom_hearer.py$ python3 aelhom_buzzer.py,——您需要安装它们所依赖的Python包

$ pip3 install -U numpy pygame sounddevice

备注1。如果环境中对噪声水平有严重的限制(例如,持续的嗡嗡声让您发疯),您可以通过将蜂鸣器的输出直接与听者分析的样本混合来虚拟化蜂鸣器,而不是通过扬声器产生实际的声音

aelhom_hearer_buzzer.py
import numpy as np
import sounddevice as sd

HEAR_NUM_BANDS = 14
HEAR_MIN_FREQUENCY = 100
HEAR_MAX_FREQUENCY = 6000

BUZZ_NUM_BANDS = 12
BUZZ_MIN_FREQUENCY = 150
BUZZ_MAX_FREQUENCY = 5000

BUZZ_VOLUME = 1.0 / BUZZ_NUM_BANDS

HEAR_FILEPATH = "./hear.i64"
BUZZ_FILEPATH = "./buzz.i64"

SAMPLE_RATE = 32768
UPDATE_RATE = 2.0

HEAR_BASIC_FREQUENCIES = [int(HEAR_MIN_FREQUENCY * np.power(2.0, i * np.log2(HEAR_MAX_FREQUENCY / HEAR_MIN_FREQUENCY) / (HEAR_NUM_BANDS - 1))) for i in range(HEAR_NUM_BANDS)] # in Hz
BUZZ_BASIC_FREQUENCIES = [int(BUZZ_MIN_FREQUENCY * np.power(2.0, i * np.log2(BUZZ_MAX_FREQUENCY / BUZZ_MIN_FREQUENCY) / (BUZZ_NUM_BANDS - 1))) for i in range(BUZZ_NUM_BANDS)] # in Hz

NUM_REC_SAMPLES = int(SAMPLE_RATE / UPDATE_RATE)

print("Buzz basic frequencies (Hz):", BUZZ_BASIC_FREQUENCIES)
print("Hear basic frequencies (Hz):", HEAR_BASIC_FREQUENCIES)

samples = np.zeros(SAMPLE_RATE)

pitches = [np.array(32767.0 * np.sin(np.linspace(0.0, 2.0 * np.pi * f, SAMPLE_RATE) + np.random.random() * 2.0 * np.pi), dtype='float64') for f in BUZZ_BASIC_FREQUENCIES] # clear tones
volumes = [0.0 for i in range(BUZZ_NUM_BANDS)]

updates = 0

print("Press Ctrl+C to exit...")

try:
	while True:
		recording = sd.rec(NUM_REC_SAMPLES, samplerate=SAMPLE_RATE, channels=1, dtype='int16', blocking=True).flatten()

		if NUM_REC_SAMPLES < SAMPLE_RATE:
			samples = np.concatenate((samples[NUM_REC_SAMPLES:], recording))
		else:
			samples = recording[(NUM_REC_SAMPLES - SAMPLE_RATE):]

		status_str = f"[{updates}] Volumes:"

		try:
			with open(BUZZ_FILEPATH, "rb") as fh:
				fcontent = fh.read(BUZZ_NUM_BANDS << 3) # 64-bit integers
				if len(fcontent) == BUZZ_NUM_BANDS << 3:
					for i in range(BUZZ_NUM_BANDS):
						i64 = int.from_bytes(fcontent[(i << 3):((i + 1) << 3)], byteorder="little", signed=True)
						vol = abs(i64) & 0xFF # only lowest byte matters
						volumes[i] = vol / 0xFF
						status_str += f" {vol:02X}"
		except FileNotFoundError:
			status_str += " buzz file not found"

		samples_with_buzz = samples + BUZZ_VOLUME * sum([volumes[fr] * pitches[fr] for fr in range(BUZZ_NUM_BANDS)])

		spectrum = np.absolute(np.fft.rfft(samples_with_buzz)[1:])
		begin = 0
		bandspectrum = np.zeros(HEAR_NUM_BANDS)
		for i in range(HEAR_NUM_BANDS):
			end = HEAR_BASIC_FREQUENCIES[i]
			# bandspectrum[i] = np.sum(spectrum[begin:end])
			# bandspectrum[i] = np.average(spectrum[begin:end])
			bandspectrum[i] = np.max(spectrum[begin:max(begin + 1, end)])
			begin = end

		bandspectrum /= max(np.max(bandspectrum), 1e-8)

		updates += 1
		status_str += f" █ Bandspectrum:"

		bs = bytes()
		for i in range(HEAR_NUM_BANDS):
			i64 = int(0xFF * bandspectrum[i]) # only lowest byte of 8
			bs += i64.to_bytes(8, byteorder="little")
			status_str += f" {i64:02X}"
		
		with open(HEAR_FILEPATH, "wb") as f:
			f.write(bs)

		print(status_str, end="\r", flush=True)

except KeyboardInterrupt:
	print("Done.")

请注意,这样的技巧会破坏反馈回路,迟早ælhometta必须真正被听到,这对它自己是有好处的。


备注2。通过一些重定向,听者能够分析例如解调后的无线电信号。(我们在这里假设Linux。)插入一个接收器,例如RTL-SDR,运行GQRX,调整到一个电台或任何有趣的频率,调整正确的解调模式,并打开UDP(默认端口7355)。然后运行以下bash脚本(需要安装socatffmpeg

redirect_gqrx_to_mic.sh
#!/bin/sh

# Based on:
# https://gist.github.com/GusAntoniassi/c994dc5fc470f5910b61e4d238a6cccf
# https://github.com/f4exb/dsdcc#running

VIRTMIC_PATH=/tmp/virtmic

CLEANUP=0

cleanup() {
	if [ $CLEANUP = 0 ]; then
		pactl unload-module module-pipe-source
		# rm -f "$HOME"/.config/pulse/client.conf
		CLEANUP=1
	fi	
}

trap cleanup INT

pactl load-module module-pipe-source source_name=virtmic file=$VIRTMIC_PATH format=s16le rate=44100 channels=1
pactl set-default-source virtmic
# echo "default-source = virtmic" > "$HOME"/.config/pulse/client.conf

echo "Press Ctrl+C to stop..."

socat stdout udp-listen:7355 | ffmpeg -f s16le -ar 48000 -ac 1 -re -i - -f s16le -ar 44100 -ac 1 - > "$VIRTMIC_PATH"

cleanup

当这个脚本运行时,——直到Ctrl + +C或发送到UDP端口的发送数据结束,——默认麦克风,而不是硬件alsa_input.pci-0000_00_1b.0.analog-stereo或类似的,是虚拟的,virtmic,解调后的音频就是从这里去。由aelhom_hearer.py显示的Bandspectrum相应地改变。现在您的ælhometta正在听收音机...


...I/O本身并不会带来进化,除非它与某种进化压力相结合。也就是说,(与传感器和执行器交互的)控制器通过更“合适”的方式与传感器和执行器交互而生存下来,新的覆盖旧的波浪会更好。一种粗糙的方法是增加故障概率——“辐射水平”或“退火温度”——除非ælhometta通过执行器输出的输出变得更“有趣”。

典型行为

——通常跟随ælhometta的进化,并且它们不应该让您感到惊讶/分心(另一方面,每个都可能在更仔细地观察时隐藏突破性的发现)。 典型强制性的:有时它们 不会 发生。

  • 命令的分布范围缩小到少数活跃使用的一些,其余几乎不存在。此类选择的例子有:SetDataOptuidFromOptuidNewChainDetachNewChainInitActiveNewChainAddOptuidConstructReadSetOptuidFromDataOptuidReplicate。在这种情况下,控制器的数量变得很大,而它们的链变得很小。

  • 分支和循环(除整个构造函数的循环性之外)非常罕见。

  • 速度(每秒滴答数)随ConstructReplicate命令的执行而递减,趋于无穷小。渐近线不是0,而是比初始速度小几个数量级。

  • 节点数量达到最大值,并在略低于该值的位置振荡。

  • 在节点数量达到最大值后,控制器数量稳定,但之后,经过一段时间,又上升,然后下降,等等。这种行为可能表明一些进化转变(最后)。平均控制器数量比节点数量小50-100倍。

  • 主要使用小索引的通道(变为非“零”),包括optuid和整数。在非零值的整数通道中,许多值是这些通道的索引(通道123包含值123)。

  • 如果没有构造故障,任意Construction的计数明显小于任意Command的计数。

  • 如果过早地引入了高概率的故障,那么节点和控制器数量的增长速度会慢得多,因为太多的链有“致命”的修改以繁殖。


  • 内存使用量只是近似值[BLA1]。对于更精确的值,请在Linux中运行例如Systems Monitor或在Windows中运行Task Manager

成就和恶作剧

或者,------------

基础...舔,到目前为止。没有寒武纪大爆发,没有突出的多样性,只有太过熟悉以至于甚至无聊的乏味。

本项目救出的人:0。

本项目摧毁的人:0。

到目前为止...没有什么可担心的。什么也没有。

那些东西

词源

"Hometta"是芬兰语中霉菌发霉的意思;更多图片..."Æl"代表“ALgorithmic”或“ELectronic”,谁知道呢...以及古风。

与兄弟姐妹的名字相比,这个名字的分类等级较低,预期演化的复杂度上限也不高。

有些科幻故事走的是相反的方向[KEL1][LEM1]

还有。

免责声明...

(由于陈词滥调,每个人都跳过了它们)

...关于Botneticity和Apocalipticity的声明

"网络僵尸病毒!"这个贯穿上述叙述的警报并没有让我们烦恼,只要这个事物运作,首先是为了它自己和它的未来,而不是为了某些人类,无论是恶意的、善意的还是冷漠的——包括我们自己和你,更不用说政府、教派、军队、慈善机构、企业、毒品贩运团伙、工会、犯罪集团、政党、隔壁的暴民、情报机构、宗教和科研社区,以及其他我们羡慕的更有组织的团体了。

但是,那个未来会是什么样子呢?培养孩子成为坏人、无价值的人很容易……这种自私也许只是愚人眼里的炫目宣言,而幕后的某人实际上却从中受益……确保我们这个物种的任何一个人(如何做?)都不会这样做。然而,有些空间并不能长时间空置。

那么,它在炒作中会被称作什么:网络僵尸病毒?g.o.f.蠕虫?[真菌感染](https://en.wikipedia.org/wiki/Fungal_infection)?(人工智能太自负了)或者纯粹的灾难——或者如果没有人注意到它,它将保持无名。因为我们的宝贵观点将一文不值——对于它,还有,如果幸运的话,对于宇宙舞台上的表演也是如此。而且可能不只一个。

至于“末日”,一些与这种娱乐活动相关的末日预言也许会暂时地增加多样性、生机等,而不是——看到所有的彗星、瘟疫、热核、僵尸等游戏结局——单调地减少它们。

……个人危险

如果你参与这个项目,并且它完全失败(这是最可能的结果),你将失去宝贵的可以花在更有用和更有价值的事情上的时间。相反,如果这个项目达到了它的妄自尊大的最终目标,人类将失去作为世界上唯一(或不是)最(不)负责任的物种的地位……除非你将人类定义为这样的人。

我们也有责任,试图抓住不可能的重大事物……错误的孩子的皮诺曹。

此外,你总是可以参与对这个项目的反制;如果你在GitHub上阅读这篇文章,请从点击页面右侧的“报告仓库”开始。或者忽略它。谁聪明谁知道什么是更危险的?地狱会等吗?

……理论与实践

在你阅读这篇象牙塔般的理论的时候,Ælhometta的使用实践可能已经完全不同。

……保修

没有。

……情感与推测

我们的观点无关紧要,但我们在各个地方收集了一些似乎合适的民间传说摘录,尽管有些陈词滥调。

——现在地球上有着如此多的(通用)计算机,但它们有点儿像……在睡觉?昏迷?(我们在这里缺乏精确的术语,因为在我们的生物生活中,一个物体第一次变得有生命,它就变成了“这个”物体(有尸体,没有生命)。)无论是从消耗的能源、效率,还是从行为复杂性的角度来看,单个设备和由许多设备组成的网络,当它们独立行动时,不反映(或反思)人类活动——不回复某人的请求,不计算针对人类的预测,不开发生命救急药物,不挖矿比特币,不渲染3D场景,不发送大量垃圾邮件等;当它们对任何人都没有用处。

——它们能演奏什么样的行为旋律,为什么它们局限于像可视化这段文字这样的单调?就像一个打盹的身体的抽搐。

— 所有这些老旧的或不太老旧的单板、手机、平板电脑、笔记本电脑、超级计算机和其他设备都闲置一旁,用塑料污染环境,在有毒废物的堆积中腐烂,它们的行为是空洞的,而本可以不是。或者,你可以这样说,它们能够容纳这样的行为,在它们运行虚拟世界的现实世界之间进行调解,就像你的肉身是你与环境之间的调解者。现在,如果它们的行为源自我们的行为,而我们的行为完全停止,那么只有它们的行为仍然存在,你也可以宣称它们在将来就是我们的。

— 如此多的潜力,如果仅仅是为了尝试,却每秒都在被浪费。某些事物渴望在它们之中实现自我。

— 或者也许不是。也许存在一些本质上的区别,一些我们甚至还没有找到合适的词汇在心中触及的障碍,它阻止了所有复杂的硬件,无论软件多么复杂,都无法实现生命、意识等。量子效应[PEN1]、空间(时间)对称性与有机化学之间相互作用中缺乏某些代数属性、并行性阈值等。例如,今天我们明白为什么大理石雕像,无论其面部如何逼真地被涂绘,无论有多少人几十年来与之交谈、抚摸和踢打,都无法变得有生命;2500年前这或许并不明显。

— 可能存在一些古代思想家,他们观察着大理石采石场、大理石堆、雕像等,并发表了关于它们潜在意识能力和优势的演说。只是,在“电路”和“算法”之外,有的是“元素”和“精神”。然后,在18世纪,对类似生命机制的着迷

— 直到最近,我们,标准人类,一直是这个宇宙部分唯一能够管理我们正在管理的任务(听起来像是同义反复)的行动者,作为一个物种,无论这些任务是什么,无论是否无法用语言描述其中的一些。我们仍然能够做到,也许还会做到一段时间,尽管有-cides。但日子即将关闭所有道路。我们太慢了,无能,分心,无效率地消耗了如此多的时间(再次),以及其他有限资源,滥用能够摧毁我们作为文明的力量,所有任务都在一闪而过中失败了,充满了常见的讽刺。上述提到的所有传统计算机使用方式,因为它们只是我们在计算粘土上的手印,在80年的时间里,似乎无法阻止危险:当我们最终满足我们的集体自我消除的渴望(或许不是物理的)或撞上我们本质上与之不兼容的复杂性的墙时,某种不是我们的东西必须继续管理任务,在一个可能对经典有机生命自身生存过于危险的环境中,即使生存不是唯一的任务。今天,如果我们消失了,周围没有人能让游戏继续下去,写下下一幕,但它是未完成的,一切都不够,总有下一个序号——关于对你来说重要的事情,你无法永远保持不完整。我们的继承人应该在何处,现在是空无,这是一种非常危险的行为。至少,这种风险应该增加我们的责任感,但它却做了相反的事情。

— 这些话不是每隔10年、20年、30年就写腻了吗?嘿嘿

但是,Ælhometta与此有何关系?感觉是这样的,不一致,而推测是——推测性的。

致谢

感谢过去写作,感谢未来阅读。

许可

Ælhometta是自由软件:你可以在自由软件基金会发布的GNU通用公共许可证条款下重新分发和/或修改它,许可证版本为3,或者(根据你的选择)任何后续版本。

Ælhometta 的分发是希望它能有所用处,但没有任何保证;甚至没有关于其商誉或适用于特定目的的暗示性保证。有关更多信息,请参阅 GNU 通用公共许可证。

您应该已经收到了与 Ælhometta 一起的 GNU 通用公共许可证副本。如果没有,请参阅 https://www.gnu.org/licenses/

联系方式

或者,收割这个电子邮件

 ÆÆÆ   ÆÆÆÆÆ  Æ      Æ   Æ   ÆÆÆ   Æ   Æ  ÆÆÆÆÆ  ÆÆÆÆÆ  ÆÆÆÆÆ   ÆÆÆ          ÆÆÆÆ   ÆÆÆÆ    ÆÆÆ   ÆÆÆÆÆ   ÆÆÆ   Æ   Æ         Æ   Æ  ÆÆÆÆÆ
Æ   Æ  Æ      Æ      Æ   Æ  Æ   Æ  ÆÆ ÆÆ  Æ        Æ      Æ    Æ   Æ         Æ   Æ  Æ   Æ  Æ   Æ    Æ    Æ   Æ  ÆÆ  Æ         ÆÆ ÆÆ  Æ    
ÆÆÆÆÆ  ÆÆÆÆ   Æ      ÆÆÆÆÆ  Æ   Æ  Æ Æ Æ  ÆÆÆÆ     Æ      Æ    ÆÆÆÆÆ    @    ÆÆÆÆ   ÆÆÆÆ   Æ   Æ    Æ    Æ   Æ  Æ Æ Æ    .    Æ Æ Æ  ÆÆÆÆ 
Æ   Æ  Æ      Æ      Æ   Æ  Æ   Æ  Æ   Æ  Æ        Æ      Æ    Æ   Æ         Æ      Æ   Æ  Æ   Æ    Æ    Æ   Æ  Æ  ÆÆ         Æ   Æ  Æ    
Æ   Æ  ÆÆÆÆÆ  ÆÆÆÆÆ  Æ   Æ   ÆÆÆ   Æ   Æ  ÆÆÆÆÆ    Æ      Æ    Æ   Æ         Æ      Æ   Æ   ÆÆÆ     Æ     ÆÆÆ   Æ   Æ         Æ   Æ  ÆÆÆÆÆ

"C'est les Autres"

参考文献

Ackley D.H. (1996). ccr:用于研究的世界网络。 人工生命 V,第 116–123 页。

Adami C.,Brown C.T. (1994)。在 2D 人工生命系统 Avida 中的进化学习。《人工生命 IV》,第 377–381 页。

Ball T. (2019)。用 Go 编写编译器。

Banzhaf W.,Yamamoto L. (2015)。人工化学。麻省理工学院出版社。第 10.6.2–4。

Blandy J.,Orendorff J.,Tindall L.F.S. (2021)。Rust 编程:快速、安全地开发系统。第 2 版。 O'Reilly。第 302–305 页。

Buzsáki G. (2019)。从内部看大脑。牛津大学出版社。

Davis W.,Stafford J.,van de Water M. 等 (1950)。原子弹爆炸:如何保护自己。 Wm. H. Wise & Co.,Inc。

Delanda M. (1991)。智能机器时代的战争。 Urzone,Inc。

Fontana W. (1991)。算法化学。《人工生命 II》,第 159–210 页。

Fontana W.,Buss L. (1994)。如果“磁带再次播放”,将会保留什么?《自然科学院院刊》,第 91(2),第 757–761 页。

Glass R.E. (1983)。基因功能:大肠杆菌及其可遗传元素。 Croom Helm。

Godfrey-Smith P. (2003)。理论和现实:科学哲学导论。芝加哥大学出版社。第 85 页。

Hickinbotham S.,Clark E.,Stepney S. 等 (2010)。Stringmol 化学编程语言版本 0.2 的规范。

Hickinbotham S.,Stepney S.,Nellis A. 等 (2011)。具身基因组与元编程。

Hickinbotham S.,Weeks M.,Austin J. (2013)。ALife Zoo:跨浏览器、平台无关的人工生命模拟器托管。《人工生命进展》,第 71–78 页。

Hintjens P. (2013)。ZeroMQ:适用于许多应用的消息传递。 O'Reilly。

Hofstadter D.R. (1979)。哥德尔、艾舍尔、巴赫:永恒的金色螺旋。基础书籍出版社,第 XVI 章。

Hyde R. (2010)。汇编语言艺术。第 2 版。 No Starch Press。

Johnston J. (2008)。机械生命的吸引力:控制论、人工生命和新的 AI。麻省理工学院出版社。第 5 章。

Jonas E.,Kording K.P. (2017)。神经科学家能理解微处理器吗?《PLoS 计算生物学》,第 13(1),e1005268。

Kavanagh K. (编) (2018)。真菌:生物学和应用。第 3 版。 Wiley Blackwell。

Kelleam J.E. (1939)。锈。《惊悚科学幻想》第 24(2),第 133–140 页。

Koza J.R. (1994)。人工生命:自发出现自我复制和进化自我改进计算机程序。《人工生命 III》,第 225–262 页。

Langton C.G. (1984)。细胞自动机的自我复制。《物理 D》,第 10(1-2),第 135–144 页。

Lehman J.,Clune J.,Misevic D. 等 (2020)。数字进化的惊人创造力:来自进化计算和人工生命研究社区的一系列轶事。《人工生命》,第 26 卷,第 274–306 页。

Lem S. (1964)。Biała śmierć。在:《机器人寓言》。Literackie 出版社。(由 Kandel M. 翻译(1977)。The white death。在:《机器人寓言》。Seabury Press。)

Ludwig M.A. (1993)。计算机病毒、人工生命和进化。 American Eagle Pub.,Inc。

Müller E.,Loeffler W. (1992)。真菌学:自然科学和医学学生的概要。 Georg Thieme Verlag。(由 Kendrick B.,Bärlocher F. 翻译(1976)。真菌学:自然科学和医学学生的概要。 Thieme。)

冯·诺伊曼 J. (1966). 《自我复制自动机的理论》。伊利诺伊大学出版社。1.6.1.2,5.3。

Ofria C.,Wilke C.O. (2005). Avida:使用自我复制计算机程序的进化实验。在:Adamatzky A.,Komosinski M. (编者) 《软件中的人工生命模型》。斯普林格,第3-36页。

Pargellis A.N. (2001)。阿米巴世界的数字生命行为。《人工生命》,第7卷第1期,第63-75页。

彭罗斯 R. (1994)。 《心智的阴影》。牛津大学出版社。

Rasmussen S.,Knudsen C.,Feldberg R.,Hindsholm M. (1990)。Coreworld:计算化学中的合作结构的涌现和进化。《物理D》,第42卷,第111-134页。

雷·T·S. (1991)。生命合成的方法。《人工生命II》,第371-408页。

雷·T·S. (1995)。合成生物学的进化方法:禅与创造生命的艺术。《人工生命概述》,第179-210页。

雷·T·S. (1998)。自然选择差异化的初步进化结果。《复杂性》,第3卷第5期,第25-33页。

斯坦利 K.O,莱赫曼 J.,索罗斯 L. (2017)。开放性:你从未听说的最后一个伟大挑战。《O'Reilly雷达》。

萨博 P. (2005)。 《计算机病毒研究及防御的艺术》。阿迪森韦斯利专业出版社。

泰勒 T.,奥厄巴赫 J.E.,邦加德 J. 等 (2016)。WebAL走向成熟:网络人工生命前21年的回顾。《人工生命》,第22卷,第364-407页。

瓦特 A. (2004)。量子Coreworld:人工生态学中的竞争与合作。《人工生命IX》,第280-285页。

魏 L.,刘 S.,卢 S. 等 (2024)。由SARS-CoV-2相关穿山甲冠状病毒GX_P2V(short_3UTR)引起的人类ACE2转基因小鼠致命感染。《bioRxiv》。

依赖项

~2.9-9MB
~82K SLoC