Probablyfuck

From Esolang
Jump to navigation Jump to search

Probablyfuck is a variant of brainfuck inspired by the ideas of stochastic computing. Cell values are probabilistic bit streams (also known as Bernoulli processes), which you can operate on with brainfuck-like instructions.

Details

The tape is initialized with an infinite number of random bit streams, each with a probability of 0.5. Individual cells can be forced to take on a value of 0 with [!]. boolfuck programs can be converted to probablyfuck in this manner, but program size can be greatly reduced by taking advantage of probabilistic features.

The program is ran an infinite number of times, each time with the next bit from each bit stream. At the end of every run, each cell has a probability of being 0 or 1 based on how each run changes it, and the resulting tape of probabilities is the result of the probablyfuck program.

Instructions

Instruction Behaviour
! Inverts the current bit.
# Fetches the next bit from the current bit stream.
<> Moves the cell pointer left or right.
[...] Runs the code within while the current bit stream returned 1 on this specific run.

Examples

Multiplication

[>[>!>]]

If the tape is initialized with two independent streams with probabilities of p and q, and a third and fourth stream are both set to 0, this will give the third stream a probability of pq. At the end of the program, the cell pointer has a pq probability of being on the fourth cell, and a 1 - pq probability of remaining at the first cell.

Here is an alternate method, which guarantees that the cell pointer returns to the first cell, but destroys the operands in the process.

[!>[!>!<]<]

Squaring

A naive implementation of squaring might look like this.

[[>!>]]

This is the same as multiplication, but it checks the first bit stream twice instead of checking two different bit streams. The problem with this is that, because the same bit is checked twice regardless of whether it's 0 or 1, the output will simply be the input bit stream, instead of actually multiplying the probabilities together.

This is solved by the # operator, which can be used to delay the bit stream after the first check. The operator decorrelates the two values, allowing the multiplication to give the correct result.

[#[>!>]]