# Substitution

Paradigm(s) | Declarative |
---|---|

Designed by | User:Hakerh400 |

Appeared in | 2021 |

Computational class | Unknown |

Reference implementation | Unimplemented |

File extension(s) | `.txt` |

**Substitution** is a declarative programming language invented by User:Hakerh400 in 2021.

## Syntax

Source code consists of zero or more **statements**.

### Statement

A statement consists of two **expressions** separated by an equals sign.

### Expression

An expression can be one of the following:

**Structure****Identifier****Substitution**

### Structure

A structure is either a **constant**, or a **pair**.

Constants are represented by alphanumeric strings that start with an uppercase letter. Examples: `A`

, `B`

, `C`

, `Xyz`

, `MyConstant`

. Two constants are equal iff they have the same name.

A pair consists of two expressions encapsulated into parentheses. Examples: `(A B)`

, `(A (B C))`

, `((Abcde Xyz) ((P Q) R))`

. Two pairs are equal iff both of their corresponding expressions are equal. No pair is equal to a constant.

### Identifier

Identifiers are represented by alphanumeric strings that start with a lowercase letter. Examples: `abc`

, `xyz`

, `myIdent`

. Two identifiers that have the same name are equal. Two identifiers that do not have the same name may or may not be equal.

### Substitution

Represented by three expressions encapsulated into brackets. Example: `[myIdent A (X Y)]`

.

Let , , , be any expressions. Substitution `[ ]`

is equal to expression ```
iff any of the following is true:
```

`is equal to`

`and`

`is equal to`

`is not equal to`

`and`

`is a constant and`

`is equal to`

`is not equal to`

`and`

`is equal to`

`( )`

(for some expressions`and`

`) and`

`is equal to`

`([ ] [ ])`

Here is an example: is `[(A B) A C]`

equal to `(C B)`

? First, according to the third substitution rule, we conclude that `[(A B) A C]`

is equal to `([A A C] [B A C])`

. Using the first substitution rule, we conclude that `[A A C]`

is equal to `C`

. Using the second rule, we conclude that `[B A C]`

is equal to `B`

. Since two pairs are equal iff they contain equal expressions, we conclude that `[(A B) A C]`

is indeed equal to `(C B)`

.

Another example: consider substitution `[(A A) (A A) B]`

. Using the first rule, we conclude that it is equal to `B`

.

## Semantics

If each identifier in the program can be replaced by a finite structure such that all statements are true, then the interpreter outputs `sat`

. Otherwise, the interpreter outputs `unsat`

.

## Examples

### Empty program

If there are no statements, the output is `sat`

.

### Same identifier

Program:

x = x

We can replace `x`

with any structure (for example constant `A`

) and we get `A = A`

, which is true, because both `A`

have the same name. The output is sat.

### Same constant

Program:

A = A

This also trivially outputs sat.

### Different constants

Program:

A = B

This is unsat, because `A`

is not equal to `B`

(they do not have the same name).

### Transitivity of equality

Program:

x = A x = B

From the first statement we conclude that `x`

must be `A`

, but the second statement asserts that `x`

is `B`

, so this is unsat.

### Infinite structure

Program:

x = (A x)

This is unsat, because `x`

cannot be a finite structure.

### Infinite structure using a substitution

Program:

f = (A Arg) x = [f Arg x]

This is also unsat. Identifier `f`

is used like a function with formal argument `Arg`

and `[f Arg x]`

represents calling `f`

with argument `x`

. It reduces to `x = (A x)`

, which is the previous example.

### Exclude a constant

Program:

[x A B] = [x A C]

This simply asserts that constant `A`

does not appear anywhere in `x`

. For example, `x`

can be `B`

, `C`

, `Xyz`

, `(X, ((Y, Z), (P, Q)))`

, but it cannot be `A`

, `(A, B)`

, `((X, A), (Y, Z))`

, or anything that contains `A`

. This is useful in implementing multi-argument functions. We can assert that the constant that represents the second formal argument does not apper in the structure that is passed as the first argument.

### Negation

It is also possible to assert that two expressions are not equal. If we want to assert that two identifiers `x`

and `y`

are not equal, we can write the following program:

[(x x) (y y) A] = ([x (y y) A] [x (y y) A])

Note that `A`

can be any constant, even a constant that appears in `x`

or `y`

. This exploits the definition of substitution. The second and the third substitution rule can be applied iff the first two parameters of the substitution are not equal. However, since we don't know whether `x`

and `y`

are constants or pairs, we encapsulate them into pairs and ensure that the result is not a constant (because a pair cannot be equal to a constant).

### Russell's Paradox

Program:

x = [A x B]

Suppose that `x = A`

, then we conclude that `[A x B] = [A A B] = B`

and therefore `x = B`

. Since `A != B`

, it is a contradiction. Therefore, `x != A`

. However, then `[A x B] = A`

and thus `x = A`

, a contradiction. The system is unsat.

### Disjunction

It is also possible to implement a disjunction. If we want to assert that identifier `x`

is either `A`

or `B`

, we can do the following:

x = [A y B]

where `y`

is a new identifier that is not used anywhere else in the program. If `y = A`

, then `x = B`

, otherwise `x = A`

.

### Generalised disjunction

If we have any two expressions and and we want to assert that `x`

is either or , then we can do the following:

(x x) = [( ) y ( )] [ y A] = [ y B]

where `y`

is a new identifier that is not used anywhere else in the program, and `A`

and `B`

are any two constants. We can also optionally assert that using negation.

### Single statement

Any program can be written using a single statement. If we have two statements

= =

we can reduce them to

( ) = ( )

## Computational class

Unknown.

## Interpreters

Unimplemented.