Fonksiyonlar için eta-denklik Haskell'in seq işlemi ile karşılaştırılabilir mi?


14

Lemma: Eta denkliği varsayalım (\x -> ⊥) = ⊥ :: A -> B.

İspat: ⊥ = (\x -> ⊥ x)eta-denklik ve (\x -> ⊥ x) = (\x -> ⊥)lambda altında azalma ile.

Haskell 2010 raporu, bölüm 6.2 seqfonksiyonu iki denklemle belirtir :

seq :: a -> b -> b
seq ⊥ b = ⊥
seq ab = b, eğer bir ≠ ⊥

Daha sonra "Sonuç olarak, ⊥ \ x -> ⊥ ile aynı değildir, çünkü seq onları ayırt etmek için kullanılabilir."

Benim sorum şu, bu gerçekten tanımının bir sonucu seqmu?

Örtük argüman, seqeğer o zaman hesaplanamaz olurdu seq (\x -> ⊥) b = ⊥. Ancak böyle bir seqşeyin hesapsız olacağını kanıtlayamadım. Bana öyle geliyor ki böyle bir seqhem monoton hem de sürekli, onu hesaplanabilir olma alanına sokuyor.

Bazıları için aramak için çalışarak seq kudreti çalışması gibi uygulamak bir algoritma xnerede f x ≠ ⊥etki alanını numaralandırma tarafından f⊥ ile başlayan. Her ne kadar böyle bir uygulama, mümkünse bile, seqpolimorfik yapmak istediğimizde oldukça kıllı olur .

Bir kanıt yok hesaplanabilir olduğunu var mı seqolduğunu belirler (\x -> ⊥)ile ⊥ :: A -> B? Alternatif olarak, bazı inşaat var seqtanımlamak olmadığını (\x -> ⊥)sahip ⊥ :: A -> B?

Yanıtlar:


6

İlk olarak, ile λ x arasındaki seqfarkı açıklayalım . :λx.

bottom :: a
bottom = bottom

eta :: a -> b
eta x = bottom

-- This terminates
fortytwo = seq eta 42

-- This does not terminate
infinity = seq bottom 42

λx.seqseqseqλseqλx. katılıyorum, ötekinde değil.

λ[DE]=λx.seq

λseqλx.η[DE][DE]λx.seq


1
GHC ve / veya Hugs ⊥ ve λx.⊥'da deneysel bir gerçektir. Neyse ki, Haskell bir uygulama tarafından tanımlanmamış. Benim sorum Haskell'in seq ile ilgili olarak yetersiz olduğunu gösteriyor.
Russell O'Connor

"Etkili Scott etki alanları" ile ne demek istediğinize bir referans verebilir misiniz? Bu muhtemelen kısmi düzenin karar verilebileceği anlamına gelmez. Ayrıca, STLC polimorfik değildir, ancak Haskell. Genellikle Haskell, Sistem F'de veya türevlerinden birinde yorumlanır. Bu tartışmanızı nasıl etkiler?
Russell O'Connor

Doktora bölüm 1.1.4 Tez andrej.com/thesis/thesis.pdf etkili Scott alanlarının kısa tanımı vardır ve bu aslında ilk Google o serbestçe kullanılabilir vurmak olduğunu.
Andrej Bauer

2
Benim için bir kanıt yazarsanız, eta kuralının (foldr (\ ab -> fab) z xs) 'nin (foldr fz xs)' ye göre optimize edilmesine izin veren Haskell 98'in bir uygulamasını alırsınız. (n ^ 2) ila O (n) arasındadır (bkz. ghc.haskell.org/trac/ghc/ticket/7436 ). Daha cazip olan, (NewTypeWrapper. F) içindeki bir NewTypeWrapper'ın f'nin eta genişlemesini zorlamadan optimize edilmesine ve şu anda GHC'de newTypes tarafından uygulanan bazı asimptotik performans cezalarının önlenmesine (örneğin foldr kullanımı) izin verecektir.
Russell O'Connor

1
λx.λx.seqseq

2

seqAlıntı yaptığınız belirtimin tanımı olmadığını unutmayın . Haskell raporunu alıntılamak için "seq işlevi denklemler : [ve sonra verdiğiniz denklemler] tarafından tanımlanır ".

Önerilen argüman, seq (\ x -> ⊥) b = ⊥ ise seq'in hesaplanamayacağı gibi görünmektedir.

Bu tür davranışların şartnamelerini ihlal eder seq.

Önemli olarak, seqpolimorfik seqolduğu için, iki parametrenin herhangi birinde yapısökücüler (projeksiyonlar / desen eşleştirme vb.) Olarak tanımlanamaz.

\ :: A -> B ile (\ x -> ⊥) tanımlayan hesaplanabilir bir seq olmadığını gösteren bir kanıt var mı?

Eğer seq' (\x -> ⊥) bbiri ilk parametreyi (bir işlevdir) bir değere uygulayıp sonra çıkabileceğimizi düşünebilir. Ancak, parametrik polimorfik tipi nedeniyle seqilk parametreyi asla bir işlev değeri ile tanımlayamaz (bir miktar kullanım için bir tane olsa bile seq). Parametriklik, parametreler hakkında hiçbir şey bilmediğimiz anlamına gelir. Ayrıca, seqasla bir ifade alıp "bu ⊥?" (bkz. Durma problemi), seqsadece onu değerlendirmeye çalışabilir ve kendisi ⊥'ye yönelebilir.

Ne seqyapar, daha sonra (tam olarak, ama en üstteki kurucusuna "zayıf baş normal formda" [1], yani,) ilk parametre değerlendirmek ikinci parametre döndürmektir. İlk parametre (yani, sonlandırıcı olmayan bir hesaplama) olursa , o zaman değerlendirmek seqsonlandırılmamasına neden olur ve dolayısıyla seq ⊥ a = ⊥.

[1] seq Varlığında Ücretsiz Teoremler - Johann, Voigtlander http://www.iai.uni-bonn.de/~jv/p76-voigtlaender.pdf


Seq için verdiğim spesifikasyon seq'un tanımıdır, çünkü Haskell 2010 raporunun Bölüm 6.2'de söylediği tam olarak budur. Seq işlem tanımınız Haskell 2010 raporu tarafından desteklenmiyor: "Head normal form" kelimeleri raporda yalnızca bir kez tamamen farklı bir bağlamda yer alıyor. Ayrıca, GHC'nin ikinci argümanı ilk argümandan önce seq için azaltacağı ya da ilk argümanın hiç azalmayacağı anlayışıyla tutarsızdır, çünkü katılık analizörü bunun statik olmayan bir durum olduğunu kanıtlamıştır.
Russell O'Connor

Parametriklik, herhangi bir yapısökücüyü uygulayamayacağımızı doğrudan söylemez veya ilk parametreyi hiçbir zaman bir işlev değeri ile tanımlayamayacağımızı da söylemez. Tüm parametre kenti, sabit noktalara sahip polimorfik lambda hesabı için, seq'in katı fonksiyonları emebileceğini veya daha genel olarak terimler için tutulan belirli sıkı ilişkilerin seq içerdiğini söylüyor. Parametrikliğin (\ x -> ⊥) ve ne kanıtlamak için kullanılabileceğinin makul olduğunu itiraf ediyorum; ⊥, ama titiz bir kanıt görmek istiyorum.
Russell O'Connor

Bir işlev söz konusu olduğunda ( başka bir türün f : forall a . a -> Tolduğu yerde T), o fzaman hangi dekonstrüktörlerin uygulanacağını bilmediği için herhangi bir dekonstrüktör ilk argümanına uygulanamaz. Tipler üzerinde "dava" yapamayız. Yukarıdaki cevabı geliştirmeye çalıştım ( seqnormal formda değerlendirme hakkında bilgi vermeyi de içeren ).
dorchard

Daha sonra zaman bulursam sıkı kanıtı yapmaya çalışabilirim (Reynolds tarzında ilişkileri kullanmak iyi bir yaklaşım olabilir).
dorchard

@ RussellO'Connor: seq'in açıklaması bu davranışlarla "tutarsız" değildir, sadece işlevsel bir özelliktir (ve davranışlar, nihai sonucu değiştirmeyen optimizasyonlardır).
Blaisorblade

2

λx.λx.

Samson Abramsky bu konuyu uzun zaman önce ele aldı ve " The Lazy Lambda Calculus " adlı bir makale yazdı . Yani, resmi tanımlar istiyorsanız, burası bakabileceğiniz yerdir.


1
Görünüşe göre, bu detaylar sadece "Haskell çekirdeğine" desugaring ile tanımlanır. Nerede tanımlanıyor? Raporda Sec. 1.2 : "Çekirdek resmi olarak belirtilmese de, esasen basit bir anlamsal semantiğe sahip lambda taşının hafif şekerli bir çeşididir. Her sözdizimsel yapının çekirdeğe çevirisi sözdizimi tanıtıldıkça verilir."
Blaisorblade

Haskell 2010 raporu da aynı şeyi söylüyor .
Blaisorblade

Abramsky'ye referansınız için teşekkürler! Soruyu nasıl cevapladığını görmek için göz gezdirdim
Blaisorblade

2

Bunu kanıtlamak λ x. Ram ‌ ≠ Ω, Abramsky'nin tembel lambda kalkülüs teorisi ( Uday Reddy tarafından alıntılanan makalesinin 2. sayfası) için belirlediği hedeflerden biridir , çünkü ikisi de zayıf kafa normal formundadır. Tanım 2.7 itibariyle, açıkça eta indirgeme λ x tartışıyor. M x → M genellikle geçerli değildir, ancak M her ortamda sona ererse mümkündür. Bu, M'nin toplam bir işlev olması gerektiği anlamına gelmez - yalnızca M'yi değerlendirmenin sona erdirilmesi gerektiği anlamına gelir (örneğin bir lambdaya indirgeyerek).

Sorunuz pratik kaygılarla (performans) motive olmuş gibi görünüyor. Ancak, Haskell Raporu tamamen net olmasa da, λ x eşitliğinden şüpheliyim. ‌ ‌ ile ⊥ Haskell'in faydalı bir uygulamasını üretecektir; Haskell '98'i uygulasın ya da uygulamasın tartışmalı olsa da, söze göre, yazarların durumun böyle olmasını istediği açıktır.

Son olarak, rastgele bir girdi türü için elemanlar nasıl oluşturulur? (QuickCheck'in bunun için Keyfi tip sınıfını tanımladığını biliyorum, ancak bu tür kısıtlamaları buraya eklemenize izin verilmiyor). Bu parametrikliği ihlal eder.

Güncellendi : Bu hakkı kodlamayı başaramadım (çünkü Haskel'de çok akıcı değilim) ve bunu düzeltmek iç içe runSTbölgeler gerektiriyor gibi görünüyor . Bu tür keyfi öğeleri kaydetmek, daha sonra okumak ve evrensel olarak kullanılabilir hale getirmek için tek bir referans hücresi (ST monad'da) kullanmayı denedim. Parametriklik break_parametricity, önerilen seq'in üreteceği öğeleri kurtarabilirken, aşağıda tanımlanamayacağını (altta döndürme, örneğin bir hata hariç) kanıtlar .

import Control.Monad.ST
import Data.STRef
import Data.Maybe

produce_maybe_a :: Maybe a
produce_maybe_a = runST $ do { cell <- newSTRef Nothing; (\x -> writeSTRef cell (Just x) >> return x) `seq` (readSTRef cell) }

break_parametricity :: a
break_parametricity = fromJust produce_maybe_a

İtiraf etmeliyim ki burada gerekli olan parametrik kanıtın resmileştirilmesinde biraz bulanıkım, ama parametrikliğin gayri resmi kullanımı Haskell'de standart; ama Derek Dreyer'in yazılarından, gerekli teorinin bu son yıllarda hızla çözüldüğünü öğrendim.

düzenlemeler:

  • ML benzeri, zorunlu ve türlenmemiş diller için incelenen bu uzantılara ihtiyacınız olup olmadığından veya klasik parametrik teorilerinin Haskell'i kapsadığından emin değilim.
  • Ayrıca, Derek Dreyer'den bahsetmiştim, çünkü daha sonra sadece Uday Reddy'nin çalışmasına rastladım - sadece son zamanlarda "Reynolds'ın özü" nden öğrendim. (Parametriklik ile ilgili literatürü sadece son bir ayda okumaya başladım).

(\x -> writeSTRef cell (Just x) >> return x)Rastgele girişleri değerlendirmek hücreye yazma işlemi gerçekleştirmez. Yalnızca dizilenmiş diziye giren ST komutları runSTyürütülür. Benzer şekilde, çalıştırma main = (putStrLn "Hello") `seq` (return ())ekrana hiçbir şey yazdırmaz.
Russell O'Connor

@ RussellO'Connor, elbette haklısınız - seq tartıştığımız davranışa sahip olmadığından test etmek zor. Ama hala eleman üretmenin kendi başına parametrikliği bozduğunu düşünüyorum. Bunu örneklemek için cevabı düzeltmeye çalışacağım.
Blaisorblade

Hm, cevabın açık bir şekilde düzeltilmesi için runST bölgelerinin yuvalanması ve hücrenin iç bölgedeki dış bölgeden kullanılması gerekir, ancak buna izin verilmez.
Blaisorblade
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.