Saya sudah pemrograman selama beberapa tahun, tetapi saya sangat tidak terbiasa dengan CS teoritis. Saya baru-baru ini mencoba mempelajari bahasa pemrograman, dan sebagai bagian dari itu, ketik pengecekan dan inferensi.
Pertanyaan saya adalah, jika saya mencoba menulis inferensi jenis dan memeriksa program untuk bahasa pemrograman, dan saya ingin membuktikan bahwa typechecker saya berfungsi, apa sebenarnya bukti yang saya cari?
Dalam bahasa sederhana, saya ingin pemeriksa tipe saya dapat mengidentifikasi kesalahan dalam sepotong kode yang mungkin terjadi saat runtime. Jika saya menggunakan sesuatu seperti Coq untuk mencoba membuktikan bahwa implementasi saya benar, apa yang sebenarnya akan "ditunjukkan oleh bukti kebenaran" ini?
coq
type-inference
proof-assistants
Vivek Ghaisas
sumber
sumber
2 + "hello"
itu 'macet'). Setelah ini diformalkan, Anda kemudian dapat membuktikan teorema jenis kesehatan. Itu berarti bahwa tidak ada program yang dapat diketik yang dapat berkembang menjadi kesalahan ketik langsung. Secara formal, Anda membuktikan bahwa jika suatu program dapat diketik, dan untuk setiap n ≥ : jika M menjalankan n langkah untuk menjadi N , maka N tidak memiliki kesalahan ketik langsung. (1/2)Jawaban:
Pertanyaannya dapat ditafsirkan dalam dua cara:
Yang pertama sebenarnya adalah pertanyaan dalam verifikasi program dan tidak ada hubungannya dengan pengetikan. Hanya perlu menunjukkan bahwa implementasi Anda memenuhi spesifikasinya, lihat jawaban Andrej.
Biarkan saya berbicara tentang pertanyaan selanjutnya. Seperti yang dikatakan Andrej, dari sudut pandang abstrak, sistem pengetikan tampaknya memberlakukan properti pada program. Dalam praktiknya, sistem pengetikan Anda berupaya mencegah terjadinya kesalahan, yang berarti bahwa program yang diketikkan tidak boleh menunjukkan kelas kesalahan yang diminati. Untuk menunjukkan bahwa T melakukan apa yang menurut Anda seharusnya, Anda harus melakukan dua hal.T T
Pertama, Anda menetapkan secara formal apa artinya bagi program untuk memiliki kesalahan pengetikan segera . Ada banyak cara ini dapat didefinisikan - terserah Anda. Biasanya kami ingin mencegah program seperti
2 + "hello"
. Dengan kata lain, Anda perlu mendefinisikan subset program, menyebutnya Buruk , yang berisi persis program dengan kesalahan pengetikan langsung.Cara membuktikan teorema ini bergantung pada perincian bahasa, sistem pengetikan, dan pilihan Anda yang Buruk .
Perhatikan bahwa tidak semua sistem pengetikan memiliki "pengurangan subjek", misalnya jenis sesi. Dalam hal ini, teknik bukti yang lebih canggih diperlukan.
sumber
Itu pertanyaan yang bagus! Itu menanyakan apa yang kita harapkan dari mengetik dalam bahasa yang diketik.
Catatan pertama bahwa kita dapat mengetikkan bahasa pemrograman apa pun dengan unitype : cukup pilih satu huruf, ucapkan
U
, dan katakan bahwa setiap program memiliki tipeU
. Ini tidak terlalu berguna, tetapi itu benar.int
Tidak ada akhir dari seberapa ekspresif tipe Anda. Pada prinsipnya mereka bisa berupa pernyataan logis apa saja, mereka bisa menggunakan teori kategori dan yang lainnya, dll. Sebagai contoh, tipe dependen akan membiarkan Anda mengekspresikan hal-hal seperti "fungsi ini memetakan daftar ke daftar sehingga outputnya adalah input yang diurutkan". Anda dapat melangkah lebih jauh, saat ini saya sedang mendengarkan ceramah tentang "logika pemisahan bersamaan" yang memungkinkan Anda untuk berbicara tentang bagaimana program bersamaan bekerja dengan keadaan bersama. Barang mewah.
Seni mengetik dalam desain bahasa pemrograman adalah salah satu penyeimbangan antara ekspresif dan kesederhanaan :
Kesederhanaan tidak dapat diremehkan, karena tidak setiap programmer memiliki gelar PhD dalam teori bahasa pemrograman.
Jadi, mari kita kembali ke pertanyaan Anda: bagaimana Anda tahu bahwa sistem tipe Anda baik ? Nah, buktikan teorema yang menunjukkan tipe Anda menjadi seimbang. Akan ada dua jenis teorema:
Teorema yang mengatakan bahwa tipe Anda berguna . Mengetahui bahwa suatu program memiliki tipe harus menyiratkan beberapa jaminan, misalnya bahwa program tersebut tidak akan macet (itu akan menjadi teorema Keselamatan ). Keluarga teorema lain akan menghubungkan tipe-tipe tersebut ke model semantik sehingga kita dapat mulai menggunakan matematika nyata untuk membuktikan hal-hal tentang program kita (itu akan menjadi teorema Kecukupan , dan banyak lainnya). Unitype di atas buruk karena tidak memiliki teorema yang berguna.
Teorema yang mengatakan bahwa tipe Anda sederhana . Yang mendasar adalah dapat diputuskan apakah ekspresi yang diberikan memiliki tipe tertentu. Fitur kesederhanaan lainnya adalah memberikan algoritma untuk menyimpulkan suatu tipe. Teorema lain tentang kesederhanaan adalah: bahwa suatu ekspresi memiliki paling banyak satu jenis, atau bahwa suatu ekspresi memiliki jenis utama (yaitu, yang "terbaik" di antara semua jenis yang dimilikinya).
Sulit untuk lebih spesifik karena jenis adalah mekanisme yang sangat umum. Tapi saya harap Anda tahu untuk apa Anda menembak. Seperti kebanyakan aspek desain bahasa pemrograman, tidak ada ukuran keberhasilan mutlak. Sebaliknya, ada ruang kemungkinan desain, dan yang penting adalah memahami di mana di ruang Anda berada, atau ingin berada.
sumber
Ada beberapa hal berbeda yang bisa Anda maksud dengan "buktikan bahwa typechecker saya berfungsi". Yang, saya kira, adalah bagian dari pertanyaan Anda;)
Separuh dari pertanyaan ini membuktikan bahwa teori tipe Anda cukup baik untuk membuktikan sifat apa pun tentang bahasa tersebut. Jawaban Andrej menangani masalah ini dengan sangat baik. Bagian lain dari pertanyaannya adalah — mengasumsikan bahasa dan sistem tipenya sudah diperbaiki — bagaimana Anda bisa membuktikan bahwa pemeriksa tipe Anda sebenarnya mengimplementasikan sistem tipe dengan benar? Ada dua perspektif utama yang bisa saya lihat di sini.
Salah satunya adalah: bagaimana kita bisa percaya bahwa beberapa implementasi tertentu sesuai dengan spesifikasinya? Tergantung pada tingkat jaminan yang Anda inginkan, Anda mungkin senang dengan rangkaian uji yang besar, atau Anda mungkin menginginkan semacam verifikasi formal, atau lebih mungkin gabungan keduanya . Sisi positif dari perspektif ini adalah bahwa itu benar-benar menyoroti pentingnya menetapkan batasan pada klaim yang Anda buat: apa sebenarnya arti "benar"? bagian mana dari kode yang diperiksa, vs bagian mana yang dianggap benar-benar TCB? dll. Kelemahannya adalah bahwa berpikir terlalu keras tentang hal ini akan menyebabkan lubang kelinci filosofis turun - well, "downside" jika Anda tidak menikmati lubang kelinci itu.
Perspektif kedua adalah pandangan yang lebih matematis tentang kebenaran. Ketika berhadapan dengan bahasa dalam matematika, kita sering membuat "model" untuk "teori" kita (atau sebaliknya) dan kemudian mencoba membuktikan: (a) semua yang dapat kita lakukan dalam teori yang dapat kita lakukan dalam model, dan (b) semua yang dapat kita lakukan dalam model dapat kita lakukan dalam teori. (Ini adalah Kesehatan dan Kelengkapanteorema. Yang mana yang tergantung pada apakah Anda "memulai" dari teori sintaksis atau dari model semantik.) Dengan pola pikir ini kita dapat menganggap implementasi pemeriksaan tipe Anda sebagai model tertentu untuk teori tipe yang dimaksud. Jadi, Anda ingin membuktikan korespondensi dua arah ini antara apa yang bisa dilakukan oleh implementasi Anda dan apa yang menurut teori Anda harus bisa lakukan. Sisi positif dari perspektif ini adalah bahwa itu benar-benar berfokus pada apakah Anda telah membahas semua kasus sudut, apakah implementasi Anda lengkap dalam arti tidak meninggalkan program apa pun yang seharusnya diterima sebagai jenis-aman, dan apakah implementasi Anda masuk akal rasa tidak membiarkan dalam program apa pun ia harus menolak sebagai salah ketik. Kelemahannya adalah bukti korespondensi Anda cenderung terpisah dari implementasinya sendiri,
sumber