Mengapa bahasa tidak termasuk implikasi sebagai operator logis?

60

Ini mungkin pertanyaan yang aneh, tetapi mengapa tidak ada implikasi sebagai operator logis dalam banyak bahasa (Java, C, C ++, Python Haskell - meskipun sebagai yang terakhir ada pengguna yang mendefinisikan operatornya sepele untuk menambahkannya)? Saya menemukan implikasi logis yang jauh lebih jelas untuk ditulis (terutama dalam menegaskan atau menyatakan seperti pernyataan) kemudian negasi dengan atau:

encrypt(buf, key, mode, iv = null) {
    assert (mode != ECB --> iv != null);
    assert (mode == ECB || iv != null);
    assert (implies(mode != ECB, iv != null)); // User-defined function
}
Maciej Piechotka
sumber
28
Karena itu tidak dimasukkan ke dalam C; jika sudah dimasukkan maka C ++, Java dan C # akan memilikinya.
m3th0dman
4
Tetapi C tidak memilikinya, karena itu bukan bagian yang umum dari bahasa assembly. Sementara semua set instruksi yang saya ketahui termasuk dan, atau tidak, saya tahu tidak ada yang termasuk menyiratkan - tidak diragukan lagi seseorang akan bersama untuk memberi tahu saya beberapa set instruksi yang tidak jelas yang tidak lama ...
Jack Aidley
4
Mungkin itu dianggap berlebihan karena (1) itu kurang primitif daripada "^", "v", "~", (2) menghemat sedikit mengetik karena "A => B" setara dengan "~ A v B" .
Giorgio
4
Bahasa yang berhubungan dengan konstruksi logis lebih cenderung memilikinya. Terutama di antaranya adalah prolog
9
Saya terkejut Anda berpikir assert# 1 lebih jelas dari # 2. Saya telah menatap nomor 1 untuk beberapa waktu dan masih tidak dapat melihat bagaimana perilakunya dapat dianggap intuitif. (Terutama dengan tambahan !=membalik logika)
Chris Burt-Brown

Jawaban:

61

Mungkin bermanfaat terkadang, tidak diragukan. Beberapa poin menentang operator semacam itu:

  • Karakter -dan >bernilai, baik dalam isolasi dan gabungan. Banyak bahasa sudah menggunakannya untuk maksud lain. (Dan banyak yang tidak dapat menggunakan set karakter unicode untuk sintaks mereka.)
  • Implikasi sangat kontra-intuitif, bahkan untuk orang yang berpikiran logis seperti programmer. Fakta bahwa tiga dari empat entri tabel kebenaran truemengejutkan banyak orang.
  • Semua operator logis lainnya simetris, yang akan membuat ->pengecualian untuk ortogonalitas.
  • Pada saat yang sama, ada solusi yang mudah: gunakan operator !dan ||.
  • Implikasi digunakan jauh lebih jarang daripada logis and/ or.

Ini mungkin sebabnya operator jarang hari ini. Tentu saja itu bisa menjadi lebih umum, karena bahasa dinamis baru menggunakan Unicode untuk semuanya dan operator yang berlebihan menjadi lebih modis lagi.

Kilian Foth
sumber
22
Poin pertama Anda hanya menentang penggunaan '->' sebagai simbol untuk operator, bukan menentang memiliki operator. Yang lainnya adalah poin yang bagus.
AShelly
14
"Pada saat yang sama, ada solusi yang mudah: gunakan! Dan &&.": Sebenarnya, cara paling sederhana untuk mensimulasikan "->" (atau "=>", karena lebih umum dalam Matematika), adalah menggunakan !dan ||, bukan !dan &&: A -> Bsama dengan !A || Byang setara dengan !(A && !B).
Giorgio
22
"Fakta bahwa tiga dari empat entri tabel kebenaran benar-benar mengejutkan banyak orang." Wat. Saya tahu operator lain dengan fitur yang sama yang sering digunakan ...
l0b0
9
@ l0b0, saya seorang programmer yang mempelajari CS, tapi itu sudah lama sekali. Saya lupa bahwa "menyiratkan" adalah operasi formal dengan dua operan yang mengembalikan nilai kebenaran, jadi pada awalnya saya bingung dengan sifat pertanyaan ini. Dalam pembicaraan sehari-hari, saya hanya menggunakan "menyiratkan" ketika operan pertama sudah diketahui benar ("X benar, jadi Y harus benar"). Setelah satu menit, saya ingat bagaimana formal "menyiratkan" bekerja, tetapi kenyataannya tetap - bahkan untuk seseorang yang pernah mempelajari logika formal, maksudnya tidak jelas bagi saya. Dan jika saya belum pernah mempelajarinya, itu pada akhirnya tidak masuk akal.
Ben Lee
5
(a) Dalam C -> digunakan sebagai operator. Tidak ada yang mengeluh tentang itu. Saya akan tetap menggunakan =>. (B) Kontra-intuitif untuk siapa? Definisi implikasinya adalah definisi. (c) pengurangan tidak komutatif. Tidak ada yang mengeluh tentang itu. (d) Saya pikir maksud Anda! dan || Karena diutamakan (dan) seringkali juga dibutuhkan. Argumen yang sama dapat digunakan untuk && atau ||; ambil pilihanmu. (e) Mungkin itu karena tidak ada dalam sebagian besar bahasa. Banyak kegunaan || bisa secara singkat dan (setidaknya bagi saya) secara intuitif digantikan oleh implikasi.
Theodore Norvell
54

Saya percaya jawabannya terletak pada dasar matematika . Implikasi biasanya dianggap dan didefinisikan sebagai operasi aljabar boolean yang diturunkan, bukan elementer. Bahasa pemrograman mengikuti konvensi ini.

Ini adalah Proposisi I Bab II dari Investigasi Hukum Berpikir George Boole (1854) :

Semua operasi Bahasa, sebagai instrumen penalaran, dapat dilakukan oleh sistem tanda yang terdiri dari unsur-unsur berikut, yaitu .:

1 Simbol literal, seperti x, y, & c., Mewakili hal-hal sebagai subjek dari konsepsi kami.

Ke-2 Tanda-tanda operasi, sebagai +, -, ×, berdiri untuk operasi-operasi pikiran dengan mana konsepsi hal-hal digabungkan atau diselesaikan sehingga membentuk konsepsi baru yang melibatkan unsur-unsur yang sama.

Ke-3 Tanda identitas, =.

Dan simbol-simbol Logika ini dalam penggunaannya tunduk pada hukum yang pasti, sebagian setuju dengan dan sebagian berbeda dari hukum simbol yang sesuai dalam ilmu Aljabar.

Tanda Boole + mewakili "operasi pikiran" yang sama dengan yang kita kenal sekarang sebagai asor 'boolean dan penyatuan set. Demikian pula tanda-tanda - dan × sesuai dengan negasi boolean kami, komplemen dari set, boolean ´and 'dan persimpangan set.

BERASAL DARI
sumber
+1 - jawaban solid. Aljabar Boolean dan penyederhanaan dalam logika yang memungkinkan drive banyak metodologi pemrograman. Menggunakan "tersirat ..." berpotensi mengganggu kondisi "tidak peduli".
3
1. Itu tergantung pada definisi. Dimungkinkan untuk mendefinisikan atau sebagai a || b = !(!a && !b)(saya bertemu atau sebagai operator turunan dalam logika). 2. Alasan mengapa hal ini dilakukan biasanya adalah untuk menyederhanakan bukti induksi. Saya percaya (kita tahu bahwa operator turunan hanya jalan pintas sehingga kita tidak perlu memiliki case terpisah untuk mereka). @ GlenH7: Kondisi "tidak peduli" apa? a --> bsama dengan !a || b.
Maciej Piechotka
3
Juga - kami memiliki operator turunan lainnya seperti xor ( !=) nxor ( ==) ...
Maciej Piechotka
5
Sebenarnya, Anda bisa mendapatkan semuanya dari NAND !(a && b)atau NOR !(a || b). Sebagai contoh, NOT a == a NAND a, a AND b == NOT(a NAND b), a OR b == (NOT a) NAND (NOT b). Tetapi hanya dengan menyediakan operator NAND menempatkan Anda dalam ranah bahasa esoterik (yang sangat cocok, mengingat nama pengguna penjawab ;-)).
Stefan Majewsky
1
@Stefan: Anda juga dapat memperoleh semuanya dari IMPL.
Mason Wheeler
37

UPDATE: Pertanyaan ini adalah topik blog saya pada bulan November 2015 . Terima kasih untuk pertanyaan yang menarik!


Visual Basic 6 (dan VBScript) miliki Impdan Eqvoperator. Tidak ada yang menggunakannya. Keduanya dihapus di VB.NET; setahu saya, tidak ada yang mengeluh.

Saya bekerja di tim kompiler Visual Basic (sebagai pekerja magang) selama setahun penuh dan tidak pernah sekalipun menyadari bahwa VB bahkan memiliki operator tersebut. Seandainya saya bukan orang yang menulis kompiler VBScript, dan karena itu harus menguji implementasi mereka, saya mungkin tidak akan memperhatikan mereka. Jika orang di tim kompiler tidak tahu tentang fitur dan tidak menggunakannya, itu memberitahu Anda sesuatu tentang popularitas dan kegunaan dari fitur tersebut.

Anda menyebutkan bahasa mirip-C. Saya tidak dapat berbicara dengan C atau C ++ atau Java tetapi saya dapat berbicara dengan C #. Ada daftar fitur yang disarankan pengguna untuk C # secara harfiah lebih panjang dari lengan Anda. Sepengetahuan saya, tidak ada pengguna yang pernah mengusulkan operator semacam itu ke tim C #, dan saya telah berulang kali memeriksa daftar itu.

Fitur yang ada dan tidak digunakan dalam satu bahasa, dan tidak pernah diminta dalam bahasa lain adalah kandidat yang tidak mungkin untuk membuatnya menjadi bahasa pemrograman modern. Terutama ketika tidak ada cukup waktu dan usaha dan uang yang tersedia dalam anggaran untuk membuat fitur yang orang lakukan inginkan.

Eric Lippert
sumber
IMP kembali sebagai operator ke hari GWBASIC. Saya ingat sejak 1979.
zarchasmpgmr
1
Saya telah membaca bahwa IMPL sangat membantu untuk kontrak kode. (Yang VB tidak punya.)
Mason Wheeler
3
Pemrogram VBScript mungkin adalah kelompok yang paling tidak mungkin menggunakan operator seperti itu. Saya berharap sekarang bahwa PowerShell memiliki operator yang menyiratkan sehingga saya bisa lebih mudah & secara jelas menerapkan beberapa [switch]parameter filter.
brianary
Saya ingat IMP dari DEC BASIC. Saya tidak ingat EQV. Operator yang sering saya harapkan adalah "dan bukan", yang akan mempromosikan operator tangan kanan sebelum meniadakannya. Dengan demikian, 0xABCD12345678ul ~& 0x00200000uakan menghasilkan 0xABCD12145678ul daripada 0x12145678ul.
supercat
19

Saya hanya bisa menebak, tetapi alasannya mungkin karena ada solusi yang cukup sederhana dan mudah dibaca. Mari kita perhatikan contoh Anda:

if (mode != ECB) assert (iv != null);

assert (mode != ECB --> iv != null);  // <-- that's only one character shorter

Jika Anda memerlukan ekspresi, operator inline-if yang tersedia di sebagian besar bahasa (sering disebut operator ternary) dapat digunakan. Memang, ini tidak seanggun A --> B, tetapi jumlah kasus penggunaan mungkin tidak membenarkan penambahan (dan pemeliharaan!) Operator lain:

assert (mode != ECB ? iv != null : true);
Heinzi
sumber
2
Pada menegaskan - ada alasan bagus. Yang pertama akan menghasilkan (dalam banyak implementasi) pesan "kegagalan pernyataan: iv! = Null" sedangkan yang kedua "kegagalan pernyataan: mode! = ECB -> iv! = Null".
Maciej Piechotka
2
+1, saya akan menanyakan hal yang sama pada pertanyaan ini (karena saya tidak terlalu akrab dengan "implikasi", itu tidak pernah muncul sehari-hari). The ifpernyataan jauh, jauh lebih jelas untuk hampir semua orang.
Izkata
12

Eiffel memiliki Implikasi

Sebenarnya memiliki lebih banyak. Ini memiliki sejumlah operator semi-ketat dan juga ketat.

Alasan pemrogram tidak menggunakan hal-hal seperti itu adalah karena mereka tidak pernah dilatih untuk mengetahui dengan tepat apa mereka, bagaimana menggunakannya, dan kapan menggunakannya - serta bagaimana merancang dengan mereka. Karena mereka tidak pernah dilatih, mereka tidak pernah memintanya dari penulis kompiler, itulah sebabnya orang-orang kompiler tidak repot-repot menempatkan mekanisme seperti itu di kompiler. Ketika siswa Ilmu Komputer dan programmer Shade-tree mulai mendapatkan pendidikan yang lebih bulat, maka para penyusun akan mulai mengejar ketinggalan.

Ternyata sekali Anda memiliki bahasa dengan operator Boolean tersebut dan Anda tahu cara mendesain dengan mereka dan menggunakannya, maka Anda menggunakannya.

Di Eiffel penggunaan kata kunci "menyiratkan" agak menonjol karena Desain-oleh-Kontrak karena sifat berat pernyataan Boolean dari kontrak. Ada beberapa kontrak yang hanya dapat ditulis dengan benar dan efisien dengan operator "menyiratkan". Ini kemudian memunculkan komentar bahwa bahasa tanpa kontrak lebih jauh tanpa alasan untuk melihat, melatih, dan mengimplementasikan penggunaan implikasi.

Tambahkan ke ini bahwa kebanyakan programmer adalah "matematika-dan-logika-lemah" memberitahu kita sisa cerita. Bahkan jika Anda matematika-dan-logika-berat dalam pendidikan Anda, ketika seseorang memilih bahasa yang tidak mengimplementasikan konstruksi seperti implikasi, maka orang cenderung berpikir hal-hal seperti itu tidak perlu atau tidak berguna. Satu jarang mempertanyakan bahasa dan masuk ke ruang gema dari: "Yah kompiler tidak melihat kebutuhan" dan "Yah programmer tidak melihat kebutuhan" - lingkaran yang tak berujung dan ganas.

Sebagai gantinya, orang-orang penyusun perlu mendukung teori, menulis notasi bahasa yang disarankan atau disiratkan oleh teori (misalnya Teori Berorientasi Objek) terlepas dari apa yang dipikirkan atau diminta oleh massa programmer yang tidak dicuci. Dari sana, para profesor, guru, dan profesional lainnya perlu melatih para ahli muda yang cakap berdasarkan teori mentah dan BUKAN "teori-melalui-lensa-bahasa". Ketika ini terjadi, orang-orang akan tiba-tiba bangun dan menyadari apa yang telah mereka lewatkan dan apa yang telah dilakukan pada mereka.

Saat ini - ada banyak teori di luar sana yang menyamar sebagai Berorientasi Objek, tetapi hanya OO-melalui-kaca-gelap-of-[pilih-bahasa-Anda]. Seseorang tidak dapat membaca sebagian besar buku "teori" tentang OO karena mereka ingin menafsirkan apa teorinya melalui lensa dari beberapa bahasa. Benar-benar salah dan salah. Ini akan seperti mengajar berbasis matematika pada kalkulator saya atau aturan slide saya. TIDAK - seseorang mengizinkan kenyataan untuk mengajarkan satu tentang dirinya sendiri dan kemudian menggunakan notasi untuk menggambarkan apa yang diamati - yang disebut "sains". Tumbuk lain yang disebut OO berbasis-bahasa-X ini sangat miring sehingga nyaris tidak mewakili kenyataan.

Jadi, menjauhlah dari bahasanya, lihat teori mentah, dan mulai lagi. Jangan biarkan batasan, kendala, dan pekerjaan cat suatu bahasa memberi tahu Anda apa teorinya. Biarkan saja realitas teori menentukan notasinya sendiri dan kemudian pindah dari sana ke merumuskan bahasa.

Dari sana, Anda akan mulai mendapatkan bagaimana implikasi dan "implikasi" tidak hanya berguna, tetapi elegan dan sangat keren!

Selamat menikmati!

Larry
sumber
7

Python memiliki operator implikasi dalam semacam cara tersembunyi.

Operator yang kurang dari atau sama dengan kelebihan beban untuk menerima nilai boolean. Sebagai hasilnya, seseorang dapat menggunakannya sebagai operator implikasi.

Bukti dengan Contoh (Kode Python):

print (False <= False) # This will print True.
print (False <= True)  # This will print True.
print (True <= False)  # This will print False.
print (True <= True)   # This will print True.

Ingat tabel kebenaran dari operator implikasi adalah:

LEFT RIGHT RESULT
F    F     T
F    T     T
T    F     F
T    T     T
Mackenzie
sumber
2
Ini mengagumkan, tapi sayangnya memiliki sifat ketatnya salah: f() implies g()tidak harus mengevaluasi g()apakah f()ini False, tapi <=tidak mengevaluasi g()dalam kasus ini.
Jon Purdy
2
@ Jon Purdy - Sebenarnya, evaluasi hubung singkat adalah fitur opsional dari operator biner. Jadi secara teknis, ini adalah implementasi sah dari operator-implikasi. Yang sedang berkata, saya benar-benar ragu bahwa Guido van Rossum bahkan bermaksud ini menjadi operator-implikasi. Ini hanya kekhasan dari membandingkan boolean.
Mackenzie
Tentu, saya mengatakan itu pengamatan yang menarik, tetapi bukan sesuatu yang harus Anda gunakan dalam program nyata karena tidak terjadi hubungan arus pendek dan itu bisa mengejutkan seseorang jika mereka diharapkan did_all_possible_stuff = x.do_required_stuff() and (x.supports_optional_stuff() <= x.do_optional_stuff())bekerja.
Jon Purdy
2
Ini bekerja di C dan C ++ juga.
Ben Voigt
5

Eiffel memiliki operator "tersirat" dan sangat bagus untuk membuat pra dan pasca kondisi. Itu membuat kode lebih mudah dibaca, sayangnya itu tidak pernah menjadi kehebatan mendasar untuk bahasa seperti C dan terlalu sedikit orang menggunakan eiffel sehingga keindahan "menyiratkan" sebagai operator tidak dikenal.

Lothar
sumber
2

Bagi saya, masalah besar dengan menyiratkan datang ketika kondisi awal salah; misalnya: "Jika matahari berwarna hijau, maka saya adalah kelelawar buah." Benar!

Dalam logika formal hanya berfungsi untuk menetapkan "Benar" ke nilai ketika kondisi implikasi tidak terpenuhi. Tetapi dalam pemrograman, itu bisa mengarah pada hasil kontra-intuitif dan mengejutkan.

Saya benar-benar berpikir contoh @Heinzi berikan di atas:

if (sun.color() == "green") then assert(me.species() == "fruitbat")

Jauh lebih mudah untuk dipahami, dan kurang rentan terhadap kesalahan karena kesalahpahaman logika.

Dalam konteks pengujian, saya hanya akan berhenti saat asumsi saya menjadi salah:

assert(sun.color() == "green")
assert(me.species() == "fruitbat")

Jadi, untuk titik @Eric Lippert, sebagai seorang programmer saya tidak tahu kapan saya akan menggunakan operator tersirat. Perilaku "False is True" tampaknya berguna dalam konteks matematika, logika formal, tetapi dapat menyebabkan hasil yang tidak terduga dalam logika program.

...

Tidak ada yang menyebutkan yang umum "?" operator, di mana "A? B: true" sama dengan "menyiratkan". Tetapi sementara logika formal berlaku untuk kondisi "lain", "?" memungkinkan pengembang menetapkannya secara eksplisit.

Dalam logika formal, menggunakan "true" berhasil, tetapi dalam pemrograman, jika kondisinya salah, maka jawaban yang lebih baik lebih seperti "null" atau "void" atau "skip", atau bahkan mungkin false.

Saya pikir seseorang harus menjelaskan mengapa "menyiratkan" adalah operator yang lebih berguna daripada pernyataan "?", Atau "jika", atau hanya aliran program biasa.

rampok
sumber