ルジャンドル
この言語は、ルジャンドル予想が偽、つまりn ^ 2と(n + 1)^ 2の間に素数がないような整数n> 0が存在する場合にのみチューリング完全です。この言語はUnderloadからいくつかのインスピレーションを受けていますが、いくつかの点で非常に異なっています。
Legendreのプログラムは、一連の正の整数で構成されています(0は、言語の目的全体を本質的に否定するため、特に禁止されています)。各整数は、ルジャンドルの基本コマンド、または潜在的なユーザー定義のコマンドに対応しています。どのコマンドに割り当てられるかは、その平方と次の整数(OEISシーケンスA014085に相当)の間の素数の数に基づきます。
言語のコマンドは、任意の大きな正の整数を保持できるスタックを変更します。スタックが0を保持する場合、0はすぐに削除されます。コマンドの詳細は次のとおりです。
2(このコマンドを生成する最小の整数:1):プログラム内の次の整数をスタックにプッシュします。
3(最小の生成整数:4):スタックの一番上の整数をポップし、それに関連するコマンドを実行します。
4(最小:6):上の整数をポップします。1だった場合、スタックの一番上の整数を増やします。
5(10):上の2つのスタックアイテムを交換します。
6(15):スタックの一番上の整数をデクリメントします。結果が0の場合、0をポップして破棄します。
7(16):スタックの一番上の整数を複製します。
8(25):実行を停止し、スタックの内容を出力します。
これは基本的な命令セットであり、ループはもちろんのこと、面白いことは何もできません。ただし、別のコマンドがあり、ルジャンドルの推測が誤りであることが証明された場合にのみアクセスできます。
- 0(不明):スタックからすべての項目を削除し、それらを新しい関数に結合します。この関数は、スタックの元の一番下から始まり、「コマンド番号」が等しいコマンドとしてアクセス可能な一番上で終わるすべてのコマンドを実行しますプログラムソースの次の整数に対応するもの。
このコマンドに何らかの方法でアクセスできる場合、言語はチューリング完全になります。これは、Minskyマシンをシミュレートできるためです。
コマンド8が実行されるか、プログラムの最後に到達すると、プログラムは終了し、スタック上の各整数に対応する(Unicode)文字が出力されます。
サンプルプログラム
1 2 1 3 1 10 4
この単純なプログラムは、2(3)、最後に10をプッシュしてから4(コマンド:3)を実行し、10(コマンド:5)をポップして実行し、2と3を入れ替えます。
1 5 3 15 2 1 6 7
このプログラムは、整数からコマンドへの間接的な対応の使用方法を示しています。最初に5がプッシュされ、次に2つのコマンドをエンコードする3つの異なる方法を使用して15と1がプッシュされます。次に、1がポップされ、その結果、15が16にインクリメントされ、最終的に実行されます。プログラムは、スタック上の番号5の2つのインスタンスで終了します。
1 1 1 5 ? 24 1 15 1 31 ? 31 24 31
このプログラムは、?を使用して0コマンドを使用する方法を示しています。プレースホルダー番号として。プログラムは、最初に関数9に「1 5」を格納し、次に10に「15 31」を格納してから、関数9(24を使用)を実行します。 。その後、プログラムは停止します。
ミンスキー機
MinskyマシンをLegendreコードに変換するには、0コマンドを使用する必要があります。Legendreの推測が偽でない限り、このコマンドにはアクセスできないため、プレースホルダーを使用しましたか?代わりに。
すべてのMinskyマシンの命令行名には、相互に異なるA014085対応の整数と、ベースコマンド、および24(9)と31(10)が必要であることに注意してください。
初期化:
1 1 1 1 ? 24
x INC(A / B)y:
A:
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:
A:
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
最終プログラムを作成するには、すべての部分を追加し(x、y、zを対応する部分で置き換え)、単一の整数を追加して、チェーンの最初の命令を開始します。これは、ルジャンドルの推測が反例によって間違っていることが証明された場合の言語のチューリング完全性を証明するはずです。
通訳
このインタープリターはPython(3)で記述されており、上記の3つの例すべてでテストされています。-a /-allowZeroフラグを使用して、?使用するには、ファイルから直接コードを実行する-f /-fileと、代わりにPythonリストとしてスタックを出力する-s /-stackOutを使用します。ファイルが指定されていない場合、インタープリターは一種のREPLモードに入ります。これは--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())