Convergaptor
Paradigm(s) | Unknown |
---|---|
Designed by | Hakerh400 |
Appeared in | 2020 |
Computational class | Unknown |
Major implementations | Unimplemented |
File extension(s) | .txt |
Convergaptor is a programming language which performs computation by searching for bit patterns in the decimal expansion of the real number defined by the source code.
Overview
Input and output are sequences of bits. Source code represents a methematical formula that defines a real number in interval [0, 1)
. If the number evaluates to something outside this interval, or is not a real number, or does not converge, then spin in an infinite loop.
Then the obtained real number is written in binary (base 2) and the decimal digits (bits) after the decimal point are extracted to form an infinite sequence of bits.
That sequence is then interpretted as follows. We split the sequence into subsequences such that each subsequence:
- has odd length
- ends with
0
- has
1
s on each even position in the subsequence (0-indexed), except the last bit (which is0
)
For example, if the source code defines number 1 / 7
, the decimal expansion is
0.00100100100100100100...
and the subsequences are
0 0 100 100 100 100 100 100 ...
Now drop all bits at even positions in each subsequence:
_ _ 0 0 0 0 0 0 ...
We represent empty sequences by _
. Then we consider consecutive pairs of subsequences (the first two, the second two, and so on)
[_ _] [0 0] [0 0] [0 0] ...
Each pair contains two sequences (we call them x
and y
respectively). If there are multiple pairs with the same x
, then keep only the first pair of them and drop the others. In this example, we obtain
[_ _] [0 0]
We dropped all other pairs that have 0
as the x
parameter, so we are left with exactly two pairs. If there is a pair whose x
is equal to the input, then output y
of that pair. Otherwise spin in an infinite loop.
In this example, if the input is an empty sequence, the program outputs nothing and halts. If the input is a single 0
, then the program outputs 0
and halts. In all other cases, it spins in an infinite loop.
Syntax
Source code consists of one or more mathematical function definitions. Definition looks like this:
f(x, y) = pow(add(pow(x, 2), pow(y, 2)), div(1, 2));
For example, this function named f
takes two arguments x
and y
and returns the Euclidean distance between the points (0, 0)
and (x, y)
in the plane (assuming x
and y
are real numbers).
Function definition consists of left side and right side separated by =
and ends with ;
. On the left side we have function name followed by parentheses in which we have formal argument names separated by commas. The number of arguments is called function arity. When called, it must be called with the exact number of arguments that matches its arity. In case of zero arity (constant function) the parentheses can be omitted, both in the definition and/or when calling the function.
On the right side of the equals sign, we have either a constant (zero-arity function) or a function call. A function call is represented by function name followed by parentheses and arguments. Each argument is either a constant or another function call. In the above example, we call function pow
with arguments add(pow(x, 2), pow(y, 2))
and div(1, 2)
. All arguments and return values (for any function) are complex numbers of unlimited precision.
There are predefined (native) and user-defined functions. The main function is the first function that appers in the source code and its arity must be zero. Its return value is the real number whose decimal expansion we examine.
Any user-defined function may call other user-defined functions or native functions, but recursion is not allowed (neither direct or indirect).
Native functions
The following functions are predefined:
0
,1
,2
, ... - Literal integers (can be arbitrary large) are constant functions that return the value obtained by parsing the integer in base 10add(x, y)
- Addsx
andy
sub(x, y)
- Subtractsy
fromx
mul(x, y)
- Multipliesx
withy
div(x, y)
- Dividesx
byy
pow(x, y)
- Raisesx
to the power ofy
log(x, y)
- Returns the logarithm ofy
with basex
floor(x)
- Roundsx
downceil(x)
- Roundsx
upre(x)
- Real part ofx
im(x)
- Imaginary part ofx
There are some compare functons:
eq(x, y, a, b)
- Ifx = y
then returnsa
, otherwise returnsb
lt(x, y, a, b)
- Ifx < y
then returnsa
, otherwise returnsb
gt(x, y, a, b)
- Ifx > y
then returnsa
, otherwise returnsb
le(x, y, a, b)
- Ifx <= y
then returnsa
, otherwise returnsb
ge(x, y, a, b)
- Ifx >= y
then returnsa
, otherwise returnsb
And also iterating functons:
sum<x, start, end>(y)
- Iteratesx
fromstart
toend
(inclusively) and for eachx
evaluatesy
(substitutesx
in it with the current value ofx
) and returns the sum of ally
s. Ifstart
is larger thanend
, then returns0
prod<x, start, end>(y)
- Similar tosum
, but returns the product of ally
s. In case ofstart > end
returns1
instead of0
lim<x, y>(z)
- Evaluatesz
whenx
approachesy
liminf<x>(y)
- Evaluatesy
whenx
approaches positive infinity
Note that <>
is a special part of the syntax.
Examples
Truth-machine
main = div(18879, pow(2, 15));
We cannot output infinitely many 1
s, but this program outputs 0
if the input is 0
and outputs 111
if the input is 1
. Here is how the computation goes (each line prepresents a step that is taken, as explained in the overview paragraph):
0.1001001101111110000000... 100 100 110 1111110 0 0 0 0 0 0 ... 0 0 1 111 _ _ _ _ _ _ ... [0 0] [1 111] [_ _] [_ _] [_ _] ... [0 0] [1 111] [_ _]
Now we can see that on input 0
it outputs 0
and on input 1
it outputs 111
. It also halts on empty string.
Cat
main = div( add( generate(0), generate(1) ), 4 ); generate(x) = liminf<inf>( sum<n, 2, inf>( div(prepare(n), pow( 2, sub( mul(sum<k, 2, n>( calc(k) ), 2), mul(calc(n), x) ) )) ) ); encapsulate(x) = liminf<inf>( mul(sum<n, 0, inf>( add( mul(getBit(x, n), pow(2, mul(n, 2))), ge(x, pow(2, n), pow(2, add(mul(n, 2), 1)), 0) ) ), 2) ); prepare(x) = dropFirstTwoBits(encapsulate(x)); calc(x) = sub(digitsNum(encapsulate(x)), 2); dropFirstTwoBits(x) = mod(x, pow(2, sub(digitsNum(x), 2))); digitsNum(x) = ceil(log(2, x)); getBit(x, i) = mod(divf(x, pow(2, i)), 2); mod(a, b) = sub(a, mul(divf(a, b), b)); divf(a, b) = floor(div(a, b));
It uses a modified version of Champernowne formula and produces the following real number (in base 2):
0.00100100110110101001010010110101101110011100111101111010101001010100101011010101101011100101110010 1111010111101110100111010011101101110110111110011111001111110111111010101010010101010010101011010101 0110101011100101011100101011110101011110101110100101110100101110110101110110101111100101111100101111 1101011111101110101001110101001110101101110101101110111001110111001110111101110111101111101001111101 0011111011011111011011111110011111110011111111011111111010101010100101010101001010101011010101010110 1010101110010101011100101010111101010101111010101110100101011101001010111011010101110110101011111001 0101111100101011111101010111111010111010100101110101001011101011010111010110101110111001011101110010 1110111101011101111010111110100101111101001011111011010111110110101111111001011111110010111111110101 1111111011101010100111010101001110101011011101010110111010111001110101110011101011110111010111101110 1110100111011101001110111011011101110110111011111001110111110011101111110111011111101111101010011...
Extracting the subsequences and obtaining input-output pairs gives the following:
---> 0 ---> 0 1 ---> 1 00 ---> 00 01 ---> 01 10 ---> 10 11 ---> 11 000 ---> 000 001 ---> 001 010 ---> 010 011 ---> 011 100 ---> 100 101 ---> 101 110 ---> 110 111 ---> 111 0000 ---> 0000 0001 ---> 0001 0010 ---> 0010 0011 ---> 0011 0100 ---> 0100 0101 ---> 0101 0110 ---> 0110 0111 ---> 0111 1000 ---> 1000 1001 ---> 1001 1010 ---> 1010 1011 ---> 1011 1100 ---> 1100 1101 ---> 1101 1110 ---> 1110 1111 ---> 1111 00000 ---> 00000 00001 ---> 00001 00010 ---> 00010 00011 ---> 00011 00100 ---> 00100 00101 ---> 00101 00110 ---> 00110 00111 ---> 00111 01000 ---> 01000 01001 ---> 01001 01010 ---> 01010 01011 ---> 01011 01100 ---> 01100 01101 ---> 01101 01110 ---> 01110 01111 ---> 01111 10000 ---> 10000 10001 ---> 10001 10010 ---> 10010 10011 ---> 10011 10100 ---> 10100 10101 ---> 10101 10110 ---> 10110 10111 ---> 10111 ...
As can be seen, each input maps to the exactly same output.
Computational class
Unknown.
Interpreters
No interpreters exist yet.