Ensemencer

From Esolang
Jump to navigation Jump to search

Uses the standard Mersenne twister implementation MT19937, to seed its main memory space. Named after the French verb meaning to sow (seeds).

Description

Ensemencer has the following parts:

  • an input buffer from which it can read user input, and also write to.
  • an instruction stream, which is read byte by byte
  • a data field, which is a series of 32 bit values seeded by a particular Mersenne twister seed (initialised to 0 before execution).

There is an instruction pointer, which moves forwards one byte at a time. The data pointer moves forwards one step (32bit Mersenne twister value) every data read.

The Mersenne twister has a period of 219937-1. When the instruction pointer reaches the end of the instruction stream, it reads the remaining values of the data field (to reset it), and also resets the instruction pointer to the beginning of the instruction stream and repeats until a halt ! instruction is encountered.

The seed is generated using the MT19937 init_genrand() algorithm, which is limited to 32bit seeds. This is not the default in Python3, and not what Seed uses. These use the init_by_array() and can accept larger seeds. (I need to check the actual size limit for these seeds, I suspect up to 64bit system dependent seeds can be used, but these are scaled down to 32bit?)

The main function of the MT in this language is to provide reproducible and portable data values.

Commands

Command Description
# Read value from input buffer and set seed
. Output next data byte (MT32bit >> 24)
{int [0-9]+} Read {int} data values and discard them
? Conditional skip, skip next instruction byte if MT32bit & 1 is true
< Read data byte and insert at head of input stream
- Next - skip remaining commands and begin program loop again (a convenience operator)
! Halt
{EOF} Read the remainder of the data field values (to 219937-1) and reset instruction stream

Examples

Hello, World!

152.
77.
52982..
584.
152.
101.
681.
16.
592.
1057.
100.
254.
79.
!

Truth machine

Integer input {0, 1}

#
1182 ?.
6?!
84.
306<

Character input {48, 49} / {"0", "1"}

#
1261 ?.
?!
265.
286<

Binary cat ({"0", "1"} input)

#
86622.

Inverting binary cat (0 -> 1, 1 -> 0)

#
46?-
186217.

Two-state FSM: Parity machine

Implements an example in Minksy's Computation: Finite and Infinite Machines Fig 2.3-2

The last 0/1 output indicates whether an odd number of 1's have been received as input over the history of the machine's operation.

#       Qzero input
1261?.  zero in zero out
5?-
1019?.  one in one out
#       Qone input
238?.   zero in one out
26?<
4?-
340.    one in zero out

This code has a side effect where a line-feed input (ASCII 10) produces output rc in one of the states. This was unintentional, but further demonstrates that the machine can be in two distinct states. The alphabetic characters to the right are NOPs and demonstrate a method of commenting. The purpose of this example is to prove that by locating sufficient skips based on varying seeds, multiple distinct states can be implemented in this language. Tools to automate the discovery of seeds and offsets which give the desired output and skip behaviour should make writing arbitrary automata possible. There is more flexibility and options with this language than in Seed, so the generation process should be more interesting, and have more opportunity for creativity.

Multi-state FSM: duplicate first of a group of similar bits: e.g. 10011 -> 11000111

... in progress (I think it's possible).

Computational class

This language was designed to have minimal features to be Turing complete, but not in obviously useful ways. It can re-execute instructions, conditionally avoid executing instructions, and can read and write data (to some extent). The finite limits of the Mersenne twister (and the usable number of seeds) mean that it should not be TC. Hopefully it can be used to implement arbitrary finite state machines, and, at least theoretically, be equivalent to a bounded-storage machine. It is possible however that some FSMs cannot be realised with this language (because creating arbitrary outcomes is non-trivial), and certainly some very unlikely data combinations will not exist in the finite period of the twister.

See also

External resources