Tất cả xuất phát từ sự không ổn định của vấn đề tạm dừng. Giả sử chúng ta có một hàm mã chết "hoàn hảo", một số Turing Machine M và một số chuỗi đầu vào x và một thủ tục trông giống như thế này:
Run M on input x;
print "Finished running input";
Nếu M chạy mãi mãi, thì chúng ta sẽ xóa câu lệnh in, vì chúng ta sẽ không bao giờ đạt được nó. Nếu M không chạy mãi mãi, thì chúng ta cần giữ nguyên câu lệnh in. Do đó, nếu chúng ta có một công cụ loại bỏ mã chết, nó cũng cho phép chúng ta giải quyết vấn đề Ngừng, vì vậy chúng ta biết rằng không thể có loại bỏ mã chết như vậy.
Cách chúng ta giải quyết vấn đề này là "xấp xỉ bảo thủ". Vì vậy, trong ví dụ về Máy Turing của tôi ở trên, chúng tôi có thể giả sử rằng việc chạy M trên x có thể kết thúc, vì vậy chúng tôi chơi nó an toàn và không xóa câu lệnh in. Trong ví dụ của bạn, chúng tôi biết rằng bất kể chức năng nào làm hoặc không dừng lại, rằng không có cách nào chúng tôi sẽ đạt được tuyên bố in đó.
Thông thường, điều này được thực hiện bằng cách xây dựng một "biểu đồ luồng điều khiển". Chúng tôi thực hiện các giả định đơn giản hóa, chẳng hạn như "kết thúc vòng lặp while được kết nối với đầu và câu lệnh sau", ngay cả khi nó chạy mãi mãi hoặc chỉ chạy một lần và không truy cập cả hai. Tương tự, chúng tôi giả định rằng một câu lệnh if có thể đến tất cả các nhánh của nó, ngay cả khi trong thực tế, một số không bao giờ được sử dụng. Những loại đơn giản hóa này cho phép chúng tôi loại bỏ "mã chết rõ ràng" như ví dụ bạn đưa ra, trong khi vẫn có thể quyết định được.
Để làm rõ một vài nhầm lẫn từ các ý kiến:
Nitpick: đối với M cố định, điều này luôn luôn có thể quyết định. M phải là đầu vào
Như Raphael nói, trong ví dụ của tôi, chúng tôi coi Máy Turing là đầu vào. Ý tưởng là, nếu chúng tôi có một thuật toán DCE hoàn hảo, chúng tôi sẽ có thể xây dựng đoạn mã tôi đưa cho bất kỳ Máy Turing nào và có DCE sẽ giải quyết vấn đề tạm dừng.
không thuyết phục. trở lại như một tuyên bố thẳng thừng trong một thực thi thẳng về phía trước không có chi nhánh không khó để quyết định. (và trình biên dịch của tôi nói với tôi rằng nó có khả năng tìm ra điều này)
Đối với vấn đề njzk2 nêu ra: bạn hoàn toàn đúng, trong trường hợp này bạn có thể xác định rằng không có cách nào để đưa ra tuyên bố sau khi hoàn trả. Điều này là do nó đủ đơn giản để chúng ta có thể mô tả tính không thể truy cập của nó bằng cách sử dụng các ràng buộc biểu đồ luồng điều khiển (nghĩa là không có các cạnh đi ra khỏi câu lệnh return). Nhưng không có loại bỏ mã chết hoàn hảo, loại bỏ tất cả các mã không sử dụng.
Tôi không lấy bằng chứng phụ thuộc đầu vào để làm bằng chứng. Nếu tồn tại loại đầu vào người dùng như vậy có thể cho phép mã là hữu hạn, thì trình biên dịch sẽ cho rằng nhánh sau không chết. Tôi không thể thấy tất cả các upvote này để làm gì, cả hai đều rõ ràng (ví dụ: stdin vô tận) và sai.
Đối với TomášZato: nó không thực sự là một bằng chứng phụ thuộc đầu vào. Thay vào đó, giải thích nó như là một "forall". Nó hoạt động như sau: giả sử chúng ta có một thuật toán DCE hoàn hảo. Nếu bạn đưa cho tôi một máy Turing tùy ý M và đầu vào x, tôi có thể sử dụng thuật toán DCE của mình để xác định xem M có dừng hay không, bằng cách xây dựng đoạn mã ở trên và xem liệu lệnh in có bị xóa không. Kỹ thuật này, để lại một tham số tùy ý để chứng minh một câu lệnh forall, là phổ biến trong toán học và logic.
Tôi không hiểu đầy đủ quan điểm của TomášZato về mã là hữu hạn. Chắc chắn mã là hữu hạn, nhưng một thuật toán DCE hoàn hảo phải áp dụng cho tất cả các mã, đó là một tập hợp infinte. Tương tự như vậy, trong khi bản thân mã là hữu hạn, các bộ đầu vào tiềm năng là vô hạn, cũng như thời gian chạy tiềm năng của mã.
Đối với việc xem xét nhánh cuối cùng không chết: nó an toàn về mặt "xấp xỉ bảo thủ" mà tôi nói đến, nhưng nó không đủ để phát hiện tất cả các trường hợp mã chết như OP yêu cầu.
Hãy xem xét mã như thế này:
while (true)
print "Hello"
print "goodbye"
Rõ ràng chúng ta có thể loại bỏ print "goodbye"
mà không thay đổi hành vi của chương trình. Như vậy, nó là mã chết. Nhưng nếu có một lệnh gọi chức năng khác thay vì (true)
trong while
điều kiện, thì chúng ta không biết liệu chúng ta có thể loại bỏ nó hay không, dẫn đến tính không ổn định.
Lưu ý rằng tôi không tự mình nghĩ ra điều này. Đó là một kết quả nổi tiếng trong lý thuyết về trình biên dịch. Nó được thảo luận trong The Tiger Book . (Bạn có thể thấy nơi họ nói về trong sách của Google .