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 RR 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(iDIMENSION(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.