Itu semua berasal dari ketidakpastian masalah penghentian. Misalkan kita memiliki fungsi kode mati "sempurna", beberapa Mesin Turing M, dan beberapa string input x, dan prosedur yang terlihat seperti ini:
Run M on input x;
print "Finished running input";
Jika M berjalan selamanya, maka kami menghapus pernyataan cetak, karena kami tidak akan pernah mencapainya. Jika M tidak berjalan selamanya, maka kita perlu menjaga pernyataan cetak. Jadi, jika kita memiliki penghapus kode mati, itu juga memungkinkan kita menyelesaikan Masalah Pemutusan, jadi kita tahu tidak akan ada penghapus kode mati semacam itu.
Cara kita menyiasatinya adalah dengan "perkiraan konservatif." Jadi, dalam contoh Mesin Turing saya di atas, kita dapat mengasumsikan bahwa menjalankan M pada x mungkin selesai, jadi kami memainkannya dengan aman dan tidak menghapus pernyataan cetak. Dalam contoh Anda, kami tahu bahwa apa pun fungsi yang dilakukan atau tidak dihentikan, tidak mungkin kami akan mencapai pernyataan cetak itu.
Biasanya, ini dilakukan dengan membangun "grafik aliran kendali". Kami membuat asumsi yang disederhanakan, seperti "akhir putaran sementara terhubung ke awal dan pernyataan setelah", bahkan jika itu berjalan selamanya atau hanya berjalan sekali dan tidak mengunjungi keduanya. Demikian pula, kami mengasumsikan bahwa pernyataan if dapat mencapai semua cabangnya, bahkan jika pada kenyataannya beberapa tidak pernah digunakan. Jenis penyederhanaan ini memungkinkan kami untuk menghapus "kode mati jelas" seperti contoh yang Anda berikan, namun tetap dapat diperhitungkan.
Untuk mengklarifikasi beberapa kebingungan dari komentar:
Nitpick: untuk fixed M, ini selalu decidable. M harus menjadi input
Seperti yang dikatakan Raphael, dalam contoh saya, kami menganggap Mesin Turing sebagai input. Idenya adalah bahwa, jika kita memiliki algoritma DCE yang sempurna, kita akan dapat membuat cuplikan kode yang saya berikan untuk Mesin Turing apa pun , dan memiliki DCE akan menyelesaikan masalah penghentian.
tidak meyakinkan. kembali sebagai pernyataan tumpul dalam eksekusi tanpa cabang langsung tidak sulit untuk diputuskan. (dan kompiler saya memberitahu saya ia mampu mencari tahu ini)
Untuk masalah njzk2 memunculkan: Anda benar sekali, dalam hal ini Anda dapat menentukan bahwa tidak ada cara pernyataan setelah pengembalian dapat dicapai. Ini karena cukup sederhana sehingga kita dapat menggambarkan ketidakterjangkauannya dengan menggunakan batasan grafik aliran-kontrol (yaitu tidak ada tepi keluar dari pernyataan kembali). Tetapi tidak ada eliminator kode mati yang sempurna, yang menghilangkan semua kode yang tidak digunakan.
Saya tidak mengambil bukti yang bergantung pada input untuk bukti. Jika ada semacam input pengguna yang dapat memungkinkan kode menjadi terbatas, benar bagi kompilator untuk menganggap bahwa cabang berikut ini tidak mati. Saya tidak bisa melihat untuk apa semua upvotes ini, itu jelas (mis. Stdin tak berujung) dan salah.
Untuk TomášZato: ini bukan bukti yang bergantung pada input. Sebaliknya, tafsirkan sebagai "forall". Ini berfungsi sebagai berikut: anggap kita memiliki algoritma DCE yang sempurna. Jika Anda memberi saya Turing Machine M acak dan input x, saya dapat menggunakan algoritma DCE untuk menentukan apakah M berhenti, dengan membuat cuplikan kode di atas dan melihat apakah pernyataan cetak dihapus. Teknik ini, meninggalkan parameter sewenang-wenang untuk membuktikan pernyataan forall, adalah umum dalam matematika dan logika.
Saya tidak sepenuhnya mengerti poin TomášZato tentang kode menjadi terbatas. Tentunya kode ini terbatas, tetapi algoritma DCE yang sempurna harus berlaku untuk semua kode, yang merupakan kumpulan infinte. Demikian juga, sementara kode itu sendiri terbatas, set input potensial tidak lengkap, seperti potensi waktu berjalan dari kode.
Mengenai mempertimbangkan cabang terakhir yang tidak mati: aman dalam hal "perkiraan konservatif" yang saya bicarakan, tetapi tidak cukup untuk mendeteksi semua contoh kode mati seperti yang diminta OP.
Pertimbangkan kode seperti ini:
while (true)
print "Hello"
print "goodbye"
Jelas kami dapat menghapus print "goodbye"
tanpa mengubah perilaku program. Jadi, itu adalah kode mati. Tetapi jika ada pemanggilan fungsi yang berbeda alih-alih (true)
dalam while
kondisi, maka kita tidak tahu apakah kita dapat menghapusnya atau tidak, yang mengarah pada ketidakpastian.
Perhatikan bahwa saya tidak membuat ini sendirian. Ini adalah hasil yang terkenal dalam teori kompiler. Ini dibahas dalam The Tiger Book . (Anda mungkin dapat melihat di mana mereka berbicara di dalam buku Google .