Yineleme Recursion'un yerini alabilir mi?


41

Yığın Overflow'u görüyordum, örneğin, burada , burada , burada , burada , burada ve bazılarında "yinelemeyi kullanan herhangi bir programın yalnızca yinelemeyi kullanan bir programa dönüştürülebileceğini" söylemek istemiyorum.

Evet, bunun mümkün olduğunu söyleyen son derece yükseltilmiş bir cevabı olan çok iyi bir iş parçacığı bile vardı .

Şimdi yanlış olduklarını söylemiyorum. Sadece cevap bu yetersiz bilgi ve bilgisayar konusundaki anlayışımı sayıyor.

Her yinelemeli fonksiyonun özyineleme olarak ifade edilebileceğine inanıyorum ve wikipedia'nın bu yönde bir ifadesi var. Ancak, konuşmanın doğru olduğundan şüpheliyim. Birincisi, ilkel olmayan özyinelemeli işlevlerin yinelemeli olarak ifade edilebileceğinden şüpheliyim.

Ayrıca hiper-işlemlerin yinelemeyle ifade edilebileceğinden de şüpheliyim.

Onun içinde cevap benim için (Bu arada anlamıyorum olan) Söz @YuvalFIlmus o eklemeler bir dizi içine matematiksel işlemlerin herhangi dizisini dönüştürmek mümkün olmadığını söyledi.

Eğer YF'nin cevabı gerçekten doğruysa (Sanırım doğru, ama aklı başımın üstünde kaldı), o zaman bu her özyinelemenin yinelemeye dönüştürülemeyeceği anlamına gelmiyor mu? Çünkü her bir özyinelemeyi yinelemeye dönüştürmek mümkün olsaydı, tüm işlemleri bir toplama sırası olarak ifade edebilirdim.

Sorum şu:

Her özyineleme yinelemeye dönüştürülebilir mi ve neden?

Lütfen parlak bir lise öğrencisi veya bir lisans öğrencisinin anlayacağı bir cevap verin. Teşekkür ederim.

PS İlkel özyinelemenin ne olduğunu bilmiyorum (Ackermann işlevi hakkında bilgiliyim ve ilkel özyinelemeli olmadığını biliyorum ama yine de hesaplanabilir. Bu konuda benim bilgim Ackermann işlevindeki Wikipedia sayfasından geliyor.)

PPS: Cevap evetse, örneğin ilkel olmayan özyinelemeli bir fonksiyonun yinelemeli bir versiyonunu yazabilir misiniz? Örneğin Ackermann. Anlamama yardımcı olacak.


21
Bir işlemcide çalıştırdığınız her şey yinelemelidir. Özyinelemeli olarak daha yüksek bir dilde yazabilirsiniz, ancak yine de bir çok yinelemeli assembler komutunda derlenir. Tam anlamıyla, derleyici tam olarak ne istediğinizi yapar, tüm fantezi özyinelemenizi bir CPU için yinelenen talimatlara dönüştürür.
Davor

6
Düşük düzeyde, çoğumuz özyinelemenin yinelemeye ve yığına eşit olduğunu biliriz. Bağlam içermeyen gramerler, yinelemeyi modellerken, aşağı itme otomatları yığın hafızalı yinelemeli "programlar" dır.
Hendrik Ocak

2
Sadece başka cevapların ortaya çıkıp çıkmadığını görmek için en az 24 saat beklemenin iyi bir fikir olduğunu işaret edin. Kabul edilen soru oldukça açık ve bana açık bir şekilde yanıt veriyor ve kasıtlı olarak meseleleri gereğinden fazla karmaşıklaştırıyor gibi görünüyor. Sorunuza verilen temel cevap, "özyineleme için kullanılan yığın açıkça yinelemeli bir şekilde uygulanabilir" dir ve bundan daha karmaşık olması gerekmez. Belleğin sınırlandırılmamış olması veya devreye girmemesi ile ilgili hususlar, bu özellik yinelemeli yığınlar için de gerekli olduğu için gerekli değildir.
16'da

Turing makine emülatörünü sadece yinelemeyle uygulamak mümkündür
Sarge Borsch

Uzun zaman önce karşılaştığım karşılaştırmalı bir dil sınıfında, Ackermann'ın meclisindeki, FORTRAN'daki (modern Fortran'daki değil) ve tercih edilen özyinelemeli bir dilde yazması gerekti. Yani evet, pratikte mümkün. Ve elbette teoride mümkündür. Örneğin, soruya Turing makinelerinin ve lambda hesaplamasının eşdeğer olduğunu ispatlayın .
David Hammen,

Yanıtlar:


51

Özyineleme yineleme artı sınırsız bellek ile değiştirmek mümkündür .

Yalnızca yinelemeye (döngülerde) söyleyin ve sınırlı miktarda bellek varsa, sahip olduğunuz tek şey sonlu bir otomat. Sınırlı miktarda bellek ile hesaplamada sınırlı sayıda olası adım vardır, bu yüzden hepsini sınırlı bir otomat ile simüle etmek mümkündür.

Sınırsız belleğe sahip olmak anlaşmayı değiştirir. Bu sınırlandırılmamış bellek, eşdeğer ifade gücüne sahip olduğu ortaya çıkan birçok biçimi alabilir. Örneğin, bir Turing makinesi basit tutuyor: tek bir bant var ve bilgisayar kasette yalnızca bir adım ileri veya geri hareket edebilir - ancak özyinelemeli işlevlerle yapabileceğiniz her şeyi yapmak için bu yeterlidir.

Turing makinesi, talep üzerine yetişen fazladan depolamaya sahip, ideal bir bilgisayar modeli (sonlu durumlu makine) olarak görülebilir. Teyp üzerinde sonlu bir sınırın bulunmasının yanı sıra, girdi verilse bile, ne kadar bant gerektiğinin güvenilir bir şekilde tahmin edilemeyeceğini unutmayın. Girişten ne kadar bant gerekeceğini tahmin edebiliyorsanız (yani hesaplayabilirseniz), maksimum bant boyutunu hesaplayarak ve sonra da sonlu bant dahil olmak üzere tüm sistemi sonlu durumlu bir makine olarak ele alarak hesaplamanın durup durmayacağına karar verebilirsiniz. .

Bir Turing makinesini bilgisayarlarla simüle etmenin bir başka yolu da aşağıdaki gibidir. Turing makinesini, bandın başlangıcını bellekte saklayan bir bilgisayar programı ile simüle edin. Hesaplama, belleğe uyan kasetin bir kısmına ulaşırsa, bilgisayarı daha büyük bir bilgisayarla değiştirin ve hesaplamayı yeniden çalıştırın.

Şimdi bir bilgisayarla özyinelemeli bir hesaplama benzetmek istediğinizi varsayalım. Özyinelemeli işlevleri yürütme teknikleri iyi bilinmektedir: her bir işlev çağrısında yığın çerçeve adı verilen bir bellek parçası vardır . Önemli olarak, özyinelemeli fonksiyonlar etrafındaki değişkenleri geçirerek çoklu aramalar yoluyla bilgiyi yayabilir. Bilgisayardaki uygulama açısından, bu, bir işlev çağrısının bir (büyük) * üst çağrının yığın çerçevesine erişebileceği anlamına gelir .

Bilgisayar bir işlemcidir - sonlu durumlu bir makine (çok sayıda durumla birlikte, ancak burada hesaplama teorisi yapıyoruz, bu yüzden önemli olan sonlu olmasıdır) - sonlu bir hafıza ile birleştirilmiş. Mikroişlemci döngü sırasında bir devle çalışıyor: “güç açıkken bellekten bir talimat okuyun ve uygulayın”. (Gerçek işlemciler bundan çok daha karmaşıktır, ancak hesaplayabileceklerini etkilemez, yalnızca ne kadar hızlı ve kolay bir şekilde yaptıklarını etkilemez.) Bir bilgisayar yinelemeyi sağlamak için döngüdeyken özyinelemeli işlevleri yürütebilir. İsteğe bağlı hafıza boyutunu artırmak için de dahil olmak üzere erişim hafızasına

Özyinelemeyi ilkel özyinelemeyle sınırlarsanız, yinelemeyi sınırlı yinelemeyle sınırlayabilirsiniz . Yani, öngörülemeyen bir çalışma süresine sahip döngülerdeyken kullanmak yerine, döngü başlangıcında yineleme sayısının bilindiği döngülerde kullanabilirsiniz. Programın başında yineleme sayısı bilinmiyor olabilir: önceki döngüler tarafından hesaplanmış olabilir.

Burada bir kanıt bile çizmeyeceğim, ancak ilkel özyinelemeden tam özyinelemeye gidip döngülerden döngüdeyken gelmeye kadar sezgisel bir ilişki var: her iki durumda da, ne zaman olacağını önceden bilmemeyi içerir. Dur. Tam özyinelemeyle, bu koşulu sağlayan bir parametre bulana kadar devam ettiğiniz minimizasyon operatörü ile yapılır. Döngüler ile bu, döngü koşulu sağlanıncaya kadar devam ettirilerek yapılır.

forwhilen


Detaylı açıklama için kabul edilen, istenen düzeyde tutulur.
16'da Tobi Alafin

12
Bence gerçek bilgisayarlardan daha fazla dikkat çekiyor, özyineleme de bellek kullanıyor (artan arama yığını). Bu yüzden pratik uygulamalarda sınırsız belleğe gerek yoktur (çünkü her şey onunla eşit olarak sınırlanmıştır). Ve özyineleme sıklıkla yinelemeden daha fazla belleğe ihtiyaç duyar.
Ajan_L

@Agent_L Evet, tüm yığın çerçevelerini saklamak için özyineleme sınırsız belleğe ihtiyaç duyar. Özyinelemeli bir yaklaşımla, sınırlandırılmamış belleğe gereksinim vardır, ancak yinelemelerde olduğu gibi işlemlerin sıralanmasından sezgisel olarak ayrılmaz.
Gilles 'SO- kötülük' dur

Belki de ilgi çeken kilise Turing tezi olacaktır. Turing makineleri, (içsel) özyineleme kavramı olmayan yüksek derecede yinelemeli makinelerdir. Lambda hesabı, hesaplamaları özyinelemeli bir şekilde ifade etmek için tasarlanan bir dildir. Kilise-Turing tezi, tüm lambda ifadelerinin bir Turing makinesinde değerlendirilebileceğini, özyineleme ve yinelemeyi birbirine bağladığını gösterdi.
Cort Ammon

1
@BlackVegetable Özyinelemeli bir yöntemin dahili değişkenleri yoksa ve kullandığı tek bellek çağrı yığınıdır (TCO tarafından optimize edilebilir), o zaman yinelemeli sürümü büyük olasılıkla ayrıca dahili değişkenler içermez ve yalnızca sabit miktarda bellek kullanır ( değişkenler) sayaç gibi tüm yinelemelerde paylaşılır.
Ajan_L

33

Her bir özyineleme, CPU'nuzun şahit olduğu şekilde bir getirme-çalıştırma sonsuz yineleme kullanarak keyfi programlar yürüten yinelemeye dönüştürülebilir. Bu, Böhm-Jacopini teoreminin bir şeklidir . Üstelik, birçok Turing tamamlanmış hesaplama modelinde, örneğin Turing makineleri ve tezgah makineleri gibi özyineleme yoktur .

İlkel özyinelemeli fonksiyonlar sınırlı yineleme kullanan programlara karşılık gelir , yani bir döngünün önceden yürütüldüğü yineleme sayısını belirlemelisiniz. Sınırlı yineleme, genel olarak özyinelemeyi simüle edemez, çünkü Ackermann işlevi ilkel özyinelemeli değildir. Ancak sınırlandırılmamış yineleme, kısmen hesaplanabilir işlevleri simüle edebilir.


25

a(n,m)

s

push(s,x)xxpop(s)empty(s)

Ackermann(n0,m0):

  • s= (boş yığını )
  • push(s,n0)
  • push(s,m0)
  • while(true):
    • mpop(s)
    • if(empty(s)):
      • return m (bu döngü biter)
    • npop(s)
    • if(n=0):
      • push(s,m+1)
    • else if(m=0):
      • push(s,n1)
      • push(s,1)
    • else:
      • push(s,n1)
      • push(s,n)
      • push(s,m1)

Bunu Ceylon'da uyguladım , isterseniz WebIDE'de çalıştırabilirsiniz . (Yığını, döngünün her yinelemesinin başlangıcında çıkar.)

Tabii ki, bu sadece gizli çağrı yığınını özyinelemeden parametreleri ve dönüş değerleriyle açık bir yığına taşıdı.


15
Bunun önemli bir nokta olduğunu düşünüyorum. Açık bir şekilde, özyinelemenin özel bir şey olmadığını ve derleyicinin yapmasına izin vermek yerine, çağrı kümesini takip ederek çıkarılabileceğini açıkça gösterdiniz. Özyineleme, bu tür programları yazmayı kolaylaştıran derleyici bir özelliktir.
David Richerby

4
İstenen programı yazma çabası için teşekkür ederiz.
Tobi Alafin,

15

Zaten bazı büyük cevaplar var (ki rekabet edebileceğimi bile umuyorum), ama bu basit açıklamayı yapmak istiyorum.

Özyineleme, çalışma zamanı yığınının yalnızca manipülasyonudur. Özyineleme, yeni bir yığın çerçeve ekler (özyinelemeli fonksiyonun yeni başlatılması için) ve geri dönüş, bir öznitelik çerçevesini kaldırır (özyinelemeli fonksiyonun henüz tamamlanmış yeniliği için). Özyineleme, sonuçta tümü çıkacak (umarım!) Ve sonuç arayana geri dönene kadar bazı yığın çerçeveleri eklenmesine / kaldırılmasına neden olur.

Şimdi, kendi yığınınızı yaparsanız, özyinelemeli işlev çağrılarını yığına itme ile değiştirir, özyinelemeli işlevlerden geri getirmeyi yığma atma ile değiştirir ve yığının boşalıncaya kadar süren bir döngü geçirirseniz ne olur?


2

Söyleyebileceğim kadarıyla ve kendi tecrübelerime göre, herhangi bir özyinelemeyi yineleme olarak uygulayabilirsiniz. Yukarıda bahsedildiği gibi, özyineleme, kavramsal olarak sınırsız ancak pratik olarak sınırlı olan yığını kullanır (hiç yığın taşma mesajı aldınız mı?). Programlamanın ilk günlerinde (son binyılın son yüzyılın üçüncü çeyreğinde), özyinelemeli algoritmalar uygulayan özyinelemeli olmayan dilleri kullanıyordum ve hiç problem yaşamadım. Yine de nasıl kanıtlayacağından emin değilim.

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.