Liquid DownRight
Liquid DownRight (LDR) is a somewhat frivolous variation of DownRight (designed by User:ais523 in 2010), created by User:Keymaker in 2026.
The idea/purpose
This variation was made more or less instantaneously rather than through conscious effort, although the instantaneous aspect of it probably had deep roots in the author's thinking of DownRight (and working on into-DownRight translations) during the years. At any rate, the author had the idea to investigate how DownRight fares with some modifications, and it quickly turned out it thrives surprisingly well with the changes. LDR can be considered to be a sort of conceptual simplification of DownRight, as well.
The language is essentially like DownRight, but the matrix is treated akin to a wrapping 1-dimensional array: when moving one step 'right', rather than wrapping back to the first column on the same row, the pointer will proceed to the beginning of the next row (and from the very last cell to the very first cell). Moving 'down' works as in the original, but on interpreter level it can be done by moving the pointer forwards matrixWidth - 1 steps to achieve the same effect. There is also no requirement for the co-primality of matrix dimensions.
Curiously, the variant allows for a simpler proof of its Turing-completeness than the simplest known method for DownRight. There is also a way to translate it into Cyclic Tag with a conceptually simpler method than the one for original DownRight.
Advantages, if any, of translating other languages/systems (other than Cyclic Tag, see below) into Liquid DownRight over ordinary DownRight are yet to be studied.
Proof of Turing-completeness
Cyclic tag translates easily into LDR. The resulting matrix has a constant width of two, and its height is the number of production rules multiplied by three. (For instance, 2x6 is a valid matrix size as co-primality is not required in LDR.)
All CT production rules and initial queue data are translated using a simple substitution: Every 0 becomes >v>v and every 1 becomes vvv.
For example, CT program 10; 1; 00; with initial memory 11 becomes this 2x9 matrix (empty lines withing matrix for readability):
>vvvvvv -------- ------- vvv>v>v ------- -------- ------- -------- ------- vvv ------- -------- ------- -------- ------- >v>v>v>v ------- --------
Initial queue is '>' + the CT's initial queue translated using the substitution scheme. In this example it (11) yields >vvvvvv, which is placed into topmost left cell.
Translating LDR into Cyclic Tag
Go through every row of the matrix from top to bottom, each row's cells from left to right. Each cell becomes a production rule. Take the string in the cell, and replace every 'v' with '0' * (matrixWidth - 1) + '1', and every '>' with '1'. An empty cell produces an empty production rule.
For example, this LDR program
>> -- vv> -- v> ---
becomes
11; ; 0010011; ; 0011; ;
The queue is initially 1. As the cyclic tag program begins, reading a '1' from queue and placing the first cell's contents to queue simulates the way DownRight program begins the execution at the leftmost top cell and the queue is initialized with that cell's contents.
After the initialization, the program begins running the actual instructions. Now the cyclic tag's rule pointer is targeting the second production rule.
Reading from the queue, if the first in queue is '1', that means moving 'right'. Because the rule pointer has already shifted forward by one, a simulated moving right has already happened, and now the '1' that was read adds the contents of the present cell to the queue.
If the value in queue were an encoding of the 'down' instruction, it would be a string of '0's followed by '1'. In this example '001'. This would cause the second and third CT production rules to do nothing (given '0' is read for them), but in case of the fourth rule (here the cell below the topmost left cell -- one downwards the same column, in other words) a '1' would be read and thereby simulation to moving one cell down and adding that cell's contents to the queue is completed.
If there is no more data in the queue the system halts, just like LDR. But when that happens the CT simulation is in the production rule 'off by one' due the way the translation works, but the corresponding LDR cell (if needed) can be inferred by moving the rule pointer one step backwards and seeing which cell its location corresponds to.
Interpreter
Here is a simple interpreter in Python. The program matrix is stored in 'm' as a collection of lists, where each list represents a row, with each item in it representing a cell's value. Ironically, the interpreter treats the program as 2D matrix and emulates the behaviour of treating it as 1D array (a state-printing interpreter was easier to do this way). On each cycle the interpreter prints out the first 50 characters of the memory queue (and less if there are less characters).
m = [["vv>>",">>>>"], ["",">>"], [">v",">vv"]]
p = 1
for a in m:
for b in a:
if len(b) > p:
p = len(b)
mw = len(m[0])
mh = len(m)
x = 0
y = 0
q = m[0][0]
while(len(q)):
print("q:" + q[:50])
yy = 0
while yy < mh:
s = ""
xx = 0
while xx < mw:
if xx == x and yy == y:
s = s + "[" + m[yy][xx].ljust(p) + "]"
else:
s = s + " " + m[yy][xx].ljust(p) + " "
xx = xx + 1
print(s)
yy = yy + 1
if q[0] == "v":
y = (y + 1) % mh
elif q[0] == ">":
x = x + 1
if x == mw:
x = 0
y = (y + 1) % mh
q = q[1:] + m[y][x]
See also
- DownRight, without which this variation would not exist