Program bebas bug secara teoritis

12

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)?

pengguna2443423
sumber
10
Saya cukup yakin program python ini melakukan semua yang dimaksudkan untuk dilakukan dan tidak lebih: print "Hello, World!"... bisakah Anda menjadi lebih jelas?
durron597
2
@ durron597: Apakah ada pasar untuk perangkat lunak seperti itu? Halo printer dunia, versi yang dimuat ulang? Sekarang dengan lebih banyak hello dan lebih banyak dunia?
JensG
1
@ Phoshi faugh. Cukup mungkin untuk menulis program yang cukup sederhana (misalnya, dengan menggunakan kabel pada papan tempat memotong roti) bahwa Anda dapat melihat seluruh ruang lingkup proses sekaligus yang tidak memiliki bug. Anda menyerang detail komentar saya tanpa membahas poin utama saya, yaitu memungkinkan untuk menulis program yang sangat sederhana yang tidak memiliki bug.
durron597
2
@ Phoshi "Buktikan interpreter python Anda tidak memiliki bug." Bug dalam implementasi python tidak membuat program salah. Program ini benar jika melakukan apa yang seharusnya diberikan bahwa implementasi Python sesuai dengan spesifikasi bahasa. Bukti apa pun mengambil beberapa hal sebagai aksioma - Anda harus, misalnya, harus berasumsi bahwa alam semesta akan terus ada di seluruh pelaksanaan program. Jika CPython memiliki bug, hasilnya mungkin salah, tetapi kesalahan itu tidak ada dalam program.
Doval
11
Tidak satu pun dari teorema ini yang ada hubungannya dengan bug atau keberadaan program bebas bug. Mereka adalah teorema tentang pertanyaan apa yang dapat dijawab dengan perhitungan. Teorema ini menunjukkan bahwa ada beberapa masalah yang tidak dapat dihitung, dan beberapa proposisi matematika yang tidak dapat dibuktikan atau disangkal, tetapi mereka tentu saja tidak mengatakan bahwa semua program memiliki bug atau bahwa program tertentu tidak dapat dibuktikan benar.
Charles E. Grant

Jawaban:

18

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:

int add(int a, int b) { return a + b; }

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

LaunchMissiles();

sebagai gantinya?

Oke, mungkin itu sedikit dibikin. Tetapi bahkan fungsi sederhana seperti addfungsi 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

Robert Harvey
sumber
6
Pertimbangkan fungsi yang benar-benar mengetik: int add(int a, int b) { return a - b; }...
Donal Fellows
@DonalFellows: Justru itulah alasan saya memasukkan tautan tentang Ariane 5.
Robert Harvey
2
@DonalFellows - Karakterisasi matematika tidak menyelesaikan masalah, itu hanya memindahkannya ke tempat lain. Bagaimana Anda membuktikan bahwa model matematika benar-benar mewakili kebutuhan klien?
mouviciel
1
@ JohnGaughan Itu mengasumsikan saling ketergantungan antara modul. Modul yang diberikan telah terbukti benar dan terbukti independen satu sama lain, Anda dapat menyusunnya secara rekursif menjadi modul yang lebih besar yang juga dikenal benar dan independen tanpa batas.
Doval
1
@JohnGaughan Jika integrasi modul menyebabkan bug maka Anda gagal membuktikan bahwa mereka independen. Membangun bukti baru dari bukti yang ada tidak lebih sulit daripada membangun bukti dari aksioma. Jika matematika menjadi lebih sulit secara eksponensial seperti itu, matematikawan akan kacau. Anda dapat memiliki bug di skrip bangunan Anda, tetapi itu adalah program yang terpisah. Tidak ada elemen misteri yang salah ketika Anda mencoba menyusun sesuatu, tetapi tergantung pada jumlah efek sampingnya, sulit untuk membuktikan bahwa tidak ada keadaan bersama.
Doval
12

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 telah membaca banyak artikel yang menyatakan bahwa kode tidak boleh bebas bug

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.

Apakah ini menyiratkan bahwa setiap program akan memiliki setidaknya satu perilaku yang tidak diinginkan?

Tidak. Meskipun sebagian besar aplikasi telah ditemukan memiliki setidaknya satu bug atau perilaku yang tidak diinginkan.

Atau apakah itu berarti tidak mungkin menulis kode untuk memverifikasinya?

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.

Bagaimana dengan pengecekan rekursif?

Saya tidak tahu Saya tidak terbiasa dengan itu, dan saya tidak yakin apakah itu masalah komputabilitas atau masalah optimisasi kompiler.

mctylr
sumber
1
+1 untuk menjadi yang pertama berbicara tentang spesifikasi formal dan asisten bukti. Ini adalah poin penting, yang tidak ada dalam jawaban sebelumnya.
Arseni Mourzenko
6

Saya ingin bertanya, apakah ini menyiratkan bahwa setiap kode akan mendapatkan setidaknya satu perilaku yang tidak diinginkan?

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>) .

Atau, apakah itu berarti saya tidak dapat menulis kode, yang akan memeriksanya?

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")dan exit, 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.

Thiago Silva
sumber
4

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:

  • Hanya ada satu spesifikasi.
  • sistem pemungutan suara itu unik atau kompleks.
mouviciel
sumber
5
Saya percaya NASA atau program luar angkasa lainnya telah menyarankan bahwa varian-N menderita masalah yang terlalu sering dipikirkan oleh para programmer dan dengan demikian berakhir secara independen menulis program-program yang hampir sama dengan kelemahan umum ketika cacat tersebut berada di luar tingkat yang paling sepele. Misalnya, merujuk pada informasi referensi yang sama (lihat bug lama dalam pencarian biner ), cenderung menggunakan algoritma yang sama, dan membuat kesalahan yang sama.
mctylr
@ mctylr - Ini poin yang sangat bagus. Tetapi sebenarnya, sampai saat ini, tidak ada cukup ruang dalam memori untuk menyimpan lebih dari satu varian perangkat lunak pada pesawat ruang angkasa. Jawaban mereka adalah tes, tes, tes, bilas, ulangi.
mouviciel
Program pesawat ulang-alik menggunakan tiga konfigurasi sistem pemilihan independen. Setiap perbedaan pendapat berarti (atau, benar-benar, disarankan) bahwa sistem tidak lagi benar, dan diambil offline.
4

Suatu program memiliki beberapa spesifikasi dan berjalan di beberapa lingkungan.

(contoh sinar kosmik pada orang lain jawaban berubah adduntuk FireMissiles 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.

Basile Starynkevitch
sumber
Mungkin contoh yang lebih baik dari SEU mengubah panggilan untuk Addke LaunchMissilesakan menjadi SEU mengubah beberapa nilai data yang akhirnya menghasilkan panggilan salah untuk LaunchMissiles. 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.
David Hammen
3

Apakah ini menyiratkan bahwa setiap program akan memiliki setidaknya satu perilaku yang tidak diinginkan?

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-alih a+b. Mereka menganalisis program dalam konteks mesin abstrak daripada mesin nyata yang tunduk pada gangguan peristiwa tunggal seperti sinar kosmik Robert Harvey.

David Hammen
sumber
1

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.

Jules
sumber
0

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.

Thomas Carlisle
sumber
-2

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.

Holmes
sumber
posting ini agak sulit dibaca (dinding teks). Maukah Anda mengeditnya menjadi bentuk yang lebih baik?
nyamuk