Haskell und Python

Werbung
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 Ausdrücken
rekursives Programmieren,
Typsystem
Python: Eine prozedurale Programmiersprache
prozedural; schwaches, dynamisches Typsystem,
flexible Datenstrukturen, Objektorientierung.
Ziele:
Demonstration imperativer und prozeduraler Konzepte,
Vergleich von Konzepten
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 1
Interpreter / Compiler
Interpreter
Compiler (Übersetzer)
Ablaufumgebung
führt ein Programm aus,
(bzw. wertet ein Programm aus),
Grundlage: Text des Programms
Jeder Programmbefehl wird einzeln eingelesen
und dann ausgeführt.
erzeugt aus Programm einen ausführbaren Modul.
Programmumstellungen, Optimierungen
Effekt des Programms muss gleich bleiben.
Hier erfolgt die Ausführung des Moduls
Es gibt Zwischenformen
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 2
Laufzeit / Compilezeit
Compilezeit:
Zeitraum der Analyse bzw. Übersetzung des Programms
statische Typüberprüfung, Optimierung.
Laufzeit:
Zeitraum der Ausführung des Programms
Z.B. dynamische Typüberprüfung, Ein-Ausgabe.
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 3
Programmiersprachen: wesentliche Merkmale
imperativ
Programm ist Folge von Befehlen
sukzessive Änderung des Speicherinhalts
Ergebnis: letzter Zustand
Ein imperatives Programm sagt präzise:
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: Übersichtlichkeit; Wiederverwendbarkeit
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 4
Programmiersprachen: Merkmale (2)
funktional: Programm strukturiert in Funktionsdefinitionen
Ausdrücke = Anwendung von Funktionen auf Argumente
Berechnung = Auswertung von Ausdrücken
Varianten von funktionalen Programmiersprachen:
nicht-strikt: Argumente werden so spät wie möglich ausgewertet
strikt: Argumente werden vor Funktionsaufruf ausgewertet
pur: Objekte haben nur einen Wert, keine Mutation
nicht-pur: Objekte können verändert werden, Seiteneffekte
möglich
deklarativ:
Idealfall: Spezifikation = deklaratives Programm
Betonung auf Logik, weniger algorithmisch
Beispiele: logische Programmierung, Prolog
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 5
Programmiersprachen: Merkmale (3)
objektorientiert:
Verwendung in imperativen Programmiersprachen
Strukturierung des Programm in Klassen.
Ziel: Übersichtlichkeit, Wiederverwendung
Ausführung eines Programms:
Erzeugung von Objekten
Austausch von Nachrichten zwischen Objekten
typisiert
Alle Programmiersprachen haben Typisierung
• statische Typisierung:
Programmtext
• dynamische Typisierung: Ausführungszeit des Programms
•
•
schwache Typisierung:
Typfehler zur Laufzeit sind möglich
starke Typisierung:
Typfehler zur Laufzeit sind nicht möglich
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 6
Haskell
Wichtige Eigenschaften funktionaler Programmiersprachen
Referentielle Transparenz
Gleiche Funktion, gleiche Argumente =⇒ gleicher Wert
Keine Seiteneffekte !
Verzögerte Auswertung
Nur die für das Resultat notwendigen Unterausdrücke werden
(so spät wie möglich) ausgewertet.
Polymorphes Typsystem
Nur Ausdrücke mit Typ sind erlaubt — es gibt Typvariablen.
Das Typsystem garantiert: keine dynamischen Typfehler.
Automatische Speicherverwaltung
Anforderung und Freigabe von Speicher
Funktionen sind Datenobjekte
mögliche Verwendung: in Datenobjekten, als Argument, als Resultat.
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 7
Programmierung in Haskell
Interpreter Hugs 98 und GHCi
Grundprinzipien:
• Definition von Funktionen
quadrat x = x*x
• Aufbau von Ausdrücken:
Anwendung der Funktion auf Argumente, die wieder Ausdrücke
sein können.
3*(quadrat 5)
• Nur der Wert
zurückgegeben.
P raktische Inf ormatik
1, W S
von
2004/05, F olien Haskell 1,
Ausdrücken
75
(3. N ovember2004)
Seite 8
wird
bei
der
Auswertung
Umgang mit dem Interpreter
Aufruf:
Online-Report
>:h
>:t
Ausdruck
>:set +t ...
ghci (im richtigen Fenster)
http://www.haskell.org/onlinereport
Hilfe
druckt den Typ des Ausdrucks
Optionen ändern
Module im Interpreter verwenden:
:m +Char +Numeric ...
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 9
Einfache Daten und Operatoren
•
ganze Zahlen
•
•
•
•
•
beliebig lange ganze Zahlen
rationale Zahlen
Gleitkommazahlen
Zeichen
Datenkonstruktoren
•
•
•
Arithmetische Operatoren:
Arithmetische Vergleiche:
Logische Operatoren:
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Typ Int
mit |n| ≤ 231 − 1 = 2147483647
(vom Typ Integer),
3%7
(Rational)
3.456e+10
(Float)
’a’
Char
True, False; Typ Bool
+, −, ∗, /,
==, <=, < . . .
&&, ||, not
Seite 10
Beispiel
Definition eines Polynoms x2 + y 2:
quadratsumme x y = quadrat x + quadrat y
Auswertung:
...
Main> quadratsumme 3 4
25
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 11
Typen in Haskell
Typ
Int
Integer
Float
Double
Integer ->
Integer ->
Integer ->
P raktische Inf ormatik
1, W S
Integer ->
Integer
Integer ->
2004/05, F olien Haskell 1,
Integer
Integer
(3. N ovember2004)
Konstanten, Funktionen
1,2,3,4,. . .
1,2,3,4,. . .
1.23e45
1.23e45
(+)
quadrat
quadratsumme
Seite 12
Typen in Haskell
Beispiel
Die Ausgabe des Interpreters für die Addition (+) ist komplizierter:
(+) :: forall a. (Num a) => a -> a -> a
D.h.: Für 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
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 13
(vereinfachte) Haskell-Syntax
hFunktionsDefinitioni ::= hFunktionsnameihParameteri∗ = hAusdrucki
hAusdrucki
::= hBezeichneri | hZahli
| (hAusdrucki hAusdrucki)
| (hAusdrucki)
| (hAusdruckihBinInfixOpi hAusdrucki)
hBezeichneri
::= hFunktionsnamei | hDatenkonstruktornamei
| hParameteri | hBinInfixOpi
hBinInfixOpi
::= ∗ | + | − | /
Argumente einer Funktion:
Anzahl der Argumente:
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
formale Parameter.
Stelligkeit der Funktion: (ar(f ))
(3. N ovember2004)
Seite 14
Beispiel zur Grammatik
quadratsumme
x y = (quadrat x) + (quadrat y)
quadratsumme
x,y
=
(quadrat x) + (quadrat y)
+
quadrat x
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
Funktionsname
formale Parameter
gleiches Zeichen wie in Grammatik
hAusdrucki der Form hAusdrucki + hAusdrucki
binärer Infix-Operator
Anwendung: quadrat ist ein Ausdruck
und x ist ein Ausdruck
(3. N ovember2004)
Seite 15
Haskell: Verschiedenes . . .
Prelude: vordefinierte Funktionen, Typen und Datenkonstruktoren
Präfix, Infix, Prioritäten ist möglich für Operatoren
Konventionen zur Klammerung:
s1 s2 . . . sn ≡ ((. . . (s1 s2) s3 . . .) sn)
Kontextbedingungen in Funktionsdefinitionen:
formale Parameter müssen verschiedenen sein;
Keine undefinierten Variablen im Rumpf!
Weitere Trennzeichen: “{“,“}“ Semikolon “; “
Layout-sensibel: bewirkt Klammerung mit {, }.
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 16
Fallunterscheidung
Syntax: if hAusdrucki then hAusdrucki else hAusdrucki
if“, then“, else“ sind reservierte (Schlüsselworte)
”
”
”
und dürfen 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
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 17
Bedingungen, Arithmetische Vergleiche
Die Infixoperatoren ==, <, >, <=, >=, / = haben den Typ:
Integer -> Integer -> Bool
Achtung: = ist reserviert für Funktionsdefinitionen, und let
Boolesche Ausdrücke
sind kombinierbar mit not, ||, && (nicht, oder, und)
Konstanten sind True, False.
Eine kompliziertere Bedingung: 3.0 <= x && x < 5.0
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 18
Darstellungen eines Programms
Benutzer-Syntax: vom Programmierer benutzt
Interne Syntax: “Linearisierung“; entzuckerte Version;
voll geklammert; alle Operatoren sind Präfix; kein Layout
Ableitungsbaum (Herleitungsbaum): Vom Kompiler erzeugt
Syntaxbaum: Eindeutige Darstellung des Programms in einem markierten Baum.
Hierauf lässt sich eindeutig die Ausführung des Programms definieren.
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 19
Syntaxbaum: Beispiele
if x <= 0 then 1 else x*(quadrat (x-1))
ifThenElseXXXXXXX
<=
FF
y
x
yy
yy
y
y
|y
y
iii
iiii
i
i
i
ii
iiii
it iii
FF
FF
FF
F"
1
XXXXXX
XXXXXX
XXXXXX
XXXXXX
X,
oo
o
o
oo
ooo
o
o
oo
wooo
∗
x
0
pp
ppp
p
p
p
pw pp
quadrat
x
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 20
app
−
ppp
pp
ppp
p
p
pp
pw pp
1
Syntaxbaum: Beispiele
Zwei Syntaxbäume zu
1*2:
∗ >>>
1
>>
>>
>
appFF
tt
tt
t
tt
ty t
appJJ
2
∗
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
FF
FF
FF
F"
(3. N ovember2004)
yy
yy
y
yy
y| y
Seite 21
JJJ
JJJ
JJJ
%
1
2
Aufrufhierarchie und Rekursive Definitionen
f, g, fi seien Haskell-definierte Funktionen.
f referenziert g direkt,
f referenziert g (indirekt),
f ist direkt rekursiv,
f ist rekursiv,
Verschränkte Rekursion:
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
wenn g im Rumpf von f vorkommt.
wenn es Funktionen f1, . . . , fn gibt,
so dass gilt: f referenziert direkt f1,
f1 referenziert direkt f2, . . . ,
fn referenziert direkt g.
wenn f sich selbst direkt referenziert.
wenn f sich selbst (indirekt) referenziert.
wenn f die Funktion g referenziert
und g die Funktion f
auch für allgemeinere Fälle
(3. N ovember2004)
Seite 22
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
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 23
Beispiel: Fakultät
0! := 1
n! := 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.
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 24
Entwurf rekursiver Funktionen
Wichtig: zwei Fälle sind zu beachten
den Basisfall:
den Rekursionsfall:
Ergebnis: 0 wenn das Argument x ≤ 1 ist.
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 für x ≥ 1.
• Der Basisfall hat das kleinste Argument
Es funktioniert:
Main> fakultaet 3
6
Main> fakultaet 40
815915283247897734345611269596115894272000000000
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 25
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.
Für weitere Definitionen von n!, siehe:
http://www.willamette.edu/~fruehr/haskell/evolution.html
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 26
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"
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 27
Beispiel: nächstes Schaltjahr
Ermittlung des nächsten 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>
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 28
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"
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 29
Mittlere Jahreslängen
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)
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 30
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?
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 31
Problemanalyse und funktionale Abstraktion
Zunächst: Algorithmen auf Zahlen
Problemanalyse und Erstellung eines Algorithmus:
•
•
•
Zerlegung in (einfachere) Teilprobleme
Lösen der Teilprobleme mittels Unterfunktionen
Zusammensetzen des Algorithmus
Wichtig:
sekundär:
was
wie
die Funktion leistet, d.h. welche Abbildung wird definiert.
die Funktion realisiert wird.
Zentrale Leitideen beim Entwurf sind:
• Korrektheit
• Modularität
• Effizienz
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 32
Beispiel: Wurzel aus x mit dem Newtonschen
Iterationsverfahren
Spezifikation:
√
x := y wobei y 2 = x und y ≥ 0
Newton-Verfahren (Heron-Verfahren)
√
zur Näherung von x:
Starte
Iteriere:
P raktische Inf ormatik
√
mit Schätzwert s für die Wurzel x
x
s → 0.5(s + )
s
bis alter und neuer Schätzwert
keine große Differenz mehr aufweisen.
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 33
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>
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 34
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
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 35
Operationale Semantik
Spezifikation von Wirkung und Ablauf:
Zustand:
Pro Programmkonstrukt:
Haskell:
Python:
Zustand
Übergange:
Zustand
Übergange:
Speicherbelegung als Datenstruktur oder . . .
Angabe des Zustandsübergangs
= Ausdruck
sind Reduktionen, d.h. Änderungen der Ausdrücke.
= Umgebung
Veränderungen des Speicherinhalts.
operationale Semantik = Spezifikation eines Interpreters
Vorteil: Prinzipiell immer durchführbar
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 36
Denotationale Semantik
Zuordnung:
Domain D:
Pro Programmkonstrukt:
Hürden:
P raktische Inf ormatik
Programm 7→ Funktion
Menge der möglichen Funktionen und Objekte
rekursive Angabe der Konstruktion einer
Funktion in D.
Mathematisches Vorwissen notwendig
Domainkonstruktion kann schwierig sein
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 37
Transformations-Semantik
Vorgehen zur Definition der Semantik eines Programms P :
• Semantik bereits für eine Untermenge der Programme erklärt
• Transformiere P → . . . → P 0
• Nehme die Semantik von P 0.
Verwendung:
Semantik einer vollen Programmiersprache erklärt durch:
• Semantik der Kernsprache
• Transformation:
volle Sprache −→ Kernsprache.
Semantik von Haskell ist teilweise eine Transformationssemantik
Vorteile:
P raktische Inf ormatik
Vereinfacht Semantik-Definition
Analog zur Arbeitsweise von Compilern
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 38
Logische Semantik
Beschreibung der Programmkonstrukte und Eigenschaften von Programmen mittels logischer Axiome
Herleiten von Programmeigenschaften durch logisches Schließen
Z.B. in Prädikatenlogik:
Für alle Eingaben n von natürlichen Zahlen
liefert quadrat n das Ergebnis n2. Als Formel:
∀n : quadrat(n) = n2
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 39
Auswertung von einfachen Haskell-Programmen:
Ziel: operationale Semantik von Haskell
Vorteile einer operationalen Semantik:
• formal saubere Definition der Auswertung
• auch für Funktionen höherer Ordnung
• Unabhängigkeit von Compilern
• Unabhängigkeit vom Rechnertyp (Portabilität)
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 40
Einfache Haskell-Programme
Definition: Basiswert ist entweder eine Zahl, Zeichen oder True,False.
Einfache Haskell-Programme: dürfen benutzen:
• Basiswerte und entsprechende vordefinierte Operatoren
• Funktionsdefinitionen
• if-then-else
• Anwendung von Funktionen auf Argumente
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 41
Einfache Haskell-Programme (2)
Definition:
Ein (einfaches) Haskell-Programm besteht aus:
• Menge von Funktionsdefinitionen; entsprechend obiger Beschränkungen
• 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
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 42
Berechnung und Auswertung
Prinzip der Berechnung für einfache Haskell-Programme
Folge von Transformationen
Auswertung = von main
bis ein Basiswert erreicht ist
main → t1 → t2 → . . . → tn → . . .
Es gibt drei Fälle:
1. Die Folge endet mit einem Basiswert
2. Die Folge endet, aber nicht mit einem Basiswert
3. Die Folge endet nicht
Bei 2. und 3.: Wert undefiniert.
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 43
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 [·] ≡
P [t] ≡
P raktische Inf ormatik
if s then [.] else 2,
if s then t else 2.
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 44
Auswertung
Einfache Haskell-Programm haben drei verschiedene
Arten von Auswertungsschritten
1. Definitionseinsetzung (δ-Reduktion)
2. Arithmetische Auswertung
3. Auswertung von Fallunterscheidungen
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 45
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 = Rumpf f
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 46
Definitionseinsetzung
(Rumpff [t1/x1, . . . tn/xn])
entsteht durch (paralleles bzw. unabhängiges) Ersetzen
von xi durch ti.
ti kann ein Ausdruck sein; es muss kein Basiswert sein!
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 47
Einschub: Metanotation
In Lehrbüchern, Skripten, Artikeln
über Programmiersprachen, Logik usw.:
Mischung von konkreter Syntax und Meta-Notation.
Beispiele
konkrete Syntax:
die Funktion fakultaet . . . “
”
Meta-Notation:
Sei f eine Funktion in Programm . . . “,
”
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 48
Einschub: Metanotation: Beispiel
Notation bei Definitionseinsetzungsregel :
(Rumpff [t1/x1, . . . tn/xn])
Hierbei sind alles Metavariablen:
f
Rumpff
t1, . . . , tn
x1 , . . . , x n
P raktische Inf ormatik
steht für eine Funktion
steht für den Rumpf dieser Funktion
stehen für Ausdrücke: die Argumente
stehen für die formalen Parameter der Funktion
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 49
Einschub: Metanotation: Beispiel
gutgenug
schaetzwert x =
abs(((quadrat schaetzwert) - x)) / x < 0.0000000000001
Bei Definitionseinsetzung für
gutgenug 2.0 1.0:
x1 steht für den formalen Parameter schaetzwert und
x2 steht für den formalen Parameter x
t1 steht für den formalen Parameter 2.0
...
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 50
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 Ausdrücke s, t auswerten.
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 51
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 äquivalent 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
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 52
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 können nur angewendet werden, wenn der
Bedingungsausdruck zu True oder False ausgewertet ist.
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 53
Transformationen, Reduktionen
Wir nennen eine Transformation auch Reduktion
und eine Folge von Programmtransformationen auch Reduktionsfolge
(oder Auswertung).
Beachte: Reduktionen / Transformationen sind zunächst überall im
Ausdruck erlaubt.
Erst eine Auswertungs-Strategie macht die Auswertung eindeutig.
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 54
Beispiel
x && y = if x then y
x || y = if x then True
bot
= bot
else False
else y
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
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 55
Beispiel:
Programm:
main = quadrat 5
quadrat x = x*x
Auswertung als Folge von Transformationen:
main
→
quadrat 5
→
5 * 5
→
25
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 56
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)
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 57
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"
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 58
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
P raktische Inf ormatik
then error "wurzel: not a number"
else if 2.0 >= 0 then wurzeliter 1.0 2.0
else error "wurzel: Eingabe negativ"
1, W S
2004/05, F olien Haskell 1,
(3rd N ovember2004)
Seite 59
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)
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3rd N ovember2004)
Seite 60
2.0
Beispiel: Auswertung (4)
(Definitionseinsetzung gutgenug )
if abs((( quadrat 1.0 ) - 2.0)) / 2.0 < 0.000001
else wurzeliter (verbessern 1.0 2.0) 2.0
if abs(((1.0 * 1.0 ) - 2.0)) / 2.0 < 0.000001
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
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3rd N ovember2004)
Seite 61
then 1.0
then 1.0
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
...
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3rd N ovember2004)
Seite 62
Transformationsmöglichkeiten
3 Auswertungen für 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
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 63
Satz von Church und Rosser
Satz (Church-Rosser I) Sei P ein Programm,
R1, R2 zwei verschiedene Reduktionsfolgen für main
mit jeweiligen Resultat-Basiswerten e1 bzw. e2
dann sind diese Basiswerte gleich, d.h. e1 = e2
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 64
Werte von Programmen
Definition: Sei P ein Programm und main von numerischem
oder Booleschem Typ.
Der Wert des Programms P ist:
e
undefiniert (⊥)
wenn es eine terminierende Reduktionsfolge, ausgehend
von main gibt, die mit dem Basiswert e endet,
wenn es keine mit einem Basiswert terminierende Reduktionsfolge ausgehend von main gibt.
Damit gilt:
Ein einfaches Haskell-Programm
hat einen eindeutig definierten Wert unabhängig von der Art der Auswertung
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 65
Reduktionsstrategien
Zwei wichtige Reduktionsstrategien
Applikative Reihenfolge:
Argumentauswertung vor δ-Reduktion
Normale Reihenfolge:
δ-Reduktion vor Argumentauswertung
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 66
Beschreibung: applikative Reihenfolge
werte t0 applikativ aus! Fälle:
•
•
•
•
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-Reduktion
Wenn b kein Basiswert, dann applikativ b
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 67
Beschreibung: normale Reihenfolge
werte t0 in normaler Reihenfolge aus. Fälle:
• 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 Funktion
Wenn 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-Reduktion
Wenn b kein Basiswert, dann normale R. auf b
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 68
Beispiel für Reduktionen
3 Auswertungen für
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
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 69
Prozeduraufrufe in anderen
Programmiersprachen
Prozeduraufruf mit Wertübergabe: call-by-value
Es wird nur der Wert übergeben
ähnlich zur applikative Reihenfolge
Prozeduraufruf mit Namensübergabe: call-by-name
Es wird nur der Name der Variablen übergeben
hat entfernte Ähnlichkeit zur normalen Reihenfolge
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 70
Satz 2 von Church und Rosser
SATZ (Church-Rosser-2) Sei P ein einfaches Haskell-Programm.
Wenn es irgendeine Reduktionsfolge für 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
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 71
Berechnungsvorschrift
Eine Menge von Funktionsdefinitionen,
ein Ausdruck und
eine ausführbare Auswertungsstrategie
ergibt eine Berechnungsvorschrift.
Church-Rosser-1 und Church-Rosser-2
=⇒
Funktionsdefinitionen + Ausdruck = Algorithmus
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 72
Gegenbeispiel zu C.R. 2 bei applikativ
Church-Rosser-2 gilt nicht für die applikative Reihenfolge:
nt x
= nt x
proj x y = x
main
= proj
0
(nt 1)
applikative Reihenfolge für main terminiert nicht:
(nt 1) → (nt 1) → (nt 1) → . . . . . .
Deshalb:
proj 0 (nt 1) → proj 0 (nt 1) → . . . . . .
Die normale Reihenfolge liefert sofort 0.
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 73
Optimale Anzahl der Reduktionen
Definition verzögerte Reihenfolge der Auswertung (lazy reduction):
•
•
•
normale Reihenfolge
gerichteter Graph statt Text
Vermeidung von unnötiger Doppelauswertung
durch gemeinsame Unterausdrücke (Sharing)
Church-Rosser-2 gilt auch für verzögerte Reduktion!
Falls ein Basiswert berechnet wird, gilt für #Reduktionsschritte:
# verzögerte R ≤ # applikative R ≤ # normale R
Es gilt: verzögerte Reduktion hat optimale Anzahl von Reduktionen
Haskell verwendet verzögerte Reduktion
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 74
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 (verzögerte R.)
quadrat(4 + 5) → (4 + 5)(1) ∗ (4 + 5)(1) → 9 ∗ 9 → 81
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 75
Verzögerte 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)))
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 76
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))))
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 77
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
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 78
Ein weiterer Vorteil der verzögerten Reduktion
verzögerte Reduktionenen zur Compile-Zeit
sind korrekte Programmtransformationen
d.h. die operationale Semantik bleibt erhalten
Das ist falsch bei applikativer Reihenfolge
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell 1,
(3. N ovember2004)
Seite 79
Herunterladen