home Funktionale Programmierung: λ-Kalkül und kombinatorische Logik Prof. Dr. Uwe Schmidt FH Wedel

λ-Kalkül und kombinatorische Logik

weiter

weiter

λ-Kalkül

λ
Die Assembler-Sprache der funktionalen Programmierung
gut
Das mathematische Fundament der funktionalen Programmierung
weiter
Geschichte
19[12][0-9]
Moses Schönfinkel, Haskell Curry
Kombinatorische Logik
193[0-9]
Alonzo Church, Stephen Kleene
λ-Kalkül
weiter
Sprachelemente
Expr ::= a                -- Variablen
       | (Expr Expr)      -- Applikation
       | λ a . Expr       -- Funktion
merke
Dieses ist das minimale, uninterpretierte λ-Kalkül
Es gibt nur Variablen, einstellige anonyme Funktionen und Funktionsanwendungen
weiter
Häufige Erweiterung
       | Literal            -- false,true,1,2,3,...
       | (Expr Op Expr)     -- 2-stellige Operationen
       | if Expr then Expr
                 else Expr  -- Verzweigungen
       | let a = Expr
         in Expr            -- lokale Variable
       | fix Expr           -- Fixpunkt-Kombinator
weiter
Beispiel
λ x . x + y  -- ein Ausdruck e
weiter
merke
x ist eine gebundene Variablen in e
merke
y ist eine freie Variablen in e
weiter
Definitionen
offener Term
open term
ein Ausdruck mit freien Variablen
abgeschlossener Term
closed term
ein Ausdruck ohne freie Variablen
Kombinator
ein abgeschlossener Term
weiter
Beispiele
λx.x                     -- abgeschlossen
 
(λx.(x ((λy.y a) x))) y  -- offen
merke
Gebundene Variablen können umbenannt werden, ohne die Bedeutung eines Ausdrucks zu ändern
merke
Dieses gilt nicht für jede mögliche Umbenennung!
?
Beispiel?
in Haskell
data Expr
  = Var    Ident
  | App    Expr  Expr
  | Lambda Ident Expr
  | ...
 
type Ident = String
weiter
?
Berechnung aller freien Variablen?
?
Berechnung aller gebundenen Variablen?
?
Wo kommen in der Mathematik noch gebundene Variablen vor?

weiter

Kombinatoren

Unbehagen
Im λ-Kalkül durch gebundene Variablen viele unterschiedliche Ausdrücke mit gleicher Bedeutung
Lösung
Elimination der gebundenen Variablen durch Transformation in einige wenige Standard-Kombinatoren
SKI-Kombinatoren
S
S = λf.(λg.(λx.(f x)(g x)))
K
K = λx.λy.x
I
I = λx. x
weiter
in Haskell
s f g x = f x (g x)
 
k x y   = x
 
i x     = x
weiter
abkürzende Schreibweise
λx.(λy.e) = λx y.e
weiter
Satz
(Schönfinkel)
Alle abgeschlossenen λ-Ausdrücke (alle Kombinatoren) lassen sich durch Ausdrücke nur bestehend aus S und K formulieren
Beispiel
I = SKK
  SKK
={ Def. S und K }
  ((λx y z.(x z) (y z)) (λx y.x)) (λx y.x)
={ 1. äußere Applikation }
  (λy z.((λx y.x) z) (y z)) (λx y.x)
={ 2. äußere Applikation }
  λz.((λx y.x) z) ((λx y.x) z)
={ 1. innere Applikation }
  λz.(λy.z) ((λx y.x) z)
={ 2. innere Applikation }
  λz.z
={ Def. I }
  I
Rechnen
im λ-Kalkül besteht aus der Auswertung von Funktions-Anwendungen
β-Reduktion
Eine Funktions-Anwendung auswerten heißt einen Reduktionsschritt ausführen
(die gebundene Variable einer Funktion erstzen durch den aktuellen Wert)
gut
SKK = I: Guter Test für eine Implementierung
weiter
ω-Kombinator
ω = λx.x x
merke
Selbstanwendung von x
?
Typ von x?
weiter
Ω-Kombinator
Ω = ω ω = (λx.x x)(λx.x x)
weiter
Reduktion von Ω
  Ω
={ Def. }
  (λx.x x)(λy.y y)
={ β-Reduktion }
  (λy.y y)(λy.y y)
={ β-Reduktion }
  (λy.y y)(λy.y y)
={ β-Reduktion }
  ...
merke
Die Berechnung divergiert!
merke
DIE einfachste Endlosschleife im λ-Kalkül
weiter

weiter

Reduktion und Substitution

Reduktion
eine Funktions-Anwendung auswerten
Auswertung eines λ-Terms (λx.e) a
Substitution aller freien Vorkommen der Variablen x in e durch das Argument a
weiter
Notation: Substitution
(λx.e)a → [x/a]e
Substitutions-Regeln
[x/a]x       → a
[x/a]y       → y           -- x ≠ y
[x/a](e1 e2) → ([x/a]e1)([x/a]e2)
[x/a]λx.e    → λx.e
[x/a]λy.e    → λy.([x/a]e) -- x ≠ y und y ∉ fv(e)
weiter
?
Warum y ∉ fv(e)?
Gebundene Umbenennung
Gebundene Variablen umbennen ohne die Bindungsrelation zu verändern
weiter
Regeln
zur Reduktion und Umformung
α-Äquivalenz
λx.e = λy.[x/y]e  -- y ∉ fv(e)
merke
gebundene Umbenennung
Beispiele
λx y.x y = λa b.a b
λx y.x y = λy x.y x
?
α-Äquivalenz in Haskell?
weiter
β-Reduktion
ein Substitutionsschritt
 
(λx.e) a → [x/a]e
weiter
η-Reduktion
λx.(e x) → e  -- für x ∉ fv(e)
 
Extensionalitäts-Prinzip
weiter
η-Expansion
e → λx.(e x)  -- für x ∉ fv(e)
 
Umkehrung der η-Reduktion
weiter
Praxis
β-Reduktion (Ersetzen aller Vorkommen von x durch das Argument) und α-Äquivalenz (gebundene Umbenennung) mittels Formeltransformation aus Effizienzgründen unpraktikabel
Lösung
Indirektstufe einführen
 
Variablenbindungen in einer Tabelle (Environment) speichern und beim Auswerten einer Variablen die Variable durch den assoziierten Wert ersetzen
Reduktions-Strategie
Welcher Reduktionsschritt wird als nächster gemacht?
merke
Verschiedene Strategien möglich
Beispiele
    (λx.x + x)((λy.y * y) 2)
=>
    (λx.x + x)(* 2)
=>
    (λx.x + x) 4
=>
    4 + 4
=>
    8
leftmost innermost
 
    (λx.x + x)((λy.y * y) 2)
=>
    ((λy.y * y) 2) + ((λy.y * y) 2)
=>
    (* 2) + ((λy.y * y) 2)
=>
    4 + ((λy.y * y) 2)
=>
    4 + (* 2)
=>
    4 + 4
=>
    8
leftmost outermost
 
    (λx.(λy.1) x) e
=>
    (λy.1) e
=>
    1
partial evaluation
weiter

weiter

Erweiterungen

let-Ausdrücke
Expr ::= ...
       | let x = e1 in e2
Substitutions-Regeln
let x = e1 in e2  → (λx.e2)e1
                  → [x/e1]e2
weiter
Rekursion
zum Wiederholen von Berechnungen
Υ-Kombinator
entdeckt von Haskell Curry
 
Y = λf.(λx.(f(x x))(λx.(f(x x))))
Gesetz
Υ f = f(Υ f)
              -- also
Υ f = f(f(f(...)))
weiter
Υ
ersetzt durch S und K
 
Υ = SSK(S(K(SS(S(SSK))))K)
weiter
Fixpunkt-Ausdrücke
Expr ::= ...
       | ...
       | fix e
Substitutions-Regel
fix f → f (fix f)
weiter
Beispiel
let fact = fix (λf.λn .
                if n == 0
                then 1
                else n * f(n - 1))
in
  fact 5
weiter
rekursive let-Ausdrücke
Expr ::= ...
       | ...
       | let rec x = e1 in e2
merke
in Haskell der Default
Substitutions-Regel
let rec x = e1 in e2   →   let x = fix (λx.e1) in e2
weiter
Beispiel
let rec fact = λn .
               if n == 0
               then 1
               else n * fact(n - 1))
weiter
gut
Υ-Kombinator: Guter Test für eine Implementierung des λ-Kalküls

Letzte Änderung: 02.10.2020
© Prof. Dr. Uwe Schmidt
Prof. Dr. Uwe Schmidt FH Wedel