Şu anda Turing makinelerinin genel bir hesaplama modeli olduğuna kendimi nasıl ikna edeceğimi düşünüyorum. Kilise Turing tezinin, bazı standart ders kitaplarında, örneğin Sipser'de standart muamelenin çok eksiksiz olmadığını kabul ediyorum. İşte Turing makinelerinden daha tanınabilir bir programlama diline nasıl geçebileceğimin bir taslağı.
Özyinelemesiz tanımlı işlevler ve alt yordamlar içeren ve adlandırılmış boole rasgele değişkenleri ve genel boole ifadeleri olan ve artırılabilen veya azaltılabilen bir tamsayı dizi işaretçisine sahip tek bir sınırsız boole dizisi olan if
ve while
ifadeleriyle blok yapılı bir programlama dili düşünün veya . İşaretçi başlangıçta sıfırdır ve dizi başlangıçta sıfırdır. Bu nedenle, bu bilgisayar dili C benzeri veya Python benzeri olabilir, ancak veri türlerinde çok sınırlıdır. Aslında, o kadar sınırlılar ki, işaretçiyi bir boole ifadesinde kullanmanın bir yolumuz bile yok . Varsayalımtape[n]
n
n++
n--
n
tape
n
tape
yalnızca sağa sınırsızsa, n
negatifse bir işaretçi alt akışı "sistem hatası" bildirebiliriz . Ayrıca, dilimizin exit
bir argümanla birlikte bir boole cevabı çıkarmak için bir ifadesi vardır.
O zaman ilk nokta, bu programlama dilinin bir Turing makinesi için iyi bir şartname dilidir. Bant dizisi hariç, kodun yalnızca son derece olası durumları olduğunu kolayca görebilirsiniz: Bildirilen tüm değişkenlerinin durumu ve geçerli yürütme satırı ve alt rutin yığını. İkincisinin yalnızca sınırlı bir durumu vardır, çünkü özyinelemeli işlevlere izin verilmez. Bu tür bir koddan "gerçek" bir Turing makinesi oluşturan bir "derleyici" hayal edebilirsiniz, ancak bunun ayrıntıları önemli değildir. Mesele şu ki, oldukça iyi sözdizimine sahip, ancak çok ilkel veri türlerine sahip bir programlama dilimiz var.
Yapının geri kalanı, bunu sınırlı kütüphane fonksiyonları ve ön derleme aşamaları listesi ile daha yaşanabilir bir programlama diline dönüştürmektir. Aşağıdaki gibi devam edebiliriz:
Bir ön derleyici ile, boole veri tipini ASCII gibi daha büyük ama sonlu bir sembol alfabesine genişletebiliriz. Bunun tape
bu daha büyük alfabedeki değerleri aldığını varsayabiliriz . İşaretçinin taşmasını önlemek için bandın başında bir işaretleyici ve TM'nin yanlışlıkla bantta sonsuzluğa kaymasını önlemek için bandın sonunda hareketli bir işaretleyici bırakabiliriz. Semboller ve boolean if
ve while
ifadeleri için dönüşümler arasında isteğe bağlı ikili işlemler gerçekleştirebiliriz . (Aslında if
ile uygulanabilir while
mevcut olmasaydı, hem de.)
kkbenbenk
Bir bandı sembol değerli "bellek", diğer bandı işaretsiz, tamsayı değerli "kayıt" veya "değişken" olarak adlandırıyoruz. Tam sayıları sonlandırma işaretçileri olan küçük endian ikili dosyasında saklarız. İlk olarak bir sicilin bir kopyasını ve bir sicilin ikili azalmasını uygularız. Bunu bellek işaretçisinin artması ve azalmasıyla birleştirerek, sembol belleğine rasgele erişim araması uygulayabiliriz. Tamsayıların ikili toplanmasını ve çarpılmasını hesaplamak için fonksiyonlar da yazabiliriz. Bitsel işlemlerle ikili bir ekleme işlevi ve sola kaydırma ile 2 ile çarpma işlevi yazmak zor değildir. (Ya da gerçekten sağa kaydırma, çünkü küçük endian.) Bu ilkellerle, uzun çarpma algoritmasını kullanarak iki kaydı çoğaltmak için bir işlev yazabiliriz.
Formülü kullanarak bellek bandını bir boyutlu sembol dizisinden symbol[n]
iki boyutlu sembol dizisine yeniden düzenleyebiliriz . Şimdi, tek boyutlu, rasgele erişimli, tamsayı değerli bir bellek elde etmek için, bir sonlandırma simgesiyle ikili olarak işaretsiz bir tamsayıyı ifade etmek için belleğin her bir satırını kullanabiliriz . Bellekten bir tamsayı yazmacına okuma ve bir yazmaçtan belleğe yazma uygulayabiliriz. Artık birçok özellik fonksiyonlarla uygulanabilir: İmzalı ve kayan nokta aritmetiği, sembol dizeleri, vb.symbol[x,y]
n = (x+y)*(x+y) + y
memory[x]
Sadece bir temel tesis kesinlikle ön derleyici yani özyinelemeli fonksiyonlar gerektirir. Bu, yorumlanmış dilleri uygulamak için yaygın olarak kullanılan bir teknikle yapılabilir. Her bir üst düzey, özyinelemeli işleve bir ad dizesi atarız ve düşük düzeyli kodu while
, normal parametrelerle bir çağrı yığını tutan tek bir büyük döngü halinde düzenleriz: çağrı noktası, çağrılan işlev ve bağımsız değişkenler listesi.
Bu noktada, yapı, üst düzey bir programlama dilinin, daha fazla işlevselliğin CS teorisinden ziyade programlama dilleri ve derleyicileri konusu olduğu yeterli özelliklerine sahiptir. Bu gelişmiş dilde bir Turing makinesi simülatörü yazmak da kolaydır. Dil için kendi kendine derleyici yazmak tam olarak kolay değil, ama kesinlikle standarttır. Tabii ki bu C benzeri veya Python benzeri dilde bir koddan dış TM oluşturmak için bir dış derleyiciye ihtiyacınız vardır, ancak bu herhangi bir bilgisayar dilinde yapılabilir.
Bu kabataslak uygulamanın sadece özyinelemeli işlev sınıfı için mantıkçıların Church-Turing tezini değil, aynı zamanda deterministik hesaplama için geçerli olduğu gibi genişletilmiş (yani polinom) Church-Turing tezini de desteklediğini unutmayın. Başka bir deyişle, polinom yükü vardır. Aslında, bize bir RAM makinesi veya (benim favorim) bir ağaç kaseti TM verilirse, RAM belleğiyle seri hesaplama için polilogaritmik yüke indirgenebilir.