“Kanıt bir programdır; kanıtladığı formül program için bir tür ”


37

Bu felsefi bir soru olabilir, ancak buna objektif bir cevap olduğuna inanıyorum.

Haskell hakkındaki wikipedia makalesini okursanız, aşağıdakileri bulabilirsiniz:

Dil, Haskell Curry ve entelektüel torunlarının “kanıt bir programdır; kanıtladığı formül program için bir türdür” gözlemlerine dayanır.

Şimdi soruyorum: bu gerçekten tüm programlama dilleri için geçerli değil mi? Haskell'in hangi özelliği (veya bir dizi özellik) bu ifadeyle uyumlu olmasını sağlar? Başka bir deyişle, bu ifadenin dilin tasarımını etkilemesinin dikkat çekici yolları nelerdir?


4
Neden "yakın" oy kullandığını açıklamak isteyen var mı?

1
@Grigory Javadyan: Kapatmaya oy vermedim, ama muhtemelen soru SO için sınır ötesi bir konu değil - felsefi sorular, nesnel olarak yanıtlanabilen veya başka türlü burada genellikle uygun değil. Bu durumda, bunun haklı olduğunu düşünüyorum, çünkü cevabın Haskell'in gerçekte nasıl kullanıldığına dair derin pratik sonuçları vardır.

2
@Grigory: Bu soru (kodda) gerçek bir çözüm ile gerçek bir sorun olsaydı, o zaman SO kalabilir. Programcılara kapanıp taşınmak için oy verildi.

9
Sadece buna ekliyorum çünkü biraz buğulanmışım - bu soruların yanıtları zor CS araştırmalarına atıfta bulunuyor ve bu anlamda SO'nun% 90'ından daha "nesnel". Dahası, altı farklı değişkenin (çözümün kod gerektirdiği) kriterleri, ne öznel ne de konu dışı olan çok çeşitli orijinal programlama soruları için delice dardır. SO üzerinde kapsayıcı / delesyoncu tartışmanın yeniden ortaya çıkmasını görmekten nefret ediyorum, ama eğer böyle net bir şekilde
işleyen

2
Bunun nerede bittiği konusunda kararsızım, çünkü çoğunlukla ne tür bir içeriğin Programcılar üzerinde olması gerektiği konusunda net değilim . Ama Programcılar bu soru kesinlikle değildir "sübjektif sorulara" nedeniyle varlık olarak çeşitli yerlerde açıklanan diyecekler değil . Benim cevabım olması gerektiği ve ben olabilir gayrı ve el dalgalı olarak hakkındadır hala bile Vikipedi editörleri gergin referanslarla kolayca yukarı arka çoğu kabul ederim.
CA McCann

Yanıtlar:


38

Temel kavram, evrensel olarak bazı şekillerde uygulanır, evet, ancak nadiren faydalı bir şekilde.

Başlangıç ​​olarak, bu tür varsayım perspektifinden bakıldığında, "dinamik" dillerin , programcıların gördüğü değerin doğası hakkında (diğer şeylerin yanı sıra) meta verilerini içeren, bu dinamik dillerin ne arayacağı da dahil, tek bir türe sahip olduğu kabul edilir. Bir "tip" kendileri (bu aynı şey değildir, kavramsal olarak). Bu tür kanıtların ilgisiz olması muhtemeldir, bu nedenle bu kavram çoğunlukla statik tip sistemlere sahip dillerle ilgilidir.

Ek olarak, "statik tip bir sistem" olduğu iddia edilen birçok dil, bu bağlamda pratikte dinamik olarak kabul edilmelidir, çünkü çalışma zamanında türlerin incelenmesine ve dönüştürülmesine izin verirler. Özellikle, bu, "yansıma" veya benzeri için yerleşik, varsayılan olarak desteği olan herhangi bir dil anlamına gelir. C #, örneğin.

Haskell, bir türün ne kadar bilgi vermesini beklediği konusunda olağandışıdır - özellikle işlevler, argümanları olarak belirtilenlerden başka hiçbir değere bağlı olamaz. Değişken global değişkenleri olan bir dilde, diğer taraftan, herhangi bir işlev (potansiyel olarak) bu değerleri inceleyebilir ve davranışını buna göre değiştirebilir. Bu nedenle, türlü bir Haskell işlevi, A -> Bbunun Aima edildiği kanıtlanmış bir minyatür program olarak kabul edilebilir B; Diğer birçok dilde eşdeğer bir işlev bize, yalnızca Aküresel devletin kapsamındaki her ne olduğunu bir araya getirir B.

Haskell, yansıma ve dinamik tipler gibi şeyleri desteklerken , bu özelliklerin kullanımı bir fonksiyonun imzasında belirtilmelidir; Aynı şekilde küresel devlet kullanımı için. İkisi de varsayılan olarak mevcut değildir.

Orada olan çalışma zamanı istisnaları izin verme ya da derleyici tarafından sağlanan standart dışı ilkel işlemler kullanılarak Haskell yanı, örneğin şeyleri kırmak için yollar, ancak bu 'onlar sadece won o yönden tam anlayışla kullanılacağını güçlü beklenti ile gelen t Harici kodun anlamına zarar vermeyin. Teoride, aynı şey diğer diller için de söylenebilir, ancak pratikte diğer dillerin çoğunda "hile yapmadan" işleri başarmak hem de "hile" ye daha az kaşlarını çatmaktan daha zordur. Ve elbette gerçek "dinamik" dillerde, her şey alakasız kalıyor.

Konsept Haskell'de olduğundan çok daha ileri götürülebilir.


Ancak, istisnaların bir tür sisteme tam olarak entegre edilebileceğini unutmayın.
gardenhead,

18

Curry-Howard yazışmalarının çok genel bir şey olduğu konusunda haklısın. Kendini tarihiyle ilgili biraz tanımaya değer: http://en.wikipedia.org/wiki/Curry-Howard_correspondence

Orijinal olarak formüle edildiği gibi, bu yazışmaların bir tarafta özellikle sezgisel mantığa ve diğer tarafta da basitçe yazılan lambda hesabına (STLC) uygulandığını not edersiniz.

Klasik Haskell - '98 ya da daha eski versiyonlar, STLC'ye çok yakındı ve çoğunlukla, Haskell'de verilen herhangi bir ifade ile STLC'de karşılık gelen bir terim arasında doğrudan bir çeviri yapıldı (özyineleme ile uzatıldı ve birkaç ilkel tür). Böylece bu Curry-Howard'ı çok açık bir hale getirdi. Bugün, uzantıları sayesinde, böyle bir çeviri biraz daha zor bir iştir.

Öyleyse, bir anlamda soru, Haskell'in neden STLC'ye bu kadar basitçe “küskün” olduğu. İki şey akla geliyor:

  • Türleri. Aynı zamanda bir çeşit şekerli lambda matematiği olan Scheme'den farklı olarak (diğer şeylerin yanı sıra) Haskell çok iyi yazılmış. Bu, klasik Haskell dilinde tanımların STLC'de iyi yazılmış terimler olamayacağı anlamına gelmediği anlamına gelir .
  • Saflık. Yine Şemadan farklı olarak, ancak STLC gibi, Haskell de saf, referans olarak saydam bir dildir. Bu oldukça önemli. Yan etkisi olan diller, yan etkisi olmayan dillere gömülebilir. Bununla birlikte, bunu yapmak, yalnızca yerel bir kınama değil, tüm program dönüşümüdür. Bu yüzden doğrudan yazışma için, tamamen işlevsel bir dille başlamanız gerekir.

Haskell'in, çoğu dil gibi, Curry-Howard yazışmalarının doğrudan uygulanması konusunda başarısız olduğu önemli bir yol vardır. Tam bir dil olarak Haskell, sınırsız yineleme olasılığını ve dolayısıyla fesih edilmemesini içerir. STLC'nin bir sabit nokta operatörüne sahip olmadığı, dönüş tamamlanmadığı ve güçlü şekilde normalize olduğu - yani STLC'de bir terimin azalmasının sona ermeyeceği anlamına gelir. Özyineleme olasılığı, bir kişinin Curry-Howard'ı "aldatabileceği" anlamına gelir. Örneğin let x = x in x, türü vardırforall a. a- yani, asla geri dönmediği için bana her şeyi veriyormuş gibi yapabilirim! Bunu her zaman Haskell'de yapabileceğimizden, bu, programın kendisinin sona erdiğine dair ayrı bir kanıtımız olmadığı sürece Haskell programına karşılık gelen hiçbir kanıtı "inanamayacağımız" anlamına gelir.

Haskell'den önce (özellikle de ML ailesi) önceki işlevsel programlamanın soyu, CS ile ilgili bir şeyleri kolayca kanıtlayabileceğiniz diller oluşturmaya odaklanan CS araştırmalarının bir sonucudur (diğer şeylerin yanı sıra). Tersine, Haskell, CH teorisiyle çok ilgili olan tip teorisindeki gelişmelere dayanan Agda ve Epigram gibi geliştirilmekte olan birkaç ispat asistanı için hem ana bilgisayar dili hem de ilham kaynağı olmuştur.


1
Belirsizleştirmenin, kanıtı, mantıksal bir bakış açısıyla felaket olmasına rağmen, diğer birçok özelliği koruyan belirli şekillerde baltalamasını vurgulamak iyi olabilir. Özellikle, A -> Bverilen bir işlev , ya hiç ya hiç ya hiç Aya üretmeyecektir B. Asla bir üretmeyecek Cve hangi türde bir değer sağlayacağı Bya da farklı olursa, yine de Asağlananlara bağlı olacaktır .

@ camccann - biraz nitpicky, ama ben dipten "hiç bir şey" i ayırt edecektim, daha çok Void, hayır? Tembellik, her ikisini de daha az karmaşık hale getirir. Her A -> B zaman bir fonksiyonun bir tür değer ürettiğini söyleyebilirim B, fakat bu değer beklenenden daha az bilgiye sahip olabilir.
sclv

Nitpicking eğlencelidir! "Hiçbir şey" derken, değerlendirme yapmak bağlamında değer düzeyinde demek istiyorum, oysa dip sadece somut bir şey değil, sadece bir soyutlama olarak var olur. Değerlendirilen bir ifade hiçbir zaman bir alt değeri "görmez", kullanmadığı terimleri (alt olabilir) ve kullandığı terimleri (alt olmayan değerleri olan). Tabanı kullanmaya çalışmak, bir anlamda "asla gerçekleşmez" çünkü bunu yapmaya çalışmak, kullanım gerçekleşmeden önce tüm ifadenin değerlendirmesini sonlandırır.

12

Birinci dereceden bir yaklaşıma göre, çoğu (zayıf ve / veya tek biçimli) dillerin çoğu, diller arasındaki katı dil seviyesi sınırlamasını desteklemiyor.

  • önerme (yani bir tür)
  • bir kanıt (yani, bir dizi ilkel ve / veya diğer yüksek dereceli yapılardan önermeyi nasıl inşa edebileceğimizi gösteren bir program )

ve ikisi arasındaki katı ilişki. Bir şey varsa, diğer dillerin sağladığı en iyi garantiler

  • Girdi üzerinde sınırlı bir kısıtlama verilmişse, o sırada çevrede ne olursa olsun, sınırlı bir kısıtlamaya sahip bir değer üretebiliriz. (geleneksel statik tipler, cf C / Java)
  • her yapı aynı tiptedir (dinamik tip, cf ruby ​​/ python)

Not tarafından bu tip , bir bakın önermenin dolayısıyla o sadece çok fazla bilgi açıklayan şey, ve int veya bool . Haskell'de, bir işlevin nüfuz eden bir kültürü var ancak sadece argümanlarından etkileniyor - istisnalar yok *.

Biraz daha sıkı olmak gerekirse, genel fikir şu ki (neredeyse) tüm program yapılarına katı bir sezgisel yaklaşım uygulayarak (yani sadece yapabileceğimizi ispatlayabiliriz) ve ilkel yapılar kümesini böyle sahip olduğumuz şekilde

  • Tüm dil ilkelleri için kesin teklifler
  • ilkellerin birleştirilebileceği sınırlı sayıda mekanizma

Haskell yapıları, davranışları hakkında akıl yürütmeye kendilerini iyi borç verme eğilimindedir. Biz kanıt oluşturmak durumunda (okuyun: fonksiyonu) edildiğinin ispatı Aima B, bu sahiptir çok kullanışlı özelliklere:

  • o zaman (uzun biz var gibi tutan A, bir inşa edebilir B)
  • Bu ima dayanır yalnızca üzerinde Ave hiçbir şey başka.

Böylece, yerel / küresel değişmezleri etkin bir şekilde akıl etmemize izin verdik. Asıl soruya geri dönmek için; Haskell'in bu zihniyeti en çok şaşırtan dil özellikleri:

  • Saflık / Etkilerin açık yapılara bölünmesi (etkiler hem hesaba katılır hem de yazılır!)
  • Haskell derleyicilerinde Tip Çıkarım / Kontrol
  • Kontrol ve / veya veri akışı değişmezlerini bir programın önerdiği türlere dahil etme kabiliyeti: (Polimorfizm, Tip Aileler, GADT'ler vb. İle)
  • Bilgi tutarlılığı

Hiçbiri Haskell'e özgü değildir (bu fikirlerin çoğu inanılmaz derecede eskidir). Bununla birlikte, standart kütüphanelerdeki zengin bir soyutlama setiyle (genellikle tip sınıflarında bulunur), çeşitli sözdizimi düzeyinde şekerleme ve program tasarımında saflığa sıkı bir bağlılık ile birleştirildiğinde, bir şekilde her ikisini de başarabilen bir dille bitiririz. Gerçek dünya uygulamaları için yeterince pratik , ancak aynı zamanda çoğu geleneksel dilde aklınıza gelmesi daha kolay.

Bu soru yeterince derin bir cevabı hak ediyor ve bu bağlamda adaleti yerine getiremedim. Wikipedia'da / literatürde daha fazla okuma öneririm:

* Not: Haskell'in safsızlıklarının (istisnalar, fesih dışı vb.) Bazı karmaşık yönlerini görmezden geliyor / görmezden geliyorum.


4

Hangi özellik? Tip sistemi (statik, saf, polimorfik olan). İyi bir başlangıç ​​noktası Wadler'in "Ücretsiz Teoremleri" dir. Dilin tasarımında göze çarpan etki? GÇ türü, sınıfları yazın.


0

Kleene Hiyerarşi deliller programları olmadığını bize göstermektedir.

İlk özyinelemeli ilişki ya:

R1( Program , Iteration )  Program halts at Iteration.
R2( Theorem , Proof ) Proof proves a Theorem.

Özyinelemeli olarak numaralandırılabilir ilk ilişkiler:

(exists x) R1( Program , x )  Program Halts.
(exists x) R2( Theorem , x)   Theorem is provable.

Böylece bir program bir teoremdir ve programın durduğu varolan yineleme teoremi ispatlayan kanıt gibidir.

Program = Theorem
Iteration = Proof

Bir program bir şartnameden doğru bir şekilde üretildiğinde, şartnameyi yerine getirdiğini kanıtlayabilmeliyiz ve bir programın bir şartnameyi yerine getirebildiğini ispatlayabilirsek, doğru program sentezidir. Bu yüzden programın şartnameye uygun olduğunu ispat edersek program sentezini gerçekleştiririz. Programın şartnameyi yerine getirdiği teoremi, teorem sentezlenen programa atıfta bulunan programdır.

Martin Lof'un yanlış sonuçları hiç bir bilgisayar programı üretmedi ve insanların bir program sentez metodolojisi olduğuna inanmaları şaşırtıcı. Sentezlenmekte olan bir program için hiçbir tam örnek verilmemiştir. "Bir tip giriş ve bu tip bir programın çıktısı" gibi bir özellik bir fonksiyon değildir. Bu gibi çok sayıda program vardır ve rastgele birini seçmek, özyinelemeli bir işlev değil hatta bir işlevdir. Özyinelemeli bir fonksiyonu hesaplayan gerçek bir bilgisayar programını temsil etmeyen aptalca bir programla program sentezini göstermek sadece saçma bir girişimdir.


2
sorusuna bu nasıl cevap
gnat

1
@gnat - bu cevap asıl sorudaki temel varsayımı ele alır, yani: " doesn't this really apply to pretty much all the programming languages?" Bu cevap, bu varsayımın geçersiz olduğunu iddia eder / gösterir; .
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.