Saya menemukan Curry-Howard Isomorphism relatif terlambat dalam kehidupan pemrograman saya, dan mungkin ini berkontribusi pada saya yang benar-benar terpesona olehnya. Ini menyiratkan bahwa untuk setiap konsep pemrograman terdapat analog yang tepat dalam logika formal, dan sebaliknya. Berikut adalah daftar "dasar" dari analogi semacam itu, di luar kepala saya:
program/definition | proof
type/declaration | proposition
inhabited type | theorem/lemma
function | implication
function argument | hypothesis/antecedent
function result | conclusion/consequent
function application | modus ponens
recursion | induction
identity function | tautology
non-terminating function | absurdity/contradiction
tuple | conjunction (and)
disjoint union | disjunction (or) -- corrected by Antal S-Z
parametric polymorphism | universal quantification
Jadi, untuk pertanyaan saya: apa saja implikasi yang lebih menarik / tidak jelas dari isomorfisme ini? Saya bukan ahli logika jadi saya yakin saya hanya menggores permukaannya dengan daftar ini.
Sebagai contoh, berikut adalah beberapa pengertian pemrograman yang saya tidak tahu nama-nama bernas dalam logikanya:
currying | "((a & b) => c) iff (a => (b => c))"
scope | "known theory + hypotheses"
Dan berikut adalah beberapa konsep logis yang belum saya jelaskan dalam istilah pemrograman:
primitive type? | axiom
set of valid programs? | theory
Edit:
Berikut adalah beberapa persamaan lagi yang dikumpulkan dari tanggapan:
function composition | syllogism -- from Apocalisp
continuation-passing | double negation -- from camccann
sumber
goto | jumping to conclusions
Jawaban:
Karena Anda secara eksplisit meminta yang paling menarik dan tidak jelas:
Anda dapat memperluas CH ke banyak logika dan formulasi logika yang menarik untuk mendapatkan variasi korespondensi yang sangat luas. Di sini saya mencoba untuk fokus pada beberapa yang lebih menarik daripada yang tidak jelas, ditambah beberapa yang mendasar yang belum muncul.
EDIT: Referensi yang saya rekomendasikan kepada siapa pun yang tertarik untuk mempelajari lebih lanjut tentang ekstensi CH:
"Rekonstruksi Penghakiman dari Modal Logika" http://www.cs.cmu.edu/~fp/papers/mscs00.pdf - ini adalah tempat yang bagus untuk memulai karena dimulai dari prinsip pertama dan sebagian besar ditujukan untuk dapat diakses oleh ahli teori non-logika / bahasa. (Saya penulis kedua, jadi saya bias.)
sumber
Anda sedikit mengotori hal-hal tentang nonterminasi. Kepalsuan diwakili oleh jenis yang tidak berpenghuni , yang menurut definisi tidak dapat bersifat non-terminating karena tidak ada jenis yang perlu dievaluasi sejak awal.
Non-termination merepresentasikan kontradiksi - sebuah logika yang tidak konsisten. Logika yang tidak konsisten tentu saja memungkinkan Anda membuktikan apa pun , termasuk kepalsuan.
Mengabaikan ketidakkonsistenan, sistem tipe biasanya sesuai dengan logika intuitionistik , dan oleh konstruktivis kebutuhan , yang berarti potongan tertentu dari logika klasik tidak dapat diekspresikan secara langsung, jika sama sekali. Di sisi lain, ini berguna, karena jika suatu tipe adalah bukti konstruktif yang valid, maka istilah jenis itu adalah sarana untuk membangun apa pun yang telah Anda buktikan keberadaannya .
Ciri utama dari rasa konstruktivis adalah bahwa negasi ganda tidak setara dengan non-negasi. Faktanya, negasi jarang menjadi primitif dalam sistem tipe, jadi sebaliknya kita dapat merepresentasikannya sebagai kepalsuan yang menyiratkan, misalnya
not P
menjadiP -> Falsity
. Negasi ganda dengan demikian akan menjadi fungsi dengan tipe(P -> Falsity) -> Falsity
, yang jelas tidak setara dengan sesuatu yang hanya tipeP
.Namun, ada twist menarik tentang ini! Dalam bahasa dengan polimorfisme parametrik, variabel jenis berkisar pada semua jenis yang mungkin, termasuk yang tidak berpenghuni, jadi jenis polimorfik sepenuhnya seperti
∀a. a
, dalam arti tertentu, hampir salah. Jadi bagaimana jika kita menulis hampir negasi ganda dengan menggunakan polimorfisme? Kami mendapatkan jenis yang terlihat seperti ini:∀a. (P -> a) -> a
. Apakah itu setara dengan sesuatu yang sejenisP
? Memang benar , hanya menerapkannya pada fungsi identitas.Tapi apa gunanya? Mengapa menulis tipe seperti itu? Apakah itu ada artinya dalam istilah pemrograman? Nah, Anda bisa menganggapnya sebagai fungsi yang sudah memiliki tipe di
P
suatu tempat, dan Anda perlu memberikan fungsi yang mengambilP
argumen, dengan semuanya menjadi polimorfik di tipe hasil akhir. Dalam arti tertentu, ini mewakili perhitungan yang ditangguhkan , menunggu sisanya disediakan. Dalam pengertian ini, perhitungan yang ditangguhkan ini dapat disusun bersama, diedarkan, dipanggil, apa pun. Ini seharusnya mulai terdengar familier bagi penggemar beberapa bahasa, seperti Scheme atau Ruby - karena artinya negasi ganda sesuai dengan gaya penerusan lanjutan, dan sebenarnya tipe yang saya berikan di atas persis seperti monad lanjutan di Haskell.sumber
P -> Falsity
. Saya mengerti mengapa ini berhasil (¬p ≡ p → ⊥), tetapi saya tidak mendapatkan versi kodenya.P -> ⊥
Tepatnya harus dihuni padahalP
tidak, bukan? Tetapi bukankah fungsi ini harus selalu dihuni? Atau mungkin tidak pernah, sebenarnya, karena Anda tidak dapat mengembalikan instance⊥
? Saya tidak begitu melihat persyaratannya. Apa intuisi di sini?P -> Falsity
setara denganP
false.f x = x
, yang akan instantiable iffP = ⊥
, tapi itu jelas tidak cukup umum. Jadi idenya adalah untuk mengembalikan tipe yang tidak berharga, Anda tidak membutuhkan tubuh; tetapi agar fungsinya dapat didefinisikan dan total, Anda tidak memerlukan kasing , jadi jikaP
tidak berpenghuni, semuanya berhasil? Itu agak miring, tapi saya rasa saya melihatnya. Itu sepertinya berinteraksi agak aneh dengan definisi saya tentangXor
tipe ... Saya harus memikirkannya. Terima kasih!Bagan Anda kurang tepat; dalam banyak kasus Anda bingung jenis dengan istilah.
[1] Logika untuk bahasa fungsional lengkap Turing tidak konsisten. Rekursi tidak memiliki korespondensi dalam teori yang konsisten. Dalam logika yang tidak konsisten / teori bukti yang tidak benar, Anda dapat menyebutnya sebagai aturan yang menyebabkan ketidakkonsistenan / ketidakseimbangan.
[2] Sekali lagi, ini adalah konsekuensi dari kelengkapan. Ini akan menjadi bukti anti-teorema jika logikanya konsisten - jadi, tidak mungkin ada.
[3] Tidak ada dalam bahasa fungsional, karena mereka elide fitur logis urutan pertama: semua kuantifikasi dan parametrization dilakukan di atas rumus. Jika Anda memiliki fitur orde pertama, akan ada lain jenis dari
*
,* -> *
, dll .; jenis elemen dari domain wacana. Misalnya, dalamFather(X,Y) :- Parent(X,Y), Male(X)
,X
danY
jangkauan di atas domain wacana (sebut sajaDom
), danMale :: Dom -> *
.sumber
sumber
Saya sangat suka pertanyaan ini. Saya tidak tahu banyak, tapi saya punya beberapa hal (dibantu oleh artikel Wikipedia , yang memiliki beberapa tabel rapi dan semacamnya):
Saya berpikir bahwa jenis penjumlahan / jenis gabungan ( misalnya
data Either a b = Left a | Right b
) setara dengan disjungsi inklusif . Dan, meskipun saya tidak terlalu mengenal Curry-Howard, saya pikir ini menunjukkannya. Pertimbangkan fungsi berikut:Jika saya memahami sesuatu dengan benar, tipe mengatakan bahwa ( a ∧ b ) → ( a ★ b ) dan definisi mengatakan bahwa ini benar, di mana ★ bersifat inklusif atau eksklusif atau, mana saja yang
Either
mewakili. Anda telahEither
mewakili eksklusif atau, ⊕; Namun, ( a ∧ b ) ↛ ( a ⊕ b ). Misalnya, ⊤ ∧ ⊤ ≡ ⊤, tapi ⊤ ⊕ ⊥ ≡ ⊥, dan ⊤ ↛ ⊥. Dengan kata lain, jika a dan b benar, maka hipotesisnya benar tetapi kesimpulannya salah, sehingga implikasi ini pasti salah. Namun, jelas, ( a ∧ b ) → ( a ∨ b ), karena jika a dan b benar, maka setidaknya satu benar. Jadi, jika serikat pekerja yang terdiskriminasi adalah suatu bentuk pemisahan, mereka haruslah keragaman yang inklusif. Saya pikir ini berlaku sebagai bukti, tetapi merasa lebih dari bebas untuk melecehkan saya tentang gagasan ini.Demikian pula, definisi Anda untuk tautologi dan absurditas sebagai fungsi identitas dan fungsi non-terminating, masing-masing sedikit salah. Rumus sebenarnya diwakili oleh tipe unit , yaitu tipe yang hanya memiliki satu elemen (
data ⊤ = ⊤
; sering dieja()
dan / atauUnit
dalam bahasa pemrograman fungsional). Ini masuk akal: karena tipe itu dijamin akan dihuni, dan karena hanya ada satu kemungkinan penghuninya, itu pasti benar. Fungsi identitas hanya mewakili tautologi tertentu yang a → a .Komentar Anda tentang fungsi non-terminating, tergantung pada apa yang Anda maksudkan, lebih tidak tepat. Fungsi Curry-Howard pada sistem tipe, tetapi non-terminasi tidak dikodekan di sana. Menurut Wikipedia , berurusan dengan non-termination adalah sebuah masalah, karena menambahkannya menghasilkan logika yang tidak konsisten ( misalnya , saya dapat mendefinisikan
wrong :: a -> b
denganwrong x = wrong x
, dan dengan demikian “membuktikan” bahwa a → b untuk a dan b ). Jika ini yang Anda maksud dengan "absurditas", maka Anda benar. Jika sebaliknya yang Anda maksud pernyataan palsu, maka yang Anda inginkan adalah tipe yang tidak berpenghuni, misalnya sesuatu yang didefinisikan olehdata ⊥
—Yaitu, tipe data tanpa cara untuk membangunnya. Ini memastikan bahwa itu tidak memiliki nilai sama sekali, dan karenanya harus tidak berpenghuni, yang setara dengan false. Saya pikir Anda mungkin juga bisa menggunakana -> b
, karena jika kami melarang fungsi non-terminating, maka ini juga tidak berpenghuni, tapi saya tidak 100% yakin.Wikipedia mengatakan bahwa aksioma dikodekan dalam dua cara berbeda, bergantung pada bagaimana Anda menafsirkan Curry-Howard: baik dalam kombinator atau variabel. Saya pikir tampilan kombinator berarti bahwa fungsi primitif yang kita berikan menyandikan hal-hal yang dapat kita katakan secara default (mirip dengan cara modus ponens adalah aksioma karena aplikasi fungsi primitif). Dan menurut saya tampilan variabel sebenarnya memiliki arti yang sama — bagaimanapun juga, kombinator hanyalah variabel global yang merupakan fungsi tertentu. Adapun tipe primitif: jika saya memikirkan hal ini dengan benar, maka saya pikir tipe primitif adalah entitas — objek primitif yang kami coba buktikan.
Menurut kelas logika dan semantik saya, fakta bahwa ( a ∧ b ) → c ≡ a → ( b → c ) (dan juga bahwa b → ( a → c )) disebut hukum ekivalensi ekspor, setidaknya dalam deduksi natural bukti. Saya tidak memperhatikan pada saat itu bahwa itu hanya kari — saya harap saya punya, karena itu keren!
Meskipun sekarang kami memiliki cara untuk merepresentasikan disjungsi inklusif , kami tidak memiliki cara untuk merepresentasikan variasi eksklusif. Kita harus bisa menggunakan definisi disjungsi eksklusif untuk merepresentasikannya: a ⊕ b ≡ ( a ∨ b ) ∧ ¬ ( a ∧ b ). Saya tidak tahu bagaimana menulis negasi, tapi saya tahu bahwa ¬ p ≡ p → ⊥, dan baik implikasi maupun kepalsuan itu mudah. Dengan demikian, kita harus dapat merepresentasikan disjungsi eksklusif dengan:
Ini didefinisikan
⊥
sebagai tipe kosong tanpa nilai, yang sesuai dengan kepalsuan;Xor
kemudian didefinisikan mengandung ( dan )Either
sebuah a atau b ( atau ) dan fungsi ( implikasi ) dari (a, b) ( dan ) dengan jenis bawah ( palsu ).Namun, saya tidak tahu apa artinya ini .( Sunting 1: Sekarang saya lakukan, lihat paragraf berikutnya!)Karena tidak ada nilai tipe( Edit 1: Ya, camccann .)(a,b) -> ⊥
(apakah ada?), Saya tidak dapat memahami apa artinya ini dalam program. Adakah yang tahu cara yang lebih baik untuk memikirkan definisi ini atau yang lain?Sunting 1: Terima kasih untuk jawaban camccann (lebih khusus lagi, komentar yang dia tinggalkan untuk membantu saya), saya rasa saya mengerti apa yang terjadi di sini. Untuk membuat nilai tipe
Xor a b
, Anda perlu menyediakan dua hal. Pertama, saksi keberadaan salah satu elemena
ataub
sebagai argumen pertama; yaitu, aLeft a
atau aRight b
. Dan kedua, bukti bahwa tidak ada unsur dari kedua jenis tersebuta
danb
— dengan kata lain, bukti yang(a,b)
tidak berpenghuni — sebagai argumen kedua. Karena Anda hanya akan dapat menulis fungsi dari(a,b) -> ⊥
jika(a,b)
tidak berpenghuni, apa artinya itu terjadi? Itu berarti bahwa beberapa bagian dari suatu objek bertipe(a,b)
tidak bisa dibangun; dengan kata lain, bahwa setidaknya satu, dan mungkin keduanya, daria
danb
juga tidak berpenghuni! Dalam hal ini, jika kita berpikir tentang pencocokan pola, Anda tidak mungkin mencocokkan pola pada tupel seperti itu: seandainya itub
tidak berpenghuni, apa yang akan kita tulis yang bisa cocok dengan bagian kedua dari tupel itu? Jadi, kami tidak dapat mencocokkan pola dengannya, yang dapat membantu Anda melihat mengapa hal ini membuatnya tidak berpenghuni. Sekarang, satu-satunya cara untuk memiliki fungsi total yang tidak membutuhkan argumen (seperti yang harus dilakukan, karena(a,b)
tidak berpenghuni) adalah untuk hasilnya menjadi tipe yang tidak berpenghuni juga — jika kita memikirkan hal ini dari perspektif pencocokan pola, Artinya, meskipun fungsinya tidak memiliki case, tidak ada body yang memungkinkan bisa juga, jadi semuanya baik-baik saja.Banyak dari ini adalah saya berpikir keras / membuktikan (mudah-mudahan) banyak hal dengan cepat, tetapi saya harap ini berguna. Saya sangat merekomendasikan artikel Wikipedia ; Saya belum membacanya dengan detail apa pun, tetapi tabelnya adalah ringkasan yang sangat bagus, dan sangat menyeluruh.
sumber
Either a a
seharusnya tidak menjadi teorema:Either ⊥ ⊥
masih tak berpenghuni. Tom: Seperti yang dikatakan camccann, konsistensi berarti penghentian. Dengan demikian, sistem tipe yang konsisten tidak akan memungkinkan Anda untuk mengekspresikanf :: a -> b
, dan tipe akan menjadi tidak berpenghuni; sistem tipe yang tidak konsisten akan memiliki penghuni untuk tipe, tapi sistem yang tidak akan berhenti. camccann: Apakah ada jenis sistem yang tidak konsisten yang tidak selengkap Turing, menempati beberapa titik di antara hierarki? Atau apakah langkah terakhir itu (menambahkan rekursi umum atau apa pun) persis sama dengan inkonsistensi?Berikut adalah salah satu yang agak kabur yang saya terkejut tidak dibicarakan sebelumnya: Pemrograman reaktif fungsional "klasik" sesuai dengan logika temporal.
Tentu saja, kecuali Anda seorang filsuf, matematikawan, atau programmer fungsional obsesif, ini mungkin menimbulkan beberapa pertanyaan lagi.
Jadi, pertama: apa itu pemrograman reaktif fungsional? Ini adalah cara deklaratif untuk bekerja dengan nilai yang berubah-ubah waktu . Ini berguna untuk menulis hal-hal seperti antarmuka pengguna karena masukan dari pengguna adalah nilai yang bervariasi dari waktu ke waktu. FRP "Klasik" memiliki dua tipe data dasar: peristiwa dan perilaku.
Peristiwa mewakili nilai yang hanya ada pada waktu yang berbeda. Penekanan tombol adalah contoh yang bagus: Anda dapat menganggap masukan dari keyboard sebagai karakter pada waktu tertentu. Setiap tombol ditekan hanya berupa pasangan dengan karakter tombol dan waktu penekanannya.
Perilaku adalah nilai-nilai yang ada secara konstan tetapi dapat berubah terus menerus. Posisi mouse adalah contoh yang bagus: ini hanyalah perilaku koordinat x, y. Bagaimanapun, mouse selalu memiliki posisi dan, secara konseptual, posisi ini terus berubah saat Anda menggerakkan mouse. Lagi pula, menggerakkan mouse adalah satu tindakan berlarut-larut, bukan serangkaian langkah terpisah.
Dan apakah logika temporal? Cukup tepat, ini adalah seperangkat aturan logis untuk menangani proposisi yang dikuantifikasi dari waktu ke waktu. Pada dasarnya, ini memperluas logika orde pertama normal dengan dua bilangan: □ dan ◇. Yang pertama berarti "selalu": baca □ φ sebagai "φ selalu memegang". Yang kedua adalah "akhirnya": ◇ φ berarti "φ pada akhirnya akan bertahan". Ini adalah jenis logika modal tertentu . Dua hukum berikut berhubungan dengan bilangan:
Jadi □ dan ◇ adalah ganda satu sama lain dengan cara yang sama seperti ∀ dan ∃.
Kedua bilangan ini sesuai dengan dua jenis di FRP. Secara khusus, □ berhubungan dengan perilaku dan ◇ berhubungan dengan kejadian. Jika kita berpikir tentang bagaimana jenis ini dihuni, ini seharusnya masuk akal: suatu perilaku dihuni setiap saat, sementara suatu peristiwa hanya terjadi satu kali.
sumber
Terkait hubungan antara kelanjutan dan negasi ganda, jenis panggilan / cc adalah hukum Peirce http://en.wikipedia.org/wiki/Call-with-current-continuation
CH biasanya dinyatakan sebagai korespondensi antara logika intuitionistic dan program. Namun jika kita menambahkan operator call-with-current-continuation (callCC) (yang tipenya sesuai dengan hukum Peirce), kita mendapatkan korespondensi antara logika klasik dan program dengan callCC.
sumber
Meskipun ini bukan isomorfisme sederhana, pembahasan LEM konstruktif ini adalah hasil yang sangat menarik. Secara khusus, di bagian kesimpulan, Oleg Kledgeov membahas bagaimana penggunaan monad untuk mendapatkan eliminasi negasi ganda dalam logika konstruktif adalah analog dengan membedakan proposisi yang dapat ditentukan secara komputasi (yang LEM valid dalam pengaturan konstruktif) dari semua proposisi. Gagasan bahwa monad menangkap efek komputasi adalah gagasan lama, tetapi contoh isomorfisme Curry - Howard ini membantu meletakkannya dalam perspektif dan membantu memahami apa yang sebenarnya "berarti" negasi ganda.
sumber
Dukungan lanjutan kelas satu memungkinkan Anda mengekspresikan $ P \ lor \ neg P $. Trik ini didasarkan pada fakta bahwa tidak memanggil lanjutan dan keluar dengan beberapa ekspresi sama dengan memanggil lanjutan dengan ekspresi yang sama.
Untuk tampilan lebih detail silakan lihat: http://www.cs.cmu.edu/~rwh/courses/logic/www-old/handouts/callcc.pdf
sumber
Satu hal yang penting, tetapi belum diteliti adalah hubungan 2-lanjutan (kelanjutan yang membutuhkan 2 parameter) dan stroke Sheffer . Dalam logika klasik, goresan Sheffer dapat membentuk sistem logika lengkap dengan sendirinya (ditambah beberapa konsep non-operator). Yang berarti akrab
and
,or
,not
dapat diimplementasikan hanya menggunakan stoke Sheffer ataunand
.Ini adalah fakta penting dari korespondensi jenis pemogramannya karena meminta agar satu jenis kombinator dapat digunakan untuk membentuk semua jenis lainnya.
Jenis tanda tangan dari 2-lanjutan adalah
(a,b) -> Void
. Dengan implementasi ini kita dapat mendefinisikan 1-continuation (kelanjutan normal) sebagai(a,a)
-> Void, product type as((a,b)->Void,(a,b)->Void)->Void
, sum type as((a,a)->Void,(b,b)->Void)->Void
. Ini memberi kita kekuatan ekspresif yang mengesankan.Jika kita menggali lebih jauh, kita akan menemukan bahwa grafik eksistensial Piece setara dengan bahasa dengan satu-satunya tipe datanya adalah n-lanjutan, tetapi saya tidak melihat ada bahasa yang ada dalam formulir ini. Jadi, menurut saya, menemukan seseorang bisa menarik.
sumber