User:Salpynx/Pico
An in-progress picofuck attempt, with some caveats. Defined in terms of simple translations.
I'm not 100% this should count as as picofuck variant -- it certainly doesn't have a RBF translation yet. It may be a counter-example to emphasise the features of a more meaningful group theory analysis.
The intent was that if pico()
is a single defined function in Python, it could be one in any TC language, so this could be converted into equivalent RBF code. Doing this won't really prove anything about the relationship of the hypothesised picofuck to RBF. This attempts to demonstrate my idea of deferred parsing where if a FST can pass all the information from an input source and additionally make it available to code it adds to process that input, equivalent computational functionality can be achieved. The fact that pico()
does reduce a bf like language down to one (albeit complex) semantic operation may be interesting to see in practice, but I'm not sure the theory is that surprising. This approach seems to be using all the 'frowned upon' encoding techniques, merely shifting their location.
There are still some rough edges, and the code needs further testing. I'm struggling to come up with good RBF test cases. If this code cannot be translated to RBF I think it'll be due to syntax issues, not anything computational.
I've tried to make this as simple as possible. Only one extra piece of state is explicitly added, CTX
(only 1 bit!!), but much more would need to be modelled in RBF to enable some of the Python features used. This extra state is what makes this not a simple-simple-translation.
RBF | Pico |
---|---|
+ | [[[]][]] |
< | [[[[]]][]] |
> | [[[[[]]]][]] |
( | [[][[[]][] |
) | ]] |
and now a simple translation to bf for input and output. The loop construct now handles a range of enter and exit conditions, and the change cell operation supports flips, increments, and decrements:
bf | Pico |
---|---|
- | [[[]][[]]] |
+ | [[[]][[[]]]] |
< | [[[[]]][]] |
> | [[[[[]]]][]] |
. | [[[[[[]]]]][[[]]]] |
, | [[[[[[[]]]]]][[[]]]] |
[ | [[][[[]][[]] |
] | ]] |
Reversible Brainfuck can be translated using the bf table above with a single row replaced:
[ | [[][[][[]] |
This selects the loop entry and continuation conditions (0, 1) for enter loop on zero, repeat on non-zero. Reversible Brainfuck appears to have requirements on wrapping behaviour. The current pico()
explicitly prevents negative integers for cell values and pointers, but this isn't a necessary feature. I need to decide if there is one wrapping behaviour that best encompasses all variants, and whether this tape behaviour should be configurable in the commands. Three options: 1) wrapping 2) R infinite 3) LR infinite to apply to the pointer and cell values, potentially independently.
Pico | Python |
---|---|
[ | pico( |
] | ), |
Where the following python code is inserted at the beginning of the translation (which finite-state transducers permit):
T, P, C = {}, 0, 0 def pico(*a): global T, P, C r, T[P], P, C = (lambda x: (*x, x[0] is not 0) if len(x) > 2 else (None, *(max(0, v) for v in x), 0))(([ lambda a,v: ((2 * C - 1) * (not len(a)) or (len(a) < 2 and a[0] + a[0]//abs(a[0])) or (a, 0)[a[0] < 0], v, P), lambda a,v: (1 - v if a[1] == 1 else v + 2 * a[1] - 5, P), lambda a,v: (v, P - 1), lambda a,v: (v, P + 1), lambda a,v: (v, print([bool, int, chr][a[1] - 1](v), end='') or P), lambda a,v: ([bool, int, lambda s: ord(s[0])][a[1] - 1](input('>')), P) ][((len(a) < 2) or (max(1, 0 - a[0]))) - 1](a, T.get(P, 0)))) if r is not 0: return r while (bool(T[P]) == a[1][r] - 1 and ([pico(-c, a) for c,a in a[1][2:]] or 1)): r = 1
I believe an equivalent construct could be made without this initial pre-block, but it would involve more fighting with Python's syntax, and repeat the pico()
definition for every translated symbol.
Testing
I have a few basic test cases in place.
(">>>>>+<<<<<+(+>)", {0: 0, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1})
Is one I'm happy with that tests a loop.
Slightly more complex is:
RBF: >>>>>+<<<<<+(+(<+)>>)
to test nested looping.
According to the code above the final tape is:
{5: 1, 0: 1, 2: 1, 1: 1, 3: 1}
Hello World!
[[[]][[[]]]][[[]][[[]]]][[[]][[[]]]][[[]][[[]]]][[[]][[[]]]][[[]][[[]]]][[[]][[[]]]][[[]][[[]]]][[][[[]][[]][[[[[]]]][]][[[]][[[]]]][[[]][[[]]]][[[]][[[]]]][[[]][[[]]]][[][[[]][[]][[[[[]]]][]][[[]][[[]]]][[[]][[[]]]][[[[[]]]][]][[[]][[[]]]][[[]][[[]]]][[[]][[[]]]][[[[[]]]][]][[[]][[[]]]][[[]][[[]]]][[[]][[[]]]][[[[[]]]][]][[[]][[[]]]][[[[]]][]][[[[]]][]][[[[]]][]][[[[]]][]][[[]][[]]]]][[[[[]]]][]][[[]][[[]]]][[[[[]]]][]][[[]][[[]]]][[[[[]]]][]][[[]][[]]][[[[[]]]][]][[[[[]]]][]][[[]][[[]]]][[][[[]][[]][[[[]]][]]]][[[[]]][]][[[]][[]]]]][[[[[]]]][]][[[[[]]]][]][[[[[[]]]]][[[]]]][[[[[]]]][]][[[]][[]]][[[]][[]]][[[]][[]]][[[[[[]]]]][[[]]]][[[]][[[]]]][[[]][[[]]]][[[]][[[]]]][[[]][[[]]]][[[]][[[]]]][[[]][[[]]]][[[]][[[]]]][[[[[[]]]]][[[]]]][[[[[[]]]]][[[]]]][[[]][[[]]]][[[]][[[]]]][[[]][[[]]]][[[[[[]]]]][[[]]]][[[[[]]]][]][[[[[]]]][]][[[[[[]]]]][[[]]]][[[[]]][]][[[]][[]]][[[[[[]]]]][[[]]]][[[[]]][]][[[[[[]]]]][[[]]]][[[]][[[]]]][[[]][[[]]]][[[]][[[]]]][[[[[[]]]]][[[]]]][[[]][[]]][[[]][[]]][[[]][[]]][[[]][[]]][[[]][[]]][[[]][[]]][[[[[[]]]]][[[]]]][[[]][[]]][[[]][[]]][[[]][[]]][[[]][[]]][[[]][[]]][[[]][[]]][[[]][[]]][[[]][[]]][[[[[[]]]]][[[]]]][[[[[]]]][]][[[[[]]]][]][[[]][[[]]]][[[[[[]]]]][[[]]]][[[[[]]]][]][[[]][[[]]]][[[]][[[]]]][[[[[[]]]]][[[]]]]
The Python version is:
pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(),pico(pico(pico(),),pico(pico(),),pico(pico(pico(pico(pico(),),),),pico(),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(),pico(pico(pico(),),pico(pico(),),pico(pico(pico(pico(pico(),),),),pico(),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(pico(pico(),),),),pico(),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(pico(pico(),),),),pico(),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(pico(pico(),),),),pico(),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(pico(),),),pico(),),pico(pico(pico(pico(),),),pico(),),pico(pico(pico(pico(),),),pico(),),pico(pico(pico(pico(),),),pico(),),pico(pico(pico(),),pico(pico(),),),),),pico(pico(pico(pico(pico(),),),),pico(),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(pico(pico(),),),),pico(),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(pico(pico(),),),),pico(),),pico(pico(pico(),),pico(pico(),),),pico(pico(pico(pico(pico(),),),),pico(),),pico(pico(pico(pico(pico(),),),),pico(),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(),pico(pico(pico(),),pico(pico(),),pico(pico(pico(pico(),),),pico(),),),),pico(pico(pico(pico(),),),pico(),),pico(pico(pico(),),pico(pico(),),),),),pico(pico(pico(pico(pico(),),),),pico(),),pico(pico(pico(pico(pico(),),),),pico(),),pico(pico(pico(pico(pico(pico(),),),),),pico(pico(pico(),),),),pico(pico(pico(pico(pico(),),),),pico(),),pico(pico(pico(),),pico(pico(),),),pico(pico(pico(),),pico(pico(),),),pico(pico(pico(),),pico(pico(),),),pico(pico(pico(pico(pico(pico(),),),),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(pico(pico(pico(),),),),),pico(pico(pico(),),),),pico(pico(pico(pico(pico(pico(),),),),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(pico(pico(pico(),),),),),pico(pico(pico(),),),),pico(pico(pico(pico(pico(),),),),pico(),),pico(pico(pico(pico(pico(),),),),pico(),),pico(pico(pico(pico(pico(pico(),),),),),pico(pico(pico(),),),),pico(pico(pico(pico(),),),pico(),),pico(pico(pico(),),pico(pico(),),),pico(pico(pico(pico(pico(pico(),),),),),pico(pico(pico(),),),),pico(pico(pico(pico(),),),pico(),),pico(pico(pico(pico(pico(pico(),),),),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(pico(pico(pico(),),),),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(),),),pico(pico(pico(),),pico(pico(),),),pico(pico(pico(),),pico(pico(),),),pico(pico(pico(),),pico(pico(),),),pico(pico(pico(),),pico(pico(),),),pico(pico(pico(),),pico(pico(),),),pico(pico(pico(pico(pico(pico(),),),),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(),),),pico(pico(pico(),),pico(pico(),),),pico(pico(pico(),),pico(pico(),),),pico(pico(pico(),),pico(pico(),),),pico(pico(pico(),),pico(pico(),),),pico(pico(pico(),),pico(pico(),),),pico(pico(pico(),),pico(pico(),),),pico(pico(pico(),),pico(pico(),),),pico(pico(pico(pico(pico(pico(),),),),),pico(pico(pico(),),),),pico(pico(pico(pico(pico(),),),),pico(),),pico(pico(pico(pico(pico(),),),),pico(),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(pico(pico(pico(),),),),),pico(pico(pico(),),),),pico(pico(pico(pico(pico(),),),),pico(),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(),),pico(pico(pico(),),),),pico(pico(pico(pico(pico(pico(),),),),),pico(pico(pico(),),),),
This is a simple translation of the example Hello World from the bf page, which uses nested loops not just trivial output, so is a decent confirmation of functionality:
++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
Next steps
- Refactor:
- Combine the two pointer lambdas to enable flip, inc, and dec in one command, like the cell value command (-2, x)
- Investigate combining cell and pointer lambdas ((-2, x), (-3, x), and the redundant (-4, x)) into a single 'Tape machine' lambda
- Similarly combine I/O lambdas ((-5, x), (-6, x)) into one. Reduce line count and encoding overhead.
- Functions / Combinators
- Add iota combinator or equivalent (if one isn't there already...)
- Enable anonymous function definition and use.
- Binding
- Enable an anonymous function to be bound (replace or append) to
pico
- Investigate Python's
atexit
module to enablepico()
to register a single function to be run on exit (to guarantee simple translation from any language)
- Enable an anonymous function to be bound (replace or append) to
- Don't break existing functionality. Look for bugs hiding in edge cases.
Ideal pico() command structure
- (0/(-1, x)) -- Command and control / loop
- (-2, x) -- Tape machine
- (-3, x) -- I/O
- (-4, x) -- Combinator (consider making this (-3, x)?)
- (-5, x) -- meta