Funktionale Programmierung

Werbung
Funktionale Programmierung
IFB 1/2002
Klaus Becker
Funktionale Programmierung
2
© KB 2002
Teil 1
Programmieren mit Funktionen
Funktionale Programmierung
3
© KB 2002
an Mosel, Saar und Ruwer
Funktionale Programmierung
4
© KB 2002
Kirchtürme
Funktionale Programmierung
5
© KB 2002
Kirchtürme
Funktionale Programmierung
6
© KB 2002
Dachberechnungen
Es soll ein Programm
erstellt werden, mit
dem man für
verschieden
dimensionierte
Kirchturmdächer den
Gesamtflächeninhalt
berechnen kann.
Dachstruktur
Funktionale Programmierung
7
Pyramidendreieck
Übergangsdreieck
4 * AÜbergangsTrapez
+ 4 * AÜbergangsDreieck
+ 8 * APyramidenDreieck
Übergangstrapez
© KB 2002
ADach =
Dachparameter
Funktionale Programmierung
8
Pyramidendreieck
Übergangsdreieck
bA
hÜ
Übergangstrapez
© KB 2002
hP
bQ
Funktionale Modellierung
Funktionale Programmierung
9
© KB 2002
4.0
2.0
3.0
10.0
ADach
bQ
bA
hÜ
hP
...
hP
bA
hÜ
bQ
10
Funktionale Modellierung
ADach =
Funktionale Programmierung
4 * AÜbergangsTrapez
+ 4 * AÜbergangsDreieck
+ 8 * APyramidenDreieck
ADreieck
g
h
ADreieck(g,h) = 0.5*g*h
© KB 2002
ATrapez
a
c
h
ATrapez(a,c,h) = 0.5*(a+c)*h
11
Funktionale Modellierung
Funktionale Programmierung
ADach(bQ,bA,hÜ,hP) =
© KB 2002
4 * ATrapez(bQ,sA,hÜT)
+ 4 * ADreieck(sA,hÜD)
+ 8 * ADreieck(sA,hPD)
hP
hPD
bA
sA
hÜT
hÜ
hÜD
bQ
12
Funktionale Modellierung
sA
Funktionale Programmierung
bA
© KB 2002
hPD
bA
hP
hP
hÜD
bQ
bA
hÜ
bA
hÜT
bQ
bA
hÜ
hPD
sA
hÜT
hÜ
hÜD
bQ
13
Funktionale Modellierung
sA
Funktionale Programmierung
bA
© KB 2002
hPD
bA
hP
4*ATrapez(bQ,sA,hÜT) +
4*ADreieck(sA,hÜD) +
hÜD
bQ
bA
hÜ
8*ADreieck(sA,hPD)
ADach(bQ,bA,hÜ,hP) =
4*ATrapez(bQ,sA(bA),hÜT(bQ,bA,hÜ)) +
hÜT
bQ
bA
hÜ
ADach(bQ,bA,hÜ,hP) =
4*ADreieck(sA(bA),hÜD(bQ,bA,hÜ)) +
8*ADreieck(sA(bA),hPD(bA,hP))
14
Funktionale Modellierung
sA
Funktionale Programmierung
bA
© KB 2002
sA(bA) = bA * tan(/8)
hPD
bA
hP
hPD(bA,hP) = ((bA/2)2 + hP2)
hÜD
bQ
bA
hÜ
hÜD(bQ,bA,hÜ) =
(((2 * bQ - bA)/2)2 + hÜ2)
hÜT
bQ
bA
hÜ
hÜT(bQ,bA,hÜ) =
(((bQ - bA)/2)2 + hÜ2)
15
Funktionales Programm
ADreieck(g,h) = 0.5*g*h
Funktionale Programmierung
ATrapez(a,c,h) = 0.5*(a+c)*h
© KB 2002
sA(bA) = bA * tan(/8)
hPD(bA,hP) = ((bA/2)2 + hP2)
hÜD(bQ,bA,hÜ) = (((2 * bQ - bA)/2)2 + hÜ2)
hÜT(bQ,bA,hÜ) = (((bQ - bA)/2)2 + hÜ2)
ADach(bQ,bA,hÜ,hP) =
4 * ATrapez(bQ,sA(bA),hÜT(bQ,bA,hÜ)) +
4 * ADreieck(sA(bA),hÜD(bQ,bA,hÜ)) +
8 * ADreieck(sA(bA),hPD(bA,hP))
Funk. Progr. bestehen aus Funktionsdeklarationen.
Auswertung
16
ADach(10,5,4,20)
Funktionale Programmierung

© KB 2002
// Funktionsaufruf
4 * ATrapez(10,sA(5),hÜT(10,5,4)) +
4 * ADreieck(sA(10),hÜD(10,5,4)) +
8 * ADreieck(sA(10),hPD(5,20))

4 * ATrapez(10,5 * tan(/8),hÜT(10,5,4)) +
4 * ADreieck(sA(10),hÜD(10,5,4)) +
8 * ADreieck(sA(10),hPD(5,20))

...
...

306.012
// Funktionswert
Die Auswertung erfolgt durch Termersetzung.
17
Zusammenfassung
Funktionale Programmierung
Mit Funktionen kann man
programmieren.
© KB 2002
Die Programme bestehen aus
Funktionsdeklarationen.
Die Programmauswertung erfolgt
durch Funktionsanwendung
(Termersetzung).
Funktionale Programmierung
18
© KB 2002
Methodik: Arbeitsschritte
Problemkontext
Beschreiben
Benutzer
Funktionsdeklarationen
Funktionsaufruf
Derive
Lösung
Benutzer
Deuten
Vereinfachen
Funktionswert
Beschreiben - Vereinfachen - Deuten
Funktionale Programmierung
19
Derive als Programmiersystem
Beschreiben:
ATrapez(a,c,h) := 0.5*(a+c)*h
...
ADach(10,5,4,20)
Vereinfachen:
(31675 - 21950· 2) +...
306.012
Deuten:
© KB 2002
ADreieck(g,h) := 0.5*g*h
Der Flächeninhalt des Dachs ...
20
Übungen - Aufgabe 1
Funktionale Programmierung
Es soll ein Programm zur Kalkulation der
Herstellungskosten eines Buches entwickelt werden.
Folgende Informationen sollen dabei modelliert werden:
© KB 2002
Die Buchkosten setzen sich aus den Papierkosten,
Setzkosten, Druckkosten und Bindekosten zusammen.
Das Papier wird in Bögen zum Preis von 0,43 E geliefert.
Aus jedem Bogen lassen sich 16 Seiten schneiden. Der
Druck kostet 0,27 E pro Bogen, der Satz 17,5 E pro Seite.
Für das Binden eines Buches werden 1,83 E benötigt.
Das zu erstellende Programm soll bei gegebener Seitenzahl
(z.B. 366) und der Auflage (z.B. 10000) die
Gesamtherstellungskosten errechnen.
Hinweise zu Aufgabe 1
21
Funktionale Programmierung
Modellieren Sie zunächst geeignete (Hilfs-) Funktionen.
(Black-Box-Darstellung)
Entwickeln Sie anschließend die zugehörigen
Funktionsdeklarationen.
Zur Berechnung der Anzahl der Bögen benötigt man eine
Operation zur Durchführung der ganzzahligen Division.
Benutzen Sie hierzu die folgende (in Derive vordefinierte)
Operation:
FLOOR
23
5
4
Implementieren Sie abschließend die Funktionen mit DERIVE.
© KB 2002
22
Übungen - Aufgabe 2
Funktionale Programmierung
Zur Berechnung von Flächeninhalten / Integralen wird ein
Programm benötigt, das Rechtecksummen berechnen kann.
© KB 2002
Modellieren Sie zunächst geeignete (Hilfs-) Funktionen.
(Black-Box-Darstellung)
Erstellen Sie anschließend die Funktionsdeklarationen.
Implementieren Sie abschließend die Funktionen mit DERIVE.
Funktionale Programmierung
23
© KB 2002
Lösung zu Aufgabe 1
Bogen := 0.43
Druck := 0.27
Satz := 17.5
Binden := 1.83
BogenAnzahl(Seiten) := FLOOR(Seiten - 1, 16) + 1
PapierKosten(Seiten, Auflage) := BogenAnzahl(Seiten)·Bogen·Auflage
SetzKosten(Seiten) := Seiten·Satz
DruckKosten(Seiten, Auflage) := BogenAnzahl(Seiten)·Druck·Auflage
BindeKosten(Auflage) := Auflage·Binden
Kosten(Seiten, Auflage) :=
PapierKosten(Seiten, Auflage) +
SetzKosten(Seiten) +
DruckKosten(Seiten, Auflage) +
BindeKosten(Auflage)
24
Lösung zu Aufgabe 2
Funktionale Programmierung
Funktiondeklaration ohne Spezifikation des Funktionsterms
f(x) :=
© KB 2002
Streifenbreite:
d(a, b, n) := (b - a) / n
Unterteilungsstelle:
s(a, b, n, i) := a + i·d(a, b, n)
Rechtecksumme:
RS(a, b, n) := (d(a, b, n) ·f(s(a, b, n, i)), i, 0, n - 1)
Funktionale Programmierung
25
© KB 2002
Teil 2
Datentypen / Datenstrukturen
Funktionale Programmierung
26
© KB 2002
Rechteckfiguren
Es soll ein Programm erstellt werden, mit dem man
Rechteckfiguren zu einer vorgegeben Funktion
veranschaulichen kann. Es soll dabei möglich sein,
das Intervall und die Streifenbreite vorzugeben.
27
Datenmodellierung mit Listen
Punkt als Koordinatenpaar:
Funktionale Programmierung
[0, 0]
Rechteck als Streckenzug:
[[0, 0], [2, 0], [2, 4], [0, 4], [0, 0]]
Rechteckfigur als Folge von Rechtecken:
[
[[0, 0], [2, 0], [2, 4], [0, 4], [0, 0]],
[[2, 0], [4, 0], [4, 16], [2, 16], [2, 0]],
[[4, 0], [6, 0], [6, 36], [4, 36], [4, 0]]
]
© KB 2002
Listen in DERIVE
28
Liste: Folge von Objekten (Zahlen, Terme, Listen)
Funktionale Programmierung
[0, 1, 2, 3]
© KB 2002
[1, x, x2, x3]
[[], [0], [[0]]]
Erzeugung von Listen:
- Aufzählung der Listenelemente
[1, x, x2, x3]
- Generierung mit dem VECTOR-Operator
VECTOR(xn, n, 0, 3, 1)
Term:
xn
Laufvariable:
n
Anfangswert:
0
Endwert:
3
Schrittweite:
1
VECTOR
Term
nat. Zahl
nat. Zahl
nat. Zahl
nat. Zahl
[1, x, x2, x3]
29
Spezifikation der Funktionen
Funktionale Programmierung
Rechteckpunkte:
© KB 2002
Intervallgrenze:
a
Intervallgrenze:
b
Unterteilungen:
n
Nummer:
i
Rechteck:
Intervallgrenze:
a
Intervallgrenze:
b
Unterteilungen:
n
Nummer:
i
Rechteckfigur:
Intervallgrenze:
a
Intervallgrenze:
b
Unterteilungen:
n
LU
nat. Zahl
nat. Zahl
nat. Zahl
nat. Zahl
Rechteck
nat. Zahl
nat. Zahl
nat. Zahl
nat. Zahl
RF
nat. Zahl
nat. Zahl
nat. Zahl
Koordinaten
der linken
unteren Ecke
von Rechteck
Nummer i
Koordinaten der
Punkte des
Streckenzugs zum
Rechteck Nummer i
Koordinaten der
Punkte des
Streckenzugs zur
Rechteckfigur
Programm
30
Unterteilungsstellen:
Funktionale Programmierung
d(a, b, n) := (b - a) / n
s(a, b, n, i) := a + i·d(a, b, n)
Rechteckpunkte:
LU(a,b,n,i) := [s(a,b,n,i-1), 0]
RU(a,b,n,i) := [s(a,b,n,i), 0]
LO(a,b,n,i) := [s(a,b,n,i-1), f(s(a,b,n,i-1))]
RO(a,b,n,i) := [s(a,b,n,i), f(s(a,b,n,i-1))]
Rechteck als Streckenzug:
Rechteck(a,b,n,i) :=
[LU(a,b,n,i), RU(a,b,n,i), RO(a,b,n,i), LO(a,b,n,i), LU(a,b,n,i)]
Rechteckfigur als Folge von Rechtecken:
RF(a,b,n) := VECTOR(Rechteck(a,b,n,i), i, 1, n)
© KB 2002
31
Funktion als Eingabeobjekt
Funktionale Programmierung
Spezifikation:
Randfunktion:
f
Intervallgrenze:
a
Intervallgrenze:
b
Unterteilungen:
n
„Trick“:
RF
RR
nat. Zahl
nat. Zahl
nat. Zahl
A(pply)
Term
Term
Neuer Term,
bei dem x
jeweils durch u
ersetzt ist
Funktionsterm:
T
Einsetzungsterm:
u
Beispiele:
A(x2, 4)  16; A(x2, y-1)  (y-1)2
Implementierung in Derive:
© KB 2002
Koordinaten
der Punkte des
Streckenzugs
zur
Rechteckfigur
A(T, u) := LIM(T, x, u)
32
Derive-Implementierung
Funktionsdeklarationen:
Funktionale Programmierung
A(T, u) := LIM(T, x, u)
d(a, b, n) := (b - a) / n
s(a, b, n, i) := a + i·d(a, b, n)
LU(a,b,n,i) := [s(a,b,n,i-1), 0]
RU(a,b,n,i) := [s(a,b,n,i), 0]
LO(f,a,b,n,i) := [s(a,b,n,i-1), A(f, s(a,b,n,i-1))]
RO(f,a,b,n,i) := [s(a,b,n,i), A(f, s(a,b,n,i-1))]
Rechteck(f,a,b,n,i) :=
[LU(a,b,n,i), RU(a,b,n,i), RO(f,a,b,n,i), LO(f,a,b,n,i), LU(a,b,n,i)]
RF(f,a,b,n) := VECTOR(Rechteck(f,a,b,n,i), i, 1, n)
Funktionsaufruf:
RF(-x2 + 4, 0, 2, 10)
© KB 2002
Funktionale Programmierung
33
© KB 2002
Datentypen / Datenstrukturen
Elementare Datentypen:
Zahlen: 3; 5.1; ...
(Wahrheitswerte, Zeichen, Zeichenketten)
Funktionen:
Terme: x2 - 1
(Zuordnungen: x  x2 - 1)
Listen:
inhomogen: [x2 - 1, 0, [ ] ]
(homogen: [[0], [0, 1], [0, 1, 2], [0, 1, 2, 3]])
Funktionale Programmierung
34
© KB 2002
Warteschlange
Es soll ein Programm erstellt werden, mit dem man
Druckaufträge zwischenspeichern kann. Der
Zwischenspeicher soll nach dem FIFO-Prinzip (first
in, first out) arbeiten.
35
Datenmodellierung
Druckauftrag:
Struktur
Implementierung
Druckauftrag
Funktionale Programmierung
[4, [31,62,75,92]]
Adresse, Daten
Liste
Verbund
Zahl
Daten
..
Sequenz
Zahl
Warteschlange:
[[4, [31,62,75,92]], [3, []], [7, [102,101,77]]]
Struktur
Implementierung
Warteschlange
Sequenz
..
Druckauftrag
© KB 2002
Liste
Vereinfachte Warteschlange:
[4, 3, 7]
Liste
36
Warteschlangen-Operationen
Funktionale Programmierung
Spezifikation:
© KB 2002
Schlange:
Schlange:
L
ER
Liste
erstes Element
L
OE
Liste
Schlange ohne das erste
Element
ML
Liste
Element
Schlange, mit a als neuem
letztem Element
Schlange:
L
Auftrag:
a
37
Listenoperatoren von DERIVE
Funktionale Programmierung
Vordefinierte Operatoren
© KB 2002
Liste:
L
Nummer:
i
ELEMENT
Liste
nat. Zahl
Listenelement an
der Stelle i
Bsp.: ELEMENT([3,5,7,2,9,4], 2)  5
Kurzschreibweise: [3,5,7,2,9,4]  2
Liste:
L
DIMENSION
Liste
Bsp.: DIMENSION([3,5,7,2,9,4])  6
Anzahl der Listenelemente
Implementierung
38
ER(L) := ELEMENT(L,1)
Funktionale Programmierung
OE(L) := VECTOR(ELEMENT(L,i), i, 2, DIMENSION(L))
© KB 2002
ML(L,a) := VECTOR( IF(iDIMENSION(L), ELEMENT(L,i), a),
i,
1,
DIMENSION(L)+1)
IF-Operator
Syntax: IF( Bedingung, then-Ausdruck, else-Ausdruck )
Bsp.:
IF( x = y, 1, 0)
IF( x > 0, x2, -x2 )
39
Zusammenfassung
Funktionale Programmierung
elementare Datentypen
© KB 2002
Liste als zentrale
Datenstruktur;
zur Verarbeitung von Listen
benötigt man elementare
Listenoperationen
Funktionen als
Datenobjekte
40
Methodik: Programmieren
Schritt 1:
Funktionale Programmierung
Spezifikation der Funktion
© KB 2002
a) Signatur (Typen der Parameter; Ergebnistyp)
b) Verhalten (informelle Beschreibung; Beispiele)
Schritt 2:
Deklaration der Funktion
Schritt 3:
Implementierung der Funktion
Übung: Aufgabe 3
41
Funktionale Programmierung
Implementieren und testen Sie die folgenden Operationen zur
Listenverarbeitung:
© KB 2002
L
LE
Liste
letztes Element
L
OL
Liste
Liste ohne das letzte
Element
ME
Element
Liste
Liste, mit a als neuem
erstem Element
a
L
Funktionale Programmierung
42
© KB 2002
Übung: Aufgabe 4
Eine Liste enthält die Ergebnisse einer Würfelwurfserie.
Z.B.: [3, 2, 2, 6, 4, 5, 3, 6, 1, 5]
Entwickeln Sie ein Programm, das zählt, wie oft eine
bestimmte Augenzahl in der Würfelwurfserie vorgekommt.
Hinweise:
Entwickeln Sie zunächst eine Funktion, mit der man die
interessierende Augenzahl (z. B. 6) herausfiltern kann.
[3, 2, 2, 6, 4, 5, 3, 6, 1, 5]  [0, 0, 0, 1, 0, 0, 0, 1, 0, 0]
Mit Hilfe des vordefinierten SUM-Operators kann dann die
gewünschte Anzahl bestimmt werden.
Lösung zu Aufgabe 3
43
L := [3, 5, 2, 8, 6, 5, 1]
Funktionale Programmierung
LE(L) := ELEMENT(L, DIMENSION(L))
LE(L)
1
OL(L) := VECTOR(ELEMENT(L, i), i, 1, DIMENSION(L) - 1)
OL(L)
[3, 5, 2, 8, 6, 5]
ME(L, a) := VECTOR(IF(i = 0, a, ELEMENT(L, i)), i, 0, DIMENSION(L))
ME(L, 0)
[0, 3, 5, 2, 8, 6, 5, 1]
© KB 2002
Lösung zu Aufgabe 4
44
Filter(w, L) := VECTOR(IF(ELEMENT(L, i) = w, 1, 0), i, 1, DIMENSION(L))
Funktionale Programmierung
Filter(6, [3, 4, 6, 2, 1, 6, 4])
© KB 2002
[0, 0, 1, 0, 0, 1, 0]
Zaehlen(w, L) := SUM(Filter(w, L))
Zaehlen(6, [3, 4, 6, 2, 1, 6, 4])
2
Funktionale Programmierung
45
© KB 2002
Teil 3
Kontrollstrukturen
Funktionale Programmierung
46
© KB 2002
Bearbeitung von Anfragen
Das Programm zur Verwaltung von Druckaufträgen
soll auch Anfragen von Benutzern bearbeiten
können.
Z.B.: An welcher Stelle befindet sich „mein Auftrag“
in der Warteschlange?
47
Spezifikation zur Anfrage
Funktionale Programmierung
Problem:
© KB 2002
An welcher Stelle befindet sich der erste Auftrag von
Rechner x?
Spezifikation:
Stelle
Adresse:
x
Listenel.
Schlange:
L
Liste
Bsp.: Stelle(2, [3,5,2,7,2,9,4])  3
Stelle, an der sich der
erste Auftrag von x
befindet
48
Rekursive Problemreduktion
Reduktionsschritte:
Funktionale Programmierung
Stelle(3, [])  0
© KB 2002
Stelle(3, [3, 8, 3])  1
Stelle(3, [1, 2, 1, 3, 8, 3])  1 + Stelle(3, [2, 1, 3, 8, 3])
4
3
4
Rekursive Problemreduktion:
Reduktion des Problems auf ein entsprechendes, aber
„verkleinertes“ Problem
49
Reduktionsregeln
Reduktionsschritte:
Funktionale Programmierung
Stelle(3, [])  0
Stelle(3, [3, 8, 3])  1
Stelle(3, [1, 2, 1, 3, 8, 3])  1 + Stelle(3, [2, 1, 3, 8, 3])
Reduktionsregeln:
Stelle(x, [])  0
Stelle(x, [e|R])  IF(x=e, 1, 1+Stelle(x,R))
Reduktionsregeln sind Problemreduktionsschemata.
© KB 2002
50
DERIVE-Implementierung
Reduktionsregeln:
Funktionale Programmierung
Stelle(x, [])  0
© KB 2002
Stelle(x, [e|R])  IF(x=e, 1, 1+Stelle(x,R))
Implementierung:
Stelle(x, L) :=
IF(DIMENSION(L)=0,0,
IF(x=ER(L), 1, 1+Stelle(x,OE(L))))
eine Löschanfrage
51
Problem:
Funktionale Programmierung
Lösche den ersten Auftrag von Rechner x.
© KB 2002
Spezifikation:
LöscheErstes
Adresse:
x
Listenel.
Schlange:
L
Liste
Liste ohne den ersten
vorkommenden Auftrag
von x
Bsp.: LöscheErstes(2, [3,5,2,7,2,9,4])  [3,5,7,2,9,4]
52
Rekursive Problemreduktion
Reduktionsschritte:
Funktionale Programmierung
DelEr(3, [])  []
© KB 2002
DelEr (3, [3, 8, 3])  [8, 3]
DelEr(3, [1, 2, 1, 3, 8, 3])  [1 | DelEr(3, [2, 1, 3, 8, 3])]
[1, 2, 1, 8, 3]
[2, 1, 8, 3]
[1, 2, 1, 8, 3]
Reduktionsregeln:
DelEr(x, [])  []
DelEr(x, [e|R])  IF(x=e, R, ME(e, DelEr(x,R)))
53
DERIVE-Implementierung
Reduktionsregeln:
Funktionale Programmierung
DelEr(x, [])  []
© KB 2002
DelEr(x, [e|R])  IF(x=e, R, ME(e, DelEr(x,R)))
Implementierung:
DelEr(x, L) :=
IF(DIMENSION(L)=0, [],
IF(x=ER(L), OE(L), ME(ER(L), DelEr(x, OE(L)))))
54
Reduktionskonzept
Reduktionsregeln: Problemreduktionsschemata
Funktionale Programmierung
DelEr(x, [])  []
DelEr(x, [e|R])  IF(x=e, R, ME(e, DelEr(x,R)))
Reduktionskette: Anwendung der Reduktionsregeln
DelEr(3, [1, 2, 1, 3, 8, 3])
 ME(1, DelEr(3, [2, 1, 3, 8, 3]))
 ME(1, ME(2, DelEr(3, [1, 3, 8, 3])))
 ME(1, ME(2, ME(1, DelEr(3, [3, 8, 3]))))
 ME(1, ME(2, ME(1, [8, 3])))
 [1, 2, 1, 8, 3]
© KB 2002
Funktionsaufruf
Funktionswert
55
Zusammenfassung
Funktionale Programmierung
Kontrollstrukturen
© KB 2002
DelEr(x, L) :=
IF(DIMENSION(L)=0, Fallunterscheidung
[],
IF(x=ER(L),
OE(L),
ME(ER(L), DelEr(x, OE(L))))) Komposition
Rekursion
56
Methodik: Rekursion
Schritt 1:
Funktionale Programmierung
Entwurf typischer, exemplarischer Reduktionsschritte
© KB 2002
(Korrektheitsbetrachtungen, Terminationsbetrachtungen)
Schritt 2:
Verallgemeinerung zu Reduktionsregeln
Schritt 3:
Beschreibung mit einer rekursiven Funktion
57
Übung - Aufgabe 5
Funktionale Programmierung
Entwickeln Sie funktionale Programme zur Bearbeitung der
folgenden Anfragen:
© KB 2002
- Wie viele Aufträge hat Rechner x in der Schlange?
- Lösche alle Aufträge von Rechner x in der Schlange.
- Welche Rechner haben einen Auftrag in der Schlange?
Gehen Sie dabei nach der oben beschriebenen Methode
(exemplarische Reduktionsschritte; Reduktionsregeln;
Implementierung in Derive) vor.
58
Übung - Aufgabe 6
Funktionale Programmierung
Miniprojekt: Wir betrachten die folgende Erweiterung des
Warteschlangen-Programms:
© KB 2002
Die Druckaufträge sollen jetzt zusätzlich mit
Prioritätsangaben versehen werden (dringend, eilt nicht,
brennt, ...). Diese Prioritätsangaben werden hier mit Zahlen
kodiert (je kleiner die Zahl, desto höher ist die Priorität).
Ein Druckauftrag wird im folgenden durch ein Zahlenpaar
[Adresse, Prioritätsangabe] beschrieben.
Welche Änderungen ergeben sich durch diese Erweiterung?
Mit Hilfe einer Funktion „Umschalten“ soll man vom
normalen „FIFO-Betrieb“ in den „Prioritätsbetrieb“
umschalten können. Die Druckaufträge sollen dann in der
Warteschlange umsortiert werden.
59
Lösung zu Aufgabe 5
Anfrage:
Funktionale Programmierung
Wie viele Aufträge hat Rechner x in der Schlange?
© KB 2002
Reduktionsregeln:
Anzahl(x, [])  0
Anzahl(x, [e|R])  IF(x=e, 1+Anzahl(x,R), Anzahl(x,R))
Implementierung:
Anzahl(x, L) :=
IF(DIMENSION(L)=0,0,
IF(x=ER(L),
1+Anzahl(x,OE(L)),
Anzahl(x,OE(L))))
60
Lösung zu Aufgabe 5
Anfrage:
Funktionale Programmierung
Lösche alle Aufträge von Rechner x in der Schlange.
© KB 2002
Reduktionsregeln:
DelAlle(x, [])  []
DelAlle(x, [e|R])  IF(x=e, DelAlle(x,R), ME(e, DelAlle(x,R)))
Implementierung:
DelAlle(x, L) :=
IF(DIMENSION(L)=0, [],
IF(x=ER(L),
DelAlle(x,OE(L)),
ME(ER(L), DelAlle(x, OE(L)))))
61
Lösung zu Aufgabe 5
Anfrage:
Funktionale Programmierung
Welche Rechner haben einen Auftrag in der Schlange?
© KB 2002
Reduktionsregeln:
Benutzer([])  []
Benutzer([e|R])  ME(e, Benutzer(DelAlle(e,R))
Implementierung:
Benutzer(L) :=
IF(DIMENSION(L)=0,
[],
ME(ER(L), Benutzer(DelAlle(ER(L), OE(L)))))
Funktionale Programmierung
62
© KB 2002
Teil 4
Funktionale Programmierung
63
ein Problem - drei Lösungen
Funktionale Programmierung
imperative Lösung
© KB 2002
Tauschen(x, y)
z := x
x := y
y := z
funktionale Lösung
Tauschen([x, y]) = [y, x]
Logik-basierte Lösung
Tauschen([x, y], [a, b])
 x = b, y = a
64
Programmierstile
Funktionale Programmierung
Registerbelegung
Programm:
z := x
x := y
y := z
Registermaschine
Registerbelegung
Imperative Programmierung
Das Programm besteht aus Anweisungen.
Die Registermaschine verändert die Registerbelegung gemäß den Anweisungen.
Algorithmisches Denken
© KB 2002
Erfassen u. Beschreiben von (zeitlichen) Abläufen
65
Programmierstile
Funktionale Programmierung
Anfrage
Programm:
T([x, y], [a, b])
 x = b, y = a
Inferenzmaschine
Ergebnis
Logik-basierte Programmierung
Das Programm besteht aus Fakten und Regeln.
Die Inferenzmaschine sucht eine auf den Fakten
und Regeln basierende logische Folgerungskette
zur Klärung der Anfrage.
Logisches Denken
© KB 2002
Erfassen u. Beschreiben von Sachverhalten
66
Programmierstile
Funktionale Programmierung
Ausgangsterm
Programm:
Tauschen([x, y])
= [y, x]
Reduktionsmaschine
Ergebnisterm
Funktionale Programmierung
Das Programm besteht a. Funktionsdeklarationen.
Die Reduktionsmaschine vereinfacht den Ausgangsterm mit Hilfe der Funktionsdeklarationen.
Funktionales Denken
Erfassen u. Beschreiben von Zuordnungen
© KB 2002
Funktionale Programmierung
67
© KB 2002
Funktionales Denken
Funktionsterme
beinhalten
Funktionen beschreiben
Ein-/Ausgabe-Sit. bzw. Berechnungsregeln
Berechnungssituationen
Funktionale
Funktionale
Ausdrücke / Terme
Ausdrücke /Terme sind referentiell
beschreiben
transparent
Problemwerte
Funktionale Programmierung
68
Referentielle Transparenz
Jeder (Teil-)Term beschreibt einen bestimmten Wert, der nicht
durch die Auswertung anderer (Teil-)Terme verändert werden
kann. Die Auswertung eines (Teil-)Term verändert seine Form,
aber nicht seinen Wert.
- Term muss nur einmal dargestellt / ausgewertet werden
- Reihenfolge der Auswertung irrelevant
- parallele Auswertung ist möglich
- keine Seiteneffekte, die das Verhalten komplizieren
ADach(bQ,bA,hÜ,hP) =
4 * ATrapez(bQ,sA(bA),hÜT(bQ,bA,hÜ)) +
4 * ADreieck(sA(bA),hÜD(bQ,bA,hÜ)) +
© KB 2002
8 * ADreieck(sA(bA),hPD(bA,hP))
69
Referentielle Transparenz
Funktionale Programmierung
Funktionale Programme sind i. a. referentiell transparent.
© KB 2002
ADach(bQ,bA,hÜ,hP) =
4 * ATrapez(bQ,sA(bA),hÜT(bQ,bA,hÜ)) +
4 * ADreieck(sA(bA),hÜD(bQ,bA,hÜ)) +
8 * ADreieck(sA(bA),hPD(bA,hP))
Imperative Programme sind i. a. referentiell undurchsichtig.
s := 0;
x := x + 1
s := s + x;
x := x + 1;
s := s + 1;
70
Auswertung von Würfelserien
Funktionale Programmierung
...
© KB 2002
Mit Hilfe eines Programms sollen Würfelserien
erzeugt und ausgewertet werden. Das Programm
soll insbesondere eine Häufigkeitsverteilung
erstellen.
Funktionale Programmierung
71
Programm - Version 1
Wuerfeln := RANDOM(6) + 1
WuerfelSerie(n) := VECTOR(Wuerfeln, m, 1, n)
WuerfelSerie(10)
[4, 4, 5, 5, 5, 5, 2, 3, 4, 5]
Häufigkeit(i, n) :=
DIMENSION(SELECT(x = i, x, WuerfelSerie(n)))
Häufigkeit(4, 100)
20
Häufigkeit(3, 100)
16
Verteilung(n) := VECTOR([i, Häufigkeit(i, n)], i, 1, 6)
[[ 1, 16], [2, 16], [3, 13], [4, 20], [5, 16], [6, 16]]
Nicht korrekt!
© KB 2002
Funktionale Programmierung
72
Programm - Version 2
Wuerfeln := RANDOM(6) + 1
WuerfelSerie(n) := VECTOR(Wuerfeln, m, 1, n)
WuerfelSerie(10)
[4, 4, 5, 5, 5, 5, 2, 3, 4, 5]
Häufigkeit(i, L) := DIMENSION(SELECT(x = i, x, L))
Häufigkeit(5, [4, 4, 5, 5, 5, 5, 2, 3, 4, 5])
5
Verteilung(L) := VECTOR([i, Häufigkeit(i, L)], i, 1, 6)
Verteilung([4, 4, 5, 5, 5, 5, 2, 3, 4, 5])
[[ 1, 0], [2, 1], [3, 1], [4, 3], [5, 5], [6, 0]]
Verteilung(WuerfelSerie(100))
[[ 1, 12], [2, 14], [3, 22], [4, 19], [5, 14], [6, 19]]
Korrekt!
© KB 2002
73
Der RANDOM-Operator
Funktionale Programmierung
Versuch 1:
© KB 2002
VECTOR(RANDOM(2), i, 1, 3)
[0, 0, 1]
VECTOR(RANDOM(2), i, 1, 3)
[1, 0, 1]
Versuch 2:
h(x) := VECTOR(x, i, 1, 3)
h(RANDOM(2))
[1, 1, 1]
h(RANDOM(2))
[0, 0, 0]
Keine referentielle Transparenz!
74
Auswertungsstrategien
Funktionale Programmierung
Versuch 1 - Auswertung: erst außen, dann innnen
© KB 2002
VECTOR(RANDOM(2), i, 1, 3)
 [RANDOM(2), RANDOM(2), RANDOM(2)]
 [0, 0, 1]
Versuch 2 - Auswertung: erst innen, dann außen
h(RANDOM(2))
 h(1)
 VECTOR(1, i, 1, 3)
 [1, 1, 1]
// h(x) := VECTOR(x, i, 1, 3)
Wenn keine referentielle Transparenz vorhanden ist, muss man
detailliertes Wissen über die Arbeitsweise der ausführenden
Maschine haben, um korrekte Programme zu erstellen.
Warum funktional?
75
Grund 1: (nach B. J. MacLennan, Functional Programming)
Funktionale Programmierung
Programmieren erfolgt ohne Wertzuweisungen.
Vorteile:
- Programme sind einfacher zu verstehen.
- Programme können systematischer erzeugt werden.
- Es ist einfacher, Programme zu beurteilen.
Beispiel:
ADach(bQ,bA,hÜ,hP) =
4 * ATrapez(bQ,sA(bA),hÜT(bQ,bA,hÜ)) +
4 * ADreieck(sA(bA),hÜD(bQ,bA,hÜ)) +
© KB 2002
8 * ADreieck(sA(bA),hPD(bA,hP))
Warum funktional?
76
Grund 2: (nach B. J. MacLennan, Functional Programming)
Funktionale Programmierung
Funktionale Programmierung unterstützt parallele Verarbeitung.
© KB 2002
Grund: referentielle Transparenz
Beispiel:
ADach(bQ,bA,hÜ,hP) =
4 * ATrapez(bQ,sA(bA),hÜT(bQ,bA,hÜ)) +
4 * ADreieck(sA(bA),hÜD(bQ,bA,hÜ)) +
8 * ADreieck(sA(bA),hPD(bA,hP))
77
Warum funktional?
Funktionale Programmierung
Grund 3: (nach B. J. MacLennan, Functional Programming)
© KB 2002
Funktionales Programmieren erfolgt auf einem höheren
Abstraktionsniveau.
Beispiel: Sortieren
ins(x, [])  [x]
ins(x, [e|R])  IF(x < e, [x|[e| R]], [e|ins(x, R)])
sort([])  [ ]
sort([e|R])  ins(e, sort(R))
78
Warum funktional?
Funktionale Programmierung
Grund 4: (nach B. J. MacLennan, Functional Programming)
© KB 2002
Funktionale Programmierung wird sehr viel in der KI (künstliche
Intelligenz) verwendet.
Grund 5: (nach B. J. MacLennan, Functional Programming)
Funktionale Programmierung erlaubt es, schnell Prototypen zu
entwickeln (Programme als ausführbare Spezifikationen).
Grund 6: (nach B. J. MacLennan, Functional Programming)
Funktionale Programmierung ist eng verknüpft mit der
theoretischen Informatik: liefert ein Programmiermodell, das
sich gut eignet, allgemeine Fragestellungen zu untersuchen.
Funktionale Sprachen
Funktionale Programmierung
79
© KB 2002
-Kalkül
(Church und Kleene; 30er Jahre)
LISP
(McCarthy; um 1960)
LOGO
(Papert; 80er Jahre)
ML
(Milner 1984;  Caml)
Miranda
(Turner 1985)
Haskell
(Hudak u. a. 1992)
80
Funktionale Sprachen
Reduktionsregeln:
Funktionale Programmierung
DelEr(x, [])  []
© KB 2002
DelEr(x, [e|R])  IF(x=e, R, [e | DelEr(x,R)] )
Implementierung mit Derive:
DelEr(x, L) :=
IF(DIMENSION(L)=0,
[],
IF(x=ER(L), OE(L), ME(ER(L), DelEr(x, OE(L)))))
81
Funktionale Sprachen
Reduktionsregeln:
Funktionale Programmierung
DelEr(x, [])  []
© KB 2002
DelEr(x, [e|R])  IF(x=e, R, [e | DelEr(x,R)] )
Implementierung in LOGO:
PR DelEr :x :L
PRÜFE :L = [ ]
WW RG []
WF PRÜFE :x = ER :L
WW RG OE(L)
WF RG ME ER :L DelEr :x OE :L
82
Funktionale Sprachen
Reduktionsregeln:
Funktionale Programmierung
DelEr(x, [])  []
DelEr(x, [e|R])  IF(x=e, R, [e | DelEr(x,R)] )
Implementierung in CAML:
let rec DelEr = function
(x, []) -> [] |
(x, e::r) -> if x = e
then r
else e::DelEr(x,r);;
DelEr : `a * `a list -> `a list = <fun>
© KB 2002
Funktionale Programmierung
83
© KB 2002
... und in der Schule?
Klarer
Einfache, kurze,
Programmierstil
durchschaubare
Programme
Funktionale
Programmierung
„andere“ Form des
Programmierens
Funktionales
Denken
Fazit:
Funktionale Programmierung ist
gut / bestens geeignet für die
Schule.
84
Literatur
[Becker 99] K. Becker: Funktionale Programmierung. Materialien zum Lehrplan
Informatik. LMZ 1999. (http://informatikag.bildung-rp.de/html/funktprog.html)
Funktionale Programmierung
[Becker 00] K. Becker: Problemlösen mit dem Computeralgebrasystem Derive informatisch betrachtet. (http://informatikag.bildung-rp.de/html/derive.html)
© KB 2002
[Fischbacher 97] T. Fischbacher: Funktionale Programmierung. In: LOG IN 17
(1997) Heft 3 / 4, S. 24-26.
[ISB 97] Staatliches Institut für Schulpädagogik und Bildungsforschung München
(Hrsg.): Funktionales Programmieren in Gofer. Baustein zur Didaktik der
Informatik. München, 1997.
[Puhlmann 98] H. Puhlmann: Funktionales Programmieren - Eine organische
Verbindung von Informatikunterricht und Mathematik. In: LOG IN 18 (1998) Heft
2, S. 46-50.
[Schwill 93] A. Schwill: Funktionale Programmierung mit Caml. In: LOG IN 13
(1993) Heft 4, S. 20-30.
[MacLennan ??] B.J. MacLennan: Functional Programming: Addison-Wesley ??.
[Wagenknecht 94] Christian Wagenknecht: Rekursion. Ein didaktischer Zugang
mit Funktionen. Bonn: Dümmlers Verlag 1994.
[Wolff von Gudenberg 96] J. Wolff. von Gudenberg: Algorithmen,
Datenstrukturen, Funktionale Programmierung. Eine praktische Einführung mit
Caml Light. Bonn: Addison-Wesley 1996.
Herunterladen