Para que uma linguagem imperativa seja Turing completa, ela deve ter:
- Loop condicional
- Número arbitrário de variáveis
FRACTRAN é uma linguagem composta de uma série de frações que armazena seus dados nos expoentes dos números primos.
Digamos que você queira adicionar dois números: 2 a 3 b torna-se 5 ab
455 11 1 3 11 1
---, -, -, -, -, -
33 13 11 7 2 3
Esse é um programa FRACTRAN para fazer isso acima da mudança.
Você começa com um número como 72 (2 3 3 2 ). O programa avança até encontrar um número que, quando multiplicado pela instrução, é outro número inteiro (nenhum resto é permitido).
72
seguirá em frente até chegar 11/2
. Em seguida, dividirá o número por 2
e multiplicará por 11
(o poder em 11 é uma variável). Isso dá 396
. 396
é divisível por 33 (reduzindo a potência 3 e a 11) e multiplicado por 455 (incrementando as variáveis 5, 7 e 13). E assim por diante. A descrição completa deste programa e sua tabela de estados podem ser lidas na página da FRACTRAN , incluindo um gif animado muito bom do programa acima.
Outros materiais FRACTRAN no Stack Exchange que abordam a integridade de Turing podem ser encontrados em: Converter Fractran em Brainfuck (ok, esse é um uso realmente produtivo do tempo)
O motivo pelo qual o Fractran é Turing-complete é porque simula uma máquina de registro. A fatoração primária do número armazena o conteúdo dos registros, enquanto a divisão e multiplicação é uma maneira de adicionar e subtrair condicionalmente os registros.
Parte do truque aqui (e isso começa desviando em teoria) é que por trás das cenas, esta é uma máquina de registo Minsky para o qual foi provado que certas fitas (programas) são Turing máquinas IF a fita é representado como um número de Gödel que é exatamente qual é o número FRACTRAN (na página da wikipedia vinculada):
Gödel usou um sistema baseado em fatoração primária. Ele primeiro atribuiu um número natural único a cada símbolo básico na linguagem formal da aritmética com a qual estava lidando.
Então, temos loops condicionais, variáveis arbitrárias armazenadas como números de Gödel, temos uma máquina de Turing.
Alguma outra leitura divertida que toca a natureza Collatz, como a natureza do FRACTRAN, pode ser lida em Can't Decide? Indeciso! que relacionam a conjectura de Collatz ao FRACTRAN e o problema da parada.
FRACTRAN é um pouco difícil de entender.
Considere o programa algo como:
LABEL: start
block1
block2
block3
...
END
Neste, cada bloco tem o formato:
IF(registers X >= a, Y >= b) # or any combination of registers
THEN
X -= a
Y -= b
I += n
J += m
goto start
A primeira instrução do programa de multiplicação acima:
455
---
33
Seria escrito desta forma como:
IF(register `3` >= 1 && `11` >= 1)
THEN
`3` -= 1
`11` -= 1
`5` += 1
`7` += 1
`13` += 1
goto start
E assim você pode ver claramente o armazenamento de dados e as construções de loop necessárias para a integridade de Turing. É muito rudimentar, mas existe e funciona como uma simples máquina de registro - mas é tudo o que você realmente precisa para fazer.
Ainda não está convencido?
Isso se baseia amplamente em uma palestra de Dimitri Hendricks sobre Modelos de Computação
Isso requer o programa muito simples (2/3)
que é um somador (2 a 3 b -> 3 a + b ). Mas é destrutivo - o valor em 2 é limpo como parte do processo.
Vamos escrever um FRACTRAN de nível superior que facilita a não destruição.
O programa original pode ser considerado como:
2
α: - → α
3
Em F 2 , pode-se especificar 'funções' de um tipo.
10 1
α: - → α, - → β
3 1
3
β: - → β
5
Para converter um programa F 2 (P) em um programa FRACTRAN padrão, é necessário:
- P claro de loops de comprimento 1
- Substitua letras gregas (funções) por novos números primos
- Substitua as transições:
ás
p: - → q, - → r, - -> s, ...
bdf
torna-se:
aq cr es
-, -, -, ...
bp dp fp
O que isso fez é usar os primos p, q, re es para armazenar o estado do programa.
E então temos a máquina de registro ... ela tem um número finito de registros que armazenam números grandes arbitrários e duas instruções:
- inc (x i , m) - incremente o registro ie vá para a linha m
- jzdec (x i , m 1 , m 2 ) - se o registro i for 0, vá para a linha m, então diminua i e vá para a linha m2.
Esta máquina registradora foi mostrada como Turing completa.
Em seguida, ele mostra o processo em vários slides da compilação de um programa de máquina de registro em um programa FRACTRAN como parte de um processo mecânico.
Basicamente:
p (i)
inc (x (i), m) = ---- → m
1 1
1 1
jzdec (x (i), m1, m2) = ---- → m2, - → m1
p (i) 1
E, portanto, devido à equivalência entre esses dois modelos de computação, o FRACTRAN é Turing completo.
Btw, se você realmente quer ter uma ideia, leia Code Golf: Fractran, no qual algumas pessoas escreveram um programa FRACTRAN para executar outro programa FRACTRAN.