Tập hợp tối thiểu các tính năng / cấu trúc ngôn ngữ làm cho nó hoàn chỉnh là gì?
Tập hợp tối thiểu các tính năng / cấu trúc ngôn ngữ làm cho nó hoàn chỉnh là gì?
Câu trả lời:
Một tarpit Turing là một loại ngôn ngữ lập trình bí truyền mà phấn đấu để được Turing hoàn tất trong khi sử dụng càng ít yếu tố càng tốt. Brainfuck có lẽ là tarpit nổi tiếng nhất, nhưng có rất nhiều.
Iota và Jot là các ngôn ngữ chức năng với hai và ba ký hiệu tương ứng, dựa trên phép tính tổ hợp SK (I) .
OISC ( Máy tính đặt một lệnh) biểu thị một loại tính toán bắt buộc chỉ yêu cầu một lệnh của một hoặc nhiều đối số, thường là trừ và nhánh nếu nhỏ hơn hoặc bằng 0, hoặc trừ ngược lại và bỏ qua nếu mượn. MMU x86 thực hiện hướng dẫn cũ và do đó hoàn thành Turing.
Nói chung, để một ngôn ngữ bắt buộc phải hoàn thành Turing, nó cần:
Một hình thức lặp lại có điều kiện hoặc nhảy có điều kiện (ví dụ while
, if
+ goto
)
Một cách để đọc và viết một số hình thức lưu trữ (ví dụ: biến, băng)
Để ngôn ngữ chức năng lambda-tính toán trở thành TC, nó cần:
Khả năng trừu tượng hóa các hàm trên các đối số (ví dụ: trừu tượng lambda, trích dẫn)
Khả năng áp dụng các hàm cho các đối số (ví dụ: giảm)
Tất nhiên có nhiều cách khác để xem xét tính toán, nhưng đây là những mô hình phổ biến cho các bạt Turing. Lưu ý rằng máy tính thực không phải là máy Turing phổ dụng vì chúng không có bộ nhớ không giới hạn. Nói một cách chính xác, chúng là những cỗ máy lưu trữ có giới hạn. Nếu bạn tiếp tục bổ sung bộ nhớ cho họ, họ sẽ tiếp cận một cách bất thường các máy Turing. Tuy nhiên, ngay cả máy lưu trữ giới hạn và máy trạng thái hữu hạn cũng hữu ích cho việc tính toán; họ chỉ đơn giản là không phổ quát .
Nói đúng ra, I / O không bắt buộc đối với tính đầy đủ của Turing; TC chỉ khẳng định rằng một ngôn ngữ có thể tính toán hàm bạn muốn chứ không phải ngôn ngữ đó có thể hiển thị cho bạn kết quả. Trong thực tế, mọi ngôn ngữ hữu ích đều có cách tương tác với thế giới bằng cách nào đó.
Từ quan điểm thực tế hơn: nếu bạn có thể dịch tất cả các chương trình bằng ngôn ngữ hoàn chỉnh Turing sang ngôn ngữ của bạn, thì (theo như tôi biết), ngôn ngữ của bạn phải là Turing-Complete. Do đó, nếu bạn muốn kiểm tra xem một ngôn ngữ bạn thiết kế có hoàn chỉnh hay không, bạn chỉ cần viết Brainf *** cho trình biên dịch YourL Language và chứng minh / chứng minh rằng nó có thể biên dịch tất cả các chương trình BF hợp pháp.
Để làm rõ, tôi có nghĩa là ngoài một trình thông dịch cho YourL Language, bạn viết một trình biên dịch (bằng bất kỳ ngôn ngữ nào) có thể biên dịch bất kỳ chương trình BF nào thành YourL Language (tất nhiên giữ cùng một ngữ nghĩa).
</sarcasm>
Một hệ thống chỉ có thể được coi là hoàn thành Turing nếu nó có thể làm bất cứ điều gì mà một máy Turing phổ dụng có thể. Vì máy Turing phổ dụng được cho là có thể giải quyết bất kỳ chức năng tính toán nào trong thời gian nhất định, các hệ thống hoàn chỉnh của Turing có thể, bằng cách mở rộng, cũng làm như vậy.
Để kiểm tra xem một cái gì đó đã hoàn thành Turing chưa, hãy xem bạn có thể triển khai máy Turing bên trong nó không. Nói cách khác, kiểm tra xem nó có thể mô phỏng như sau không:
Đây là những yêu cầu tối thiểu thực sự cho một hệ thống được coi là hoàn thành Turing. Không hơn không kém. Nếu nó không thể mô phỏng bất kỳ thứ nào trong số này theo cách nào đó, thì nó không hoàn thành. Các phương pháp mà người khác đề xuất chỉ có nghĩa là đến cuối cùng vì có một số hệ thống hoàn chỉnh Turing không có các tính năng đó.
Lưu ý rằng không có cách nào thực sự để xây dựng một hệ thống hoàn chỉnh Turing thực sự. Điều này là do không có cách nào để mô phỏng thực sự sự vô hạn của băng của máy Turing trong không gian vật lý.
Một ngôn ngữ lập trình đang hoàn tất nếu bạn có thể thực hiện bất kỳ phép tính nào với nó. Không chỉ có một bộ tính năng làm cho một ngôn ngữ hoàn chỉnh, vì vậy các câu trả lời nói rằng bạn cần các vòng lặp hoặc rằng bạn cần các biến là sai vì có những ngôn ngữ không có nhưng vẫn hoàn thành.
Alan Turing đã tạo ra máy turing phổ dụng và nếu bạn có thể dịch bất kỳ chương trình nào được thiết kế để hoạt động trên máy vạn năng để chạy trên ngôn ngữ của bạn thì nó cũng hoàn thành Turing. Điều này cũng hoạt động một cách gián tiếp để bạn có thể nói ngôn ngữ X đang hoàn tất nếu tất cả các chương trình sử dụng ngôn ngữ hoàn chỉnh Y có thể được dịch cho X vì tất cả các chương trình máy turing phổ dụng có thể được dịch sang chương trình Y.
Độ phức tạp thời gian, độ phức tạp không gian, dễ định dạng đầu vào / đầu ra và dễ viết bất kỳ chương trình nào không được đưa vào phương trình để máy tính về mặt lý thuyết có thể thực hiện tất cả các phép tính nếu các tính toán không bị dừng do mất điện hoặc Trái đất bị mặt trời nuốt chửng.
Thông thường để chứng minh tính hoàn chỉnh của họ, họ tạo ra một trình thông dịch cho bất kỳ ngôn ngữ nào được chứng minh là ngôn ngữ hoàn chỉnh nhưng để nó hoạt động, bạn cần phương tiện đầu vào và đầu ra, hai điều thực sự không bắt buộc đối với một ngôn ngữ phải hoàn thành. Nó đủ để chương trình của bạn có thể thay đổi trạng thái khi khởi động và bạn có thể kiểm tra bộ nhớ sau khi chương trình bị tạm dừng.
Để làm cho một ngôn ngữ thành công, nó cần nhiều hơn là hoàn thiện và mặc dù điều này đúng cho cả các tarpits. Tôi không nghĩ rằng Brainfuck có thể đã được phổ biến không ,
và .
.
Bạn không thể biết nó sẽ lặp lại vô hạn hay dừng lại.
Giải thích: Với một số đầu vào, không thể biết trong mọi trường hợp (sử dụng máy Turing khác) nếu sự việc sẽ lặp đi lặp lại vô tận hoặc cuối cùng sẽ dừng lại, ngoại trừ bằng cách chạy nó (cung cấp cho bạn câu trả lời nếu nó dừng, nhưng không nếu nó lặp!).
Điều này có nghĩa là bạn phải có khả năng lưu trữ một lượng dữ liệu có khả năng không giới hạn theo một cách nào đó - phải có một băng tương đương với băng vô hạn, bất kể bị xáo trộn như thế nào! (Nếu không, chỉ có một số trạng thái hữu hạn và sau đó bạn có thể kiểm tra xem bạn đã từng qua trạng thái đó trước đó chưa và cuối cùng dừng lại). Nói chung, máy Turing có thể tăng hoặc thu nhỏ kích thước trạng thái của chúng bằng một số phương tiện có thể kiểm soát được.
Vì máy Turing phổ dụng ban đầu của Turing có vấn đề tạm dừng không thể giải quyết, nên máy Turing hoàn chỉnh của riêng bạn cũng phải có vấn đề tạm dừng không thể giải quyết.
Các hệ thống hoàn chỉnh Turing có thể mô phỏng bất kỳ hệ thống hoàn chỉnh Turing nào khác, vì vậy nếu bạn có thể xây dựng trình giả lập cho một số hệ thống hoàn chỉnh Turing nổi tiếng trong hệ thống của mình, điều đó chứng tỏ rằng hệ thống của bạn cũng đã hoàn thành Turing.
Chẳng hạn, giả sử bạn muốn chứng minh rằng Snakes & Ladder đã hoàn thành Turing, được cung cấp một bảng với mô hình lưới lặp lại vô hạn (với một phiên bản khác ở phía trên và bên trái). Biết rằng máy Minsky 2 bộ đếm đã hoàn thành Turing (có 2 bộ đếm không giới hạn và 1 trạng thái trong số hữu hạn), bạn có thể tạo một bảng tương đương trong đó vị trí X và Y trên lưới là giá trị hiện tại của 2 bộ đếm và đường dẫn hiện tại là trạng thái hiện tại. Bang! Bạn vừa chứng minh rằng Rắn & Thang đã hoàn thành.
Một điều kiện cần thiết là một vòng lặp có số lần lặp tối đa không được xác định trước lần lặp hoặc đệ quy trong đó độ sâu đệ quy tối đa không được xác định trước. Ví dụ, đối với ... trong ... các vòng lặp khi bạn tìm thấy chúng trong nhiều ngôn ngữ mới hơn là không đủ để làm cho ngôn ngữ trở nên hoàn chỉnh (nhưng chúng sẽ có các phương tiện khác). Lưu ý rằng điều này không có nghĩa là số lần lặp giới hạn hoặc độ sâu đệ quy giới hạn, nhưng độ sâu lặp lại và độ sâu đệ quy tối đa phải được tính toán trước.
Ví dụ, hàm Ackermann không thể được tính bằng ngôn ngữ mà không có các tính năng này. Mặt khác, rất nhiều phần mềm rất phức tạp và rất hữu ích có thể được viết mà không yêu cầu các tính năng này.
Mặt khác, với mỗi lần lặp đếm và mỗi độ sâu đệ quy tính trước, không chỉ có thể nó được quyết định liệu một chương trình sẽ tạm dừng hay không, nhưng nó sẽ ngăn chặn.
Tôi biết đây không phải là câu trả lời chính xác, nhưng một khi bạn rút 'tối thiểu' ra khỏi 'Turing-perfect' và đưa 'thực tế' trở lại nơi nó thuộc về, bạn sẽ thấy các tính năng quan trọng nhất phân biệt ngôn ngữ lập trình với ngôn ngữ đánh dấu là
tiếp theo đến
để kiểm tra các xác nhận này, hãy bắt đầu bằng ngôn ngữ đánh dấu, giả sử, HTML. chúng ta có thể phát minh ra HTML + chỉ với các biến hoặc chỉ có điều kiện (MS đã làm điều đó với các nhận xét có điều kiện) hoặc một loại cấu trúc vòng lặp (trong trường hợp không có điều kiện có thể sẽ kết thúc giống như vậy <repeat n='4'>...</repeat>
). thực hiện bất kỳ điều nào trong số này sẽ làm cho HTML + (hoặc) mạnh hơn đáng kể so với HTML đơn giản, nhưng nó vẫn sẽ mang nhiều dấu ấn hơn là ngôn ngữ lập trình; với mỗi tính năng mới, bạn làm cho nó ít hơn một ngôn ngữ khai báo và nhiều ngôn ngữ bắt buộc hơn.
Nhiệm vụ tối thiểu trong logic và lập trình chắc chắn rất quan trọng và thú vị, nhưng nếu tôi phải dạy cho n00 người trẻ hay già 'lập trình' và 'cách học lập trình', tôi sẽ khó bắt đầu với chiều rộng và chiều rộng đầy đủ của các nền tảng lý thuyết của sự hoàn thiện Turing. toàn bộ bản chất của nấu ăn và lập trình là làm mọi thứ, theo đúng thứ tự, lặp đi lặp lại cho đến khi sẵn sàng, như mẹ bạn đã làm. đó là về số tiền đó cho tôi.
sau đó một lần nữa, tôi không bao giờ kết thúc CS của tôi.