79
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¨ ucken 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 Informatik 1, WS 2004/05, F olien Haskell 1, (3. November2004) Seite 1

Haskell und Python - ki.informatik.uni-frankfurt.de · Interpreter / Compiler Interpreter f¨uhrt ein Programm aus, (bzw. wertet ein Programm aus), Grundlage: Text des Programms Jeder

Embed Size (px)

Citation preview

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

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

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

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

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

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

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

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

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

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

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

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

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

(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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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