Thuật toán để giải quyết vấn đề Tạm dừng của Turing's's


23

"Alan Turing đã chứng minh vào năm 1936 rằng một thuật toán chung để giải quyết vấn đề tạm dừng cho tất cả các cặp đầu vào chương trình có thể không tồn tại"

Tôi có thể tìm một thuật toán chung để giải quyết vấn đề tạm dừng cho một số cặp đầu vào chương trình có thể không?

Tôi có thể tìm một ngôn ngữ lập trình (hoặc ngôn ngữ), nơi tôi cho mọi loại chương trình trong ngôn ngữ này, nó có thể quyết định xem chương trình đó có kết thúc hoặc chạy mãi không?



3
CACM đã có một bài viết rất thú vị vào tháng 5: Chứng minh chấm dứt chương trình
Christoph Walesch

3
"một thuật toán chung [...] cho một số cặp đầu vào chương trình có thể" - gần như là tự mâu thuẫn. Tôi đoán bạn muốn giới hạn bản thân trong một lớp con vô hạn của tất cả các chương trình?
Raphael

Câu trả lời:


25

Tôi có thể tìm một thuật toán chung để giải quyết vấn đề tạm dừng cho một số cặp đầu vào chương trình có thể không?

Vâng, chắc chắn rồi. Ví dụ: bạn có thể viết một thuật toán trả về "Có, nó chấm dứt" cho bất kỳ chương trình nào không chứa vòng lặp cũng không đệ quy và "Không, nó không chấm dứt" đối với bất kỳ chương trình nào có while(true)vòng lặp chắc chắn sẽ đạt được và không chứa một tuyên bố phá vỡ, và "Dunno" cho mọi thứ khác.

Tôi có thể tìm một ngôn ngữ lập trình (hoặc ngôn ngữ), nơi tôi cho mọi loại chương trình trong ngôn ngữ này, nó có thể quyết định xem chương trình đó có kết thúc hoặc chạy mãi không?

Không, nếu ngôn ngữ đó là Turing - hoàn thành, không.

Tuy nhiên, có các ngôn ngữ hoàn chỉnh không Turing như Coq , Agda hoặc Microsoft Dafny mà Vấn đề tạm dừng có thể quyết định được (và trên thực tế được quyết định bởi các hệ thống loại tương ứng của chúng, làm cho chúng trở thành ngôn ngữ tổng thể (nghĩa là một chương trình không thể chấm dứt sẽ không biên dịch)).


1
Lớp các hàm đệ quy nguyên thủy là một "ngôn ngữ lập trình" nổi tiếng mà vấn đề tạm dừng có thể quyết định được.
Raphael

Có một số ngôn ngữ " tổng thể lập trình chức năng " trong đó tất cả các chương trình đều có thể chấm dứt.
Anderson Green

3

Tôi nghĩ rằng tất cả các câu trả lời ở đây hoàn toàn và hoàn toàn bỏ lỡ điểm. Câu trả lời cho câu hỏi là: giả sử chương trình có ý định tạm dừng, thì vâng, bạn tốt hơn có thể cho thấy nó dừng lại. Nếu bạn không thể hiển thị nó dừng dễ dàng thì chương trình sẽ bị coi là rất tệ và bị từ chối bởi Kiểm soát chất lượng.

Việc bạn có thực sự có thể viết một thuật toán máy phù hợp hay không phụ thuộc vào ngôn ngữ lập trình đầu vào và mức độ tham vọng của bạn. Đó là một mục tiêu thiết kế hợp lý cho một ngôn ngữ lập trình để làm cho nó dễ dàng có thể chứng minh sự chấm dứt.

Nếu ngôn ngữ là C ++, có lẽ bạn không thể viết công cụ này, thực sự không chắc là bạn sẽ khiến trình phân tích cú pháp hoạt động, chứ đừng nói đến việc chứng minh chấm dứt. Đối với một ngôn ngữ có cấu trúc tốt hơn, bạn sẽ có thể tạo ra một bằng chứng hoặc ít nhất là làm như vậy với các giả định nhất định: trong trường hợp sau, công cụ sẽ đưa ra các giả định này. Một cách tiếp cận tương tự sẽ bao gồm các xác nhận chấm dứt trong ngôn ngữ và sử dụng chúng trong các tình huống phức tạp trong đó công cụ sẽ tin tưởng vào các xác nhận đó.

Điểm mấu chốt là dường như không ai hiểu rằng việc chứng minh chương trình tạm dừng là thực sự có thể bởi vì các lập trình viên (tốt) có ý định viết các chương trình tạm dừng như vậy luôn luôn làm như vậy một cách có chủ ý và với một bức tranh tinh thần về lý do tại sao họ chấm dứt và hành động chính xác: mã đó là cố tình được viết để rõ ràng rằng họ dừng lại và đúng và nếu một thuật toán hợp lý không thể chứng minh điều này, có thể với một số gợi ý, thì chương trình nên bị từ chối.

Vấn đề: các lập trình viên không viết các chương trình tùy ý, vì vậy luận điểm của định lý tạm dừng không thỏa mãn và kết luận không được áp dụng.


4
Tôi nghĩ đó là bạn, người hoàn toàn và hoàn toàn bỏ lỡ quan điểm. Đoạn đầu tiên trong câu trả lời của bạn không áp dụng cho câu hỏi vì nó hỏi về thuật toán - không phải là điều mà con người có thể hoặc không thể chứng minh. Phần còn lại của câu trả lời trả lời đoạn đầu tiên của câu hỏi, tức là liệu một thuật toán có thể chứng minh chấm dứt cho một số chương trình hay không. Mọi người trong số các câu trả lời trước đã nói "có" với câu trả lời đó.
sepp2k

3
Khẳng định của bạn rằng có thể viết một thuật toán có thể chứng minh chấm dứt mọi chương trình được viết tốt bằng một ngôn ngữ Turing-Complete đủ đơn giản là hoàn toàn sai. Đối với mọi thuật toán có thể cố gắng chứng minh chấm dứt, có những vấn đề trong đó mọi chương trình giải quyết vấn đề đó không thể được chứng minh để ngăn chặn bằng thuật toán đó. Vì vậy, trừ khi bạn nói rằng mọi chương trình giải quyết vấn đề đó đều được viết sai theo định nghĩa (sẽ là lố bịch), điều đó sẽ bác bỏ quan điểm của bạn.
sepp2k

1
@Sam Nếu ai đó hỏi tôi liệu một số mã dừng lại, tôi sẽ xem mã và cố gắng tìm ra nó. Nhưng tôi không phải là một thuật toán. Và vâng, có thể viết một thuật toán có thể kiểm tra xem một chương trình có tạm dừng nhiều chương trình hay không. Nhưng đó không phải là những gì Yttrill nói. Yttrill cho biết tất cả các chương trình được viết tốt đều có thể. Và như tôi đã nói trong bình luận trước đây của tôi, điều đó chỉ đơn giản là sai trừ khi bạn cho rằng một số vấn đề nhất định chỉ có thể được giải quyết bằng các chương trình được viết xấu (một lần nữa sẽ là lố bịch).
sepp2k

1
@Sam "có vẻ đơn giản với tôi rằng các chương trình cố tình viết để tạm dừng có thể dễ dàng phân tích cho các điều kiện tạm dừng" - nếu đó là trường hợp, tại sao chúng ta không có các công cụ như vậy? Không phải như thể mọi người không cố gắng. (Một thủ phạm là ghi đè phương thức: tại thời điểm biên dịch, bạn không biết tất cả mã sẽ được thực thi.)
Raphael

1
@Sam "có một vòng lặp vô hạn" là một điều khó tiếp cận, ngay cả đối với vòng lặp trong thế giới thực. Tất nhiên tôi được dạy cách tìm bất biến vòng lặp, nhưng điều đó không có nghĩa là tôi có thể tìm thấy một (một cách dễ dàng) trong nhiều trường hợp. Theo như tôi biết, đoán và chứng minh là tiêu chuẩn vàng những ngày này. Một lần nữa, nếu có thuật toán một cách hợp lý chung, tôi sẽ mong đợi họ được đưa vào biên dịch lớn hoặc IDE (mà làm thực hiện một số tầm thường, kiểm tra cú pháp). Bạn có thể đưa ra một tham chiếu đến một thuật toán hợp lý mạnh mẽ?
Raphael

3

xuất sắc và (thăm dò vô tình sâu) câu hỏi. thực sự có những chương trình phát hiện tạm dừng có thể thành công trên các bộ đầu vào hạn chế. nó là một lĩnh vực hoạt động nghiên cứu. nó có mối quan hệ rất chặt chẽ với các khu vực chứng minh định lý (tự động).

tuy nhiên khoa học máy tính dường như không có thuật ngữ chính xác cho "các chương trình" mà "đôi khi" thành công. từ "thuật toán" thường được dành riêng cho các chương trình luôn dừng lại.

khái niệm này dường như khác biệt rõ rệt so với các thuật toán xác suất trong đó các nhà lý thuyết CS khẳng định có một số xác suất được biết hoặc tính toán về sự thành công của họ.

có một thuật ngữ semialgorithms được sử dụng đôi khi nhưng dường như nó là một từ đồng nghĩa với đệ quy đếm được hoặc noncomputable.

Vì vậy, cho các mục đích ở đây, gọi chúng là thuật toán quasial . khái niệm này khác với quyết định so với không thể giải quyết được.

AXBYXYXYBA

trong CS, "hệ thống phân cấp thuật toán gần như" này dường như chỉ được nghiên cứu chủ yếu cho đến nay.

nó xuất hiện trong nghiên cứu hải ly bận rộn [1] và vấn đề về PCP [2]. trong thực tế, một cuộc tấn công điện toán dựa trên DNA vào PCP có thể được coi là một thuật toán chuẩn. [3] và nó được thấy trong các lĩnh vực khác đã được ghi nhận như định lý chứng minh [4].

[1] Cuộc tấn công thiên niên kỷ mới vào vấn đề hải ly bận rộn

[2] Giải quyết vấn đề tương ứng Bài viết của Zhao (v2?)

[3] Sử dụng DNA để giải quyết vấn đề tương ứng bài bị ràng buộc của Kari et al

[4] chứng minh chấm dứt chương trình của Cook et al, Comm. của ACM

(vì vậy đây thực sự là một câu hỏi rất sâu sắc mà không đáng có trên TCS.SE imho ... có lẽ ai đó có thể hỏi lại nó theo cách sao cho phù hợp và ở lại)


ps là một ví dụ ấn tượng về khả năng của các thuật toán quasial mạnh mẽ như thế nào, tham chiếu ACM cho thấy chức năng ackermanns có thể được chứng minh là dừng bởi một thuật toán quasial, nhưng nó lớn hơn (không thể tính toán được) bởi tất cả các hàm đệ quy nguyên thủy.
vzn

1
"từ" thuật toán "thường được dành riêng cho các chương trình luôn dừng lại." - Tôi không chắc đó là sự thật. Có rất nhiều thuật toán chấm dứt một phần xung quanh (đặc biệt là trong xác minh) và tôi chưa bao giờ nghe ai nói "thuật toán".
Raphael

có những cách sử dụng không chính thức của "thuật toán". "Chấm dứt một phần" là ok nhưng thăm dò nonstd. như đã nêu, dường như chưa có thuật ngữ nào. wikipedia định nghĩa một thuật toán là một phương pháp hiệu quả, nghĩa là có thể quyết định với các đặc điểm sau (1) luôn đưa ra một số câu trả lời thay vì không bao giờ trả lời; (2) luôn đưa ra câu trả lời đúng và không bao giờ trả lời sai; (3) luôn luôn được hoàn thành trong một số bước hữu hạn, thay vì số lượng vô hạn; (4) làm việc cho tất cả các trường hợp vấn đề của lớp.
vzn

và sau đó trong cùng một bài viết có ghi "Làm sáng tỏ thêm thuật ngữ" phương pháp hiệu quả "có thể bao gồm yêu cầu, khi đưa ra một vấn đề từ bên ngoài lớp mà phương thức có hiệu quả, phương thức có thể dừng hoặc lặp lại mãi mãi mà không dừng lại , nhưng không được trả lại kết quả như thể đó là câu trả lời cho vấn đề. " tức là nó gần như mâu thuẫn với chính nó!? rõ ràng, đáng chú ý, có một số nhầm lẫn thực sự về vấn đề chính và thuật ngữ hiện tại là không nghiêm ngặt. lưu ý từ "thuật toán" gần hơn một milimet cũ hoặc đã thay đổi đáng kể ....
vzn

Đó là sự thật: ý nghĩa truyền thống có lẽ là "phương pháp hiệu quả" theo cách Wikipedia nói (không có mâu thuẫn trong câu bạn trích dẫn; tuy nhiên nó hơi không rõ ràng) - mọi người không nghĩ ra các hàm / thuật toán không chấm dứt (đối với một số đầu vào). Tôi nghĩ rằng điều này đã thay đổi kể từ những năm 1950; như tôi đã nói, ngày nay mọi người gọi một phương thức chấm dứt một phần là "thuật toán".
Raphael

2

Miễn là ngôn ngữ lập trình trong câu hỏi đủ phức tạp (nghĩa là nếu nó hoàn thành Turing), thì luôn có các chương trình trong ngôn ngữ mà không chương trình nào có thể chứng minh để chấm dứt.

Vì tất cả các ngôn ngữ nguyên thủy nhất đều là Turing hoàn chỉnh (chỉ mất một số thứ như biến và điều kiện), bạn thực sự chỉ có thể xây dựng các ngôn ngữ đồ chơi rất nhỏ mà bạn có thể giải quyết vấn đề tạm dừng.

Chỉnh sửa: Trước các ý kiến, hãy để tôi nói rõ hơn: Bất kỳ ngôn ngữ nào bạn có thể thiết kế mà bạn có thể giải quyết vấn đề tạm dừng nhất thiết phải là Turing-không đầy đủ. Điều này loại trừ bất kỳ ngôn ngữ nào có chứa một tập hợp các thành phần cơ bản phù hợp (ví dụ: "biến, điều kiện và bước nhảy", hoặc như @ sepp2k nói, "chung" trong khi -loop).

Rõ ràng tồn tại một số ngôn ngữ "đơn giản" thực tế như thế (ví dụ: người giải quyết định lý như Coq và Agda). Nếu những điều đó thỏa mãn khái niệm của bạn về "ngôn ngữ lập trình", bạn có thể điều tra xem liệu chúng có thỏa mãn một loại hoàn chỉnh nào đó không, hoặc liệu vấn đề tạm dừng có thể giải quyết được cho chúng hay không.


3
"Vì tất cả trừ các ngôn ngữ nguyên thủy nhất đều hoàn thành Turing (nó chỉ mất một số thứ như biến và điều kiện)" Điều đó không đúng. Trước hết, bạn ít nhất sẽ cần đệ quy hoặc một số hình thức xây dựng vòng lặp (cần mạnh mẽ như vòng lặp while - một vòng đếm đơn giản là không đủ). Thứ hai, tôi không nghĩ rằng có rất nhiều người sẽ gọi các ngôn ngữ như Coq hoặc Agda (hoàn toàn và do đó không hoàn chỉnh) các ngôn ngữ nguyên thủy hoặc đồ chơi.
sepp2k

@ sepp2k: Vâng, vâng. Số học Peano cũng khá hữu ích và không hoàn thành Turing. Một tuyên bố đơn giản, tôi cho rằng. Nếu OP đủ quen thuộc với vấn đề này, cô ấy hy vọng sẽ có thể điền vào các chi tiết kỹ thuật.

3
Có một khoảng cách lớn giữa việc "đủ phức tạp" và hoàn thành Turing. Coq thực sự phức tạp, và nó phù hợp cho một loạt các nhiệm vụ thực tế.

1
@Kerrek SB Vâng, có thể ngôn ngữ Turing-Complete được sử dụng theo những cách có thể chứng minh được để chấm dứt. Nếu bạn có thể chứng minh rằng một công thức đệ quy luôn tiếp cận điều kiện kết thúc của nó (như hàm giai thừa), bạn có thể chứng minh rằng nó chấm dứt ngay cả khi bạn không thể xử lý mọi loại đệ quy.

@ArtB: Chắc chắn, luôn có một số chương trình có thể được chứng minh là chấm dứt. Câu hỏi đầu tiên của OP có thể gợi ý về điều đó, mặc dù tôi không chắc là mình theo dõi đầy đủ. Chẳng hạn, bạn không thể có một "thuật toán chung" để xác định xem có bất kỳ họ chương trình cụ thể nào kết thúc hay không, trong khi ngược lại, bạn thể xây dựng một nhóm hàm bị hạn chế để giả sử một hàm thuộc về họ đó, bạn có thể nói về mặt thuật toán xem nó có chấm dứt. (Tôi không chắc liệu gia đình đó có thể không tầm thường hay không. Tôi đoán là có thể, nhưng tôi không thể làm một ví dụ.)

2

TT

Điều này khá tầm thường. Nếu chúng ta kết hợp bất kỳ tập hợp con nào của việc tạm dừng TM và bất kỳ tập hợp con nào của các TM không tạm dừng, kết quả sẽ là tập hợp các TM mà vấn đề tạm dừng có thể quyết định được (chạy song song cả hai máy, nếu máy đầu tiên chấp nhận TM dừng lại, nếu cái thứ hai chấp nhận thì máy không dừng lại). Tuy nhiên điều này sẽ không dẫn đến nhiều ngôn ngữ thú vị.

ALogTimecM


1

Có bạn có thể, nhưng tôi nghi ngờ nó sẽ hữu ích. Bạn có thể phải thực hiện phân tích trường hợp và sau đó bạn chỉ có thể tìm kiếm các trường hợp rõ ràng nhất. Ví dụ: bạn có thể grep một tệp cho mã while(true){}. Nếu tập tin có mã đó, nó sẽ không bao giờ chấm dứt ^. Nói chung, bạn có thể nói rằng một chương trình không có vòng lặp hoặc đệ quy sẽ luôn chấm dứt và có một số trường hợp bạn có thể làm có thể đảm bảo rằng chương trình sẽ hoặc không chấm dứt, nhưng ngay cả một chương trình cỡ trung thì điều này rất khó khăn và trong nhiều trường hợp sẽ không thể cho bạn một câu trả lời.

tl; dr: Có, nhưng bạn sẽ không thể có nó hữu ích cho hầu hết các chương trình hữu ích.


^ Có, về mặt kỹ thuật nếu mã đó không nằm trên đường dẫn mã hoặc có các luồng khác thì nó vẫn có thể chấm dứt, nhưng tôi đang đưa ra quan điểm chung ở đây.


4
Tại sao bạn nghĩ Coq và Agda không hữu ích? Bạn đang đánh giá quá cao giá trị của Turing-đầy đủ.

Tôi đã sử dụng Coq, nhưng yêu cầu của tôi vẫn còn vì hầu hết các phần mềm thương mại được viết bằng Java / C ++ / Ruby / C # mà tuyên bố của tôi là đúng. Các loại chương trình 90% mọi người quan tâm đến việc viết sẽ không có lợi. Về cơ bản, nếu bạn không biết về Coq / Agda, v.v. bạn không phải là thị trường mục tiêu cho nó.

5
Tôi muốn nói rằng 99% các chương trình trong thế giới thực sẽ được hưởng lợi từ việc được triển khai trong một tập hợp con không hoàn chỉnh của ngôn ngữ. Bạn sẽ không thực hiện chức năng Ackermann mỗi ngày. 100% CRUD không cần ngôn ngữ "thực". Xử lý dữ liệu hầu như luôn luôn tầm thường. Xem dự án Terminator - chúng thậm chí còn phục vụ một tập hợp con tốt của các chương trình C ++ có thể, quá đủ cho các công cụ trong thế giới thực (bao gồm trình điều khiển và mã cấp thấp khác).

Hầu hết các dự án trong thế giới thực đều muốn sử dụng lại các thư viện được viết bằng ngôn ngữ Turing-perfect và sử dụng IDE và trình gỡ lỗi và hướng dẫn của họ. Có, bạn có thể thực hiện mọi thứ bằng các ngôn ngữ không phải Turing, nhưng tôi không thể tưởng tượng một số người thực sự nói "Tôi muốn làm X" và câu trả lời của tôi là "Sử dụng Coq". ps- cảm ơn vì đã giới thiệu tôi với Dự án Kẻ hủy diệt .

4
một tỷ lệ rất lớn không thể tưởng tượng được của logic nghiệp vụ đã được triển khai trong một SQL không hoàn chỉnh Turing. Và DSL và eDSL đang tăng lên. Vì vậy, hầu hết các lập trình viên ứng dụng kinh doanh sẽ sớm quên đi tất cả các ngôn ngữ "mục đích chung".
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.