Technische Universität Braunschweig Institut für Programmierung und Reaktive Systeme Dr. Werner Struckmann 31. Januar 2013 Programmieren für Fortgeschrittene Übersicht Art der Veranstaltung: Wintersemester, Bachelor, 5 LP, 2 VL + 2 UE + Rechnerübungen In dieser Veranstaltung werden grundlegende Konzepte und Paradigmen heutiger Programmiersprachen betrachtet. Solide Kenntnisse der objektorientierten und imperativen Programmierung sowie der Programmiersprache Java werden vorausgesetzt. Kurzbeschreibung: Gegenstand der Programmierausbildung in den ersten Semestern ist das Programmieren in der objektorientierten Sprache Java. Es existieren aber viele weitere Programmiersprachen und auch andere Programmierparadigmen. In dieser Vorlesung wird hierüber zunächst ein Überblick gegeben, anschließend werden grundlegende Konzepte der Programmiersprachen aus einer allgemeinen Sichtweise behandelt. In den Übungen werden die allgemeinen Konzepte an konkreten Programmiersprachen verdeutlicht. Das Schwergewicht in den Übungen liegt auf der funktionalen Programmierung. Insbesondere besteht die Möglichkeit, die Programmiersprache Haskell zu erlernen. Stichwörter: Sprachen der Informatik, Programmiersprachen, Programmierparadigmen, Konzepte höherer Programmiersprachen, funktionale Programmierung, Haskell. Termine: Beginn: Di. Vorlesung Di. Übung: Do. Sprechstunde: Mi. 16. Oktober 2012 15:00–16:30 Uhr 09:45–11:15 Uhr 10:30–11:30 Uhr IZ 161 IZ 160 IZ 244 Diese Datei wird im Laufe des Semesters wöchentlich aktualisiert! Gliederung der Veranstaltung 1 Einführung 1.1 Sprachen und Paradigmen 1.2 Definition von Programmiersprachen 1.3 Implementierung von Programmiersprachen 2 Datenstrukturen und Anweisungen 2.1 Semantische Grundbegriffe 2.1.1 Namen und Attribute 2.1.2 Deklarationen, Blöcke und Gültigkeits- und Sichtbarkeitsbereiche 2.1.3 Überladung und Auflösung von Namen 2.1.4 Umgebung und Speicherzuweisung 2.1.5 Variable und Konstante 2.1.6 Alias-Namen und Garbage-Collection 2.2 Datentypen und Typsysteme 2.2.1 Grundbegriffe 2.2.2 Einfache Datentypen 2.2.3 Typkonstruktoren 2.2.4 Typäquivalenz 2.2.5 Typüberprüfung und -berechnung 2.2.6 Typkonversion 2.2.7 Polymorphismus 2.3 Ausdrücke und Anweisungen 2.3.1 Ausdrücke 2.3.2 Primitive Anweisungen 2.3.3 Strukturierte Anweisungen 2.3.4 Selektionsanweisungen 2.3.5 Iterationsanweisungen 2.3.6 Sprunganweisungen 3 Unterprogramme, Programme und Module 3.1 Unterprogramme 3.1.1 Grundbegriffe 3.1.2 Semantik von Unterprogrammen 3.1.3 Parameterübergabemechanismen 3.1.4 Prozedurumgebungen, Aktivierungen und Speicherbelegung 3.2 Hauptprogramme 3.3 Abstrakte Datentypen und Module 3.3.1 Algebraische Spezifikation abstrakter Datentypen 3.3.2 Abstrakte Datentypen und Module 4 Paradigmenübergreifende Konzepte 4.1 Generische Programmeinheiten 4.2 Zusicherungen –2– 4.3 Annotationen 4.4 Ereignisbehandlung 4.5 Parallele und verteilte Programmierung 4.5.1 Grundlagen 4.5.2 Standardprobleme der Parallelprogrammierung 4.5.3 Sprachkonzepte 4.5.4 Eigenschaften paralleler und verteilter Programme Quellenverzeichnis A Übungen A.1 Funktionale Programmierung A.1.1 Das funktionale Paradigma A.1.2 Funktionale Sprachen im Überblick A.1.3 Rekursive Spezifikationen A.1.4 Der λ-Kalkül A.1.5 Das Komprehensionsprinzip A.1.6 Currying, strikte Funktionen, Funktionen höherer Ordnung A.1.7 Komplexität rekursiver Algorithmen A.1.8 Korrektheit rekursiver Algorithmen B Übungsaufgaben B.1 1. Übungsblatt B.2 2. Übungsblatt –3– 1 Einführung 1.1 Sprachen und Paradigmen Natürliche, künstliche und formale Sprachen; Programmiersprachen; spezielle Sprachklassen; grundlegende Programmierkonzepte, imperatives, funktionales, prädikatives und objektorientiertes Paradigma; prozedurales und deklaratives Paradigma; Entwicklung der Programmiersprachen; Sprachgenerationen; hybride Paradigmen: imperativ-basierte objektorientierte Programmierung; Skriptsprachen; Datenstrukturen; Typsysteme; paradigmenübergreifende Konzepte; Prinzipien des Sprachentwurfs. 1.2 Definition von Programmiersprachen Lexik; Lexem; Token; Syntax; kontextfreie Grammatik; Syntaxdiagramm; Backus-NaurForm; operationelle, denotationale, axiomatische, algebraische Semantik; Pragmatik; Beispielsprache und Beispielprogramm; Sprachreport. 1.3 Implementierung von Programmiersprachen Klassen von Programmiersprachen; Interpreter; Compiler; Interpretation von Zwischenbzw. Bytecode; virtuelle Maschine; Just-in-Time-Compiler. 2 Datenstrukturen und Anweisungen 2.1 Semantische Grundbegriffe 2.1.1 Namen und Attribute Name; Speicherstelle; Wert; statische und dynamische Attribute; Deklaration; Bindung; Bindungszeit; statische und dynamische Bindung; semantische Funktionen: Symboltabelle; Umgebung; Speicher. 2.1.2 Deklarationen, Blöcke und Gültigkeits- und Sichtbarkeitsbereiche Deklaration und Definition; Verbundanweisung; Block; explizite und implizite Deklarationen; globale, lokale und nichtlokale Deklarationen; Gruppen von Deklarationen; Bindung; Bindungszeit; statische und dynamische Bindungen; explizite und implizite Bindungen; Gültigkeitsbereich (Scope) einer Bindung bzw. einer Deklaration; Lücke im Gültigkeitsbereich; Sichtbarkeit; statischer (lexikalischer) Scope; die Regeln „Deklaration-vorBenutzung“ und „kleinster umfassender Block“; Blockstruktur; lokale, nichtlokale und globale Deklarationen; Blöcke mit Namen; Scope-Resolution-Operator; visibility by selection; externe Deklarationen; Gültigkeitsbereiche bei Rekursionen; wechselseitige Rekursion; Attributdeklaration; Prototyp; Forward-Deklaration; Aufbau einer Symboltabelle; dynamischer Scope. –4– 2.1.3 Überladung und Auflösung von Namen Wiederverwendung von Funktionsnamen und Operatoren; Überladung (Overloading) von Namen; explizite und implizite Typumwandlung; Auflösung von mehrdeutigen Namen (Overload resolution); Redefinition von Operatoren; Überladung allgemeiner Namen. 2.1.4 Umgebung und Speicherzuweisung Umgebung; Speicherzuweisung; Speicherzuweisung bei blockstrukturierten Sprachen; Aktivierung einer Prozedur, Aktivierungssegment; Speicherobjekt; Lebenszeit (extent) eines Objekts; Zeiger (Pointer); new- und delete-Operationen; Heap; Belegung (Alloziierung) und Freigabe (Dealloziierung) von Speicher; automatische bzw. kellerbasierte Speicherbelegung; dynamische bzw. manuelle Speicherbelegung; Aufbau des Speichers zur Laufzeit; Speicherklassen; Zuordnung zu den Speicherklassen. 2.1.5 Variable und Konstante Variable; Speichermodell; Zuweisung; L- und R-Wert einer Variablen; Storage-Semantik; Pointer-Semantik: Assignment-by-Sharing und Assignment-by-Cloning; Konstante; Wertsemantik; Übersetzungszeitkonstante; Manifest-Konstante; dynamische Konstante; statische Laufzeitkonstante; Funktionskonstante und -variable; Funktionsliterale. 2.1.6 Alias-Namen und Garbage-Collection Alias-Name; Seiteneffekt; Beispiele für Auftreten von Alias-Namen; hängende Referenzen; Garbage; Garbage Collection. 2.2 Datentypen und Typsysteme 2.2.1 Grundbegriffe Abstraktion; Maschinenabhängigkeit; Datentyp; Wertemenge und Operationen; Typüberprüfung; Typberechnung; Typkonstruktor; Typdeklaration; Typäquivalenz; Typkompabilität; Typanpassung; Typsystem; starke/schwache Typisierung; dynamische Typisierung. 2.2.2 Einfache Datentypen Vordefinierter Typ; einfacher Datentyp; arithmetischer Datentyp; char; boolean; Aufzählungstyp; Unterbereichstyp; Ordinaltyp; Realtyp; Mengentyp; Speicherung ganzer Zahlen; Subtraktion ganzer Zahlen; Dualzahldarstellung rationaler Zahlen; Speicherung von Gleitkommazahlen; gemoetrische Reihe; Rundungsfehlerproblematik. 2.2.3 Typkonstruktoren Mengentheoretische Operationen; kartesisches Produkt; Selektor; Record-Struktur; Vereinigung; disjunkte Vereinigung; variante Record-Struktur; Tag; discriminated/undiscrimanted union; Teilmenge; subtype; Arrays; assoziative Arrays; Funktionen; Indextyp; Wertetyp; mehrdimensionale Typen; allgemeine Funktionstypen; Listen; Tupel; Zeigertypen –5– (pointer); Referenztypen; rekursive Datentypen und Zeigertypen; Bezeichnungen für Typen. 2.2.4 Typäquivalenz Typäquivalenz; Strukturäquivalenz; Typnamen; anonyme Datentypen; Namensäquivalenz; Deklarationsäquivalenz. 2.2.5 Typüberprüfung und -berechnung Statische und dynamische Typüberprüfung; Typberechnung (type inference); Typkompabilität; Zuweisungskompabilität; implizite Datentypen; überlappende Datentypen; Werte, die zu mehreren Datentypen gehören; überladene Operationen. 2.2.6 Typkonversion Implizite Typkonversion (coercion); explizite Typkonversion (cast); widening und narrowing. 2.2.7 Polymorphismus Polymorphismus; Überladen von Operatoren; Vererbung; Monomorphismus; explizite und implizite Typisierung; polymorphe Typüberprüfung; Prinzip der Hindley-Milner-Typüberprüfung; Grundlagen der Unifikation; Formen des Polymorphismus: impliziter parametrischer Polymorphismus, Ad-Hoc-Polymorphismus, reiner Polymorphismus. 2.3 Ausdrücke und Anweisungen 2.3.1 Ausdrücke Ausdruck vs. Anweisung; ausdrucksorientierte Sprache; primitive und zusammengesetzte Ausdrücke; Operand; Operator; Überladen von Operatoren; Operator vs. Funktion; Stelligkeit; Prioritätsregel; Assoziativitätsregel; Funktionsaufruf; Klammerung; strikte Auswertung eines Ausdrucks (applicative order evaluation); Seiteneffekt; Sequenzoperator; unvollständige Auswertung von Ausdrücken; short circuit evaluation; If- und Case-Operator; Typanpassungen; Ausdrücke und Zuweisungen gemischten Typs; nichtstrikte Auswertung eines Ausdrucks (verzögerte Auswertung, delayed evaluation); Ersetzungsregel; normal order evaluation (lazy evaluation). 2.3.2 Primitive Anweisungen Leere Anweisung; Deklaration; Ausdrucksanweisung; Zuweisung; Prozedur-, Funktionsund Methodenaufruf. 2.3.3 Strukturierte Anweisungen Strukturierte Anweisungen; die Begriffe „single-entry“, „single-exit“ und „multiple-exit“; Sequenz; Verbundanweisung; Block. –6– 2.3.4 Selektionsanweisungen Selektion; bewachte Auswahl (guarded if); Wächter; Nichtdeterminismus; If-Anweisung; Dangling-Else-Problem und Lösungen; Typ des Kontrollausdrucks; Case- bzw. SwitchAnweisung. 2.3.5 Iterationsanweisungen Iteration; bewachte Schleife (guarded do); while-Schleife; do-Schleife; repeat-Schleife; Ausstiegspunkte; break-, continue- und exit-Anweisung; for-Schleife; Varianten der forSchleife; Iterator. 2.3.6 Sprunganweisungen goto-Anweisung; Problematik; Ergebnis von C. Böhm und G. Jacopini. 3 Unterprogramme, Programme und Module 3.1 Unterprogramme 3.1.1 Grundbegriffe Unterprogramm; Abstraktion; Prozedur vs. Funktion vs. Methode; Prozedurspezifikation; Parameter; Deklaration; Definition; Prototyp; variable Parameterzahl; Prozedurrumpf; Prozeduraufruf; Aktivierung; Rufer und Gerufener; Return-Anweisung; Prozedur/Funktion als Konstante; Funktionsliterale; Unterprogramme und Objekte als Parameter. 3.1.2 Semantik von Unterprogrammen Unterprogramme und Umgebungen; activation record; definierende (statische) und rufende (dynamische) Umgebung; formale und aktuelle Parameter; lokale und nichtlokale Referenzen in einem Prozedurrumpf; geschlossene Form einer Prozedur; Abschluss, Closure. 3.1.3 Parameterübergabemechanismen Pass by value; pass by reference; pass by value-result; pass by result; pass by name; Seiteneffekte; Jensens device; Parameterüberprüfung. 3.1.4 Prozedurumgebungen, Aktivierungen und Speicherbelegung Umgebung; Aktivierung; Aktivierungssegment; Speicherbelegung bei statischen Umgebungen; Speicherbelegung bei kellerbasierten Laufzeitumgebungen; flache und geschachtelte Umgebungen; Rücksprung-Adresse; Umgebungszeiger; Adressierung lokaler und globaler Variabler; Rückgabewert; dynamischer Verweis; statischer Verweis; Heap. –7– 3.2 Hauptprogramme Flache und geschachtelte Sprachen; imperatives, objektorientiertes, funktionales und logisches Paradigma; hybride Paradigmen. 3.3 Abstrakte Datentypen und Module 3.3.1 Algebraische Spezifikation abstrakter Datentypen Abstrakte und konkrete Datentypen; generische und spezifische Datentypen; Spezifikation; Schnittstelle; Kapselung und Geheimnisprinzip; Signatur, Sorte, Algebra, Axiom; natürliche Zahlen als ADT; Implementierung eines abstrakten Datentyps; algebraische Spezifikation; Import-Anweisung. 3.3.2 Abstrakte Datentypen und Module Modul; abstrakte Datentypen und Module; Namenskonflikte; qualifizierte Namen; Importund Export-Listen; getrennte Übersetzung; Namespaces; Packages; Module in Modula-2; opaquer Typ. 4 Paradigmenübergreifende Konzepte 4.1 Generische Programmeinheiten Generische Unterprogramme, Klassen und Module; Typebounds; Wildcards; Programmierung generischer Einheiten ohne generische Sprachkonzepte. 4.2 Zusicherungen Hoare’sche Logik; Hoare’scher Kalkül; Nachbedingung; Vorbedingung; Schleifeninvariante; Axiomenschema; Ableitungsregeln; Zustand; partielle und totale Korrektheit; Korrektheit und relative Vollständigkeit des Kalküls; die assert-Anweisung; Anwendungen der assert-Anweisung; Anwendung in öffentlichen und privaten Methoden; Nachbedingungen; Vorbedingungen; Schleifeninvariante; Kontrollflussinvariante; komplexe Zusicherungen; Klasseninvariante. 4.3 Annotationen Annotation; Pragma; Beispiel: inline-Pragma. 4.4 Ereignisbehandlung Ein-Ausgabe-Programmierung; ereignisgesteuerte Programmierung; Beispiel: Delegation based event handling. –8– 4.5 Parallele und verteilte Programmierung 4.5.1 Grundlagen Multicore-Architekturen; vom sequenziellen zum parallelen Programm; elementare Aktion; Ausführung paralleler Prozesse; Fairness; Nebenläufigkeit; unabhängige und gekoppelte Anweisungen und Prozesse; interleaving semantics; Szenarium; synchrone/asynchrone Arbeitsweise; Thread; Prozess; leicht- und schwergewichtige Prozesse. 4.5.2 Standardprobleme der Parallelprogrammierung Gegenseitiger Ausschluss; Algorithmus von Dekker; Erzeuger-Verbraucher-Problem; speisende Philosophen; Leser-Schreiber-Problem. 4.5.3 Sprachkonzepte Konstrukte zur Prozessverwaltung: cobegin-coend-Anweisung, fork-join-Anweisung, Prozessdeklarationen, Koroutinen; Kommunikation: gemeinsame Variable, Nachrichtenaustausch; Synchronisation: aktives Warten, Semaphore, Monitore, kritische Regionen, Rendezvous-Konzept. 4.5.4 Eigenschaften paralleler und verteilter Programme Sicherheitseigenschaft; Lebendigkeitseigenschaft; partielle, totale Korrektheit; Verklemmung; Verschwörung; schwache, starke Fairness. –9– Quellenverzeichnis [1] Alber, Klaus; Struckmann, Werner: Einführung in die Semantik von Programmiersprachen. Mannheim Wien Zürich: BI-Wissenschaftsverlag, 1988 [2] Ben-Ari, Mordechai: Principles of Concurrent and Distributed Programming. 2. Auflage. Harlow, London: Addison-Wesley, 2006 [3] Block, Marco; Neumann, Adrian: Haskell – Intensivkurs. 1. Auflage. Berlin Heidelberg: Springer Verlag, 2011 [4] Bramer, Max: Logic Programming with Prolog. 1. Auflage. Springer Verlag (USA), 2005 [5] Breymann, Ulrich: C++ – Einführung und professionelle Programmmierung. 9., neu bearbeitete Auflage. München: Hanser Verlag, 2007 [6] Broy, Manfred: Informatik – Eine grundlegende Einführung, Teil 1. 1. Auflage. Berlin Heidelberg: Springer Verlag, 1992 [7] Chakravarty, Manuel M.; Keller, Grabriele C.: Einführung in die Programmierung mit Haskell. 1. Auflage. München: Pearson Education Deutschland GmbH, 2004 [8] Doberkat, Ernst-Erich: Haskell – Eine Einführung für Objektorientierte. 1. Auflage. München: Oldenbourg Verlag, 2012 [9] Duden: Informatik. 4. Auflage. Mannheim: Dudenverlag, 2006 [10] Henning, Peter A.; Vogelsang, Holger: Taschenbuch Programmiersprachen. 2. Auflage. München: Carl Hanser Verlag, 2007 [11] Hohlfeld, Bernhard; Struckmann, Werner: Einführung in die Programmverifikation. Mannheim Wien Zürich: BI-Wissenschaftsverlag, 1992 [12] Hudak, Paul: Conception, Evolution, and Application of Functional Programming Languages. In: ACM Computing Surveys 21 (1989), Nr. 3, S. 359–411 [13] Hutton, Graham: Programming in Haskell. 1. Auflage. Cambridge: Cambridge University Press, 2007 [14] Jones, Simon P. (Hrsg.): Haskell 98 Language and Libraries – The Revised Report. 2002 . – Im Netz unter http://www.haskell.org erhältlich. [15] Lee, Kent D.: Programming Languages – An Active Learning Approach. 1. Auflage. New York: Springer, 2008 [16] Louden, Kenneth C.: Compiler Construction: Principles and Practice. 1. Auflage. Boston: PWS Publishing Company, 1997 – 10 – [17] Louden, Kenneth C.; Lambert, Kenneth A.: Programming Languages: Principles and Practice. 3. Auflage. Boston: Course Technology, 2012 [18] Manes, Ernest G.; Arbib, Michael A.: Algebraic Approaches to Program Semantics. 1. Auflage. New York Berlin: Springer Verlag, 1986 [19] Mitchell, John C.: Concepts in Programming Languages. Nachdruck der 1. Auflage. Cambridge: Cambridge University Press, 2007 [20] O’Donnell, John; Hall, Cordelia; Page, Rex: Discrete Mathematics Using a Computer. 2. Auflage. London: Springer Verlag, 2006 [21] Pepper, Peter; Hofstedt, Petra: Funktionale Programmierung. 1. Auflage. Berlin: Springer Verlag, 2006 [22] Pierce, Benjamin C.: Types and Programming Languages. 1. Auflage. Cambridge: MIT Press, 2002 [23] Rechenberg, Peter; Pomberger, Gustav: Informatik-Handbuch. 1. Auflage. München Wien: Carl-Hanser-Verlag, 1997 [24] Sebesta, Robert W.: Concepts of Programming Languages. 10. Auflage. Boston: Addison-Wesley, Pearson Education, 2012 [25] Sethi, Ravi: Programming Languages: Concepts & Constructs. 2. Auflage. Reading, Mass.: Addison Wesley, 1996 [26] Struckmann, Werner; Wätjen, Dietmar: Mathematik für Informatiker – Grundlagen und Anwendungen. 1. Auflage. Heidelberg: Spektrum Akademischer Verlag, 2007 [27] Vogt, Carsten: C für Java-Programmierer. 1. Auflage. München: Hanser Verlag, 2007 – 11 – A Übungen A.1 Funktionale Programmierung A.1.1 Das funktionale Paradigma Partielle und totale Funktionen; Definition von Funktionen durch Tabellen und Ausdrücke; Wiederholung: Rekursion, Formen der Rekursion; Funktionen höherer Ordnung; undefinierte Funktionswerte. Grundideen des funktionalen Paradigmas; funktionale Programmiersprachen; Grundfunktionen; primitive Datentypen; Konstante; Variable; Terme; Signatur; Funktionsdefinitionen; Wächter; Anwendung und Auswertung; applikative Algorithmen; Gültigkeits- und Sichtbarkeitsbereich; generische und spezifische Datentypen; Listen und ihre Operationen; Beispiele applikativer Algorithmen; Sortieren durch Einfügen; Sortieren durch Auswählen; extensionale und intensionale Beschreibungen; Texte; Tupel; Currying; Funktionen als Datentyp. A.1.2 Funktionale Sprachen im Überblick Die Sprachen Lisp, Scheme, Common Lisp, ML und Haskell im Überblick; Auswertung von Ausdrücken; Rekursion; λ-Ausdrücke; Listenkomprehension; Currying; einige einführende Beispiele zu Scheme und Haskell. A.1.3 Rekursive Spezifikationen Rekursive Spezifikationen; Beispiele; algorithmische Sichtweise; Auswertungstrategien; algebraische Sichtweise; geordnete Mengen; Domain (cpo); monotone Abbildungen; stetige Abbildungen; Fixpunkte; kleinster Fixpunkt; Fixpunktsatz; Produktdomain; kleenesche Semantik; Semantik rekursiver Spezifikationen. A.1.4 Der λ-Kalkül Kalküle; freie und gebundene Vorkommen; Umbenennung; Alonzo Church; Church’sche These; λ-Kalkül; λ-Term; Applikation; λ-Abstraktion; β-Regel; α-Konversion; anonyme Funktionen; λ-Ausdrücke in Haskell; Sections in Haskell; Beispiele für Funktionen; natürliche Zahlen; Addition; Church-Rosser-Eigenschaft; Reduktionsstrategien; Problematik der Semantik ungetypter λ-Terme; Variationen des λ-Kalküls; Bedeutung des λ-Kalküls. A.1.5 Das Komprehensionsprinzip Kurzwiederholung: Prädikatenlogik 1. Stufe mit Beispielen; ZFC-Axiome der Mengenlehre; Kontinuumshypothese als Beispiel für eine Aussage, die in ZFC weder beweisbar noch widerlegbar ist; Komprehensionsaxiom; das Komprehensionsaxiom in Haskell; Russellsches Paradoxon. – 12 – A.1.6 Currying, strikte Funktionen, Funktionen höherer Ordnung Totale Abbildungen der Form A × B → C und A → (B → C); Kardinalitätsbetrachtungen; Bijektion Φ : (A × B → C) → (A → (B → C)); die Haskell-Funktionen curry und uncurry; Situation bei partiellen Funktionen; strikte und nichtstrikte Funktionen; Funktionen höherer Ordnung; die Haskell-Funktionen map, filter und fold. A.1.7 Komplexität rekursiver Algorithmen Komplexität rekursiver Algorithmen; Beispielalgorithmen; Mastertheorem; Rekurrenzgleichungen; lineare (in)homogene Rekurrenzgleichungen mit konstanten Koeffizienten; nicht lineare Rekurrenzgleichungen; Beispiele: Lösung linearer Rekurrenzgleichungen, Anzahl der Binärbäume; erzeugende Funktionen; Erinnerung: landausche Symbole, Komplexitätsklassen; Beispielanalysen Fibonacci-Zahlen sowie Komplexität des Fibonacci-Algorithmus. A.1.8 Korrektheit rekursiver Algorithmen Wiederholung der Begriffe: Abstraktion, Spezifikation, Semantik, partielle und totale Korrektheit; Erinnerung: Hoare’scher Kalkul, Schleifeninvariante, natürliche und noethersche Induktion; Korrektheit rekursiver Algorithmen: Berechnungsinduktion, strukturelle Induktion, Terminierung; Beispiele. – 13 – B Übungsaufgaben B.1 1. Übungsblatt Aufgabe 1: Wiederholung: Programmierung rekursiver Methoden. Aufgabe 2: McCarthy-Funktion: Korrektheit und Komplexität rekursiver Funktionen; Abwärtsinduktion. B.2 2. Übungsblatt Aufgabe 3: Rekursive Spezifikationen, Fixpunkte, monotone, stetige Funktionale. Aufgabe 4: Domaintheorie: Produktdomain. – 14 –