Legendre
Essa linguagem é apenas completa em Turing se, e somente se, a conjectura de Legendre for falsa, ou seja, existe um número inteiro n> 0, de modo que não haja números primos entre n ^ 2 e (n + 1) ^ 2. Essa linguagem se inspira no Underload, embora em alguns aspectos seja muito diferente dela.
Os programas no Legendre são compostos de séries de números inteiros positivos (0 é especialmente proibido, porque essencialmente nega todo o objetivo do idioma). Cada número inteiro corresponde a um comando base no Legendre, ou a um comando potencial definido pelo usuário. O comando ao qual está atribuído é baseado no número de primos entre seu quadrado e o próximo número inteiro (equivalente à sequência OEIS A014085 ).
Os comandos do idioma modificam uma pilha, que pode conter números inteiros positivos arbitrariamente grandes. Se a pilha contiver 0, o 0 será removido imediatamente. Em detalhes, os comandos são:
2 (menor número inteiro produzindo este comando: 1): Coloque o próximo número inteiro no programa na pilha.
3 (menor número inteiro de produção: 4): pop o número inteiro superior na pilha e execute o comando associado a ele.
4 (menor: 6): pop o número inteiro superior. Se fosse 1, aumente o número inteiro superior na pilha.
5 (10): Troque os dois principais itens da pilha.
6 (15): Decrementa o número inteiro superior na pilha. Se isso resultar em 0, coloque o 0 e descarte-o.
7 (16): duplique o número inteiro superior na pilha.
8 (25): Interrompa a execução e imprima o conteúdo da pilha.
Este é o conjunto de instruções básicas, que é incapaz de fazer qualquer coisa interessante, muito menos fazer um loop. No entanto, há outro comando, que pode ser acessado apenas se a conjectura de Legendre for falsa.
- 0 (desconhecido): remova todos os itens da pilha e combine-os em uma nova função, que executará todos os comandos começando na parte inferior original da pilha e terminando na parte superior, acessível como um comando cujo "número de comando" seja igual a aquele ao qual o próximo número inteiro na fonte do programa corresponde.
Se esse comando estiver acessível de alguma forma, o idioma se tornará completo em Turing, pois é possível simular uma máquina Minsky.
Quando o comando 8 é executado ou o final do programa é alcançado, o programa termina e o caractere (Unicode) correspondente a cada número inteiro na pilha é impresso.
Programas de exemplo
1 2 1 3 1 10 4
Este programa simples empurra o número 2, depois 3 e finalmente um 10, antes de executar um 4 (comando: 3), o que faz com que o 10 (comando: 5) seja exibido e executado, trocando os 2 e 3.
1 5 3 15 2 1 6 7
Este programa demonstra o uso da correspondência indireta de número inteiro para comando. Primeiro, um 5 é pressionado, depois um 15 e um 1, usando três maneiras diferentes de codificar o comando 2. Em seguida, o 1 é exibido e, como resultado, o 15 é incrementado para 16 e, finalmente, executado. O programa termina com duas instâncias do número 5 na pilha.
1 1 1 5 ? 24 1 15 1 31 ? 31 24 31
Este programa demonstra o uso do comando 0, usando? como um número de espaço reservado. O programa primeiro armazena '1 5' na função 9, depois '15 31 'em 10, antes de executar a função 9 (usando 24), que empurra 5 para a pilha e a diminui repetidamente, até atingir 0 e é removida . Então, o programa pára.
Minsky machine
Para converter uma máquina Minsky em código Legendre, o comando 0 deve ser usado. Como esse comando é inacessível, a menos que a conjectura de Legendre seja falsa, usei um espaço reservado? em vez de.
Observe que todos os nomes das linhas de instruções da máquina Minsky precisam ter números inteiros com diferentes correspondências A014085 entre si e com os comandos base, além de 24 (9) e 31 (10).
Inicialização:
1 1 1 1 ? 24
x INC (A / B) y:
UMA:
1 y 1 24 1 ? 1 6 1 1 16 1 24 ? x
B:
1 y 1 24 1 ? 1 10 1 6 1 1 16 1 10 1 24 ? x
x DEC (A / B) yz:
UMA:
1 4 1 10 1 15 1 10 1 31 1 1 1 10 1 z 1 1 1 16 1 24 1 31 1 ? 1 24 1 15 1 y 1 6 16 1 24 16 1 ? 1 1 16 1 10 1 1 16 1 24 ? x
B:
1 4 1 10 1 15 1 10 1 31 1 1 1 10 1 z 1 1 1 16 1 24 1 31 1 ? 1 24 1 15 1 10 1 y 1 6 16 1 24 16 1 ? 1 1 16 1 10 1 1 16 1 10 1 24 ? x
x HALT:
1 25 ? x
Para criar o programa final, anexe todas as partes (com x, y, z substituídos por seus pares) e adicione um único número inteiro para iniciar a primeira instrução na cadeia. Isso deve provar a completude de Turing da linguagem, caso a conjectura de Legendre seja falsa por contra-exemplo.
Intérprete
Este intérprete é escrito em Python (3) e foi testado nos três exemplos acima. Use os sinalizadores -a / - allowZero para permitir? para ser usado, -f / - file para executar o código diretamente de um arquivo e -s / - stackOut para gerar a pilha como uma lista Python. Se nenhum arquivo for fornecido, o intérprete entra em uma espécie de modo REPL, que é melhor usado com --stackOut.
import sys
import argparse
import io
class I_need_missing(dict): #used to avoid try/except statements. Essentially a dict
def __missing__(self,key):
return None
def appropriate(integer,prev): #returns number of primes between the square of the integer given and the next
return_value = 0
if prev[integer]:
return prev[integer],prev
if integer == "?":
return 0,prev
for i in range(integer ** 2, (integer + 1) ** 2):
t = False
if i > 1:
t = True
for j in range(2,int(i ** 0.5)+1):
t = i/j != round(i/j)
if not t:
break
return_value += t
prev[integer] = return_value
return return_value,prev
def run_command(commandseries,stack,functions,prev): #Runs the appropriate action for each command.
command,prev = appropriate(commandseries.pop(0),prev)
halt = False
if command == 0: #store in given number
functions[appropriate(commandseries.pop(0),prev)[0]] = stack
stack = []
elif command == 2:#push
stack.append(commandseries.pop(0))
elif command == 3:#execute top instruction
commandseries.insert(0,stack.pop())
elif command == 4:#pop, add 1 to new top if popped value was 1
if stack.pop() == 1:
stack[-1] += 1
elif command == 5:#swap top two integers/?
stack[-1],stack[-2] = stack[-2],stack[-1]
elif command == 6:#subtract 1 from top of stack
stack[-1] -= 1
if stack[-1] == 0:
stack.pop()
elif command == 7:#duplicate top of stack
stack.append(stack[-1])
elif command == 8:#halt
halt = True
else:#run custom
try:
commandseries[0:0] = functions[command]
except TypeError:
print("Warning: unassigned function " + str(command) + " is unassigned", file = sys.stderr)
return commandseries,stack,functions,prev,halt
def main(stack,functions,prev):
#Parser for command line options
parser = argparse.ArgumentParser(description = "Interpreter for the Legendre esoteric programming language.")
parser.add_argument("-a","--allowZero", action = "store_true")
parser.add_argument("-f","--file")
parser.add_argument("-s","--stackOut", action = "store_true")
args = parser.parse_args()
allow_zero = bool(args.allowZero)
#Program decoding starts
pre = ""
if not args.file:
pre = input()
if pre == "":
return
else:
pre = open(args.file).read()
mid = pre.split()
final = []
for i in mid:
if i == "?" and allow_zero:
final.append("?")
elif i != 0 or allow_zero: #and allow_zero)
final.append(int(i))
halt = False
#Functional programming at its best
while final and not halt:
final,stack,functions,prev,halt = run_command(final,stack,functions,prev)
#Halting and output
else:
if args.stackOut:
print(stack)
else:
for i in stack:
print(i == "?" and "?" or chr(i),end = "")
print("")
if args.file or halt:
return
else:
main(stack,functions,prev)
if __name__ == '__main__':
main([],I_need_missing(),I_need_missing())