Page 1
Haskell und Python
Haskell: Eine funktionale Programmiersprache
funktional, nicht-strikt, hat ein polymorphes und starkes Typsystem,
flexible Datenstrukturen, gute Abstraktionseigenschaften,
Ziele: pures Programmieren,Auswerten von Ausdruckenrekursives Programmieren,Typsystem
Python: Eine prozedurale Programmiersprache
prozedural; schwaches, dynamisches Typsystem,
flexible Datenstrukturen, Objektorientierung.
Ziele: Demonstration imperativer und prozeduraler Konzepte,Vergleich von Konzepten
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 1
Page 2
Interpreter / Compiler
Interpreter fuhrt ein Programm aus,(bzw. wertet ein Programm aus),Grundlage: Text des ProgrammsJeder Programmbefehl wird einzeln eingelesenund dann ausgefuhrt.
Compiler (Ubersetzer) erzeugt aus Programm einen ausfuhrbaren Modul.Programmumstellungen, OptimierungenEffekt des Programms muss gleich bleiben.
Ablaufumgebung Hier erfolgt die Ausfuhrung des Moduls
Es gibt Zwischenformen
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 2
Page 3
Laufzeit / Compilezeit
Compilezeit: Zeitraum der Analyse bzw. Ubersetzung des Programmsstatische Typuberprufung, Optimierung.
Laufzeit: Zeitraum der Ausfuhrung des ProgrammsZ.B. dynamische Typuberprufung, Ein-Ausgabe.
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 3
Page 4
Programmiersprachen: wesentliche Merkmale
imperativ
Programm ist Folge von Befehlen
sukzessive Anderung des Speicherinhalts
Ergebnis: letzter Zustand
Ein imperatives Programm sagt prazise:was (welche Anweisung),wann (Reihenfolge der Anweisungen)womit (Speicherplatz/Variable) zu geschehen hat.
prozedural: Strukturierung in (imperativen) Programmiersprachen
Prozedur = Unterprogramm
Aufruf mit Argumenten im Programm
Ziel: Ubersichtlichkeit; Wiederverwendbarkeit
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 4
Page 5
Programmiersprachen: Merkmale (2)
funktional: Programm strukturiert in Funktionsdefinitionen
Ausdrucke = Anwendung von Funktionen auf Argumente
Berechnung = Auswertung von Ausdrucken
Varianten von funktionalen Programmiersprachen:
nicht-strikt: Argumente werden so spat wie moglich ausgewertet
strikt: Argumente werden vor Funktionsaufruf ausgewertet
pur: Objekte haben nur einen Wert, keine Mutation
nicht-pur: Objekte konnen verandert werden, Seiteneffekte
moglich
deklarativ:
Idealfall: Spezifikation = deklaratives Programm
Betonung auf Logik, weniger algorithmisch
Beispiele: logische Programmierung, Prolog
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 5
Page 6
Programmiersprachen: Merkmale (3)
objektorientiert:Verwendung in imperativen ProgrammiersprachenStrukturierung des Programm in Klassen.Ziel: Ubersichtlichkeit, Wiederverwendung
Ausfuhrung eines Programms:Erzeugung von ObjektenAustausch von Nachrichten zwischen Objekten
typisiertAlle Programmiersprachen haben Typisierung• statische Typisierung: Programmtext• dynamische Typisierung: Ausfuhrungszeit des Programms
• schwache Typisierung:Typfehler zur Laufzeit sind moglich
• starke Typisierung:Typfehler zur Laufzeit sind nicht moglich
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 6
Page 7
Haskell
Wichtige Eigenschaften funktionaler Programmiersprachen
Referentielle TransparenzGleiche Funktion, gleiche Argumente =⇒ gleicher WertKeine Seiteneffekte !
Verzogerte AuswertungNur die fur das Resultat notwendigen Unterausdrucke werden(so spat wie moglich) ausgewertet.
Polymorphes TypsystemNur Ausdrucke mit Typ sind erlaubt — es gibt Typvariablen.Das Typsystem garantiert: keine dynamischen Typfehler.
Automatische SpeicherverwaltungAnforderung und Freigabe von Speicher
Funktionen sind Datenobjektemogliche Verwendung: in Datenobjekten, als Argument, als Resultat.
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 7
Page 8
Programmierung in Haskell
Interpreter Hugs 98 und GHCi
Grundprinzipien:
• Definition von Funktionenquadrat x = x*x
• Aufbau von Ausdrucken:Anwendung der Funktion auf Argumente, die wieder Ausdruckesein konnen.3*(quadrat 5)
• Nur der Wert von Ausdrucken wird bei der Auswertungzuruckgegeben. 75
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 8
Page 9
Umgang mit dem Interpreter
Aufruf: ghci (im richtigen Fenster)Online-Report http://www.haskell.org/onlinereport
>:h Hilfe>:t Ausdruck druckt den Typ des Ausdrucks>:set +t ... Optionen andern
Module im Interpreter verwenden:
:m +Char +Numeric ...
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 9
Page 10
Einfache Daten und Operatoren
• ganze Zahlen Typ Int
mit |n| ≤ 231 − 1 = 2147483647• beliebig lange ganze Zahlen (vom Typ Integer),• rationale Zahlen 3%7 (Rational)• Gleitkommazahlen 3.456e+10 (Float)• Zeichen ’a’ Char
• Datenkonstruktoren True, False; Typ Bool
• Arithmetische Operatoren: +,−, ∗, /,• Arithmetische Vergleiche: ==, <=, < . . .• Logische Operatoren: &&, ||, not
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 10
Page 11
Beispiel
Definition eines Polynoms x2 + y2:
quadratsumme x y = quadrat x + quadrat y
Auswertung:
...
Main> quadratsumme 3 4
25
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 11
Page 12
Typen in Haskell
Typ Konstanten, FunktionenInt 1,2,3,4,. . .Integer 1,2,3,4,. . .Float 1.23e45Double 1.23e45Integer -> Integer -> Integer (+)Integer -> Integer quadrat
Integer -> Integer -> Integer quadratsumme
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 12
Page 13
Typen in Haskell
Beispiel
Die Ausgabe des Interpreters fur die Addition (+) ist komplizierter:
(+) :: forall a. (Num a) => a -> a -> a
D.h.: Fur alle Typen a, die man als numerisch klassifiziert hat,
d.h. die in der Typklasse Num sind,
hat (+) den Typ a -> a -> a
Z.B. gilt:
(+)::Integer -> Integer -> Integer
(+)::Double -> Double -> Double
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 13
Page 14
(vereinfachte) Haskell-Syntax
〈FunktionsDefinition〉 ::= 〈Funktionsname〉〈Parameter〉∗ = 〈Ausdruck〉〈Ausdruck〉 ::= 〈Bezeichner〉 | 〈Zahl〉
| (〈Ausdruck〉 〈Ausdruck〉)| (〈Ausdruck〉)| (〈Ausdruck〉〈BinInfixOp〉 〈Ausdruck〉)
〈Bezeichner〉 ::= 〈Funktionsname〉 | 〈Datenkonstruktorname〉| 〈Parameter〉 | 〈BinInfixOp〉
〈BinInfixOp〉 ::= ∗ | + | − | /
Argumente einer Funktion: formale Parameter.Anzahl der Argumente: Stelligkeit der Funktion: (ar(f))
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 14
Page 15
Beispiel zur Grammatik
quadratsumme x y = (quadrat x) + (quadrat y)
quadratsumme Funktionsnamex,y formale Parameter= gleiches Zeichen wie in Grammatik(quadrat x) + (quadrat y) 〈Ausdruck〉 der Form 〈Ausdruck〉+ 〈Ausdruck〉+ binarer Infix-Operatorquadrat x Anwendung: quadrat ist ein Ausdruck
und x ist ein Ausdruck
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 15
Page 16
Haskell: Verschiedenes . . .
Prelude: vordefinierte Funktionen, Typen und Datenkonstruktoren
Prafix, Infix, Prioritaten ist moglich fur Operatoren
Konventionen zur Klammerung:
s1 s2 . . . sn ≡ ((. . . (s1 s2) s3 . . .) sn)
Kontextbedingungen in Funktionsdefinitionen:
formale Parameter mussen verschiedenen sein;
Keine undefinierten Variablen im Rumpf!
Weitere Trennzeichen: “{“,“}“ Semikolon “; “
Layout-sensibel: bewirkt Klammerung mit {, }.Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 16
Page 17
Fallunterscheidung
Syntax: if 〈Ausdruck〉 then 〈Ausdruck〉 else 〈Ausdruck〉
”if“,
”then“,
”else“ sind reservierte (Schlusselworte)
und durfen nicht als Funktionsnamen bzw. Parameternamen verwendet
werden.
Der erste Ausdruck ist eine Bedingung. Diese muss Typ Bool haben.
Typisierung: if Bool . . . then typ else typ
(if 1 then 1 else 2) ergibt einen Fehler
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 17
Page 18
Bedingungen, Arithmetische Vergleiche
Die Infixoperatoren ==, <, >, <=, >=, /= haben den Typ:
Integer -> Integer -> Bool
Achtung: = ist reserviert fur Funktionsdefinitionen, und let
Boolesche Ausdrucke
sind kombinierbar mit not, ||, && (nicht, oder, und)
Konstanten sind True, False.
Eine kompliziertere Bedingung: 3.0 <= x && x < 5.0
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 18
Page 19
Darstellungen eines Programms
Benutzer-Syntax: vom Programmierer benutzt
Interne Syntax: “Linearisierung“; entzuckerte Version;
voll geklammert; alle Operatoren sind Prafix; kein Layout
Ableitungsbaum (Herleitungsbaum): Vom Kompiler erzeugt
Syntaxbaum: Eindeutige Darstellung des Programms in einem mar-
kierten Baum.
Hierauf lasst sich eindeutig die Ausfuhrung des Programms definie-
ren.
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 19
Page 20
Syntaxbaum: Beispiele
if x <= 0 then 1 else x*(quadrat (x-1))
ifThenElse
ttiiiiiiiiiiiiiiiiiiii
��,,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
<=
||yyyy
yyyy
y
""FFFF
FFFF
F 1 ∗wwoooooooooooooooo
��x 0 x app
wwppppppppppp
��
quadrat −
wwppppppppppppppp
��
x 1
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 20
Page 21
Syntaxbaum: Beispiele
Zwei Syntaxbaume zu 1*2:
∗����
����
��
��>>>
>>>>
> app
yyttttttttt
""FFFF
FFFF
F
1 2 app
||yyyy
yyyy
y
%%JJJJJJJJJJJ 2
∗ 1
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 21
Page 22
Aufrufhierarchie und Rekursive Definitionen
f, g, fi seien Haskell-definierte Funktionen.
f referenziert g direkt, wenn g im Rumpf von f vorkommt.f referenziert g (indirekt), wenn es Funktionen f1, . . . , fn gibt,
so dass gilt: f referenziert direkt f1,f1 referenziert direkt f2, . . . ,fn referenziert direkt g.
f ist direkt rekursiv, wenn f sich selbst direkt referenziert.f ist rekursiv, wenn f sich selbst (indirekt) referenziert.Verschrankte Rekursion: wenn f die Funktion g referenziert
und g die Funktion fauch fur allgemeinere Falle
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 22
Page 23
Beispiel: Aufrufhierarchie
quadrat x = x*x
quadratsumme x y = (quadrat x) + (quadrat y)
quadratsumme ruft direkt die Funktion quadrat auf,
quadratsumme ruft direkt die (eingebaute) Funktion ∗ auf
Die Funktion quadratsumme ist somit nicht rekursiv
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 23
Page 24
Beispiel: Fakultat
0! := 1n! := n ∗ (n− 1)!
n! ist die Anzahl aller Permutationen einer n-elementigen Menge.
rekursive Definition:
fakultaet:: Integer -> Integer
fakultaet x = if x <= 0 then 1
else x*(fakultaet (x-1))
Diese Funktion ist rekursiv, da sie im Rumpf sich selbst wieder aufruft.
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 24
Page 25
Entwurf rekursiver Funktionen
Wichtig: zwei Falle sind zu beachten
den Basisfall: Ergebnis: 0 wenn das Argument x ≤ 1 ist.den Rekursionsfall: Ergebnis: x*(fakultaet (x-1)), wenn x > 1 ist.
Terminierung bei rekursiven Aufrufen :• Argumente werden mit jedem rekursiven Aufruf kleiner
fakultaet x ruft fakultaet (x-1) auf fur x ≥ 1.• Der Basisfall hat das kleinste Argument
Es funktioniert:
Main> fakultaet 3
6
Main> fakultaet 40
815915283247897734345611269596115894272000000000
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 25
Page 26
Eine falsche Definition
fakultaet_nt:: Integer -> Integer
fakultaet_nt x = if x == 0 then 1
else x*(fakultaet_nt (x-1))
Diese Funktion terminiert nicht bei negativen Eingaben:
fakultaet_nt (-5) ruft fakultaet_nt (-6) auf usw.
Fur weitere Definitionen von n!, siehe:
http://www.willamette.edu/~fruehr/haskell/evolution.html
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 26
Page 27
Beispiel: Berechnung von Schaltjahren
Tropisches Jahr = 365.242190517 6= 365 Tage.
Gregorianischen Kalender: Schaltjahre mit 366 Tagen als Korrektur
Ein Jahr ist ein Schaltjahr, wenn es durch 4 teilbar ist, aber nicht
durch 100. Jahre die durch 400 teilbar sind, sind wieder Schaltjahre.
ist_ein_schaltjahr n =
if n > 1582
then n ‘mod‘ 400 == 0 || (n ‘mod‘ 4 == 0 && n ‘mod‘ 100 /= 0)
else error "Jahreszahl vor Einfuehrung des Gregorianischen Kalenders"
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 27
Page 28
Beispiel: nachstes Schaltjahr
Ermittlung des nachsten Schaltjahres mit j ≥ n:
naechstes_schaltjahr n = if (ist_ein_schaltjahr n)
then n
else naechstes_schaltjahr (n+1)
*Main> naechstes_schaltjahr 1997
2000
*Main> naechstes_schaltjahr 2097
2104
*Main>
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 28
Page 29
Schaltjahre: Orthodox
Der orthodoxe Kalender hat bei den durch 100 teilbaren Jahreszahlen
eine andere Definition der Schaltjahre:
ist_ein_schaltjahr_ortho n =
if n > 1582 then
(n ‘mod‘ 100 == 0 && (n ‘mod‘ 900 == 200 || n ‘mod‘ 900 == 600))
|| (n ‘mod‘ 4 == 0 && n ‘mod‘ 100 /= 0)
else error "Jahreszahl vor Einfuehrung"
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 29
Page 30
Mittlere Jahreslangen
mittlere_jahreslaenge::Double
mittlere_jahreslaenge = 365.242190517
mittlere_jahreslaenge_gregor =
(mittlere_jahreslaenge_sum 2000 2399 0) / 400.0
mittlere_jahreslaenge_sum von bis summe =
if von > bis then summe
else if ist_ein_schaltjahr von
then mittlere_jahreslaenge_sum (von+1) bis (summe + 366)
else mittlere_jahreslaenge_sum (von+1) bis (summe + 365)
mittlere_jahreslaenge_ortho::Double
mittlere_jahreslaenge_ortho =
(mittlere_jahreslaenge_ortho_sum 2000 2899 0) / 900.0
mittlere_jahreslaenge_ortho_sum von bis summe =
if von > bis then summe
else if ist_ein_schaltjahr_ortho von
then mittlere_jahreslaenge_ortho_sum (von+1) bis (summe + 366)
else mittlere_jahreslaenge_ortho_sum (von+1) bis (summe + 365)
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 30
Page 31
Unterschied Gregorianisch und Orthodox
schaltjahr_anders n =
if ist_ein_schaltjahr n == ist_ein_schaltjahr_ortho n
then schaltjahr_anders (n+1)
else n
Welches Jahr ist das erste unterschiedliche nach 2004?
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 31
Page 32
Problemanalyse und funktionale Abstraktion
Zunachst: Algorithmen auf Zahlen
Problemanalyse und Erstellung eines Algorithmus:
• Zerlegung in (einfachere) Teilprobleme• Losen der Teilprobleme mittels Unterfunktionen• Zusammensetzen des Algorithmus
Wichtig: was die Funktion leistet, d.h. welche Abbildung wird definiert.sekundar: wie die Funktion realisiert wird.
Zentrale Leitideen beim Entwurf sind:• Korrektheit• Modularitat• Effizienz
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 32
Page 33
Beispiel: Wurzel aus x mit dem Newtonschen
Iterationsverfahren
Spezifikation:
√x := y wobei y2 = x und y ≥ 0
Newton-Verfahren (Heron-Verfahren)
zur Naherung von√
x:
Starte mit Schatzwert s fur die Wurzel√
x
Iteriere: s → 0.5(s +x
s)
bis alter und neuer Schatzwertkeine große Differenz mehr aufweisen.
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 33
Page 34
Beispiel Wurzelberechnung in Haskell
wurzel x = wurzeliter 1.0 x
wurzeliter schaetzwert x =
if gutgenug schaetzwert x then schaetzwert
else wurzeliter (verbessern schaetzwert x) x
quadrat x = x*x
gutgenug:: Double -> Double -> Bool
gutgenug schaetzwert x =
abs(((quadrat schaetzwert) - x) / x) < 0.000001
mittelwert:: Double -> Double -> Double
mittelwert x y = (x + y) / 2.0
verbessern schaetzwert x =
mittelwert schaetzwert (x / schaetzwert)
*Main> wurzel 2.0
1.4142156862745097
*Main>
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 34
Page 35
Semantik von Programmiersprachen
Semantik = Bedeutung eines Programms (Programmtextes)
ausgehend vom Syntaxbaum des Programms.
Methoden der Semantik-Definition:
Operationale Semantik
Denotationale Semantik
Transformations-Semantik
logische Semantik
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 35
Page 36
Operationale Semantik
Spezifikation von Wirkung und Ablauf:
Zustand: Speicherbelegung als Datenstruktur oder . . .Pro Programmkonstrukt: Angabe des Zustandsubergangs
Haskell: Zustand = AusdruckUbergange: sind Reduktionen, d.h. Anderungen der Ausdrucke.
Python: Zustand = UmgebungUbergange: Veranderungen des Speicherinhalts.
operationale Semantik = Spezifikation eines Interpreters
Vorteil: Prinzipiell immer durchfuhrbar
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 36
Page 37
Denotationale Semantik
Zuordnung: Programm 7→ FunktionDomain D: Menge der moglichen Funktionen und Objek-
tePro Programmkonstrukt: rekursive Angabe der Konstruktion einer
Funktion in D.
Hurden: Mathematisches Vorwissen notwendigDomainkonstruktion kann schwierig sein
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 37
Page 38
Transformations-Semantik
Vorgehen zur Definition der Semantik eines Programms P :• Semantik bereits fur eine Untermenge der Programme erklart• Transformiere P → . . . → P ′
• Nehme die Semantik von P ′.
Verwendung:
Semantik einer vollen Programmiersprache erklart durch:• Semantik der Kernsprache• Transformation: volle Sprache −→ Kernsprache.
Semantik von Haskell ist teilweise eine Transformationssemantik
Vorteile: Vereinfacht Semantik-DefinitionAnalog zur Arbeitsweise von Compilern
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 38
Page 39
Logische Semantik
Beschreibung der Programmkonstrukte und Eigenschaften von Pro-
grammen mittels logischer Axiome
Herleiten von Programmeigenschaften durch logisches Schließen
Z.B. in Pradikatenlogik:
Fur alle Eingaben n von naturlichen Zahlen
liefert quadrat n das Ergebnis n2. Als Formel:
∀n : quadrat(n) = n2
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 39
Page 40
Auswertung von einfachen Haskell-Programmen:
Ziel: operationale Semantik von Haskell
Vorteile einer operationalen Semantik:
• formal saubere Definition der Auswertung
• auch fur Funktionen hoherer Ordnung
• Unabhangigkeit von Compilern
• Unabhangigkeit vom Rechnertyp (Portabilitat)
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 40
Page 41
Einfache Haskell-Programme
Definition: Basiswert ist entweder eine Zahl, Zeichen oder True,False.
Einfache Haskell-Programme: durfen benutzen:• Basiswerte und entsprechende vordefinierte Operatoren• Funktionsdefinitionen• if-then-else• Anwendung von Funktionen auf Argumente
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 41
Page 42
Einfache Haskell-Programme (2)
Definition: Ein (einfaches) Haskell-Programm besteht aus:• Menge von Funktionsdefinitionen; entsprechend obiger Beschrankungen• Ausdruck (main) vom Typ eines Basiswertes.
Wert des Programms = Wert von main
Beispiel
quadrat x = x * x
kubik x = x * x * x
w = 2
main = if w >= 0 then quadrat w else kubik w
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 42
Page 43
Berechnung und Auswertung
Prinzip der Berechnung fur einfache Haskell-Programme
Auswertung =Folge von Transformationen
von main
bis ein Basiswert erreicht ist
main → t1 → t2 → . . . → tn → . . .
Es gibt drei Falle:1. Die Folge endet mit einem Basiswert2. Die Folge endet, aber nicht mit einem Basiswert3. Die Folge endet nicht
Bei 2. und 3.: Wert undefiniert.
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 43
Page 44
Berechnung und Auswertung:
Notation P [t]
Bedeutung: P [·] ist ein Ausdruck P mit Platzhalter [·]
P [t] bedeutet den Ausdruck P mit t anstelle des Platzhalters
Beispiel:P [·] ≡ if s then [.] else 2,P [t] ≡ if s then t else 2.
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 44
Page 45
Auswertung
Einfache Haskell-Programm haben drei verschiedene
Arten von Auswertungsschritten
1. Definitionseinsetzung (δ-Reduktion)
2. Arithmetische Auswertung
3. Auswertung von Fallunterscheidungen
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 45
Page 46
Definitionseinsetzung (δ-Reduktion)
Auswerten einer Anwendung von f auf n Argumente:
P [(f t1 . . . tn)] → P [(Rumpff [t1/x1, . . . tn/xn])]
Bedingungen:
Die Definition von f ist: f x1 . . . xn = Rumpff
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 46
Page 47
Definitionseinsetzung
(Rumpff [t1/x1, . . . tn/xn])
entsteht durch (paralleles bzw. unabhangiges) Ersetzen
von xi durch ti.
ti kann ein Ausdruck sein; es muss kein Basiswert sein!
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 47
Page 48
Einschub: Metanotation
In Lehrbuchern, Skripten, Artikeln
uber Programmiersprachen, Logik usw.:
Mischung von konkreter Syntax und Meta-Notation.
Beispiele
konkrete Syntax:”die Funktion fakultaet . . .“
Meta-Notation:”Sei f eine Funktion in Programm . . .“,
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 48
Page 49
Einschub: Metanotation: Beispiel
Notation bei Definitionseinsetzungsregel :
(Rumpff [t1/x1, . . . tn/xn])
Hierbei sind alles Metavariablen:
f steht fur eine FunktionRumpff steht fur den Rumpf dieser Funktiont1, . . . , tn stehen fur Ausdrucke: die Argumentex1, . . . , xn stehen fur die formalen Parameter der Funktion
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 49
Page 50
Einschub: Metanotation: Beispiel
gutgenug schaetzwert x =
abs(((quadrat schaetzwert) - x)) / x < 0.0000000000001
Bei Definitionseinsetzung fur gutgenug 2.0 1.0:
x1 steht fur den formalen Parameter schaetzwert und
x2 steht fur den formalen Parameter x
t1 steht fur den formalen Parameter 2.0
. . .
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 50
Page 51
Arithmetische Auswertungen
P [v op w] → P [r]wenn: v, w arithmetische Basiswerte,
op ein zweistelliger arithmetischer Operator,r Resultat von v op w
P [op v] → P [r]wenn: v arithmetischer Basiswert,
op einstelliger arithmetischer Operator,r Resultat von op v
Beachte: Wenn s op t ausgewertet werden soll,
dann zuerst die Ausdrucke s, t auswerten.
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 51
Page 52
Boolesche Auswertungen
P [v op w] oder P [op w]
wobei op einer der Operatoren &&, ||, not sein kann.
Wird als Anwendung des Operators auf Argumente ausgewertet.
Definitionen, in der Wirkung aquivalent zu den vordefinierten:
x && y = if x then y else False
x || y = if x then True else y
not x = if x then False else True
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 52
Page 53
Auswertung der Fallunterscheidung
Fallunterscheidung (if-Reduktion)
P [(if True then e1 else e2)] → P [e1]P [(if False then e1 else e2)] → P [e2]
Beachte Diese zwei Regeln konnen nur angewendet werden, wenn der
Bedingungsausdruck zu True oder False ausgewertet ist.
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 53
Page 54
Transformationen, Reduktionen
Wir nennen eine Transformation auch Reduktion
und eine Folge von Programmtransformationen auch Reduktionsfolge
(oder Auswertung).
Beachte: Reduktionen / Transformationen sind zunachst uberall im
Ausdruck erlaubt.
Erst eine Auswertungs-Strategie macht die Auswertung eindeutig.
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 54
Page 55
Beispiel
x && y = if x then y else False
x || y = if x then True else y
bot = bot
Auswertungen unter der Annahme der obigen Definition
True && True → if True then True else False → True
True && False → if True then False else False → False
True || True → if True then True else True → True
True || False → if True then True else False → True
True && bot → if True then bot else False → bot → bot . . .
True || bot → if True then True else bot → True
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 55
Page 56
Beispiel:
Programm:
main = quadrat 5
quadrat x = x*x
Auswertung als Folge von Transformationen:
main
→quadrat 5
→5 * 5
→25
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 56
Page 57
Beispiel: Auswertung
Programm:
wurzel x = if not (x + 0.1 > x)
then error "wurzel: not a number"
else if x >= 0 then wurzeliter 1.0 x
else error "wurzel: Eingabe negativ"
wurzeliter schaetzwert x =
if gutgenug schaetzwert x then schaetzwert
else wurzeliter (verbessern schaetzwert x) x
quadrat x = x*x
gutgenug schaetzwert x =
abs(((quadrat schaetzwert) - x) / x) < 0.000001
mittelwert x y = (x + y) / 2.0
verbessern schaetzwert x =
mittelwert schaetzwert (x / schaetzwert)
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 57
Page 58
Beispiel Auswertung
Folge von Transformationen:
wurzel 2.0
(Definitionseinsetzung)
if not ( 2.0 + 0.1 > 2.0)
then error "wurzel: not a number"
else if 2.0 >= 0 then wurzeliter 1.0 2.0
else error "wurzel: Eingabe negativ"
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 58
Page 59
Beispiel: Auswertung (2)
(Auswertung arithmetischer Ausdruck)if not ( 2.1 > 2.0)
then error "wurzel: not a number"
else if 2.0 >= 0 then wurzeliter 1.0 2.0
else error "wurzel: Eingabe negativ"
(Auswertung arithmetischer Ausdruck)
if not True then error "wurzel: not a number"
else if 2.0 >= 0 then wurzeliter 1.0 2.0
else error "wurzel: Eingabe negativ"
(Auswertung Boolescher Ausdruck)
if False then error "wurzel: not a number"
else if 2.0 >= 0 then wurzeliter 1.0 2.0
else error "wurzel: Eingabe negativ"
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3rd November2004) Seite 59
Page 60
Beispiel: Auswertung (3)
(if-Auswertung)
if 2.0 >= 0 then wurzeliter 1.0 2.0
else error "wurzel: Eingabe negativ"
if True then wurzeliter 1.0 2.0
else error "wurzel: Eingabe negativ"
wurzeliter 1.0 2.0
if gutgenug 1.0 2.0 then 1.0
else wurzeliter (verbessern 1.0 2.0) 2.0
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3rd November2004) Seite 60
Page 61
Beispiel: Auswertung (4)
(Definitionseinsetzung gutgenug )
if abs((( quadrat 1.0 ) - 2.0)) / 2.0 < 0.000001 then 1.0
else wurzeliter (verbessern 1.0 2.0) 2.0
if abs(((1.0 * 1.0 ) - 2.0)) / 2.0 < 0.000001 then 1.0
else wurzeliter (verbessern 1.0 2.0) 2.0
if abs((1.0 - 2.0 )) / 2.0 < 0.000001 then 1.0
else wurzeliter (verbessern 1.0 2.0) 2.0
if abs(-1.0) / 2.0 < 0.000001 then 1.0
else wurzeliter (verbessern 1.0 2.0) 2.0
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3rd November2004) Seite 61
Page 62
Beispiel: Auswertung (5)
if 1.0 / 2.0 < 0.000001 then 1.0
else wurzeliter (verbessern 1.0 2.0) 2.0
if 0.5 < 0.000001 then 1.0
else wurzeliter (verbessern 1.0 2.0) 2.0
if False then 1.0
else wurzeliter (verbessern 1.0 2.0) 2.0
wurzeliter (verbessern 1.0 2.0) 2.0
if gutgenug (verbessern 1.0 2.0) 2.0 then (verbessern 1.0 2.0)
else wurzeliter (verbessern (verbessern 1.0 2.0) 2.0) 2.0
. . .
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3rd November2004) Seite 62
Page 63
Transformationsmoglichkeiten
3 Auswertungen fur quadrat (4+5) :
1. quadrat(4 + 5) → (4 + 5) ∗ (4 + 5) → 9 ∗ (4 + 5) → 9 ∗ 9 → 81
2. quadrat(4 + 5) → (4 + 5) ∗ (4 + 5) → (4 + 5) ∗ 9 → 9 ∗ 9 → 81
3. quadrat(4 + 5) → (quadrat 9) → 9 ∗ 9 → 81
Beobachtungen:
• Ergebnis ist gleich• Anzahl der Reduktionen verschieden
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 63
Page 64
Satz von Church und Rosser
Satz (Church-Rosser I) Sei P ein Programm,
R1, R2 zwei verschiedene Reduktionsfolgen fur main
mit jeweiligen Resultat-Basiswerten e1 bzw. e2
dann sind diese Basiswerte gleich, d.h. e1 = e2
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 64
Page 65
Werte von Programmen
Definition: Sei P ein Programm und main von numerischem
oder Booleschem Typ.
Der Wert des Programms P ist:
e wenn es eine terminierende Reduktionsfolge, ausgehend
von main gibt, die mit dem Basiswert e endet,undefiniert (⊥) wenn es keine mit einem Basiswert terminierende Reduk-
tionsfolge ausgehend von main gibt.
Damit gilt:
Ein einfaches Haskell-Programm
hat einen eindeutig definierten Wert un-
abhangig von der Art der Auswertung
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 65
Page 66
Reduktionsstrategien
Zwei wichtige Reduktionsstrategien
Applikative Reihenfolge:
Argumentauswertung vor δ-Reduktion
Normale Reihenfolge:
δ-Reduktion vor Argumentauswertung
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 66
Page 67
Beschreibung: applikative Reihenfolge
werte t0 applikativ aus! Falle:
• t0 ist Basiswert. fertig.• t0 ≡ s t,
Wenn s kein Funktionsname und keine Anwendung,dann applikativ s
• t0 ≡ f t1 . . . tn.Wenn ar(f) ≤ n, dann applikativ ti, 1 ≤ i ≤ ar(f) von links nach
rechts.Wenn ar(f) ≤ n und alle ti Basiswerte, dann δ-Reduktion.Wenn n < ar(f), dann fertig: keine Reduktion.
• t0 ≡ if b then e1 else e2.Wenn b Basiswert, dann if-ReduktionWenn b kein Basiswert, dann applikativ b
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 67
Page 68
Beschreibung: normale Reihenfolge
werte t0 in normaler Reihenfolge aus. Falle:• t0 ist Basiswert. fertig.• t0 ≡ s t,
Wenn s kein Funktionsname und keine Anwendung.Dann normale R. auf s
• t0 ≡ f t1 . . . tn und f keine eingebaute Funktion,Wenn ar(f) ≤ n, dann δ-Reduktion auf f t1 . . . tar(f).Wenn ar(f) > n: keine Reduktion.
• t0 ≡ f t1 . . . tn und f ist eingebaute FunktionWenn ar(f) ≤ n und Argumente von f keine Basiswerte,dann normale R. auf ar(f) Argumente von links nach rechts.Wenn ar(f) ≤ n, und ar(f) Argumente von f sind Basiswerte,dann eingebaute Funktion aufrufen.Wenn ar(f) > n: keine Reduktion.
• t0 ≡ if b then e1 else e2.Wenn b Basiswert, dann if-ReduktionWenn b kein Basiswert, dann normale R. auf b
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 68
Page 69
Beispiel fur Reduktionen
3 Auswertungen fur quadrat (4+5) :
1. quadrat(4 + 5) → (4 + 5) ∗ (4 + 5) → 9 ∗ (4 + 5) → 9 ∗ 9 → 81
normale Reihenfolge der Auswertung
2. quadrat(4 + 5) → (4 + 5) ∗ (4 + 5) → (4 + 5) ∗ 9 → 9 ∗ 9 → 81
3. quadrat(4 + 5) → (quadrat 9) → 9 ∗ 9 → 81
applikative Reihenfolge der Auswertung
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 69
Page 70
Prozeduraufrufe in anderen
Programmiersprachen
Prozeduraufruf mit Wertubergabe: call-by-value
Es wird nur der Wert ubergeben
ahnlich zur applikative Reihenfolge
Prozeduraufruf mit Namensubergabe: call-by-name
Es wird nur der Name der Variablen ubergeben
hat entfernte Ahnlichkeit zur normalen Reihenfolge
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 70
Page 71
Satz 2 von Church und Rosser
SATZ (Church-Rosser-2) Sei P ein einfaches Haskell-Programm.
Wenn es irgendeine Reduktionsfolge fur main gibt,
die mit einem Basiswert e terminiert,
dann terminiert auch die normale Reihenfolge der Auswertung von main
und liefert als Basiswert (Resultat) genau e.
Die normale Reihenfolge ist ausreichend zur Auswertung
Haskell benutzt normale Reihenfolge der Auswertung
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 71
Page 72
Berechnungsvorschrift
Eine Menge von Funktionsdefinitionen,
ein Ausdruck und
eine ausfuhrbare Auswertungsstrategie
ergibt eine Berechnungsvorschrift.
Church-Rosser-1 und Church-Rosser-2
=⇒Funktionsdefinitionen + Ausdruck = Algorithmus
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 72
Page 73
Gegenbeispiel zu C.R. 2 bei applikativ
Church-Rosser-2 gilt nicht fur die applikative Reihenfolge:
nt x = nt x
proj x y = x
main = proj 0 (nt 1)
applikative Reihenfolge fur main terminiert nicht:
(nt 1) → (nt 1) → (nt 1) → . . . . . .
Deshalb:
proj 0 (nt 1) → proj 0 (nt 1) → . . . . . .
Die normale Reihenfolge liefert sofort 0.
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 73
Page 74
Optimale Anzahl der Reduktionen
Definition verzogerte Reihenfolge der Auswertung (lazy reduction):
• normale Reihenfolge• gerichteter Graph statt Text• Vermeidung von unnotiger Doppelauswertung
durch gemeinsame Unterausdrucke (Sharing)
Church-Rosser-2 gilt auch fur verzogerte Reduktion!
Falls ein Basiswert berechnet wird, gilt fur #Reduktionsschritte:
# verzogerte R ≤ # applikative R ≤ # normale R
Es gilt: verzogerte Reduktion hat optimale Anzahl von Reduktionen
Haskell verwendet verzogerte Reduktion
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 74
Page 75
Beispiel
1. 4 Reduktionen: (normale R.)quadrat(4 + 5) → (4 + 5) ∗ (4 + 5) → 9 ∗ (4 + 5) → 9 ∗ 9 → 81
2. 4 Reduktionen:quadrat(4 + 5) → (4 + 5) ∗ (4 + 5) → (4 + 5) ∗ 9 → 9 ∗ 9 → 81
3. 3 Reduktionen (applikative R.)quadrat(4 + 5) → (quadrat 9) → 9 ∗ 9 → 81
4. 3 Reduktionen (verzogerte R.)quadrat(4 + 5) → (4 + 5)(1) ∗ (4 + 5)(1) → 9 ∗ 9 → 81
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 75
Page 76
Verzogerte Auswertung: komplexeres Beispiel
fakultaet x = if x <= 0 then 1
else x*(fakultaet (x-1))
Die Reduktionsschritte:
fakultaet 3
if 3 <= 0 then 1 else 3*(fakultaet (3-1))
if False then 1 else 3*(fakultaet (3-1))
3* (fakultaet (3-1))
3*(if (3-1) <= 0 then 1 else (3-1) *(fakultaet ( (3-1) -1)))
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 76
Page 77
Beispiel . . .
3*(if 2 <= 0 then 1 else 2*(fakultaet (2-1)))
3* (if False then 1 else 2*(fakultaet (2-1)))
3*(2* (fakultaet (2-1)) )
3*(2*(if (2-1) <= 0 then 1 else (2-1) *(fakultaet ( (2-1) -1))))
3*(2*(if 1 <= 0 then 1 else 1*(fakultaet (1-1))))
3*(2* (if False then 1 else 1*(fakultaet (1-1))) )
3*(2*(1* (fakultaet (1-1))))
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 77
Page 78
Beispiel . . .
3*(2*(1*(if (1-1)<= 0 then 1 else(1-1)*(fakultaet ((1-1)-1)))))
3*(2*(1*(if 0 <= 0 then 1 else 0*(fakultaet (0-1)))))
3*(2*(1* (if True then 1 else 0*(fakultaet (0-1)))))
3*(2* (1*1))
3*(2*1)
3*2
6
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 78
Page 79
Ein weiterer Vorteil der verzogerten Reduktion
verzogerte Reduktionenen zur Compile-Zeit
sind korrekte Programmtransformationen
d.h. die operationale Semantik bleibt erhalten
Das ist falsch bei applikativer Reihenfolge
Praktische Informatik 1, WS 2004/05, Folien Haskell 1, (3. November2004) Seite 79