Sabit nokta birleştirici - Fixed-point combinator

Matematik ve de bilgisayar biliminin , genel olarak, bir sabit nokta bir fonksiyonu fonksiyonu ile kendi eşlenen bir değerdir.

Gelen kombinatoriyel mantık için bilgisayar biliminin , bir sabit noktalı combinator (veya fixpoint combinator ) a nın daha yüksek dereceden fonksiyonu bu döner argümanı fonksiyonunun bir sabit nokta, eğer varsa.

Biçimsel olarak, f fonksiyonunun bir veya daha fazla sabit noktası varsa, o zaman

ve bu nedenle, tekrarlanan uygulama ile,

Y birleştirici

Klasik tiplendirilmemiş lambda hesabında her fonksiyonun sabit bir noktası vardır.

Özel bir uygulama düzeltme olduğunu Curry'nin paradoksal combinator Y ile temsil,

Gelen fonksiyonel programlama , Y combinator resmen tanımlamak için kullanılabilir özyinelemeli fonksiyonlar özyinelemeye desteklemeyen bir programlama dilinde.

Bu birleştirici Curry'nin paradoksunun uygulanmasında kullanılabilir . Curry'nin paradoksunun kalbi, türlenmemiş lambda hesabının tümdengelimli bir sistem olarak sağlam olmamasıdır ve Y birleştiricisi, anonim bir ifadenin sıfırı, hatta birçok değeri temsil etmesine izin vererek bunu gösterir. Bu matematiksel mantıkta tutarsızdır.

Tek değişkenli bir işleve uygulanan Y birleştiricisi genellikle sonlanmaz. Y birleştiricisini iki veya daha fazla değişkenli fonksiyonlara uygulayarak daha ilginç sonuçlar elde edilir . İkinci değişken bir sayaç veya indeks olarak kullanılabilir. Ortaya çıkan işlev , zorunlu bir dilde bir süre veya bir for döngüsü gibi davranır .

Bu şekilde kullanıldığında Y birleştiricisi basit özyineleme uygular. Lambda hesabında, bir fonksiyon gövdesindeki bir fonksiyonun tanımına atıfta bulunmak mümkün değildir. Özyineleme yalnızca bir işlevi parametre olarak ileterek elde edilebilir. Y combinator programlama bu tarzı gösterir.

Sabit nokta birleştirici

Y, combinator lambda Diferensiyel bir sabit noktalı combinator bir uygulamasıdır. Sabit nokta birleştiriciler, diğer işlevsel ve zorunlu dillerde de kolayca tanımlanabilir. Lambda hesabındaki sınırlamalar nedeniyle lambda hesabındaki uygulama daha zordur. Sabit nokta birleştirici birkaç farklı alanda kullanılabilir:

Sabit nokta birleştiriciler bir dizi farklı işleve uygulanabilir, ancak normalde fazladan bir parametre olmadıkça sonlandırılmaz. Sabitlenecek işlev parametresine başvurduğunda, işleve başka bir çağrı çağrılır, bu nedenle hesaplama hiçbir zaman başlamaz. Bunun yerine, hesaplamanın başlamasını tetiklemek için ekstra parametre kullanılır.

Sabit noktanın tipi, sabitlenen fonksiyonun dönüş tipidir. Bu bir gerçek veya bir işlev veya başka bir tür olabilir.

Türlenmemiş lambda hesabında, sabit nokta birleştiriciyi uygulama işlevi, Church kodlaması gibi bir kodlama kullanılarak ifade edilebilir . Bu durumda (işlevleri tanımlayan) belirli lambda terimleri değer olarak kabul edilir. Kodlamadaki sabit nokta birleştiricinin "çalışması" (beta indirgemesi), sonuç için daha sonra sabit nokta değeri olarak yorumlanabilecek bir lambda terimi verir.

Alternatif olarak, bir fonksiyon, tamamen lambda hesabında tanımlanan bir lambda terimi olarak düşünülebilir.

Bu farklı yaklaşımlar, bir matematikçinin ve bir programcının sabit nokta birleştiricisini nasıl görebileceğini etkiler. Bir lambda hesabı matematikçisi, bir fonksiyona uygulanan Y birleştiricisini sabit nokta denklemini karşılayan bir ifade ve dolayısıyla bir çözüm olarak görebilir.

Buna karşılık, bazı genel programlama görevlerine yalnızca sabit nokta birleştirici uygulamak isteyen bir kişi, bunu yalnızca özyinelemeyi uygulamanın bir aracı olarak görebilir.

Değerler ve etki alanları

Her ifadenin bir değeri vardır. Bu genel matematikte doğrudur ve lambda hesabında da doğru olmalıdır. Bu, lambda hesabında, bir fonksiyona sabit nokta birleştirici uygulamanın size değeri fonksiyonun sabit noktası olan bir ifade verdiği anlamına gelir.

Bununla birlikte, bu lambda hesabı alanındaki bir değerdir, fonksiyonun alanındaki herhangi bir değere karşılık gelmeyebilir, bu nedenle pratik anlamda mutlaka fonksiyonun sabit bir noktası değildir ve yalnızca lambda hesabı alanında denklemin sabit bir noktasıdır.

Örneğin, düşünün

Küme bir imza numaraları , yani Church kodlama uygulanabilir f bir lambda terimi ile temsil edilebilir. Bu denklemin reel sayılarda çözümü yoktur. Ama karmaşık sayıların alanında i ve -i çözümlerdir. Bu, başka bir alanda bir denklemin çözümlerinin olabileceğini gösterir. Ancak, yukarıdaki denklemin çözümü için kullanılan lambda terimi bundan daha tuhaftır. Lambda terimi , x'in bir değer olarak i veya -i olabileceği durumu temsil eder . Alan değişikliğinde bu iki değeri birbirinden ayıran bilgiler kaybolmuştur.

Lambda hesabı matematikçisi için bu, lambda hesabı tanımının bir sonucudur. Programcı için bu, lambda teriminin beta indirgemesinin sonsuza kadar döngüye gireceği ve asla normal bir forma ulaşmayacağı anlamına gelir.

İşleve karşı uygulama

Sabit nokta birleştirici matematikte tanımlanabilir ve daha sonra diğer dillerde uygulanabilir. Genel matematik, genişleme özelliklerine dayalı bir işlevi tanımlar . Yani, aynı eşlemeyi yapıyorlarsa iki işlev eşittir. Lambda hesabı ve programlama dilleri, işlev kimliğini kasıtlı bir özellik olarak görür . Bir işlevin kimliği, uygulanmasına dayanır.

Bir lambda hesabı işlevi (veya terimi), bir matematiksel işlevin bir uygulamasıdır. Lambda hesabında, sabit nokta birleştiricinin matematiksel tanımını karşılayan bir dizi birleştirici (uygulama) vardır.

"Birleştirici" nedir?

Kombinasyon mantığı , daha yüksek mertebeden bir fonksiyon teorisidir. Bir birleştirici , kapalı bir lambda ifadesidir, yani serbest değişkeni yoktur. Birleştiriciler, değerleri değişken olarak adlandırmadan ifadedeki doğru yerlerine yönlendirmek için birleştirilebilir.

Programlamada kullanım

Sabit nokta birleştiriciler , işlevlerin özyinelemeli tanımını uygulamak için kullanılabilir . Ancak, pratik programlamada nadiren kullanılırlar. Basit bir şekilde yazılan lambda hesabı gibi güçlü bir şekilde normalleştirici tip sistemler , sonlandırmaya izin vermez ve bu nedenle sabit nokta birleştiricilere genellikle bir tip atanamaz veya karmaşık tip sistem özellikleri gerektirir. Ayrıca, sabit nokta birleştiriciler, daha fazla işlev azaltma gerektirdiğinden ve her bir karşılıklı özyinelemeli tanım grubu için bir demet oluşturup ayırdıklarından, özyinelemeyi uygulamak için diğer stratejilere kıyasla genellikle verimsizdir.

faktör fonksiyonu

Faktör işlevi, sabit nokta birleştiricinin nasıl uygulanabileceğine iyi bir örnek sağlar. Sonuç, zorunlu bir dilde tek bir döngüde uygulanacağı gibi basit özyinelemeyi gösterir. Kullanılan sayıların tanımı Kilise kodlamasında açıklanmıştır .

Kendini parametre olarak alan fonksiyon

Bu YF n'yi şu şekilde verir:

Ayar verir

Bu tanım, F'yi yinelenecek bir döngünün gövdesi rolüne sokar ve faktöriyelin matematiksel tanımına eşdeğerdir:

Lambda hesabında sabit nokta birleştiriciler

Y tarafından keşfedilen combinator Haskell B. Curry olarak tanımlanır

Bunun beta indirgemesi şunları sağlar:

( Y tanımı gereği )
( λf'nin β-indirgenmesiyle : Y'nin g'ye uygulanması)
(λx'in β-indirgenmesiyle: sol fonksiyondan sağ fonksiyona uygulanır)
(ikinci eşitlikle)

Bu eşitliği tekrar tekrar uygulamak şunları verir:

(Yukarıdaki eşitlik, soldan sağa çok adımlı β-indirgemelerinin bir dizisi olarak düşünülmelidir. Lambda terimi , genel olarak, terime β-indirgemeyebilir . Bunun yerine eşitlik işaretleri, β-eşdeğerlikleri olarak yorumlanabilir. her iki yönde de ilerlemeye izin vermek için çok adımlı β-indirgemeleri.)

Sabit nokta birleştiricinin eşdeğer tanımı

Bu sabit nokta birleştirici, aşağıdaki gibi y olarak tanımlanabilir .

y için bir ifade , bir let ifadesinin tanımından kurallar kullanılarak türetilebilir . İlk olarak, kuralı kullanarak

verir

Ayrıca, kullanarak

verir

Ve sonra eta azaltma kuralını kullanarak ,

verir

Y birleştiricisinin türetilmesi

Curry'nin Y birleştiricisi, y tanımından kolaylıkla elde edilebilir .

ile başlayan,

Bir lambda soyutlaması, uygulanan ifadede değişken adına başvuruyu desteklemez, bu nedenle x parametresi olarak x'e geçirilmelidir . Biz değiştirmek gibi bu düşünebiliriz x tarafından xx , ancak resmi olarak bu doğru değil. Bunun yerine tanımlayarak y tarafından verir

let ifadesi, z'nin parametre olduğu y fonksiyonunun tanımı olarak kabul edilebilir . Örnekleme z olarak y çağrısında verir

Ve, z parametresi her zaman y işlevini geçtiği için ,

Kullanılması eta azaltma kuralını,

verir

Bir let ekspresyonu lambda soyutlama olarak ifade edilebilir ; kullanarak

verir

Bu muhtemelen lambda hesabında sabit nokta birleştiricinin en basit uygulamasıdır. Bununla birlikte, bir beta indirgemesi, Curry'nin Y birleştiricisinin daha simetrik biçimini verir:

Ayrıca bkz . let ve lambda ifadeleri arasında çeviri yapma .

Diğer sabit nokta birleştiriciler

Türlenmemiş lambda hesabında sabit nokta birleştiriciler özellikle nadir değildir. Aslında sonsuz sayıda var. 2005'te Mayer Goldberg, türlenmemiş lambda hesabının sabit nokta birleştiricileri kümesinin özyinelemeli olarak sayılabilir olduğunu gösterdi .

Y, combinator ifade edilebilir SKI-taşı olarak

John Tromp tarafından bulunan SK hesabındaki en basit sabit nokta birleştiricisi ,

normal formda olmadığına dikkat edin, ki bu daha uzundur. Bu birleştirici lambda ifadesine karşılık gelir

Aşağıdaki sabit nokta birleştiricisi, Y birleştiricisinden daha basittir ve β, Y birleştiricisine indirgenir; bazen Y birleştiricisinin kendisi olarak anılır:

Diğer bir yaygın sabit nokta birleştiricisi, Turing sabit nokta birleştiricisidir (adını keşfedicisi Alan Turing'den almıştır ):

Bu avantaj, fazla olmasıdır beta-azaltır , oysa ve sadece ortak terim beta-azaltır.

ayrıca basit bir değere göre arama formuna sahiptir:

Karşılıklı özyineleme için analog , Y* olarak gösterilebilen çok değişkenli bir sabit nokta birleştiricidir .

Katı sabit nokta birleştirici

Bir de sıkı bir programlama dili Y combinator yığın taşması kadar genişleyecektir veya kuyruk optimizasyon görüşmemiz durumunda durdurmak asla. Z combinator (uygulamalı değerlendirme sırası uygulanır da adlandırılan istekli diller,) sıkı dilde çalışacaktır. Z, combinator genleşmesini önler, açık bir şekilde tanımlanmış aşağıdaki argüman , Z tanımı sağ tarafında g:

ve lambda hesabında Y birleştiricisinin bir eta-genişlemesidir :

Standart olmayan sabit nokta birleştiriciler

Türlenmemiş lambda hesabında, sabit nokta birleştirici olarak aynı Böhm ağacına sahip olan , yani aynı sonsuz uzantıya sahip olan terimler vardır λx.x (x (x ... )). Bunlara standart olmayan sabit nokta birleştiricileri denir . Herhangi bir sabit nokta birleştirici de standart değildir, ancak standart olmayan tüm sabit nokta birleştiriciler, bazıları "standart" olanları tanımlayan denklemi karşılayamadığı için sabit nokta birleştirici değildir. Bu garip birleştiricilere kesinlikle standart olmayan sabit nokta birleştiriciler denir ; bir örnek aşağıdaki birleştiricidir:

nerede

Standart olmayan sabit nokta birleştiriciler kümesi özyinelemeli olarak numaralandırılamaz.

Diğer dillerde uygulama

(Y birleştiricisi, lambda hesabında sabit nokta birleştiricinin özel bir uygulamasıdır. Yapısı lambda hesabının sınırlamaları tarafından belirlenir. Diğer dillerde sabit nokta birleştiricinin uygulanmasında bu yapının kullanılması gerekli veya yararlı değildir. )

Bazı programlama paradigmalarında uygulanan basit sabit nokta birleştirici örnekleri aşağıda verilmiştir.

Tembel işlevsel uygulama

Haskell'de olduğu gibi tembel değerlendirmeyi destekleyen bir dilde , geleneksel olarak adlandırılan sabit nokta birleştiricinin tanımlayıcı denklemini kullanarak bir sabit nokta birleştiricisi tanımlamak mümkündür . Haskell'in tembel veri türleri olduğundan, bu birleştirici aynı zamanda veri oluşturucularının sabit noktalarını tanımlamak için de kullanılabilir (yalnızca özyinelemeli işlevleri uygulamak için değil). Tanım burada ve ardından bazı kullanım örnekleri verilmiştir. Hackage'da orijinal örnek: fix

fix, fix' :: (a -> a) -> a
fix f = let x = f x in x         -- Lambda dropped. Sharing.
                                 -- Original definition in Data.Function.
-- alternative:
fix' f = f (fix' f)              -- Lambda lifted. Non-sharing.

fix (\x -> 9)                    -- this evaluates to 9

fix (\x -> 3:x)                  -- evaluates to the lazy infinite list [3,3,3,...]

fact = fix fac                   -- evaluates to the factorial function
  where fac f 0 = 1
        fac f x = x * f (x-1)

fact 5                           -- evaluates to 120

Katı işlevsel uygulama

Katı bir işlevsel dilde, f'nin argümanı önceden genişletilir ve sonsuz bir çağrı dizisi verir,

.

Bu, düzeltmeyi fazladan bir parametre ile tanımlayarak çözülebilir.

let rec fix f x = f (fix f) x (* note the extra x; here fix f = \x-> f (fix f) x *)

let factabs fact = function   (* factabs has extra level of lambda abstraction *)
   0 -> 1
 | x -> x * fact (x-1)

let _ = (fix factabs) 5       (* evaluates to "120" *)

Zorunlu dil uygulaması

Bu örnek, sabit nokta birleştiricinin biraz yorumlayıcı bir uygulamasıdır. fixer adlı düzeltme işlevini içeren bir sınıf kullanılır . Sabitlenecek işlev, sabitleyiciden miras alan bir sınıfta bulunur. Düzeltme fonksiyonu sanal işlevi olarak tespit edilecek işlevini erişir. Katı işlevsel tanımlamaya gelince, fix'e açıkça fazladan bir x parametresi verilir , bu da tembel değerlendirmeye gerek olmadığı anlamına gelir.

template <typename R, typename D>
class fixer
{
public:
    R fix(D x)
    {
        return f(x);
    }
private:
    virtual R f(D) = 0;
};

class fact : public fixer<long, long>
{
    virtual long f(long x)
    {
        if (x == 0)
        {
            return 1;
        }
        return x * fix(x-1);
    }
};

long result = fact().fix(5);

Lisp , Scheme veya Racket gibi zorunlu işlevli bir dilde Landin (1963), sabit nokta birleştirici oluşturmak için değişken atamanın kullanılmasını önerir:

(define Y!
  (lambda (f-maker)
    ((lambda (f)
       (set! f (f-maker (lambda (x) (f x)))) ;; assignment statement
       f)
     'NONE)))

Atama ifadeleri için aksiyomlu bir lambda hesabı kullanarak, Y! değere göre çağrı Y birleştiricisiyle aynı sabit nokta yasasını karşılar:

Yazıyor

Gelen Sistem F (polimorfik lambda taşı), bir polimorfik sabit nokta combinator türü vardır;

∀a.(a → a) → bir

burada a bir tür değişkenidir . Yani fix , a → a'yı eşleyen ve onu a türünde bir değer döndürmek için kullanan bir işlev alır.

Özyinelemeli veri türleri ile genişletilmiş, basit bir şekilde yazılan lambda hesabında , sabit nokta operatörleri yazılabilir, ancak "yararlı" bir sabit nokta operatörünün türü (uygulaması her zaman dönen) kısıtlanabilir.

Gelen basitçe daktilo Lambda calculus bir noktada kendi kendini uygulama alt vadede başa çünkü, sabit nokta combinator Y tipi atanamıyor uygulama kurala göre:

sonsuz tip nerede . Aslında hiçbir sabit nokta birleştiricisi yazılamaz; bu sistemlerde, özyineleme için herhangi bir destek dile açıkça eklenmelidir.

Y birleştiricisi için yazın

Özyinelemeli veri türlerini destekleyen programlama dillerinde , özyinelemeyi tür düzeyinde uygun şekilde hesaba katarak Y birleştiricisini yazmak mümkündür. x değişkenini kendi kendine uygulama ihtiyacı, (Rec a -> a) ile eşbiçimli olacak şekilde tanımlanan bir tür (Rec a) kullanılarak yönetilebilir.

Örneğin, aşağıdaki Haskell kodda, elimizdeki Inve outtürleri ile izomorfizim, iki yönden isimlerini olmak:

In :: (Rec a -> a) -> Rec a
out :: Rec a -> (Rec a -> a)

hangi yazmamıza izin verir:

newtype Rec a = In { out :: Rec a -> a }

y :: (a -> a) -> a
y = \f -> (\x -> f (out x x)) (In (\x -> f (out x x)))

Veya eşdeğer olarak OCaml'de:

type 'a recc = In of ('a recc -> 'a)
let out (In x) = x

let y f = (fun x a -> f (out x x) a) (In (fun x a -> f (out x x) a))

Alternatif olarak:

let y f = (fun x -> f (fun z -> out x x z)) (In (fun x -> f (fun z -> out x x z)))

Genel bilgi

Sabit noktalı combinators Özyinelemeyi uygulamak için kullanılabilir, çünkü, gibi olanlar gibi yinelemeli hesaplamalar, belirli türleri tanımlamak için kullanmak mümkündür sabit nokta yineleme , iteratif yöntemler , yinelemeli birleştirme içinde ilişkisel veri tabanları , veri akışı analizi , İLK ve bağlamdan bağımsız bir dilbilgisi , geçişli kapatma ve diğer kapatma işlemleri türlerinde terminal olmayan kümeleri TAKİP EDİN .

Bunun için bir fonksiyon , her giriş sabit bir nokta olan denir kimlik fonksiyonu . Resmi olarak:

Hepsi üzerinde evrensel nicelemenin aksine , sabit nokta birleştirici , sabit noktası olan bir değer oluşturur . Sabit nokta birleştiricinin dikkat çekici özelliği, rastgele verilen bir işlev için sabit bir nokta oluşturmasıdır .

Diğer işlevlerin, bir kez uygulandıktan sonra başka uygulamaların hiçbir etkisinin olmadığı özel özelliği vardır. Daha resmi:

Bu tür işlevlere idempotent denir (ayrıca bkz. İzdüşüm (matematik) ). Tüm çift tamsayılar için 0 ve tüm tek tamsayılar için 1 döndüren işlev böyle bir işlevin bir örneğidir .

Olarak lambda hesabı , bir kimlik işleve bir sabit noktalı bir bağdaştırıcının veya İdempotent fonksiyonu uygulanarak bir görüş hesaplama noktadan tipik olarak sona hesaplama ile sonuçlanır. Örneğin, elde ederiz

burada ortaya çıkan terim yalnızca kendisine indirgenebilir ve sonsuz bir döngüyü temsil eder.

Sabit nokta birleştiriciler, daha kısıtlayıcı hesaplama modellerinde mutlaka bulunmaz. Örneğin, basitçe yazılan lambda hesabında bulunmazlar .

Y, combinator sağlar yineleme bir dizi olarak tanımlanması yeniden yazma kuralları dilde doğal yineleme destek gerektirmeden.

Anonim işlevleri destekleyen programlama dillerinde , sabit nokta birleştiriciler anonim özyinelemeli işlevlerin tanımlanmasına ve kullanılmasına izin verir , yani bu tür işlevleri tanımlayıcılara bağlamak zorunda kalmadan . Bu ayarda, sabit nokta birleştiricilerinin kullanımına bazen anonim özyineleme denir .

Ayrıca bakınız

Notlar

Referanslar

Dış bağlantılar