Thiết kế một máy tính hướng dẫn!


31

Lưu ý: Tôi sẵn sàng đưa tiền thưởng cho bất kỳ câu trả lời nào mà tôi thấy thú vị.

Thách thức của bạn là thiết kế một máy tính tập lệnh Turing- Complete (OISC):

OISC là một máy trừu tượng chỉ sử dụng một hướng dẫn - không cần phải sử dụng opcode ngôn ngữ máy. Với sự lựa chọn sáng suốt cho một hướng dẫn duy nhất và được cung cấp nguồn lực vô hạn, OISC có khả năng trở thành một máy tính phổ quát giống như các máy tính truyền thống có nhiều hướng dẫn.

Dưới đây là một số ví dụ về các lệnh đơn tạo ra một OISC hoàn chỉnh.

Quy tắc:

Bạn phải cung cấp một giải thích hoặc bằng chứng về nó

Bạn phải cung cấp một thông dịch viên cho ngôn ngữ của bạn. Trình thông dịch này chỉ nên bị hạn chế bởi bộ nhớ / thời gian (ví dụ: không có hạn chế do người dùng áp dụng). Nếu bạn không cung cấp một thông dịch viên cho ngôn ngữ của bạn (vì bất kỳ lý do nào khác ngoài sự lười biếng), bạn phải chứng minh rằng có thể viết một ngôn ngữ. Một thông dịch viên phải có thể .

Bạn phải chứng minh tính đầy đủ của nó

Bạn phải bao gồm một bằng chứng chính thức rằng ngôn ngữ của bạn là Turing-Complete. Một cách đơn giản để làm điều này là bằng cách chứng minh rằng nó có thể diễn giải hoặc có hành vi tương tự như một ngôn ngữ hoàn chỉnh Turing khác. Ngôn ngữ cơ bản nhất để giải thích sẽ là Brainf ** k .

Ví dụ: một ngôn ngữ bình thường có tất cả các lệnh giống như Brainf ** k (và thiếu cùng giới hạn bộ nhớ do người dùng áp dụng) là Turing-perfect vì mọi thứ có thể được thực hiện trong Brainf ** k đều có thể được thực hiện bằng ngôn ngữ .

Dưới đây là danh sách các ngôn ngữ Turing-hoàn thành rất đơn giản để thực hiện.

Yêu cầu bổ sung của OISC

  • OISC này chỉ nên có một hướng dẫn - nó không thể có nhiều hướng dẫn với một trong số chúng làm cho nó trở nên hoàn chỉnh.

  • OISC của bạn có thể sử dụng bất kỳ cú pháp nào bạn muốn. Bạn nên xác định trong câu trả lời của mình hướng dẫn là gì, dữ liệu là gì và không có gì (ví dụ: khoảng trắng). Sáng tạo!

  • Đối số không chỉ cần là số nguyên. Ví dụ: /// là một ví dụ đẹp về OISC hoàn chỉnh.

  • Làm thế nào và nếu đầu vào và đầu ra được thực hiện và đưa ra là tùy thuộc vào bạn. Hầu hết các OISC triển khai I / O thông qua các vị trí bộ nhớ cụ thể, nhưng có thể có những cách khác để làm như vậy và bạn được khuyến khích tìm một.

  • Câu trả lời hợp lệ phải cung cấp một số mã ví dụ trong OISC của bạn, bằng cách đưa nó vào bài đăng hoặc liên kết đến một thử thách đơn giản được giải quyết bằng ngôn ngữ.

Bỏ phiếu

Cử tri, xin nhớ đừng upvote đệ trình nhàm chán. Ví dụ:

  • Độ dài tương đương
  • Việc triển khai OISC hiện tại (người trả lời, vui lòng tạo riêng của bạn!)
  • Một "OISC" trong đó đối số đầu tiên chỉ định một lệnh để gọi ( ví dụ )

Tuy nhiên, bạn nên nâng cấp các bài nộp thú vị, sáng tạo, chẳng hạn như:

  • Một OISC dựa trên phương trình toán học
  • Một ZISC hoàn chỉnh dựa trên mạng thần kinh
  • Một OISC trong đó I / O đầu ra xảy ra theo những cách khác ngoài các vị trí bộ nhớ nhất định

Chiến thắng

Như với , câu trả lời có nhiều phiếu nhất sẽ chiến thắng! Chúc may mắn!


10
"Hướng dẫn" là gì? Và làm thế nào để chúng ta đếm chúng?
Thuật sĩ lúa mì

1
@NoOneIs Tôi muốn tôi biết đủ chỉ để bầu chọn xD
Brian H.

2
Tôi đánh giá thấp điều này. Tôi nghĩ rằng đây là một ý tưởng rất thú vị, nhưng bạn không giải thích chính xác OISC là gì và làm thế nào để xác nhận một cái gì đó là một. Tôi đã biến BF thành một OISC, nhưng điều đó rõ ràng trái với tinh thần của câu hỏi, nhưng về mặt kỹ thuật có giá trị.
NoOneIsĐây là

1
@MDXF Tôi không nghĩ bạn nhận được ///: nó có lệnh thay thế và nó có các lệnh in, đây không chỉ là tác dụng phụ của lệnh thay thế
Lemon

1
@NoOneIsHere Vì cuộc thi nổi tiếng . Vâng, nó hợp lệ, nhưng nó có điểm kém (kiểm phiếu), vì vậy nó sẽ không thắng.
dùng202729

Câu trả lời:


20

XOISC

OISC này dựa trên bộ kết hợp X của Fokker , được định nghĩa như sau:

X=λf .f (λg h x .g x (h x)) (λa b c .a)

Nếu chúng tôi thừa nhận thực tế rằng tính toán SKI là Turing hoàn thành thì -combinator ở trên cũng hoàn thành Turing. Điều này là do S , Ktôi có thể được viết theo X , như thế này:XSKIX

S=X (X X)K=X XI=S K K=X (X X) (X X) (X X)

XOISC hoạt động như thế nào

Bên trong XOISC có một ngăn xếp (ban đầu trống), từ đó hướng dẫn lấy làm đối số thực hiện như sau:n

  • Pop yếu tố (chức năng f 1 ... f N ) từ ngăn xếp, push e 1 ( f 2 ( ... ( f N X ) ... ) )nf1fNf1 (f2 ((fN X)))

Khi không còn hướng dẫn nào nữa, XOISC sẽ đẩy tất cả các đối số dòng lệnh (nếu có) vào ngăn xếp, ví dụ:

[s1,, sMstack before, a1,, aNarguments]

Các tính toán cuối cùng sẽ được .((((s1 s2)) sM) a1))aN


Vì một lệnh trong XOISC chỉ mất một đối số (bù bộ nhớ), không có lý do gì để sử dụng tên cho lệnh đó. Vì vậy, một tệp nguồn hợp lệ sẽ chỉ tạo thành các số nguyên được phân tách bằng dòng mới hoặc khoảng trắng, ví dụ như:

0 0 2 0 1 0 1

Hãy thử trực tuyến!

Thí dụ

Hãy lấy ví dụ trên (ngăn xếp tăng dần sang phải):

0bật 0 và áp dụng (ví dụ: đẩy đơn X):[X]0một lần nữa chỉ cần đẩy X:[X, X]2pop 2 (một,b) và đẩy một (b X):[X (X X)]0chỉ cần đẩy X:[X (X X), X]1pop 1 (một) và đẩy một X:[X (X X), X X]0chỉ cần đẩy X:[X (X X), X X, X]1pop 1 (một) và đẩy một X:[X (X X), X X, X X]

((X (X X)) (X X)) (X X)X (X X) (X X) (X X)S K K

Turing hoàn chỉnh

Ý tưởng bằng chứng

X

X

((X (X X)) (X X)) (X X)

  • X0
  • tiếp theo chúng tôi ở một cấp độ mới của dấu ngoặc đơn, vì vậy chúng tôi lại chỉ cần một 0
  • Bây giờ hai dấu ngoặc đơn đóng, vì vậy chúng ta cần bật 2 phần tử: 2
  • một lần nữa chúng ta ở một cấp độ mới của dấu ngoặc đơn, vì vậy chúng ta cần một 0
  • hai dấu ngoặc đơn, đóng lại một lần nữa 2
  • và một lần nữa

Vì vậy, chúng tôi kết thúc với một chương trình XOISC khác (nhưng tương đương về mặt ngữ nghĩa):

0 0 2 0 2 0 2 Hãy thử trực tuyến!

X

Bằng chứng chính thức

Cho rằng tính toán SKI đã hoàn thành Turing, chúng ta cần chỉ ra hai điều:

  1. X
  2. X

Phần đầu tiên - chứng minh ba điểm tương đương trong phần giới thiệu - rất tẻ nhạt và tốn không gian, nó cũng không thú vị lắm. Vì vậy, thay vì đặt nó trong bài viết này, bạn có thể tìm thấy ở đây * .

X -combinators, có một chương trình sẽ để lại biểu thức đó dưới dạng một biểu thức trên ngăn xếp:

XXf gfg

0XF1Giáo dụcFNG1Giáo dụcGKfgf g cũng như:

F1Giáo dụcFN G1Giáo dụcGK-1 (GK+1)fggff g

Thông dịch viên

Đầu vào

Vì phép tính lambda chưa được yêu cầu yêu cầu chúng ta xác định các kiểu dữ liệu của riêng mình cho mọi thứ chúng ta muốn và điều này rất khó hiểu, người phiên dịch nhận thức được các chữ số của Giáo hội - điều này có nghĩa là khi bạn cung cấp đầu vào, nó sẽ tự động chuyển đổi các số thành chữ số Church tương ứng.

Ví dụ ở đây là một chương trình nhân hai số: Hãy thử trực tuyến!

Bạn cũng có thể cung cấp các hàm làm đối số bằng cách sử dụng các chỉ mục De Bruijn , ví dụ: bộ Skết hợp \\\(3 1 (2 1))(hoặc λλλ(3 1 (2 1))). Tuy nhiên nó cũng thừa nhận S, K, Ivà tất nhiênX combinator.

Đầu ra

Theo mặc định, trình thông dịch sẽ kiểm tra xem đầu ra có mã hóa một số nguyên hay không, nếu có, nó sẽ xuất ra số tương ứng (ngoài kết quả). Để thuận tiện, có-b cờ thông báo cho trình thông dịch thử kết hợp một boolean thay thế (xem ví dụ cuối cùng).

Nhà lắp ráp

Tất nhiên, bất kỳ ngôn ngữ cấp thấp nào cũng cần một trình biên dịch chuyển đổi ngôn ngữ cấp cao sang ngôn ngữ đó, bạn chỉ cần sử dụng bất kỳ đầu vào nào (xem ở trên) và dịch nó sang chương trình XOISC bằng cách sử dụng -acờ, thử trực tuyến! **


* Trong trường hợp liên kết không hoạt động, có một bản sao dưới dạng nhận xét HTML trong bài đăng này.

** Điều này dẫn đến một chương trình kiểm tra tính nguyên thủy, hãy thử trực tuyến!


1
Có lý do gì bạn chọn bộ kết hợp X thay vì bộ kết hợp Iota không?
Trái cây Esolanging

1
@EsolangingFnut: Vâng, có một số tùy chọn khác, cuối cùng tôi đã chọn cái đó vì nó sử dụng ít ứng dụng nhất để xây dựng SK. Có vẻ như nó sẽ hoạt động tốt nhất (tbh tôi đã không tự mình so sánh).
ბიმო

1
Btw. có một so sánh tốt đẹp của một số tổ hợp trong bài báo được liên kết nếu bạn quan tâm.
ბიმო

19

Vẽ tranh

Draw là một OISC hoạt động trên lưới 2D, đánh dấu các ô vuông theo cách tương tự như máy B của Wang. Tuy nhiên, để giữ cho ngôn ngữ đơn giản và OISC-y nhất có thể, tất cả các hướng dẫn (trong đó có tổng cộng một) đánh dấu hình vuông vừa bước, và để có thể dừng lại, bước lên một hình vuông được đánh dấu chấm dứt chương trình.

Chương trình bao gồm một chuỗi các dòng chứa mã định danh dòng (chuỗi tùy ý không bao gồm # hoặc khoảng trắng), hai số nguyên ( xy) và hai số nhận dạng dòng khác ( ab).

Các chương trình chạy như sau:
Bắt đầu từ dòng xác định là startvới con trỏ trỏ đến vị trí (0, 0), di chuyển con trỏ bởi số lượng do xyvà đánh dấu vuông con trỏ tại là trên (trừ hình vuông đã được đánh dấu, trong trường hợp thực hiện chấm dứt). Sau đó, nhảy đến dòng anếu ít nhất một trong các hình vuông liền kề trực tiếp cũng được đánh dấu và để dòng bkhác.

Thông dịch viên được khuyến khích xuất kết quả cuối cùng của lưới dưới dạng một số hình ảnh, khung vẽ, v.v.

Turing-Hoàn thành

Draw là Turing-Complete vì có thể biên dịch một phiên bản sửa đổi (được gọi là Alternate) của máy Minsky thành ngôn ngữ.

Luân phiên hoạt động tương tự như máy Minsky hai bộ đếm, nhưng có một hạn chế lớn được đặt trên các lệnh: các lệnh phải xen kẽ giữa nhắm mục tiêu vào bộ đếm thứ nhất và bộ đếm thứ hai. Để khắc phục điều chỉnh này, một lệnh bổ sung đã được thêm vào:nop . Lệnh này hoàn toàn không thay đổi bộ đếm được nhắm mục tiêu, điều này giúp có thể "đệm" các thay đổi liên tiếp vào một bộ đếm, đáp ứng các hạn chế được nêu ở trên. Điều này cũng có nghĩa là thanh ghi cần sửa đổi không cần phải được cung cấp và, đối với bất kỳ lệnh nào, có thể được suy ra trực tiếp từ các hướng dẫn mà từ đó thực thi có thể chuyển sang nó.

Ví dụ: máy Minsky này

1 inc A 2
2 inc A 3
3 dec A 3 4
4 halt

biến thành chương trình thay thế này:

1 inc 2
2 nop 3
3 inc 4
4 nop 5
5 dec 6 8
6 nop 5
7 halt
8 halt

Hạn chế này là cần thiết do cách chương trình Draw cuối cùng xử lý các thanh ghi, nghĩa là nó hoàn toàn không phân biệt giữa chúng. Thay vào đó, chương trình Draw chỉ đơn giản là sao chép thanh ghi chưa được thay đổi bởi lệnh trước đó, sửa đổi nó theo lệnh được thực thi.

Sau đó, chương trình Thay thế được dịch trực tiếp thành Draw như sau:

Chương trình bắt đầu với khối này.

start 0 0 a a
a 3 0 b b
b -3 1 c c
c 3 0 d d
d -3 2 e e
e 3 0 f f
f 3 -3 i1_a i1_a

inc, decnopđược dịch ở hầu hết cùng một cách như nhau. Trong mọi trường hợp, không có sự khác biệt giữa việc thay đổi thanh ghi thứ nhất hoặc thứ hai (như đã giải thích ở trên). Đây là một mức tăng, tương đương với inc 2:

i1_y 0 -2 i1_z i1_y
i1_z 3 -1 i1_a i1_a
i1_a -5 1 i1_b i1_b
i1_b 0 2 i1_c i1_c
i1_c 0 2 i1_d i1_e
i1_d 0 2 i1_d i1_f

i1_e 5 0 i2_z i2_y
i1_f 5 0 i2_z i2_y

Thay đổi các số trong các i1_xphần thành chỉ mục của lệnh hiện tại và trong các i2_xphần thành chỉ mục của lệnh tiếp theo sẽ được thực hiện.

Các nophướng dẫn có thể được dịch như vậy:

i1_y 0 -2 i1_z i1_y
i1_z 3 -1 i1_a i1_a
i1_a -5 1 i1_b i1_b
i1_b 0 2 i1_c i1_c
i1_c 0 2 i1_d i1_e
i1_d 0 2 i1_d i1_f

i1_e 5 -2 i2_z i2_y
i1_f 5 -2 i2_z i2_y

Đây là một giảm:

i1_y 0 -2 i1_z i1_y
i1_z 3 -1 i1_a i1_a
i1_a -5 1 i1_b i1_b
i1_b 0 2 i1_c i1_c
i1_c 0 2 i1_d i1_e
i1_d 0 2 i1_d i1_f

i1_e 5 -2 i3_z i3_y
i1_f 5 -4 i2_z i2_y

i3_x đề cập đến lệnh được gọi nếu bộ đếm đã là 1.

Tạm dừng lại:

i1_y 0 0 0 0
i1_z 0 0 0 0

Thay đổi nhãn phù hợp và đơn giản là xâu chuỗi mọi thứ lại với nhau. Làm điều này cho ví dụ từ phía trên sẽ cho chương trình Draw trong kho lưu trữ từ phía trên.

Phiên dịch viên

Hiện tại có hai thông dịch viên, cả hai đều được viết bằng Python. Chúng có thể được tìm thấy trên kho GitHub của Draw .

  1. draw.py : Trình thông dịch này có nghĩa là cho dòng lệnh và lấy nguồn chương trình làm đối số. Sau mỗi bước, nó xuất ra lệnh đã được thực thi và vị trí của con trỏ lệnh; sau khi chương trình tạm dừng, nó sẽ in số lượng ô được đánh dấu.
  2. draw_golly.py : Phiên bản này sử dụng Golly cho mục đích chính xác là đầu ra đồ họa dễ dàng hơn, lấy nguồn qua hộp bật lên khi bắt đầu tập lệnh. Golly có thể hơi khó tính với Python, vì vậy hãy đảm bảo bạn đã cài đặt Python 2 (và không trộn Golly 32 bit với Python 64 bit hoặc ngược lại). Đầu ra được cung cấp thông qua lưới tế bào dựng sẵn của Golly.

Hình ảnh sau đây là một ví dụ cho đầu ra từ trình thông dịch thứ hai. Chạy chương trình ví dụ trong kho lưu trữ sẽ cho điều này (hoặc tương tự):


1
Kinh ngạc! Chúc mừng bạn đã tìm được một cách rất độc đáo để thực hiện thử thách.
MD XF

Ngôn ngữ của bạn không cần phải dừng lại để hoàn thành. Quy tắc 110 không chấm dứt, tuy nhiên nó vẫn hoàn thành.
Akangka

+1 cho Golly Trình mô phỏng tự động di động tốt nhất từng có.
HighRiereactive

14

-3

Đây là ý chính.

Ký ức

Bộ nhớ là bản đồ của các băng, trong đó các khóa là các chuỗi và các giá trị là các số nguyên có kích thước tùy ý.

Ngoài ra, có một bộ nhãn, nơi chương trình có thể nhảy tới.

Có một ngăn xếp, chứa các toán hạng, là các chuỗi.

Có một điểm trừ, điều khiển nơi băng trong bộ nhớ mà nó có thể truy cập.

Một chỉ dẫn

-. Đầu tiên, nó bật một chuỗi LABELra khỏi ngăn xếp. Nếu đó LABELkhông được xác định là nhãn, nó sẽ xác định nhãn và xóa nguồn của nhãn đó (tức là nơi nó được đẩy từ đó) và hướng dẫn hiện tại. Mặt khác, nó thực hiện phép tính sau, sử dụng hai giá trị trên cùng AB:

if mem[A] < mem[B]:
    jump to LABEL
if mem[A] != mem[B]:
    mem[A]--
else:
    mem[B]++

Lưu ý rằng nếu có các đối số thừa hoặc không đủ đối số, chương trình sẽ báo lỗi, hiển thị trạng thái của chương trình.

Phần bù có thể được sửa đổi bằng cách truy cập giá trị của ..

Mã ví dụ

X-

i i X-
i i X-
i i X-
i i X-
i i X-
i i X-
i i X-

Điều này đặt biến ithành 7, bằng cách tăng 7thời gian.

X-

i i X-
i i X-
i i X-
LOOP-
    a a X-
    a a X-
    j i LOOP-

Điều này nhân i+1với hằng số 2.

Bằng chứng về sự hoàn thiện của Turing

Bỏ qua kích thước int của C ++ (nghĩa là giả sử chúng là vô hạn), -3 là Turing Complete bằng cách giảm xuống mức cân bằng 3 tế bào . Tôi có thể bỏ qua kích thước này vì có thể viết trình thông dịch cho -3 trên máy tính có bộ nhớ vô hạn có các ô lớn tùy ý.

Tôi cũng tin rằng bất kỳ BCT nào cũng có thể được viết dưới dạng chương trình -3.


Vì tôi muốn cải thiện nội dung của mình, xin vui lòng, một lời giải thích liên quan đến việc bỏ phiếu sẽ được đánh giá cao
Conor O'Brien
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.