Có tiêu chí tối thiểu cho một ngôn ngữ lập trình được Turing hoàn thành không?


55

Có tồn tại một tập hợp các cấu trúc ngôn ngữ lập trình trong một ngôn ngữ lập trình để nó được coi là Turing Complete không?

Từ những gì tôi có thể nói từ wikipedia , ngôn ngữ cần hỗ trợ đệ quy, hoặc, dường như, phải có khả năng chạy mà không cần dừng lại. Đây có phải là tất cả không?


6
Có lẽ câu hỏi của bạn nên hỏi "Có một tập hợp các cấu trúc lập trình tối thiểu không ...?", Bởi vì nó được đặt câu trả lời là "Tất cả các cấu trúc tính toán."
Dave Clarke


@DaveClarke, cảm ơn, tôi đã cập nhật điều đó. Tôi thấy rằng nhận xét của bạn đặt ra câu hỏi phần nào, mặc dù tôi cho rằng đó là vì ngôn ngữ của tôi kém. Tôi muốn hỏi liệu có hay không một vài thao tác mà nếu một ngôn ngữ có thể tính toán, thì nó sẽ tương đương.
Khanzor

Câu trả lời:


45

Tôi luôn mặc dù rằng chức năng -recursiveμ đóng đinh nó. Đây là những gì định nghĩa toàn bộ các hàm tính toán; nó là tập hợp nhỏ nhất của hàm chứa resp. đóng cửa chống lại:

  1. Hằng số chức năng0
  2. Chức năng kế nhiệm
  3. Chọn tham số
  4. Thành phần chức năng
  5. Đệ quy nguyên thủy
  6. Các -operator (tìm kiếm nhỏ nhất x như vậy mà ...)μx

Kiểm tra liên kết ở trên để biết chi tiết; bạn thấy rằng nó làm cho một ngôn ngữ lập trình rất nhỏ gọn. Nó cũng là khủng khiếp để lập trình trong - không có bữa ăn trưa miễn phí. Nếu bạn thả bất kỳ thứ nào trong số đó, bạn sẽ mất toàn bộ sức mạnh, vì vậy đó là một bộ tiên đề tối thiểu.

Bạn có thể dịch những thứ đó theo nghĩa đen thành các yếu tố cú pháp cơ bản cho các chương trình WHILE , cụ thể là

  1. Hằng số 0
  2. Tăng _ + 1
  3. Truy cập biến x
  4. Kết hợp chương trình / tuyên bố _; _
  5. Vòng lặp đếm ngược for ( x to 0 ) do _ end
  6. Trong khi các vòng lặp while ( x != 0 ) do _ end

1
Tôi nghĩ rõ ràng là bạn không thể bỏ quy tắc thứ 5 trong ngôn ngữ. Do whilevòng lặp trong 6 so với hằng số 0, các biến chỉ có thể được tăng theo quy tắc 2 và không có hằng số âm bắt đầu từ (quy tắc 1), nên whilevòng lặp trong 6 không được nhập (x = 0) hoặc là vô hạn ( x> 0 và thân vòng lặp không thể giảm nó).
MSalters

1
@MSalters Tôi nghĩ bạn đúng; đối với mô phỏng mà tôi dường như đã có trong đầu, chúng tôi cần _ - 1và tôi không thể nghĩ ra cách nào để thực hiện điều đó mà không có for. Cảm ơn đã bắt nó! ("Tốt hơn" - bao gồm _ - 1hay for? Hmm.)
Raphael

20

Có tồn tại một tập hợp các tính toán cần phải được thực hiện trong ngôn ngữ lập trình để nó được coi là Turing Complete không?

Có, để được coi là Turing hoàn thành, một ngôn ngữ lập trình cần có khả năng thực hiện bất kỳ tính toán nào có thể được thực hiện bởi máy Turing. Vì vậy, như một yêu cầu tối thiểu mà người ta có thể nói, bạn cần có khả năng triển khai một máy Turing phổ dụng - hoặc một trình thông dịch cho bất kỳ ngôn ngữ hoàn chỉnh Turing nào khác - trong đó.

Từ những gì tôi có thể nói từ wikipedia, ngôn ngữ cần hỗ trợ đệ quy, hoặc, dường như, phải có khả năng chạy mà không cần dừng lại. Đây có phải là tất cả không?

Không. Ví dụ: ngôn ngữ trong đó thao tác được phép duy nhất là đệ quy (nghĩa là chức năng duy nhất bạn có thể viết là f(x) = f(x), không hoàn thành Turing vì tất cả những gì bạn có thể viết trong đó là các chương trình không bao giờ chấm dứt. Như tôi đã nói trước đó, một ngôn ngữ hoàn chỉnh Turing cần có khả năng thực hiện bất kỳ tính toán nào có thể được thực hiện bằng máy Turing. Vì vậy, rõ ràng điều đó không đủ.

Ngoài ra, một ngôn ngữ không phải hỗ trợ đệ quy theo cách bạn nghĩ. Chỉ là một cách không hạn chế để thể hiện các vòng lặp. Đó có thể là đệ quy, nhưng cũng có thể là vòng lặp while hoặc goto. Một ngôn ngữ hoàn toàn không có chức năng vẫn có thể hoàn thành Turing. Và một lần nữa các vòng lặp hoặc các hàm đệ quy không phải là một điều kiện đủ. Bạn vẫn cần một cách để thực thi mã khác nhau tùy thuộc vào một điều kiện và cách tính giá trị mới từ các giá trị cũ (nếu không tất cả các vòng lặp / đệ quy sẽ là vô hạn hoặc hoàn toàn không chạy).


Về việc liệu có một tập hợp tối thiểu các hoạt động cần và đủ hay không, sao cho mọi ngôn ngữ hỗ trợ các hoạt động này đều hoàn chỉnh và bất kỳ ngôn ngữ nào không phải là: Không, không (trừ khi bạn định nghĩa "hoạt động" một cách mơ hồ , rằng nó trở nên vô nghĩa):

Ví dụ như tôi đã nói, có các ngôn ngữ hoàn chỉnh Turing không hỗ trợ các hàm đệ quy (hoặc bất kỳ chức năng nào). Chúng vẫn có thể hoàn thành Turing nếu chúng có gotocâu lệnh hoặc whilevòng lặp (và cách lưu trữ lượng dữ liệu tùy ý). Tuy nhiên một ngôn ngữ với các chức năng đệ quy cần không phải whilevà cũng không gotođược Turing hoàn tất. Vì vậy, gotosẽ không có trong tập hợp các hoạt động đủ cần thiết, nhưng có những ngôn ngữ không còn hoàn thành Turing nếu bạn xóa goto. Do đó không có bộ như vậy.


Phần duy nhất tôi không chắc chắn là câu trả lời của bạn cho tập hợp tối thiểu các thao tác cần thiết. Bạn dường như giới hạn định nghĩa hoạt động của mình đối với Cấu trúc điều khiển dường như là phạm vi hẹp hơn nhiều so với yêu cầu và vượt quá yêu cầu của bạn là không xác định chúng "rất mơ hồ, rằng [chúng] trở nên vô nghĩa".
Joshua Drake

@JoshuaDrake Tôi không chắc ý của bạn là gì. Tôi không giới hạn hoạt động để kiểm soát các cấu trúc. Chỉ là tôi không nói về bất kỳ hoạt động nào không kiểm soát các cấu trúc trong ví dụ truy cập của tôi vì chúng không liên quan đến ví dụ. Trên thực tế tôi có đề cập đến "một cách lưu trữ lượng dữ liệu tùy ý" - đó hầu như không phải là một cấu trúc kiểm soát.
sepp2k

Bạn đưa ra quan điểm rằng một số ngôn ngữ hỗ trợ Turing Hoàn thiện với gotonhưng một số ngôn ngữ thì dường như không cho rằng vì một số ngôn ngữ sử dụng và một số ngôn ngữ gotokhông thể là một phần của tập hợp các thao tác cần thiết cho tính hoàn chỉnh của Turing. Quan điểm của tôi gotochỉ đơn giản là một cách tổng hợp để thực hiện một thao tác chung chung hơn, chẳng hạn như một bước nhảy. Do đó, tôi tin rằng nếu bạn đơn giản trừu tượng hóa khỏi các cấu trúc điều khiển cụ thể, bạn sẽ tiến gần hơn đến một tập hợp các hoạt động ít nhất sẽ hướng đến Turing Complete.
Joshua Drake

@JoshuaDrake Tôi không nghĩ sử dụng "jump" thay vì goto đưa chúng ta đến điểm mà chúng ta có thể xác định một bộ hoạt động đủ và cần thiết. Có lẽ đúng là mọi ngôn ngữ sẽ cần một số hoạt động nhảy (và nếu đó chỉ là chức năng gọi), nhưng tôi không nghĩ rằng bạn sẽ có thể đưa ra các hoạt động tiếp theo để làm cho nó đủ. Ví dụ: phép tính lambda có hai thao tác: ứng dụng (tức là thao tác nhảy của chúng tôi) và trừu tượng hóa (tức là tạo hàm) ...
sepp2k

1
@JoshuaDrake Tôi không nghĩ rằng bài báo đang cố khẳng định rằng bất kỳ ngôn ngữ hoàn chỉnh Turing nào cũng cần phải có các hoạt động đó. Đặc biệt là vì nó đặc biệt hạn chế tuyên bố đó đối với các ngôn ngữ thủ tục. Ngoại trừ một dạng goto (tức là ứng dụng chức năng), Lambda Tính không có bất kỳ thứ gì trong số đó. Tôi nghĩ "tối thiểu" ở đây chỉ có nghĩa là trong một ngôn ngữ chỉ có các tính năng đó, bạn không thể xóa bất kỳ ngôn ngữ nào trong số đó mà không làm mất tính hoàn chỉnh của Turing. Không phải là không có bộ hoạt động tối thiểu nào khác cũng đủ để hoàn thành Turing.
sepp2k

14

Có nhiều hướng dẫn khác nhau dẫn đến ngôn ngữ hoàn chỉnh Turing. Ví dụ điển hình là "trừ và nhánh nếu không". Chúng được biết đến trong bối cảnh lập trình ngôn ngữ lắp ráp. Xem bài viết Wikipedia để biết chi tiết.

Điều này dẫn đến một đặc tính: một ngôn ngữ là Turing hoàn thành khi và chỉ khi nó có thể mô phỏng các hoạt động tìm nạp và lưu trữ các số nguyên trong bộ nhớ và thực hiện thao tác "trừ và phân nhánh nếu không" trên chúng.


13

Đây không phải là câu trả lời chung cho câu hỏi của bạn, nhưng theo định lý lập trình có cấu trúc , tất cả những gì cần thiết là khả năng lựa chọn (ví dụ, iftrong C / C ++) và lặp lại (ví dụ, whiletrong C / C ++). Chỉnh sửa: như Dave Clarke đã chỉ ra trong các bình luận, định lý lập trình có cấu trúc cũng yêu cầu trình tự. Ban đầu tôi không liệt kê điều này vì tôi cho rằng người đọc sẽ hiểu rằng các khối cơ bản của các hướng dẫn khác, chẳng hạn như những thứ được ám chỉ sau này để đọc và ghi vào kho lưu trữ, v.v., cũng cần thiết). Tất nhiên, tốt hơn là nên nói rõ ràng; bạn cần phải có khả năng làm những điều này, quá.

Vì cả hai điều này có thể được thực hiện bằng cách sử dụng lệnh nhảy có điều kiện (ví dụ: JNZtrong x86), điều đó cũng đủ cho Turing-tương đương.

Lưu ý rằng những thứ khác là bắt buộc, tức là khả năng ghi số lượng ký hiệu không giới hạn (ví dụ: bit ... 0 hoặc 1) vào một số loại bộ nhớ ngoài. Theo nghĩa đó, máy tính thực không tương đương Turing, vì không ai trong số chúng có dung lượng lưu trữ vô hạn. Tuy nhiên, mô hình Turing vẫn hữu dụng vì lượng bộ nhớ thường rất lớn và mặc dù mọi vấn đề mà máy tính thực sự có thể giải quyết đều có thể được giải quyết bằng máy tự động hữu hạn xác định, sử dụng mô hình tính toán đó không đặc biệt hữu ích (vì số lượng các tiểu bang sẽ rất lớn).

Lưu ý rằng điều này không nhất thiết là mâu thuẫn với câu trả lời của sepp2k; đây chỉ là một cách khác để suy nghĩ về cùng một câu hỏi.

BIÊN TẬP:

Cũng lưu ý rằng bạn không thực sự cần cả hai ifwhiletrong C / C ++. Bạn có thể mô phỏng ifbằng cách sử dụng whilenhư sau:

bool C;
// some code that sets C
if(C) { /* some other code /* }
// rest of the program

Các mã sau luôn luôn tương đương:

bool C;
// some code that sets C
bool C2 = C;
while(C2) { /* some other code /* C2 = false; }
// rest of the program

Chà ... việc xây dựng nên hoạt động và có thể nếu bạn cẩn thận, đó là. Cũng lưu ý rằng nếu bạn có các hàm đệ quy, cuối cùng bạn cũng cần lựa chọn; vì các hàm đệ quy mà không có lựa chọn thực sự không thể thực hiện các trường hợp cơ sở, do đó, bất kỳ hàm đệ quy nào cũng sẽ dẫn đến đệ quy vô hạn.

BIÊN TẬP:

Ngoài ra, liên quan đến câu hỏi của bạn về việc liệu khả năng viết một chương trình không dừng lại có đủ cho Turing tương đương hay không, câu trả lời là không; nó là cần thiết, nhưng không đủ Chúng ta có thể giải quyết vấn đề tạm dừng cho các chương trình được viết bằng ngôn ngữ không thể diễn tả các chương trình không dừng lại; câu trả lời là "chương trình tạm dừng" cho tất cả các trường hợp. Tuy nhiên, chúng ta có thể định nghĩa một ngôn ngữ trong đó chỉ dẫn duy nhất khiến máy đi vào một vòng lặp vô hạn ... ngôn ngữ đó không tương đương với Turing.


13

SK(S x y z)= =(x z (y z))(K x y)= =x

X= =λx.((x S) K)


5

Các cấu trúc ngôn ngữ có thể hoán đổi cho nhau

Không có bộ tiêu chuẩn tối thiểu về những gì xây dựng phải tự nhiên được cung cấp bởi một ngôn ngữ lập trình. Nếu nó cung cấp một số cấu trúc kỳ lạ bằng cách nào đó có thể được chia thành một hệ thống hoàn chỉnh Turing, thì rõ ràng các cấu trúc đó "cũng phù hợp" như bất kỳ cấu trúc nào khác.

Để chứng minh điều này - một ngôn ngữ chỉ cung cấp thao tác "trừ và rẽ nhánh nếu không" là Turing hoàn tất; tồn tại các ngôn ngữ hoàn chỉnh Turing không cung cấp một cấu trúc "trừ và nhánh nếu không" riêng biệt, ergo không có cấu trúc hoặc một tập hợp các cấu trúc nào là bắt buộc.

Các tác động của bất kỳ cấu trúc ngôn ngữ hoàn chỉnh TP nào có thể được mô phỏng bằng các cấu trúc của bất kỳ ngôn ngữ hoàn chỉnh TP nào khác.

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.