Saya telah membaca banyak artikel yang menyatakan bahwa kode tidak dapat bebas bug, dan mereka berbicara tentang teorema ini:
Sebenarnya teorema Rice tampak seperti implikasi dari masalah penghentian dan masalah penghentian berhubungan erat dengan teorema ketidaklengkapan Gödel.
Apakah ini menyiratkan bahwa setiap program akan memiliki setidaknya satu perilaku yang tidak diinginkan? Atau apakah itu berarti tidak mungkin menulis kode untuk memverifikasinya? Bagaimana dengan pengecekan rekursif? Mari kita asumsikan bahwa saya memiliki dua program. Keduanya memiliki bug, tetapi mereka tidak berbagi bug yang sama. Apa yang akan terjadi jika saya menjalankannya secara bersamaan?
Dan tentu saja sebagian besar diskusi berbicara tentang mesin Turing. Bagaimana dengan otomatisasi linear-bounded (komputer nyata)?
print "Hello, World!"
... bisakah Anda menjadi lebih jelas?Jawaban:
Ini tidak terlalu banyak sehingga program tidak bisa bebas bug; itu sangat sulit untuk membuktikannya, jika program yang Anda coba buktikan tidak sepele.
Bukan karena kurang berusaha, ingatlah. Sistem tipe seharusnya memberikan jaminan; Haskell memiliki sistem tipe yang sangat canggih yang melakukan ini, sampai taraf tertentu. Tetapi Anda tidak pernah bisa menghapus semua ketidakpastian.
Pertimbangkan fungsi berikut:
Apa yang salah dengan fungsi ini? Saya sudah tahu apa yang Anda pikirkan. Katakanlah kita telah membahas semua basis, seperti memeriksa luapan, dll. Apa yang terjadi jika sinar kosmik menyerang prosesor, menyebabkannya dieksekusi
sebagai gantinya?
Oke, mungkin itu sedikit dibikin. Tetapi bahkan fungsi sederhana seperti
add
fungsi di atas harus beroperasi di lingkungan di mana prosesor terus mengubah konteks, beralih di antara beberapa utas dan inti. Dalam lingkungan seperti itu, apa pun bisa terjadi. Jika Anda meragukan ini, maka pertimbangkan bahwa RAM dapat diandalkan, bukan karena itu bebas dari kesalahan, tetapi karena ia memiliki sistem bawaan untuk memperbaiki kesalahan bit yang pasti terjadi.Saya tahu apa yang Anda pikirkan. "Tapi saya berbicara tentang perangkat lunak, bukan perangkat keras."
Ada banyak teknik yang dapat meningkatkan tingkat kepercayaan Anda bahwa perangkat lunak bekerja sebagaimana mestinya. Pemrograman fungsional adalah salah satunya. Pemrograman fungsional memungkinkan Anda untuk alasan konkurensi yang lebih baik. Tapi pemrograman fungsional bukan bukti, tidak lebih dari tes unit.
Mengapa? Karena Anda memiliki hal-hal ini yang disebut tepi kasus.
Dan sekali Anda hanya mendapatkan sedikit di luar kesederhanaan
return a + b
, menjadi sangat sulit untuk membuktikan kebenaran program.Bacaan Lebih Lanjut
Mereka Menulis Hal yang Benar
Ledakan Ariane 5
sumber
int add(int a, int b) { return a - b; }
...Pertama, mari kita tentukan konteks apa yang ingin Anda bahas di sini. Tanya Jawab Programer di Stack Exchange menunjukkan bahwa Anda kemungkinan besar tertarik pada keberadaan dunia nyata dari alat / bahasa daripada hasil teoretis dan teorema Ilmu Komputer .
Saya harap tidak, karena pernyataan seperti itu salah. Meskipun secara umum diterima bahwa sebagian besar aplikasi skala besar tidak bebas dari bug sejauh pengetahuan dan pengalaman saya.
Yang lebih umum diterima adalah bahwa tidak ada (yaitu keberadaan, bukan kemungkinan) alat yang secara sempurna menentukan apakah suatu program yang ditulis dalam bahasa pemrograman Turing-complete sepenuhnya bebas bug.
Non-proof adalah ekstensi intuitif dari Halting Problem, dikombinasikan dengan data pengamatan dari pengalaman sehari-hari.
Ada tidak software yang ada yang dapat melakukan "bukti dari kebenaran " yang memverifikasi bahwa program memenuhi sesuai resmi spesifikasi untuk program tersebut.
Tidak. Meskipun sebagian besar aplikasi telah ditemukan memiliki setidaknya satu bug atau perilaku yang tidak diinginkan.
Tidak, Anda dapat menggunakan spesifikasi formal dan asisten bukti untuk memverifikasi mengikuti spesifikasi , tetapi karena pengalaman telah menunjukkan kesalahan masih ada di keseluruhan sistem, seperti faktor di luar spesifikasi - penerjemah kode sumber & perangkat keras, dan kesalahan yang paling sering terjadi dalam spesifikasi sendiri.
Untuk detail lebih banyak darah, lihat Coq adalah alat / bahasa / sistem seperti itu.
Saya tidak tahu Saya tidak terbiasa dengan itu, dan saya tidak yakin apakah itu masalah komputabilitas atau masalah optimisasi kompiler.
sumber
Tidak. Program yang benar dapat ditulis dan ditulis. Pikiran Anda, sebuah program bisa benar, tetapi eksekusi itu mungkin gagal karena, misalnya, keadaan fisik (seperti yang ditulis pengguna Robert Harvey dalam jawabannya di sini ), tetapi ini adalah masalah yang berbeda: kode program itu masih benar. Lebih tepatnya, kegagalan itu bukan disebabkan oleh kesalahan atau kesalahan dalam program itu sendiri, tetapi pada mesin yang mendasari yang mengeksekusinya (*).
(*) Saya meminjam definisi untuk kesalahan , kesalahan dan kegagalan dari bidang dependabilitas, masing-masing, cacat statis, keadaan internal yang salah, dan perilaku eksternal yang diamati salah sesuai spesifikasinya (lihat <makalah apa pun dari bidang itu>) .
Lihat kasus umum dalam pernyataan di atas dan Anda benar.
Anda mungkin dapat menulis program yang memeriksa apakah program X tertentu benar. Misalnya, jika Anda mendefinisikan program "hello world" sebagai satu dengan dua instruksi secara berurutan, yaitu
print("hello world")
danexit
, Anda dapat menulis sebuah program yang memeriksa apakah inputnya adalah program yang terdiri dari dua instruksi ini secara berurutan, sehingga melaporkan apakah itu adalah program "halo dunia" yang benar atau tidak.Apa yang tidak dapat Anda lakukan dengan menggunakan formulasi saat ini adalah menulis sebuah program untuk memeriksa apakah ada program yang arbitrer berhenti, yang menyiratkan ketidakmungkinan pengujian untuk kebenaran dalam kasus-kasus umum.
sumber
Menjalankan dua atau lebih varian dari program yang sama adalah teknik toleransi kesalahan yang terkenal yang disebut pemrograman varian-N (atau versi-N). Ini merupakan pengakuan atas keberadaan bug dalam perangkat lunak.
Biasanya varian ini dikodekan oleh tim pengembangan yang berbeda, menggunakan kompiler yang berbeda, dan kadang-kadang dieksekusi pada CPU yang berbeda dengan OS yang berbeda. Hasil dipilih sebelum di-output kepada pengguna. Boeing dan Airbus menyukai arsitektur semacam ini.
Masih ada dua tautan lemah, yang mengarah ke bug mode umum:
sumber
Suatu program memiliki beberapa spesifikasi dan berjalan di beberapa lingkungan.
(contoh sinar kosmik pada orang lain jawaban berubah
add
untukFireMissiles
bisa dianggap bagian dari "lingkungan")Dengan asumsi Anda dapat secara formal menentukan perilaku yang dimaksud program (yaitu spesifikasinya) dan lingkungannya, Anda kadang - kadang dapat membuktikan secara formal bahwa program tersebut adalah - dalam arti bebas bug - tepat (sehingga perilaku atau outputnya menghormati formalisasi spesifikasinya dalam formalisasi. lingkungannya).
Secara khusus, Anda dapat menggunakan penganalisa sumber statis suara, seperti misalnya Frama-C .
(tetapi keadaan terkini dari analisa semacam itu tidak mengizinkan seluruh analisis program & bukti program skala besar seperti kompiler GCC atau browser Firefox atau kernel Linux; dan saya percaya bahwa bukti-bukti seperti itu tidak akan terjadi dalam hidup saya. Saya lahir pada tahun 1959)
Namun, apa yang telah Anda buktikan adalah perilaku yang benar dari program wrt beberapa spesifikasi tertentu di beberapa (kelas) lingkungan.
Secara praktis, Anda dapat (dan NASA atau ESA mungkin ingin) membuktikan bahwa beberapa perangkat lunak pesawat ruang angkasa "bebas bug" dengan beberapa spesifikasi yang tepat - dan diformalkan -. Tetapi itu tidak berarti bahwa sistem Anda akan selalu berperilaku seperti yang Anda inginkan.
Dengan kata sederhana, jika robot pesawat ruang angkasa Anda memenuhi beberapa ET dan Anda belum menentukan itu, tidak ada cara untuk memiliki robot Anda berperilaku seperti yang Anda inginkan ....
Baca juga entri blog J.Pitrat .
BTW, Menghentikan masalah atau teorema Gödel mungkin berlaku juga untuk otak manusia, atau bahkan spesies manusia.
sumber
Add
keLaunchMissiles
akan menjadi SEU mengubah beberapa nilai data yang akhirnya menghasilkan panggilan salah untukLaunchMissiles
. SEU adalah masalah dengan komputer yang masuk ke ruang angkasa. Inilah sebabnya mengapa pesawat ruang angkasa modern seringkali menerbangkan banyak komputer. Ini menambah satu set masalah baru, konkurensi dan manajemen redundansi.Tidak.
Masalah penghentian mengatakan bahwa tidak mungkin untuk menulis sebuah program yang menguji apakah setiap program berhenti dalam jumlah waktu yang terbatas. Ini tidak berarti bahwa tidak mungkin untuk menulis suatu program yang dapat mengkategorikan beberapa program sebagai penghentian, beberapa yang lain sebagai penghentian. Maksudnya adalah selalu ada beberapa program yang tidak dapat dikategorikan oleh analis penganalisa yang terhenti.
Teorema ketidaklengkapan Gödel memiliki area abu-abu yang serupa dengan mereka. Dengan adanya sistem matematika dengan kompleksitas yang cukup, akan ada beberapa pernyataan yang dibuat dalam konteks sistem yang kebenarannya tidak dapat dinilai. Ini tidak berarti matematikawan harus menyerah pada gagasan pembuktian. Bukti tetap menjadi landasan matematika.
Beberapa program dapat dibuktikan benar. Itu tidak mudah, tetapi bisa dilakukan. Itulah tujuan pembuktian teorema formal (bagian dari metode formal). Teorema ketidaklengkapan Gödel menyerang di sini: Tidak semua program dapat dibuktikan benar. Itu tidak berarti sia-sia menggunakan metode formal karena beberapa program memang dapat dibuktikan secara formal benar.
Catatan: Metode formal mencegah kemungkinan sinar kosmik menyerang prosesor dan menjalankan
launch_missiles()
alih-aliha+b
. Mereka menganalisis program dalam konteks mesin abstrak daripada mesin nyata yang tunduk pada gangguan peristiwa tunggal seperti sinar kosmik Robert Harvey.sumber
Ada banyak jawaban bagus di sini, tetapi mereka semua tampaknya mengitari titik kritis, yaitu ini: semua teorema tersebut memiliki struktur yang sama dan mengatakan hal yang sama, dan apa yang mereka katakan bukan "mustahil untuk menulis dengan benar program"(untuk beberapa nilai tertentu dari 'benar' dan 'program' yang bervariasi dalam kasus ke kasus), tapi apa yang mereka lakukan katakanlah adalah 'tidak mungkin untuk mencegah seseorang menulis sebuah program yang salah bahwa kita tidak dapat membuktikan tidak benar' ( dll).
Mengambil contoh spesifik dari masalah penghentian, perbedaannya menjadi lebih jelas: jelas ada program yang terbukti berhenti, dan program lain yang terbukti tidak pernah berhenti. Bahwa ada kelas ketiga dari program yang perilakunya tidak dapat ditentukan dengan cara apa pun bukanlah suatu masalah jika yang ingin kita lakukan hanyalah menulis program yang dapat dihentikan, karena kita hanya dapat menghindari menulis program yang termasuk dalam kelas itu.
Hal yang sama berlaku dengan teorema Rice. Ya, untuk properti non-sepele dari suatu program kami dapat menulis sebuah program yang tidak dapat membuktikan bahwa properti itu benar atau salah; kita juga dapat menghindari penulisan program seperti itu karena kita dapat menentukan apakah suatu program dapat dibuktikan.
sumber
Jawaban saya akan dari perspektif bisnis dunia nyata dan tantangan yang dihadapi oleh setiap tim pengembangan. Apa yang saya lihat dalam pertanyaan ini dan banyak jawaban sebenarnya tentang mengendalikan cacat.
Kode dapat bebas bug. Ambil contoh kode "Hello World" untuk bahasa pemrograman apa pun, dan jalankan di platform yang dimaksudkan dan itu akan bekerja secara konsisten dan menghasilkan hasil yang diinginkan. Akhirnya ada teori tentang ketidakmungkinan kode bebas bug.
Potensi bug masuk sebagai logika menjadi lebih kompleks. Contoh Hello World yang sederhana tidak memiliki logika dan melakukan hal statis yang sama setiap kali. Segera setelah Anda menambahkan perilaku dinamis yang digerakkan oleh logika adalah apa yang memperkenalkan kompleksitas yang mengarah pada bug. Logikanya sendiri dapat cacat, atau data yang dimasukkan ke logika dapat bervariasi dengan cara yang tidak ditangani oleh logika.
Aplikasi modern juga tergantung pada run-time libraries, CLR, middleware, database, dll. Lapisan yang sekaligus menghemat waktu pengembangan secara keseluruhan, juga merupakan lapisan di mana bug di dalam lapisan tersebut dapat ada dan tidak terdeteksi melalui pengembangan & pengujian UAT dan dalam produksi.
Terakhir, rangkaian aplikasi / sistem yang aplikasi gunakan data yang mengumpankan logikanya adalah semua sumber bug potensial baik di dalam logikanya, atau di dalam perangkat lunak yang menumpukan tumpangan logika di atasnya, atau sistem hulu tempat ia mengonsumsi data.
Pengembang tidak dalam kendali 100% dari setiap bagian bergerak yang mendukung logika aplikasi mereka. Sebenarnya, kita tidak bisa mengendalikan banyak hal. Itulah sebabnya pengujian unit penting, dan konfigurasi serta manajemen perubahan adalah proses penting yang tidak boleh kita abaikan atau malas / ceroboh.
Juga, perjanjian yang terdokumentasi antara aplikasi Anda yang mengkonsumsi data dari sumber di luar kendali Anda, yang menentukan format dan spesifikasi spesifik untuk data yang ditransfer, serta batas atau kendala yang dianggap oleh sistem Anda bahwa sistem sumber bertanggung jawab untuk memastikan keluaran berada di dalam batas-batas itu.
Dalam aplikasi dunia nyata dari rekayasa perangkat lunak Anda tidak akan dapat membuatnya terbang dengan menjelaskan kepada bisnis mengapa aplikasi secara teoritis tidak dapat bebas bug. Diskusi tentang sifat antara teknologi dan bisnis ini tidak akan pernah terjadi kecuali setelah kegagalan teknologi yang berdampak pada kemampuan bisnis untuk menghasilkan uang, mencegah kehilangan uang, dan / atau membuat orang tetap hidup. Jawaban untuk "bagaimana ini bisa terjadi" tidak dapat "biarkan saya menjelaskan teori ini sehingga Anda mengerti."
Dalam hal perhitungan besar-besaran yang secara teoritis bisa memakan waktu lama untuk melakukan perhitungan dan mendapatkan hasil, aplikasi yang tidak dapat selesai dan kembali dengan hasil - itu adalah bug. Jika sifat perhitungannya sedemikian sehingga sangat memakan waktu dan intensif komputasi, Anda menerima permintaan itu dan memberikan umpan balik kepada pengguna bagaimana / kapan mereka dapat mengambil hasilnya, dan memulai benang paralel untuk mengaduknya. Jika ini perlu terjadi lebih cepat daripada yang dapat dilakukan pada satu server, dan bisnis cukup penting, maka Anda skala di banyak sistem yang diperlukan. Inilah sebabnya mengapa cloud sangat menarik, dan kemampuan untuk memintal node untuk bekerja dan menurunkannya saat selesai.
Jika ada kemungkinan untuk mendapatkan permintaan yang tidak dapat diselesaikan oleh jumlah daya komputasi, itu tidak boleh berjalan di sana berjalan hingga tak terbatas dengan proses bisnis menunggu jawaban atas apa yang dianggap bisnis sebagai masalah yang terbatas.
sumber
Saya tidak percaya kode 100% bebas bug karena kode tidak pernah benar-benar selesai. Anda selalu dapat meningkatkan apa yang Anda tulis.
Pemrograman adalah bidang sains dan matematika yang keduanya tidak ada habisnya. Hal yang hebat tentang menjadi seorang pengembang adalah pekerjaan kita tidak ada habisnya.
Ada ribuan cara plus untuk menulis satu baris kode. Idenya adalah menulis versi baris kode yang paling dioptimalkan tetapi itu mungkin tidak bebas bug. Bug bebas mengacu pada gagasan bahwa kode Anda tidak dapat dipecahkan dan semua kode dapat dipecah dalam tingkat atau metode tertentu.
Jadi bisakah kode menjadi efisien? Iya.
Bisakah kode dioptimalkan tanpa henti? Iya.
Bisakah kode bebas bug? Tidak, Anda hanya belum menemukan cara untuk memecahkannya.
Yang sedang berkata, jika Anda berusaha untuk memperbaiki diri Anda dan praktik penulisan kode Anda, kode Anda akan sulit untuk dilanggar.
sumber