Lambda počet ( λ-počet ) je formální systém vyvinutý americkým matematikem Alonzem Churchem k formalizaci a analýze konceptu vyčíslitelnosti .
Čistý λ-počet , jehož termíny , také nazývané objekty ("oba") nebo λ -termíny, jsou sestaveny výhradně z proměnných pomocí aplikace a abstrakce. Zpočátku se neočekává přítomnost žádných konstant.
λ-počet je založen na dvou základních operacích:
Základní formou ekvivalence definovanou v pojmech lambda je ekvivalence alfa. Například a : jsou alfa ekvivalentní termíny lambda a oba představují stejnou funkci (funkci identity). Termíny a nejsou ekvivalentem alfa, protože nejsou v lambda abstrakci.
Vzhledem k tomu, že výraz označuje funkci, která každému přiřadí hodnotu , pak k vyhodnocení výrazu
který zahrnuje aplikaci i abstrakci , je nutné místo proměnné provést substituci čísla 3 v termínu . Výsledkem je . Tato myšlenka může být zapsána v obecné formě jako
a nazývá se β-redukce . Vyjádření tvaru , tedy aplikace abstrakce na určitý termín, se nazývá redex . Ačkoli je β-redukce v podstatě jediným „podstatným“ axiomem λ-kalkulu, vede k velmi bohaté a složité teorii. Spolu s tím má λ-počet vlastnost Turingovy úplnosti , a proto je nejjednodušším programovacím jazykem .
-konverze vyjadřuje myšlenku, že dvě funkce jsou totožné právě tehdy, když při aplikaci na jakýkoli argument dávají stejné výsledky. -transformation překládá vzorce a do sebe navzájem (pouze pokud nemá žádné volné výskyty v : jinak se volná proměnná po transformaci stane vázanou externí abstrakcí nebo naopak).
Funkce dvou proměnných a lze ji považovat za funkci jedné proměnné , vracející funkci jedné proměnné , tedy jako výraz . Tato technika funguje úplně stejně pro funkce jakékoli arity . To ukazuje, že funkce mnoha proměnných mohou být vyjádřeny v λ-kalkulu a jsou „ syntaktickým cukrem “. Popsaný proces přeměny funkcí mnoha proměnných na funkci jedné proměnné se nazývá currying (také: currying ), podle amerického matematika Haskella Curryho , ačkoli jej jako první navrhl Moses Sheinfinkel ( 1924 ).
Skutečnost, že členy λ-kalkulu působí jako funkce aplikované na členy λ-kalkulu (tedy možná na sebe), vede k potížím při konstrukci adekvátní sémantiky λ-kalkulu. Aby měl λ-počet nějaký význam, je nutné získat množinu, do které by byl zasazen jeho prostor funkcí . V obecném případě toto neexistuje z důvodů omezení mohutností těchto dvou množin a funkcí od do : druhá má větší mohutnost než první.
Dana Scott tento problém překonala na počátku 70. let 20. století tím, že zkonstruovala koncept regionu (zpočátku na úplných svazech [1] , později jej zobecnila na kompletní částečně uspořádanou množinu se speciální topologií ) a omezila jej na funkce spojité v této topologii [ 2] . Na základě těchto konstrukcí byla vytvořena denotační sémantika programovacích jazyků , a to zejména proto, že s jejich pomocí je možné dát přesný význam dvěma důležitým konstruktům programovacích jazyků, např. jako rekurze a datové typy .
Rekurze definuje funkci jako takovou; na první pohled to lambda kalkul neumožňuje, ale tento dojem je klamný. Uvažujme například rekurzivní funkci, která vypočítá faktoriál :
f(n) = 1, pokud n = 0; jinak n × f(n - 1).V lambda počtu nemůže funkce přímo odkazovat sama na sebe. Funkci však lze předat parametr, který je s ní spojen. Tento argument je zpravidla na prvním místě. Když ji přiřadíme k funkci, získáme novou, již rekurzivní funkci. K tomu musí být do těla funkce předán argument odkazující na sebe sama (zde označený jako ).
g := λr. λn.(1, pokud n = 0; jinak n × (rr (n-1))) f := ggTo řeší konkrétní problém výpočtu faktoriálu, ale je také možné obecné řešení. Daný termín lambda představující tělo rekurzivní funkce nebo smyčky, který se předá jako první argument, vrátí kombinátor s pevnou řádovou čárkou požadovanou rekurzivní funkci nebo smyčku. Funkce se nemusí pokaždé explicitně předávat.
Existuje několik definic kombinátorů s pevným bodem. Nejjednodušší z nich:
Y = λg.(λx.g (xx)) (λx.g (xx))V počtu lambda je pevný bod ; pojďme si to ukázat:
Yg (λh.(λx.h (xx)) (λx.h (xx))) g (λx.g (xx)) (λx.g (xx)) g((λx.g(xx))(λx.g(xx))) g (Yg)Nyní, abychom definovali faktoriál jako rekurzivní funkci, můžeme jednoduše napsat , kde je číslo, pro které se faktoriál počítá. Nechte , dostaneme:
g (Y g) 4 (λfn.(1, pokud n = 0; a n (f(n-1)), pokud n>0)) (Y g) 4 (λn.(1, pokud n = 0; a n ((Y g) (n-1)), pokud n>0)) 4 1, pokud 4 = 0; a 4 (g(Yg) (4-1)), pokud 4>0 4 (g(Y g) 3) 4 (λn.(1, pokud n = 0; a n ((Y g) (n-1)), pokud n>0) 3) 4 (1, pokud 3 = 0; a 3 (g(Y g) (3-1)), pokud 3 > 0) 4 (3 (g(Y g) 2)) 4 (3 (λn.(1, pokud n = 0; a n ((Y g) (n-1)), pokud n>0) 2)) 4 (3 (1, pokud 2 = 0; a 2 (g(Y g) (2-1)), pokud 2 > 0)) 4 (3 (2 (g(Y g) 1))) 4 (3 (2 (λn.(1, pokud n = 0; an ((Y g) (n-1)), pokud n>0) 1))) 4 (3 (2 (1, pokud 1 = 0; a 1 ((Y g) (1-1)), pokud 1 > 0))) 4 (3 (2 (1) ((Y g) 0)))) 4 (3 (2 (1) ((λn.(1, pokud n = 0; a n ((Y g) (n-1)), pokud n>0) 0)))) 4 (3 (2 (1 (1), pokud 0 = 0; a 0 ((Y g) (0-1)), pokud 0 > 0)))) 4 (3 (2 (1 (1)))) 24Každá definice rekurzivní funkce může být reprezentována jako pevný bod odpovídající funkce, takže pomocí , lze každou rekurzivní definici vyjádřit jako výraz lambda. Zejména můžeme rekurzivně definovat odčítání, násobení, porovnávání přirozených čísel.
V programovacích jazycích je "λ-kalkul" často chápán jako mechanismus " anonymních funkcí " - zpětných volání , které lze definovat přímo v místě, kde se používají, a které mají přístup k lokálním proměnným aktuální funkce ( closure ).