# Imprecision

Imprecision is an esoteric programming language created by User:ais523 in 2024, inspired by Blindfolded Arithmetic.

## Specification

Imprecision programs store data in a number of variables, each of which has a name consisting of ASCII letters. (There is no limit on how many variables can be used, but any given program will use only the variables mentioned in the program and thus can only access finitely many.) Each variable stores a rational number, initially 0.

A program consists of a list of statements, each of which assigns the result of an expression to a variable (overwriting the variable's old value). The grammar of expressions is as follows, matching the grammar used for the same expressions in typical practical programming languages:

```expr ::= expr '+' expr  /* addition */
| expr '-' expr  /* subtraction */
| expr '*' expr  /* multiplication */
| expr '/' expr  /* division of rationals: produces an exact rational result */
| '(' expr ')'   /* grouping/precedence override: returns the result of the expression inside */
| variablename   /* returns the value of the named variable */
| integer        /* returns the integer (integers are written in decimal) */
```

Operator precedence is the usual for programming languages, i.e. first do multiplications and divisions left-to-right, then additions and subtractions left-to-right. The quotes in the grammar are not present in actual programs (e.g. a sample expression is `4 + x * x`, which is equivalent to `4 + (x * x)` and different from `(4 + x) * x`). Division by zero is undefined behaviour (unlike in Blindfolded Arithmetic, where it is a halt signal).

A statement itself is written by giving the variable name, an `=`, and an expression, e.g. `a = b + 5`.

There is no control flow, with the statements executing from the start to the end of the program in order. However, after the last statement is executed, the first statement is executed again, forming an infinite loop.

### Special variables

If a program contains the `halt` variable, it will halt if it ever assigns a positive value to that variable. (If a negative or zero value is assigned, this does not cause the program to halt.)

If a program contains the `input` variable, it will be initialized to an integer taken from user input, rather than 0.

If a program contains the `output` variable, then if the program halts, the value of `output` will be output to the user, rounded to the nearest integer.

Implementations should take and produce output in integer form by default, but may support command-line options to encode strings as integers, then decode the integer to string as output. The way in which this is done depends on the implementation.

## Computational class

Imprecision without I/O can easily implement a finite state machine via using a polynomial as though it were a lookup table, in order to change the value of a state variable (because it is possible to fit a polynomial with rational coefficients to produce any given finite input-output mapping among integers). However, the language finds it very difficult to read data that might be arbitrarily large, because there is no way to map (e.g.) all positive values to 0 but 0 to 1 using only the `+ - * /` operations. This makes it difficult to write a program that runs reliably after reading input, and also makes it difficult to retrieve arbitrarily large amounts of data, with the latter being one of the requirements for Turing-completeness.

ais523 suspects (but has not proven) that the language is Turing-complete anyway, via writing a program that uses approximate state variables and counter values, in the style of Analogia. Unfortunately, unlike in Analogia, there is no easy way to quantize the value of a state variable that could potentially be arbitrarily large; instead, a TCness proof would probably need to ensure that the sequence of extra error added to the counter values forms a convergent series, and thus never gets large enough to leave a counter value unreadable.