Huyền thoại
Ngôn ngữ này chỉ hoàn thành Turing khi và chỉ khi phỏng đoán của Legendre là sai, tức là tồn tại số nguyên n> 0 sao cho không có số nguyên tố nào giữa n ^ 2 và (n + 1) ^ 2. Ngôn ngữ này lấy một số cảm hứng từ Underload, mặc dù trong một số khía cạnh, nó rất khác với nó.
Các chương trình trong Legendre được tạo thành từ một loạt các số nguyên dương (0 đặc biệt bị cấm, vì về cơ bản nó phủ nhận toàn bộ mục đích của ngôn ngữ). Mỗi số nguyên tương ứng với một lệnh cơ sở trong Legendre hoặc tiềm năng do người dùng xác định. Lệnh nào được gán dựa trên số lượng số nguyên tố giữa bình phương của nó và số nguyên tiếp theo (tương đương với chuỗi OEIS A014085 ).
Các lệnh của ngôn ngữ sửa đổi một ngăn xếp, có thể chứa các số nguyên dương lớn tùy ý. Nếu ngăn xếp giữ 0, 0 sẽ bị xóa ngay lập tức. Cụ thể, các lệnh là:
2 (số nguyên nhỏ nhất tạo lệnh này: 1): Đẩy số nguyên tiếp theo trong chương trình lên ngăn xếp.
3 (số nguyên sản xuất nhỏ nhất: 4): Bật số nguyên trên cùng trên ngăn xếp và thực hiện lệnh được liên kết với nó.
4 (nhỏ nhất: 6): Pop số nguyên trên cùng. Nếu là 1, hãy tăng số nguyên trên cùng của ngăn xếp.
5 (10): Hoán đổi hai mục trên cùng.
6 (15): Giảm số nguyên trên cùng của ngăn xếp. Nếu kết quả là 0, hãy bật 0 và loại bỏ nó.
7 (16): Sao y số nguyên trên cùng của ngăn xếp.
8 (25): Dừng thực thi và in nội dung ngăn xếp.
Đây là tập lệnh cơ bản, không thể làm bất cứ điều gì thú vị, hãy để một mình vòng lặp. Tuy nhiên, có một lệnh khác, chỉ có thể được truy cập nếu phỏng đoán của Legendre chứng minh là sai.
- 0 (không xác định): Xóa tất cả các mục khỏi ngăn xếp và kết hợp chúng vào một hàm mới, nó sẽ thực thi tất cả các lệnh bắt đầu ở dưới cùng của ngăn xếp và kết thúc ở trên cùng, có thể truy cập dưới dạng một lệnh có "số lệnh" bằng một số nguyên tiếp theo trong nguồn chương trình tương ứng với.
Nếu lệnh này bằng cách nào đó có thể truy cập được, ngôn ngữ sẽ trở thành Turing-Complete, vì người ta có thể mô phỏng một máy Minsky trong đó.
Khi lệnh 8 được thực thi hoặc kết thúc chương trình, chương trình kết thúc và ký tự (Unicode) tương ứng với mỗi số nguyên trên ngăn xếp được in.
Chương trình ví dụ
1 2 1 3 1 10 4
Chương trình đơn giản này đẩy số 2, rồi 3 và cuối cùng là 10, trước khi thực hiện lệnh 4 (lệnh: 3), khiến cho số 10 (lệnh: 5) được bật và thực thi, hoán đổi 2 và 3.
1 5 3 15 2 1 6 7
Chương trình này cho thấy việc sử dụng tương ứng số nguyên-lệnh gián tiếp. Đầu tiên, 5 được đẩy, sau đó là 15 và 1, sử dụng ba cách mã hóa khác nhau cho lệnh 2. Sau đó, 1 được bật lên và kết quả là 15 được tăng lên 16 và cuối cùng được thực thi. Chương trình kết thúc với hai trường hợp của số 5 trên ngăn xếp.
1 1 1 5 ? 24 1 15 1 31 ? 31 24 31
Chương trình này cho thấy việc sử dụng lệnh 0, sử dụng? như một số giữ chỗ. Chương trình trước tiên lưu trữ '1 5' trong chức năng 9, sau đó '15 31 'trong 10, trước khi chạy chức năng 9 (sử dụng 24), đẩy 5 lên ngăn xếp và liên tục giảm xuống, cho đến khi nó về 0 và bị xóa . Sau đó, chương trình tạm dừng.
Máy Minsky
Để chuyển đổi máy Minsky thành mã Legendre, phải sử dụng lệnh 0 . Bởi vì lệnh này không thể truy cập được trừ khi phỏng đoán của Legendre là sai, tôi đã sử dụng trình giữ chỗ? thay thế.
Lưu ý rằng tất cả các tên dòng lệnh của máy Minsky cần phải có các số nguyên với các tương ứng A014085 khác nhau và các lệnh cơ sở cũng như 24 (9) và 31 (10).
Khởi tạo:
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 tháng 12 (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 NÓI:
1 25 ? x
Để tạo chương trình cuối cùng, nối thêm tất cả các phần (với x, y, z được thay thế bằng các đối tác của chúng) và thêm một số nguyên duy nhất để bắt đầu lệnh đầu tiên trong chuỗi. Điều này sẽ chứng minh tính hoàn chỉnh của ngôn ngữ trong trường hợp phỏng đoán của Legendre được chứng minh là sai bằng ví dụ mẫu.
Thông dịch viên
Trình thông dịch này được viết bằng Python (3) và đã được thử nghiệm trên cả ba ví dụ trên. Sử dụng cờ -a / - allowZero để cho phép? được sử dụng, tập tin -f / - để chạy mã trực tiếp từ tệp và -s / - stackOut để xuất ngăn xếp dưới dạng danh sách Python thay thế. Nếu không có tệp nào được đưa ra, trình thông dịch sẽ nhập vào một loại chế độ REPL, được sử dụng tốt nhất với --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())