Zyme

an evolvable language for genetic programming

Zyme is an esoteric language for genetic programming: creating computer programs by means of natural selection.

For successful evolution mutations must generate a wide range of phenotypic variation, a feat nearly impossible when randomly modifying the code of conventional programming languages. Zyme is designed to maximize the likelihood of a bytecode mutation creating a novel yet non-fatal change in program behavior.

Diverging from conventional register or stack-based architectures, Zyme uses a unique molecular automaton-based virtual machine, mimicking an abstract cellular metabolism. This design enables fuzzy control flow and precludes invalid runtime states, transforming potential crashes into opportunities for adaptation.

Interactive demonstration

Editor

Compile the source code

Genetic programming begins with an initial program, often generated randomly. However, evolution can be impeded by an unsuitable choice of this initial program. Two common ways in which programs prove inadequate are:

  • The program may be too small and lack complexity, rendering it overly fragile.
  • The program's behaviour might not produce output in the required format (or any output at all), preventing meaningful evaluation. For example, if a program should return a single byte representing a category in a classification problem, but fails to return anything, there's nothing to assess.

The Zyme assembler compiles human-readable source code into the mutable bytecode, enabling you to build bespoke initial programs for specific machine learning tasks.

Bytecode

Compile source code to generate bytecode

Mutate the bytecode

Click on each byte to mutate it.

This "Hello Creatures." source code generates three strands, which are the primitive data structure of the Zyme virtual machine. Strands are just arrays of bytes, however - given they are homoiconic - they are interpreted as both code (a sequence of instructions) and data (a sequence of integer values).

The strands are concatenated, with empty or null bytes 00 as separators to produce the bytecode ready for mutation.

Any binary data is valid bytecode on the Zyme virtual machine. This design ensures that programs cannot crash; however, they may instead return no output or perform no useful function.

Try to mutate the bytecode to reveal the hidden message1.

Console

hex view:

Execute the program

The Zyme virtual machine executes input bytecode by first splitting it into its constituent strands, then evaluating each independently and in parallel. Within each strand, execution proceeds sequentially, with each byte encoding an individual opcode. These instructions manipulate the state of the current strand to perform various arithmetic, logical and control flow operations.

Strands interact by binding to one another to form temporary complexes. Specific machine instructions control when and how binding occurs. For instance, the WAIT instruction opens a binding site, and the LOAD instruction binds to a waiting open site.

Binding can only occur successfully when the motif sequences associated with the binding sites match. Motifs are specified after the instruction, e.g., WAIT %”ABCDABCD” |. Importantly, these motifs do not require exact matches, allowing for fuzzy control flow.

1

While there are many mutations that can reveal the “Secret!” message, the most reliable method is to mutate the first byte of the second strand corresponding to the WAIT instruction of the strand containing “Hello Creatures.”. This corresponds to the 20th byte, 0F in the bytecode.

This mutation prevents the "Hello Creatures." strand from opening a binding site, preventing any other strand from binding to it. Consequently, the LOAD instruction falls back to the binding site of the strand containing the "Secret!" message, which is normally a weak match. As a result, the "Secret!" message is printed instead of "Hello Creatures.".