Algorithmen und Datenstrukturen



Ähnliche Dokumente
Kapitel 2: Modellierung. Programmieren in Haskell 1

(einsatz (2/1) (transponiere 12 endlos)) (einsatz (4/1) endlos) :+: (einsatz (6/1) endlos )))

Lineargleichungssysteme: Additions-/ Subtraktionsverfahren

Primzahlen und RSA-Verschlüsselung

Informationsblatt Induktionsbeweis

1 Mathematische Grundlagen

50. Mathematik-Olympiade 2. Stufe (Regionalrunde) Klasse Lösung 10 Punkte

Aufgabe 2: (Aminosäuren)

7 Rechnen mit Polynomen

Lineare Gleichungssysteme

1 topologisches Sortieren

Persönliche Zukunftsplanung mit Menschen, denen nicht zugetraut wird, dass sie für sich selbst sprechen können Von Susanne Göbel und Josef Ströbl

Charakteristikum des Gutachtenstils: Es wird mit einer Frage begonnen, sodann werden die Voraussetzungen Schritt für Schritt aufgezeigt und erörtert.

Einführung in die Algebra

Kulturelle Evolution 12

Gleichungen Lösen. Ein graphischer Blick auf Gleichungen

OECD Programme for International Student Assessment PISA Lösungen der Beispielaufgaben aus dem Mathematiktest. Deutschland

10 Erweiterung und Portierung

Anleitung über den Umgang mit Schildern

Kreativ visualisieren

Projektmanagement in der Spieleentwicklung

Die Gleichung A x = a hat für A 0 die eindeutig bestimmte Lösung. Für A=0 und a 0 existiert keine Lösung.

Grundlagen der Theoretischen Informatik, SoSe 2008

Einführung in. Logische Schaltungen

Woche 1: Was ist NLP? Die Geschichte des NLP.

Grundbegriffe der Informatik

Mathematischer Vorbereitungskurs für Ökonomen

Lösungsmethoden gewöhnlicher Differentialgleichungen (Dgl.)

Lineare Differentialgleichungen erster Ordnung erkennen

Beweisbar sichere Verschlüsselung

Professionelle Seminare im Bereich MS-Office

2. Vorlesung. Slide 40

DAS PARETO PRINZIP DER SCHLÜSSEL ZUM ERFOLG

ONLINE-AKADEMIE. "Diplomierter NLP Anwender für Schule und Unterricht" Ziele

Probleme beim Arbeiten mit Variablen, Termen und Gleichungen

Skript und Aufgabensammlung Terme und Gleichungen Mathefritz Verlag Jörg Christmann Nur zum Privaten Gebrauch! Alle Rechte vorbehalten!

Zwischenablage (Bilder, Texte,...)

Ist Fernsehen schädlich für die eigene Meinung oder fördert es unabhängig zu denken?

1. Man schreibe die folgenden Aussagen jeweils in einen normalen Satz um. Zum Beispiel kann man die Aussage:

Buchhaltung mit WISO EÜR & Kasse 2011

In diesem Thema lernen wir die Grundlagen der Datenbanken kennen und werden diese lernen einzusetzen. Access. Die Grundlagen der Datenbanken.

Modul 8: Bioinformatik A. Von der DNA zum Protein Proteinsynthese in silicio

1. Einleitung Rechnen und rechnen lassen

Konzepte der Informatik

Einführung in die Java- Programmierung

Betragsgleichungen und die Methode der Fallunterscheidungen

Informatik Kurs Simulation. Hilfe für den Consideo Modeler

1. Standortbestimmung

Gutes Leben was ist das?

Foliensatz; Arbeitsblatt; Internet. Je nach chemischem Wissen können die Proteine noch detaillierter besprochen werden.

Datenbanken Kapitel 2

Tipp III: Leiten Sie eine immer direkt anwendbare Formel her zur Berechnung der sogenannten "bedingten Wahrscheinlichkeit".

Lernerfolge sichern - Ein wichtiger Beitrag zu mehr Motivation

Das Briefträgerproblem

IV. Übungsaufgaben für die Jahrgangstufe 9 & 10

Mobile Intranet in Unternehmen

Grundlagen der höheren Mathematik Einige Hinweise zum Lösen von Gleichungen

Zeichen bei Zahlen entschlüsseln

Mind Mapping am PC. für Präsentationen, Vorträge, Selbstmanagement. von Isolde Kommer, Helmut Reinke. 1. Auflage. Hanser München 1999

Repetitionsaufgaben Wurzelgleichungen

5 Zweisprachige Seiten

1 Vom Problem zum Programm

4. BEZIEHUNGEN ZWISCHEN TABELLEN

L10N-Manager 3. Netzwerktreffen der Hochschulübersetzer/i nnen Mannheim 10. Mai 2016

Musterlösungen zur Linearen Algebra II Blatt 5

Wie halte ich Ordnung auf meiner Festplatte?

ZfP-Sonderpreis der DGZfP beim Regionalwettbewerb Jugend forscht BREMERHAVEN. Der Zauberwürfel-Roboter. Paul Giese. Schule: Wilhelm-Raabe-Schule

Stellen Sie bitte den Cursor in die Spalte B2 und rufen die Funktion Sverweis auf. Es öffnet sich folgendes Dialogfenster

Mehr Geld verdienen! Lesen Sie... Peter von Karst. Ihre Leseprobe. der schlüssel zum leben. So gehen Sie konkret vor!

1. Fabrikatshändlerkongress. Schlussworte Robert Rademacher

Nicht kopieren. Der neue Report von: Stefan Ploberger. 1. Ausgabe 2003

Mehr Transparenz für optimalen Durchblick. Mit dem TÜV Rheinland Prüfzeichen.

GEVITAS Farben-Reaktionstest

Korrigenda Handbuch der Bewertung

Erstellen einer Collage. Zuerst ein leeres Dokument erzeugen, auf dem alle anderen Bilder zusammengefügt werden sollen (über [Datei] > [Neu])

Speicher in der Cloud

Wir arbeiten mit Zufallszahlen

Logische Folgerung. Definition 2.11

4. Jeder Knoten hat höchstens zwei Kinder, ein linkes und ein rechtes.

Mediator 9 - Lernprogramm

Outlook. sysplus.ch outlook - mail-grundlagen Seite 1/8. Mail-Grundlagen. Posteingang

1. Was ihr in dieser Anleitung

IT-Basics 2. DI Gerhard Fließ

EINFACHES HAUSHALT- KASSABUCH

Inhalt. Allgemeine Einführung. Argumentationsvermögen. Räumliches Vorstellungsvermögen. Begabungen und Fähigkeiten messen

Folge 19 - Bäume Binärbäume - Allgemeines. Grundlagen: Ulrich Helmich: Informatik 2 mit BlueJ - Ein Kurs für die Stufe 12

8. Quadratische Reste. Reziprozitätsgesetz

Plotten von Linien ( nach Jack Bresenham, 1962 )

SEK II. Auf den Punkt gebracht!

Data Mining: Einige Grundlagen aus der Stochastik

Pädagogik. Melanie Schewtschenko. Eingewöhnung und Übergang in die Kinderkrippe. Warum ist die Beteiligung der Eltern so wichtig?

Software Engineering. Sommersemester 2012, Dr. Andreas Metzger

FAQ Spielvorbereitung Startspieler: Wer ist Startspieler?

Geld Verdienen im Internet leicht gemacht

B: bei mir war es ja die X, die hat schon lange probiert mich dahin zu kriegen, aber es hat eine Weile gedauert.

Zahlenwinkel: Forscherkarte 1. alleine. Zahlenwinkel: Forschertipp 1

SUDOKU - Strategien zur Lösung

von: Oktay Arslan Kathrin Steiner Tamara Hänggi Marco Schweizer GIB-Liestal Mühlemattstrasse Liestal ATG

Das Leitbild vom Verein WIR

etutor Benutzerhandbuch XQuery Benutzerhandbuch Georg Nitsche

Transkript:

Universität Bielefeld Vorlesungsskript Algorithmen und Datenstrukturen Robert Giegerich und Ralf Hinze 12. Juni 2012

Dieses Werk bzw. Inhalt steht unter einer Creative Commons Namensnennung-Weitergabe unter gleichen Bedingungen 3.0 Unported Lizenz: http://creativecommons.org/licenses/by-sa/3.0/

Inhaltsverzeichnis 1. Einleitung 7 1.1. Rechnen und rechnen lassen........................... 7 1.2. Die Aufgabengebiete der Informatik...................... 9 1.3. Einordnung der Informatik in die Familie der Wissenschaften........ 11 2. Modellierung 13 2.1. Eine Formelsprache für Musik.......................... 13 2.2. Typen als Hilfsmittel der Modellierung..................... 17 2.3. Die Rolle der Abstraktion in der Modellierung................. 18 2.4. Modellierung in der molekularen Genetik................... 19 2.5. Anforderungen an Programmiersprachen.................... 28 3. Eine einfache Programmiersprache 31 3.1. Datentypen.................................... 31 3.1.1. Datentypdefinitionen........................... 31 3.1.2. Typsynonyme............................... 36 3.1.3. Typdeklarationen, Typprüfung und Typinferenz........... 36 3.1.4. Typklassen und Typkontexte...................... 38 3.2. Wertdefinitionen................................. 39 3.2.1. Muster- und Funktionsbindungen.................... 39 3.2.2. Bewachte Gleichungen.......................... 42 3.2.3. Gleichungen mit lokalen Definitionen.................. 43 3.2.4. Das Rechnen mit Gleichungen...................... 46 3.2.5. Vollständige und disjunkte Muster................... 47 3.3. Ausdrücke..................................... 48 3.3.1. Variablen, Funktionsanwendungen und Konstruktoren........ 49 3.3.2. Fallunterscheidungen........................... 50 3.3.3. Funktionsausdrücke........................... 51 3.3.4. Lokale Definitionen............................ 53 3.4. Anwendung: Binärbäume............................ 54 3.5. Vertiefung: Rechnen in Haskell......................... 58 3.5.1. Eine Kernsprache/Syntaktischer Zucker................ 58

4 Inhaltsverzeichnis 3.5.2. Auswertung von Fallunterscheidungen................. 58 3.5.3. Auswertung von Funktionsanwendungen................ 59 3.5.4. Auswertung von lokalen Definitionen.................. 61 4. Programmiermethodik 63 4.1. Spezifikation................................... 63 4.2. Strukturelle Rekursion.............................. 66 4.2.1. Strukturelle Rekursion auf Listen.................... 66 4.2.2. Strukturelle Rekursion auf Bäumen................... 69 4.2.3. Das allgemeine Rekursionsschema................... 70 4.2.4. Verstärkung der Rekursion....................... 70 4.3. Strukturelle Induktion.............................. 72 4.3.1. Strukturelle Induktion auf Listen.................... 72 4.3.2. Strukturelle Induktion auf Bäumen................... 74 4.3.3. Das allgemeine Induktionsschema.................... 76 4.3.4. Verstärkung der Induktion........................ 76 4.3.5. Referential transparency......................... 78 4.4. Anwendung: Sortieren durch Fusionieren.................... 78 4.4.1. Phase 2: Sortieren eines Binärbaums.................. 79 4.4.2. Phase 1: Konstruktion von Braun-Bäumen.............. 81 4.5. Wohlfundierte Rekursion............................. 82 4.5.1. Das Schema der wohlfundierten Rekursion............... 82 4.6. Vertiefung: Wohlfundierte Induktion...................... 84 5. Effizienz und Komplexität 87 5.1. Grundlagen der Effizienzanalyse......................... 87 5.1.1. Maßeinheiten für Zeit und Raum beim Rechnen............ 87 5.1.2. Detaillierte Analyse von insertionsort................ 88 5.1.3. Asymptotische Zeit- und Platzeffizienz................. 91 5.2. Effizienz strukturell rekursiver Funktionen................... 93 5.3. Effizienz wohlfundiert rekursiver Funktionen.................. 97 5.4. Problemkomplexität............................... 99 5.5. Anwendung: Optimierung von Programmen am Beispiel mergesort..... 102 5.5.1. Varianten der Teile-Phase........................ 102 5.5.2. Berücksichtigung von Läufen...................... 106 5.6. Datenstrukturen mit konstantem Zugriff: Felder................ 107 5.7. Anwendung: Ein lineares Sortierverfahren................... 111 5.8. Vertiefung: Rolle der Auswertungsreihenfolge................. 114

Inhaltsverzeichnis 5 6. Abstraktion 117 6.1. Listenbeschreibungen............................... 117 6.2. Funktionen höherer Ordnung.......................... 120 6.2.1. Funktionen als Parameter........................ 121 6.2.2. Rekursionsschemata........................... 124 6.2.3. foldr und Kolleginnen.......................... 126 6.2.4. map und Kolleginnen........................... 132 6.3. Typklassen.................................... 135 6.3.1. Typpolymorphismus und Typklassen.................. 135 6.3.2. class- und instance-deklarationen.................. 138 6.3.3. Die Typklassen Eq und Ord....................... 139 6.3.4. Die Typklassen Show und Read..................... 140 6.3.5. Die Typklasse Num............................ 142 6.4. Anwendung: Sequenzen............................. 144 6.4.1. Klassendefinition............................. 144 6.4.2. Einfache Instanzen............................ 146 6.4.3. Generische Instanzen........................... 148 6.4.4. Schlangen................................. 149 6.4.5. Konkatenierbare Listen......................... 150 A. Lösungen aller Übungsaufgaben 151 B. Mathematische Grundlagen oder: Wieviel Mathematik ist nötig? 163 B.1. Mengen und Funktionen............................. 163 B.1.1. Der Begriff der Menge.......................... 163 B.1.2. Der Begriff der Funktion......................... 165 B.2. Relationen und Halbordnungen......................... 165 B.3. Formale Logik................................... 166 B.3.1. Aussagenlogik............................... 166 B.3.2. Prädikatenlogik.............................. 167 B.3.3. Natürliche und vollständige Induktion................. 167 Literaturverzeichnis 169 Index 169

1. Einleitung 1.1. Rechnen und rechnen lassen Man kann vorzüglich Rechnen lernen, ohne sich jemals zu fragen, was denn das Rechnen vom sonstigen Gebrauch des Verstandes unterscheidet. Wir stellen diese Frage jetzt und betrachten dazu das Rechnen so wie es uns im Leben zuerst begegnet als Umgang mit den Zahlen. Wir werden also die Natur des Rechnens an der Arithmetik studieren, und dabei am Ende feststellen, daß die Zahlen bei weitem nicht das Einzige sind, womit wir rechnen können. Zweifellos ist Rechnen ein besonderer Gebrauch des Verstandes. Eine gewisse Ahnung vom Unterschied zwischen Denken im allgemeinen und Rechnen im besonderen hat jeder, der einmal mit seinem Mathematiklehrer darüber diskutiert hat, ob der Fehler in seiner Schularbeit bloß als Rechenfehler, oder aber als logischer Fehler einzuordnen sei. Richtig Rechnen heißt Anwendung der Rechenregeln für Addition, Multiplikation etc. Dies allein garantiert das richtige Ergebnis und neben ihrer Beachtung und Anwendung ist als einzige weitere Verstandesleistung die Konzentration auf diese eintönige Tätigkeit gefragt. Kein Wunder, daß nur wenige Menschen zum Zeitvertreib siebenstellige Zahlen multiplizieren! 1 Damit soll nicht etwa das Rechnen diffamiert werden es entspricht so gerade der Natur dessen, worum es dabei geht, nämlich den Zahlen. Diese sind Größen, abstrakte Quantitäten ohne sonstige Eigenschaft. Bringe ich sie in Verbindung, ergeben sich neue, andere Größen, aber keine andere Qualität. Der Unterschied von 15 und 42 ist 27, und daraus folgt nichts. Die mathematische Differenz zweier Größen ist, so könnte man sagen, der unwesentliche Unterschied. Nur zum Vergleich: Stelle ich meinen Beitrag zum Sportverein und meine Einkommenssteuer einander gegenüber, so ergibt sich auch ein Unterschied im Betrag. Daneben aber auch einer in der Natur der Empfänger, dem Grad der Freiwilligkeit, meine Einflußmöglichkeiten auf die Verwendung dieser Gelder und vieles andere mehr. Dies sind wesentliche Unterschiede, aus ihnen folgt allerhand. Unter anderem erklären sie auch die Differenz der Beträge, und rechnen sie nicht bloß aus. Für das Rechnen jedoch spielt es keine Rolle, wovon eine Zahl die Größe angibt. Jede sonstige Beschaffenheit der betrachteten Objekte ist für das Rechnen mit ihrer Größe ohne Grit Garbo ist Mathematikerin der alten Schule. Für sie gibt es eigentlich keine Wissenschaft der Informatik soweit Informatik wissenschaftlich ist, gehört sie zur Mathematik, alles andere ist Ingeniertechnik oder Programmierhandwerk. Fragen der Programmiersprachen oder des Software Engineering sieht sie als bloße Äußerlichkeiten an. Sie kann es nicht ganz verschmerzen, daß die Mathematik von ihrer Tochter Informatik heute in vielerlei Hinsicht überflügelt wird. 1 Denkaufgabe: Was folgt daraus, wenn einer gut rechnen kann?

8 1. Einleitung Harry Hacker ist ein alter Programmierfuchs, nach dem Motto: Eine Woche Programmieren und Testen kann einen ganzen Nachmittag Nachdenken ersetzen. Er ist einfallsreich und ein gewitzter Beobachter; allerdings liegt er dabei oft haarscharf neben der Wahrheit. Zu Programmiersprachen hat er eine dezidiert subjektive Haltung: Er findet die Sprache am besten, die ihm am besten vertraut ist. Belang. Deshalb kann das Rechnen in starre Regeln gegossen werden und nimmt darin seinen überraschungsfreien Verlauf. Die kreative gedankliche Leistung liegt woanders: Sie manifestiert sich in der Art und Weise, wie man die abstrakten Objekte der Zahlen konkret aufschreibt. Wir sind daran gewöhnt, das arabische Stellenwertsystem zu verwenden. Dieses hat sich im Laufe der Geschichte durchgesetzt, da sich darauf relativ einfach Rechenregeln definieren und auch anwenden lassen. Das römische Zahlensystem mit seinen komplizierten Einheiten und der Vor- und Nachstellung blieb auf der Strecke: Den Zahlen XV und XLII sieht man den Unterschied XXVII nicht an. Insbesondere das Fehlen eines Symbols für die Null macht systematisches Rechnen unmöglich gerade wegen der Null war das Rechnen mit den arabischen Zahlen im Mittelalter von der Kirche verboten. Einstweiliges Fazit: Das Rechnen ist seiner Natur nach eine äußerliche, gedankenlose, in diesem Sinne mechanische Denktätigkeit. Kaum hatte die Menschheit Rechnen gelernt, schon tauchte die naheliegende Idee auf, das Rechnen auf eine Maschine zu übertragen. Die Geschichte dieser Idee von einfachen Additionsmaschinen bis hin zu den ersten programmgesteuerten Rechenautomaten ist an vielen Stellen beschrieben worden und soll hier nicht angeführt werden. An ihrem Endpunkt steht der Computer, der bei entsprechender Programmierung beliebig komplexe arithmetische Aufgaben lösen kann schneller als wir, zuverlässiger als wir und (für uns) bequemer. Wenn dieses Gerät existiert, stellt sich plötzlich eine ganz neue Frage: Jetzt, wo wir rechnen lassen können, wird es interessant, Aufgaben in Rechenaufgaben zu verwandeln, die es von Natur aus nicht sind (und die wir mit unserem Verstand auch nie so behandeln würden). Es gilt, zu einer Problemstellung die richtigen Abstraktionen zu finden, sie durch Formeln und Rechengesetze, genannt Datenstrukturen und Algorithmen, so weitgehend zu erfassen, daß wir dem Ergebnis der Rechnung eine Lösung des Problems entnehmen können. Wir bilden also abstrakte Modelle der konkreten Wirklichkeit, die diese im Falle der Arithmetik perfekt, in den sonstigen Fällen meist nur annähernd wiedergeben. Die Wirklichkeitstreue dieser Modelle macht den Reiz und die Schwierigkeit dieser Aufgabe, und die Verantwortung des Informatikers bei der Software-Entwicklung aus. Die eigentümliche Leistung der Informatik ist es also, Dinge in Rechenaufgaben zu verwandeln, die es von Natur aus nicht sind. Die Fragestellung Was können wir rechnen lassen?, ist neu in der Welt der Wissenschaften deshalb hat sich die Informatik nach der Konstruktion der ersten Rechner schnell aus dem Schoße der Mathematik heraus zu einer eigenständigen Disziplin entwickelt. Die Erfolge dieser Bemühung sind faszinierend, und nicht selten, wenn auch nicht ganz richtig, liest man darüber in der Zeitung: Computer werden immer schlauer.

1.2. Die Aufgabengebiete der Informatik 9 1.2. Die Aufgabengebiete der Informatik Informatik ist die Wissenschaft vom maschinellen Rechnen. Daraus ergeben sich verschiedene Fragestellungen, in die sich die Informatik aufgliedert. Zunächst muß sie sich um die Rechenmaschine selbst kümmern. In der Technischen Informatik geht es um Rechnerarchitektur und Rechnerentwurf, wozu auch die Entwicklung von Speichermedien, Übertragungskanälen, Sensoren usw. gehören. Der Fortschritt dieser Disziplin besteht in immer schnelleren und kleineren Rechnern bei fallenden Preisen. In ihren elementaren Operationen dagegen sind die Rechner heute noch so primitiv wie zur Zeit ihrer Erfindung. Diese für den Laien überraschende Tatsache erfährt ihre Erklärung in der theoretischen Abteilung der Informatik. Mit der Verfügbarkeit der Computer erfolgt eine Erweiterung des Begriffs Rechnen. Das Rechnen mit den guten alten Zahlen ist jetzt nur noch ein hausbackener Sonderfall. Jetzt werden allgemeinere Rechenverfahren entwickelt, genannt Algorithmen, die aus Eingabe- Daten die Ausgabe-Daten bestimmen. Aber was genau läßt sich rechnen, und was nicht? Mit welcher Maschine? Die Theoretische Informatik hat diese Frage beantwortet und gezeigt, daß es nicht berechenbare Probleme 2 gibt, d.h. Aufgaben, zu deren Lösung es keinen Algorithmus gibt. Zugleich hat sie gezeigt, daß alle Rechner prinzipiell gleichmächtig sind, sofern sie über einige wenige primitive Operationen verfügen. Dagegen erweisen sich die berechenbaren Aufgaben als unterschiedlich aufwendig, so daß die Untersuchung des Rechenaufwands, Komplexitätstheorie, heute ein wichtiges Teilgebiet der Theoretischen Informatik darstellt. Zwischen den prinzipiellen Möglichkeiten des Rechnens und dem Rechner mit seinen primitiven Operationen klafft eine riesige Lücke. Die Aufgabe der Praktischen Informatik ist es, den Rechner für Menschen effektiv nutzbar zu machen. Die semantische Lücke wird Schicht um Schicht geschlossen durch Programmiersprachen auf immer höherer Abstraktionsstufe. Heute können wir Algorithmen auf der Abstraktionsstufe der Aufgabenstellung entwickeln und programmieren, ohne die ausführende Maschine überhaupt zu kennen. Dies ist nicht nur bequem, sondern auch wesentliche Voraussetzung für die Übertragbarkeit von Programmen zwischen verschiedenen Rechnern. Ähnliches gilt für die Benutzung der Rechner (Betriebssysteme, Benutzeroberflächen), für die Organisation großer Datenmengen (Datenbanken) und sogar für die Kommunikation der Rechner untereinander (Rechnernetze, Verteilte Systeme). Das World Wide Web (WWW) ist das jüngste und bekannteste Beispiel für das Überbrücken der semantischen Lücke: Es verbindet einfachste Benutzbarkeit mit globalem Zugriff auf Informationen und andere Ressourcen in aller Welt. Heute bedarf es nur eines gekrümmten Zeigefingers, um tausend Computer in aller Welt für uns arbeiten zu lassen. In der Angewandten Informatik kommt endlich der Zweck der ganzen Veranstaltung zum Lisa Lista ist die ideale Studentin, den Wunschvorstellungen eines überarbeitetenn Hochschullehrers entsprungen. Sie ist unvoreingenommen und aufgeweckt, greift neue Gedanken auf und denkt sie in viele Richtungen weiter. Kein Schulunterricht in Informatik hat sie verdorben. Lisa Lista ist 12 Jahre alt. 2 Man kann solche Aufgaben auch als Ja/Nein-Fragestellungen formulieren und nennt sie dann formal unentscheidbare Probleme. Läßt man darin das entscheidende Wörtchen formal weg, eröffnen sich tiefsinnige, aber falsche Betrachtungen über Grenzen der Erkenntnis.

10 1. Einleitung Peter Paneau ist Professor der Theoretischen Informatik. Er sieht die Informatik im wesentlichen als eine formale Disziplin. Am vorliegenden Text stört ihn die saloppe Redeweise und die Tatsache, daß viele tiefgründige theoretische Probleme grob vereinfacht oder einfach umgangen werden. An solchen Stellen erhebt er mahnend der Zeigefinger... Zuge. Sie wendet die schnellen Rechner, die effizienten Algorithmen, die höheren Programmiersprachen und ihre Übersetzer, die Datenbanken, die Rechnernetze usw. an, um Aufgaben jeglicher Art sukzessive immer vollkommener zu lösen. Je weiter die Informatik in die verschiedensten Anwendungsgebiete vordringt, desto spezifischer werden die dort untersuchten Fragen. Vielleicht werden wir bald erleben, daß sich interdisziplinäre Anwendungen als eigenständige Disziplinen von der Kerninformatik abspalten. Wirtschaftsinformatik und Bioinformatik sind mögliche Protagonisten einer solchen Entwicklung. Während es früher Jahrhunderte gedauert hat, bis aus den Erfolgen der Physik zunächst die anderen Natur-, dann die Ingenieurwissenschaften entstanden, so laufen heute solche Entwicklungen in wenigen Jahrzehnten ab. Wenn die Rechner heute immer mehr Aufgaben übernehmen, für die der Mensch den Verstand benutzt, so ist insbesondere für Laien daran längst nicht mehr erkennbar, auf welche Weise dies erreicht wird. Es entsteht der Schein, daß das analoge Resultat auch in analoger Weise zustande käme. Diesen Schein nennt man künstliche Intelligenz, und seiner Förderung hat sich das gleichnamige Arbeitsfeld der Informatik gewidmet. Es lohnt sich, die Metapher von der Intelligenz des Rechners kurz genauer zu betrachten, weil sie unter Laien wie unter Informatikern manche Verwirrung stiftet. Es ist nichts weiter dabei, wenn man sagt, daß ein Rechner (oder genauer eine bestimmte Software) sich intelligent verhält, wenn er (oder sie) eine Quadratwurzel zieht, eine WWW-Seite präsentiert oder einen Airbus auf die Piste setzt. Schließlich wurden viele Jahre Arbeit investiert, um solche Aufgaben rechnergerecht aufzubereiten, damit der Rechner diese schneller und zuverlässiger erledigen kann als wir selbst. Nimmt man allerdings die Metapher allzu wörtlich, kommt man zu der Vorstellung, der Rechner würde dadurch selbst so etwas wie eine eigene Verständigkeit erwerben. Daraus entsteht gelegentlich sogar die widersprüchliche Zielsetzung, den Rechner so zu programmieren, daß er sich nicht mehr wie ein programmierter Rechner verhält. Der Sache nach gehört die Künstliche Intelligenz der Angewandten Informatik an, geht es ihr doch um die erweiterte Anwendbarkeit des Rechners auf immer komplexere Probleme. Andererseits haben diese konkreten Anwendungen für sie nur exemplarischen Charakter, als Schritte zu dem abstrakten Ziel, wirklich intelligente künstliche Systeme zu schaffen. So leidet diese Arbeitsrichtung unter dem Dilemma, daß ihr Beitrag zum allgemeinen Fortschritt der Informatik vom Lärm der immer wieder metaphorisch geweckten und dann enttäuschten Erwartungen übertönt wird. Unbeschadet solch metaphorischer Fragen geht der Vormarsch der Informatik in allen Lebensbereichen voran der rechenbare Ausschnitt der Wirklichkeit wird ständig erweitert: Aus Textverarbeitung wird DeskTop Publishing, aus Computerspielen wird Virtual Reality, und aus gewöhnlichen Bomben werden intelligent warheads. Wie gesagt: die Rechner werden immer schlauer. Und wir?

1.3. Einordnung der Informatik in die Familie der Wissenschaften 11 1.3. Einordnung der Informatik in die Familie der Wissenschaften Wir haben gesehen, daß die Grundlagen der Informatik aus der Mathematik stammen, während der materielle Ausgangspunkt ihrer Entwicklung die Konstruktion der ersten Rechenmaschinen war. Mutter die Mathematik, Vater der Computer wissenschaftsmoralisch gesehen ist die Informatik ein Bastard, aus einer Liebschaft des reinen Geistes mit einem technischen Gerät entstanden. Die Naturwissenschaft untersucht Phänomene, die ihr ohne eigenes Zutun gegeben sind. Die Gesetze der Natur müssen entdeckt und erklärt werden. Die Ingenieurwissenschaften wenden dieses Wissen an und konstruieren damit neue Gegenstände, die selbst wieder auf ihre Eigenschaften untersucht werden müssen. Daraus ergeben sich neue Verbesserungen, neue Eigenschaften, und so weiter. Im Vergleich dieser beiden Abteilungen der Wissenschaft steht die Informatik eher den Ingenieurwissenschaften nahe: Auch sie konstruiert Systeme, die abgesehen von denen der Technischen Informatik allerdings immateriell sind. Wie die Ingenieurwissenschaften untersucht sie die Eigenschaften ihrer eigenen Konstruktionen, um sie weiter zu verbessern. Wie bei den Ingenieurwissenschaften spielen bei der Informatik die Aspekte der Zuverlässigkeit und Lebensdauer ihrer Produkte eine wesentliche Rolle. Eine interessante Parallele besteht auch zwischen Informatik und Rechtswissenschaft. Die Informatik konstruiert abstrakte Modelle der Wirklichkeit, die dieser möglichst nahe kommen sollen. Das Recht schafft eine Vielzahl von Abstraktionen konkreter Individuen. Rechtlich gesehen sind wir Mieter, Studenten, Erziehungsberechtigte, Verkehrsteilnehmer, etc. Als solche verhalten wir uns entsprechend der gesetzlichen Regeln. Der Programmierer bildet reale Vorgänge in formalen Modellen nach, der Jurist muß konkrete Vorgänge unter die relevanten Kategorien des Rechts subsumieren. Die Analogie endet allerdings, wenn eine Diskrepanz zwischen Modell und Wirklichkeit auftritt: Bei einem Programmfehler behält die Wirklichkeit recht, bei einem Rechtsbruch das Recht. Eine wissenschaftshistorische Betrachtung der Informatik und ihre Gegenüberstellung mit der hier gegebenen deduktiven Darstellung ist interessant und sollte zu einem späteren Zeitpunkt, etwa zum Abschluß des Informatik-Grundstudiums, nachgeholt werden. Interessante Kapitel dieser Geschichte sind das Hilbert sche Programm, die Entwicklung der Idee von Programmen als Daten, die oben diskutierte Idee der Künstlichen Intelligenz, der Prozeß der Loslösung der Informatik von der Mathematik, die Geschichte der Programmiersprachen, die Revolution der Anwendungssphäre durch das Erscheinen der Mikroprozessoren, und vieles andere mehr.

2. Modellierung Wir haben im ersten Kapitel gelernt: Programmieren heißt, abstrakte Modelle realer Objekte zu bilden, so daß die Rechenregeln im Modell die relevanten Eigenschaften in der Wirklichkeit adäquat nachbilden. Wir werden den Vorgang der Modellierung nun anhand von zwei Beispielen kennen lernen. 2.1. Eine Formelsprache für Musik Wir haben gelernt, daß die Welt der Zahlen wegen ihres formalen Charakters die natürliche Heimat des Rechnens ist. Es gibt ein zweites Gebiet, in dem ein gewisser Formalismus in der Natur der Sache liegt: die Musik. Das Spielen eines Musikstückes mag vieles sein ein künstlerischer Akt, ein kulturelles oder emotionales Ereignis. Im Kern jedoch steht das Musikstück es bringt die Musikvorstellung des Komponisten in eine objektive Form und ist nichts anderes als ein Programm zur Ausführung durch einen Musiker (oder heute über eine Midi-Schnittstelle auch durch einen elektronischen Synthesizer). Wer immer als erster ein Musikstück niedergeschrieben hat, hat damit den Schritt vom Spielen zum Spielen lassen begründet. Diese kulturhistorische Leistung ist viel älter als die Idee einer Rechenmaschine. In der traditionellen Notenschrift ist der formale Anteil der Musik manifestiert. Die Modellierung ist hier also bereits erfolgt, allerdings ausschließlich im Hinblick auf die Wiedergabe durch einen menschlichen Interpreten, und nicht bis hin zur Entwicklung von dem Rechnen vergleichbaren Regeln. Zwar sind viele Gesetze z.b. der Harmonielehre bekannt, man kann sie aber in der Notenschrift nicht ausdrücken. So kann man zwar jeden Dur-Dreiklang konkret hinschreiben aber die allgemeine Aussage, daß ein Dur-Dreiklang immer aus einem groß en und einem kleinen Terz besteht, muß auf andere Art erfolgen. In diesem Abschnitt setzen wir die Notenschrift (natürlich nur einen kleinen Ausschnitt davon) in eine Formelsprache samt den zugehörigen Rechenregeln um. Musikstücke sind aus Noten zusammengesetzt, die gleichzeitig oder nacheinander gespielt werden. Jede Note hat einen Ton und eine Dauer. Dem Stück als Ganzem liegt ein bestimmter Takt zugrunde, und die Dauer einzelner Töne wird in Takt-Bruchteilen gemessen. Die Tonskala besteht aus 12 Halbtönen, die sich in jeder Oktave wiederholen. Wir legen das tiefe C als untersten Ton zugrunde und numerieren die Halbtöne von 0 ab aufwärts. Angaben zum Spieltempo (in Taktschlägen pro Minute) und zur Wahl des

14 2. Modellierung Instruments werden global für ganze Musikstücke gemacht. Formeln, die Musik bedeuten, können wir uns z.b. so vorstellen: Note 0 (1/4) -- Viertelnote tiefes C Note 24 (1/1) -- ganze Note c Pause (1/16) -- Sechzehntelpause Note 24 (1/4) :*: Note 26 (1/4) :*: Note 28 (1/4) -- Anfang der C-Dur Tonleiter Note 24 (1/4) :+: Note 28 (1/4) :+: Note 31 (1/4) -- C-Dur Akkord Tempo 40 m -- Musik m als Adagio Tempo 100 m -- Musik m als Presto Instr Oboe m -- Musik m von Oboe gespielt Instr VoiceAahs m -- Musik m gesummt Wir konstruieren nun die Formelwelt, deren Bürger die obigen Beispiele sind. Wir gehen davon aus, daß es Formeln für ganze Zahlen, Brüche und ein bißchen Arithmetik bereits gibt in der Formelwelt und führen neue Typen von Formeln ein: Ton, Dauer, Instrument und Musik. infixr 7 :*: infixr 6 :+: type GanzeZahl = Int -- Ganze Zahlen und Brueche setzen wir type Bruch = Rational -- als gegeben voraus. type Ton = GanzeZahl type Dauer = Bruch data Instrument = Oboe HonkyTonkPiano Cello VoiceAahs deriving Show data Musik = Note Ton Dauer Pause Dauer Musik :*: Musik Musik :+: Musik Instr Instrument Musik Tempo GanzeZahl Musik deriving Show Die neuen Formeltypen Ton und Dauer sind nur Synonyme für ganze Zahlen und Brüche entsprechend der besonderen Bedeutung, in der wir sie gebrauchen. Sie tragen keine neuen Formeln bei. Anders bei Instrument und Musik. Die Symbole Note, Pause, :*:, :+:, Instr, Tempo sind die Konstruktoren für neuartige Formeln, die Musikstücke darstellen. In der Formel m1 :*: m2 dürfen (und müssen!) m1 und m2 beliebige Formeln für Musikstücke sein, insbesondere selbst wieder zusammengesetzt. In Anlehnung an die Punkt-vor-Strich Regel der Algebra geben wir der Verknüpfung von Noten zu einer zeitlichen Abfolge (:*:) Vorrang vor der zeitlich parallelen Verknüpfung mehrerer Stimmen (:+:). Damit ist die Formel m1 :+: m2 :*: m3 zu lesen als m1 :+: (m2 :*: m3).

2.1. Eine Formelsprache für Musik 15 Umfangreiche Musikstücke können nun als wahre Formelgebirge geschrieben werden. Zuvor erleichtern wir uns das Leben in der Formelwelt, indem wir einige Abkürzungen einführen. Etwa für die Pausen: gp = Pause (1/1) hp = Pause (1/2) vp = Pause (1/4) ap = Pause (1/8) sp = Pause (1/16) Diese Definitionen sind zugleich Rechenregeln. Sie bedeuten einerseits, daß man die neuen Symbole gp, hp, vp, ap, sp überall in Musikstücken einsetzen kann es erweitert sich damit die Formelwelt. Zugleich kann man jedes Symbol jederzeit durch die rechte Seite der Definition ersetzen so daß die Musikstücke in der Formelwelt nicht mehr geworden sind. Hier sind klangvolle Namen für einige Tempi: adagio = 70; andante = 90; allegro = 140; presto = 180 Die üblichen Bezeichnungen für die 12 Halbtöne führen wir so ein: ce = 0; cis = 1; des = 1 de = 2; dis = 3; es = 3 eh = 4; eis = 5; fes = 4 ef = 5; fis = 6; ges = 6 ge = 7; gis = 8; as = 8 ah = 9; ais = 10; be = 10 ha = 11; his = 12 Diese Töne sind in der untersten Oktave angesiedelt, und wir brauchen sie hier kaum. Dagegen brauchen wir eine bequeme Notation für Noten (beliebiger Dauer) aus der C-Dur Tonleiter in der dritten Oktave: c u = Note (ce+24) u; d u = Note (de+24) u e u = Note (eh+24) u; f u = Note (ef+24) u g u = Note (ge+24) u; a u = Note (ah+24) u h u = Note (ha+24) u; c u = Note (ce+36) u Als Beispiele hier der C-Dur Akkord in neuer Schreibweise, sowie eine (rhythmisch beschwingte) C-Dur Tonleiter: cdurtonika = c (1/1) :+: e (1/1) :+: g (1/1) cdurskala = Tempo allegro( c (3/8) :*: d (1/8) :*: e (3/8) :*: f (4/8) :*: g (1/8) :*: a (1/4) :*: h (1/8) :*: c (1/2))

16 2. Modellierung Allgemein gesagt, besteht ein Dur-Dreiklang aus einen Grundton t sowie der groß en Terz und der Quinte über t. Dieses Gesetz als Formel: durdreiklang t = Note t (1/1) :+: Note (t+4) (1/1) :+: Note (t+7) (1/1) Wie wär s mit einer allgemeinen Regel zur Umkehrung eines Dreiklangs (der unterste Ton muß eine Oktave nach oben)? umk ((Note t d) :+: n2 :+: n3) = n2 :+: n3 :+: (Note (t+12) d) Als komplexe Operation auf ganzen Musikstücken betrachten wir das Transponieren. Es bedeutet, daß Töne um ein gewisses Intervall verschoben werden, während alles andere gleich bleibt. Wie muß die Rechenregel lauten, um Musikstück m um Intervall i zu transponieren? Wir geben eine Regel für jede mögliche Form von m an: transponiere i (Pause d) = Pause d transponiere i (Note t d) = Note (t+i) d transponiere i (m1 :*: m2) = (transponiere i m1) :*: (transponiere i m2) transponiere i (m1 :+: m2) = (transponiere i m1) :+: (transponiere i m2) transponiere i (Instr y m) = Instr y (transponiere i m) transponiere i (Tempo n m) = Tempo n (transponiere n m) gdurtonika = transponiere 7 cdurtonika Da das Transponieren Intervalle nicht ändert, führt es einen Dur-Dreiklang wieder in einen Dur-Dreiklang über. Es gilt folgendes Gesetz für beliebigen Grundton g und beliebiges Intervall i: transponiere i (durdreiklang t) = durdreiklang(t+i) Zur Überprüfung rechnen wir beide Seiten mittels der Definition von transponiere und durdreiklang aus und erhalten beide Male Note (t+i) (1/1) :+: Note (t+4+i) (1/1) :+: Note (t+7+i) (1/1) Hier haben wir eine Methode zur Validierung von Modellen kennengelernt: Wenn man beweisen kann, daß ein Gesetz der realen Welt auch in der Formelwelt gilt, so gibt das Modell die Wirklichkeit zumindest in dieser Hinsicht treu wieder. Bevor wir ein komplettes Lied zusammenstellen, hier zwei Regeln zur Wiederholung:

2.2. Typen als Hilfsmittel der Modellierung 17 wdh m = m :*: m ad_infinitum m = m :*: ad_infinitum m Einen um Dauer d verzögerten Einsatz erhält man durch Vorschalten einer Pause. einsatz d m = (Pause d) :*: m Unser letztes Beispiel beschreibt den Kanon Bruder Jakob, wobei wir die 2. Stimme eine Oktave über den anderen notieren. phrase1 = c (1/4) :*: d (1/4) :*: e (1/4) :*: c (1/4) phrase2 = e (1/4) :*: f (1/4) :*: g (1/2) phrase3 = g (1/8) :*: a (1/8) :*: g (1/8) :*: f (1/8) :*: e (1/4) :*: c (1/4) phrase4 = c (1/4) :*: (transponiere (-12) (g (1/4))) :*: c (1/2) strophe = wdh phrase1 :*: wdh phrase2 :*: wdh phrase3 :*: wdh phrase4 endlos = ad_infinitum strophe bruderjakob = Tempo andante (Instr VoiceAahs (einsatz (0/1) endlos :+: (einsatz (2/1) (transponiere 12 endlos)) :+: (einsatz (4/1) endlos) :+: (einsatz (6/1) endlos ))) Natürlich gehört zu einer praktischen Formelsprache für Musik noch vieles, was wir hier nicht betrachtet haben Text, Artikulation, Kontrapunkt, eine Möglichkeit zur Übersetzung der Formeln in die traditionelle Notation und in eine Folge von Midi-Befehlen, um damit einen Synthesizer zu steuern. 2.2. Typen als Hilfsmittel der Modellierung In der realen Welt verhindert (meistens) die Physik, daß unpassende Operationen mit untauglichen Objekten ausgeführt werden. Man kann eben einen Golfball nicht unter einer Fliege verstecken oder einen Rosenbusch mit einer Steuererklärung paaren. Macht es Sinn, einer streikenden (?) Waschmaschine gut zuzureden? Das Problem in einer Formelwelt ist, daß man zunächst alles hinschreiben kann, weil die Formeln sich nicht selbst dagegen sträuben. Aus diesem Grund gibt man jedem Objekt des Modells einen Typ, der eine Abstraktion der natürlichen Eigenschaften des realen Objekts ist. In der Formelsprache für Musik haben wir die Typen Ton (synonym für ganzezahl) und Dauer (synonym für positive rationale Zahl) vorausgesetzt und die Typen Musik und Instrument neu eingeführt. Die Typendeklaration legt nicht nur fest, daß Musik auf sechs

18 2. Modellierung verschiedene Weisen zusammengesetzt werden kann, und zwar durch die (Formel-) Konstruktoren Note bis Tempo. Sie sagt auch, welche Formeln zusammengefügt werden dürfen. Note muß stets einen Ton mit einer Dauer verknüpfen. Mit :*: kann man zwei Musikstücke verknüpfen, nicht aber ein Musikstück mit einem Ton. Folgende Formeln sind fehlerhaft: Note 3/4 ce Pause (1/2 :*: 1/4) Pause Cello Instr (Cello :+: Oboe) cdurtonika Tempo Oboe 100 c :+: e :+: g Möglicherweise hat sich der Autor dieser Formeln etwas Sinnvolles gedacht aber es muß in unserer Formelsprache anders ausgedrückt werden. Auch die durch Definitionen eingeführten Namen erhalten einen Typ. Er ergibt sich aus der rechten Seite der definierenden Gleichung. Wir schreiben a, b, c :: t für die Aussage Die Namen (oder Formeln) a, b, c haben Typ t und stellen fest: ce, cis, des, de, dis, es, eh, eis, fes, ef, fis :: Ton ges, ge, gis, as, ah, ais, be, ha, his :: Ton gp, hp, vp, ap, sp :: Musik cdurtonika :: Musik adagio, andante, allegro, presto :: GanzeZahl Die Namen c, d etc. bezeichnen Funktionen, die eine Dauer als Argument und Musik als Ergebnis haben. umk, wdh und ad_infinitum wandeln Musikstücke um. c, d, e, f, g, a, h, c :: Dauer -> Musik umk, wdh, ad_infinitum :: Musik -> Musik transponiere schließlich hat zwei Argumente, was wir etwas gewöhnugsbedürftig mit zwei Funktionspfeilen ausdrücken. transponiere :: GanzeZahl -> Musik -> Musik Hinter dieser Notation steht die Sichtweise, daß man einer zweistelligen Funktion wie transponiere manchmal nur ein Argument geben möchte: Unter (transponiere 7) stellen wir uns eine abgeleitete Funktion vor, die Musikstücke um eine Quinte nach oben transponiert. Natürlich hat (transponiere 7) dann den restlichen Typ Musik -> Musik. 2.3. Die Rolle der Abstraktion in der Modellierung Unsere Formelsprache für Musik erlaubt es, in direkter Analogie zur Notenschrift Musikstücke als Formeln hinzuschreiben. Darüberhinaus können wir aber auch abstrakte Zusammenhänge zwischen Musikstücken darstellen, wie etwa den Aufbau eines Dur-Dreiklangs oder das Transponieren. Worauf beruht dies Möglichkeit?

2.4. Modellierung in der molekularen Genetik 19 Sie beginnt damit, daß wir beliebige Formeln mit einem Namen versehen können, wie etwa bei gp, hp oder phrase1 bis phrase4. Diese Namen sind kürzer und (hoffentlich) lesbarer als die Formeln, für die sie stehen, aber noch nicht abstrakter. Die Abstraktion kommt mit dem Übergang zu Funktionen ins Spiel. Vergleichen wir die beiden folgenden Definitionen eines Zweiklangs: tritonus_f_1 = Note ef (1/1) :+: Note ha (1/1) tritonus t d = Note t d :+: Note (t+6) d tritonus_f_1 beschreibt einen Zweiklang von konkreter Tonlage und Dauer. tritonus dagegen abstrahiert von Tonlage und Dauer, und hält nur fest, was für den als Tritonus bekannten Zweiklang wesentlich ist ein Intervall von 6 Halbtonschritten. Dieser Unterschied macht sich auch an den Typen bemerkbar. Wir finden: tritonus_f_1 :: Musik tritonus :: Ton -> Dauer -> Musik Hier verrät uns bereits der Typ, daß in der Formel tritonus erst Ton und Dauer konkretisiert werden müssen, ehe spielbare Musik entsteht. Bei den Noten der eingestrichenen C-Dur- Skala (c, d,...) haben wir von der Dauer abtrahiert, sonst hätten wir Definitionen für 40 oder noch mehr Namen einführen müssen. Andererseits haben wir hier natürlich nicht vom Ton abstrahiert, wir wollten ja Namen für bestimmte Töne einführen. Und außerdem gibt es diese Abstraktion bereits: Eine Note von beliebigem Ton und Dauer wird gerade von dem KonstruktorNote repräsentiert, dem wir daher auch den Typ Ton -> Dauer -> Musik zuordnen. Typen halten die Objekte der Formelwelt auseinander, Funktionen stiften Zusammenhänge. Wollten wir ohne Abstraktion das Prinzip der Umkehrung eines Dreiklangs beschreiben, kämen wir über konkrete Beispiele nicht hinaus. Die Funktion umk leistet das Gewünschte mühelos. Und schließlich hält uns nichts davon ab (Übungsaufgabe!), im Kanon bruderjakob von der eigentlichen Melodie zu abstrahieren und ein allgemeines Konstruktionsprinzip für einen vierstimmigen Kanon anzugeben. Hier haben wir die Methode der funktionalen Abstraktion kennengelernt. Technisch gesehen besteht sie lediglich darin, in einer Formel einige Positionen als variabel zu betrachten. So wird aus der Formel eine Funktion, die mit einem Namen versehen und in vielfältiger Weise eingesetzt werden kann, und die zugleich selbst ein abstraktes Prinzip repräsentiert. Wir werden später noch andere Formen der Abstraktion kennenlernen, aber die funktionale Abstraktion ist sicher die grundlegendste von allen. 2.4. Modellierung in der molekularen Genetik Die Basen Adenin, Cytosin, Guanin und Thymin bilden zusammen mit Phosphor und Ribose die Nukleotide, die Bausteine der Erbsubstanz.

20 2. Modellierung data Nucleotide = A C G T deriving (Eq, Show) Die 20 Aminosäuren sind die Bausteine aller Proteine: data AminoAcid = Ala -- Alanin Arg -- Arginin Asn -- Asparagin Asp -- Aspartat Cys -- Cystein Gln -- Glutamin Glu -- Glutamat Gly -- Glycin His -- Histidin Ile -- Isoleucin Leu -- Leucin Lys -- Lysin Met -- Methionin Phe -- Phenylalanin Pro -- Prolin Ser -- Serin Thr -- Threonin Trp -- Tryptophan Tyr -- Tyrosin Val -- Valin Stp -- keine Aminosaeure; siehe unten deriving (Eq, Show) Lange Ketten von Nukleotiden bilden die Nukleinsäure, lange Ketten von Aminosäuren bilden Proteine. Chemisch werden diese Ketten auf unterschiedliche Weise gebildet: Bei den Nukleotiden verknüpfen die Phosphor-Atome die Ribose-Ringe, zwischen den Aminosäuren werden Peptidbindungen aufgebaut. Da wir aber die Chemie der Moleküle nicht modellieren wollen, wollen wir auch nicht unterscheiden, auf welche Weise die Ketten konstruiert werden. Als Formel für Kettenmoleküle schreiben wir A:C:C:A:G:A:T:T:A:T:A:T:..., oder Met:Ala:Ala:His:Lys:Lys:Leu:... Im Unterschied zur Molekularbiologie kennt also unsere Formelwelt einen Konstruktor (:), der Ketten jeglicher Art aufbaut: data [a] = [] -- leere Kette a:[a] -- (:) verlaengert Kette von a s um ein a.

2.4. Modellierung in der molekularen Genetik 21 Den Datentyp [a] nennt man einen polymorphen Listentyp. Hier ist a ein Typparameter. Dies bedeutet, das Elemente beliebigen, aber gleichen Typs mittels der Konstruktoren (:) und [] zu Listen zusammengefügt werden können. Für Listen führen wir eine spezielle Notation ein: Statt a:b:c:[] schreiben wir auch [a,b,c]. Damit können wir nun sagen, welcher Datentyp in der Formelwelt den realen Nukleinsäuren und Proteinen entsprechen soll: type DNA = [Nucleotide] type Protein = [AminoAcid] type Codon = (Nucleotide, Nucleotide, Nucleotide) Im Ruhezustand (als Informationsspeicher) ist die DNA allerdings ein Doppelmolekül: Zwei DNA-Stränge bilden die berühmte, von Watson und Crick entdeckte Doppelhelix. Sie beruht darauf, daß bestimmte Basen zueinander komplementär sind - sie können Wasserstoffbrückenbindungen aufbauen, wenn sie einander gegenüber stehen. wc_complement A = T wc_complement T = A wc_complement C = G wc_complement G = C Wir können die dopplesträngige DNA auf zwei verschiedene Weisen darstellen, als Paar von Listen oder als Liste von Paaren. type DNA_DoubleStrand = (DNA,DNA) -- als Paar zweier Einzelstraenge type DNA_DoubleStrand = [(Nucleotide,Nucleotide)] -- als Kette von Watson-Crick-Paaren dnads_exmpl1 = ([A,C,C,G,A,T],[T,G,G,C,T,A]) dnads_exmpl2 = [(A,T),(C,G),(C,G),(G,C),(A,T),(T,A)] Dabei ist die erste Version deutlich vorzuziehen. Sie deutet an, was in der Zelle auch stattfindet: Das Aufspalten oder Zusammenfügen des Doppelstrangs aus zwei Einzelsträngen. Die zweite Version dagegen suggeriert, daß existierende Watson-Crick Basenpaare zu einer Doppelkette verknüpft werden. Einzelne solche Paare sind jedoch wegen der sehr schwachen Wasserstoffbindung nicht stabil und kommen daher in der Zelle nicht vor. Wir entscheiden uns also für den Datentyp DNA_DoubleStrand. So naheliegend seine Definition auch erscheint, sie ist nicht ohne Gefahren: Formeln vom Typ DNA_DoubleStrand sollen beliebige doppelsträngige DNA-Moleküle darstellen. Das können sie auch. Aber darüber hinaus können wir formal korrekte Formeln des Typs DNA_DoubleStrand hinschreiben, denen keine Doppelhelix entspricht. incorrectdoublestrand = ([A,C,C,G,A,T],[T,G,G,C,A,T,C])

22 2. Modellierung incorrectdoublestrand ist in zweifacher Weise falsch: Erstens sind die jeweiligen Basen an mehreren Stellen nicht komplementär, und zweitens haben die beiden Einzelstränge gar noch unterschiedliche Länge. Wir stoßen hier auf eine grundlegende Schwierigkeit bei jeder Modellierung: Es gibt Objekte in der Modellwelt, die nichts bedeuten, d.h. denen keine Objekte der Wirklichkeit entsprechen. Solche Formeln, die wohlgebaut, aber ohne Bedeutung sind, nennt man syntaktisch korrekt, aber semantisch falsch. Alles geht gut, solange beim Rechnen mit den Formeln auch keine solchen Objekte erzeugt werden. Wenn doch, sind die Folgen meist unabsehbar. Im besten Fall bleibt die Rechnung irgendwann stecken, weil eine Funktion berechnet werden soll, die für solche Fälle keine Regel vorsieht. Manchmal passen die Rechenregeln auch auf die nicht vorgesehenen Formeln, und dann kann es im schlimmsten Fall geschehen, daß die Rechnung ein Ergebnis liefert, dem man nicht ansieht, daß es falsch ist. Wir werden sehen, daß selbst die Natur im Falle der DNA-Replikation dieses Problem erkannt und einen Weg zu seiner Lösung gefundenhat. Zunächst betrachten wir den Normalfall der Replikation. Weil das Komplement jeder Base eindeutig definiert ist, kann man zu jedem DNA-Einzelstrang den komplementären Doppelstrang berechnen. In der Tat geschieht dies bei der Zellteilung. Der Doppelstrang wird aufgespalten, und die DNA-Polymerase synthetisiert zu jedem der beiden Stränge den jeweils komplementären Strang. Die DNA- Polymerase können wir auf zwei verschiedene Weisen darstellen: Enerseits ist sie ein Enzym, also selbst ein Protein: dnapolymerase_sequenz = Met:Ala:Pro:Val:His:Gly:Asp:Asp:Ser... Dies hilft uns allerdings nicht dabei, die Wirkungsweise dieses Enzyms auszudrücken. Noch viele Jahrzehnte werden vergehen, ehe die Wissenschaft die Funktion eines Proteins aus der Kette seiner Aminosäuren ableiten kann. Was liegt also näher, als die Funktion der Polymerase durch eine Funktion zu modellieren: dnapolymerase :: DNA -> DNA_DoubleStrand dnapolymerase x = (x, complsinglestrand x) where complsinglestrand [] = [] complsinglestrand (a:x) = wc_complement a:complsinglestrand x Will man prüfen (lassen), ob ein Dopplestrang tatsächlich korrekt aufgebaut ist, kann man dies nun einfach tun. data Bool = True False -- die abstrakten Urteile Wahr und Falsch wellformeddoublestrand :: DNA_DoubleStrand -> Bool wellformeddoublestrand (x,y) = (x,y) == dnapolymerase x

2.4. Modellierung in der molekularen Genetik 23 (Zur Unterscheidung von der definierenden Gleichung schreiben wir den Vergleich zweier Formeln als ==. Dabei werden beide Formeln zunächst ausgerechnet und dann verglichen.) Blickt man etwas tiefer ins Lehrbuch der Genetik, so findet man, daß auch die Natur nicht ohne Fehler rechnet: Mit einer (sehr geringen) Fehlerrate wird in den neu polymerisierten Strang ein falsches (nicht komplementäres) Nukleotid eingebaut. Dadurch wird die Erbinformation verfälscht. Daher gibt es ein weiteres Enzym, eine Exonuclease, die fehlerhafte Stellen erkennt und korrigiert. Sie muß dabei ein subtiles Problem lösen: Gegeben ein Doppelstrang mit einem nicht komplementären Basenpaar darin welcher Strang ist das Original, und welcher muß korrigiert werden? Die Natur behilft sich dadurch, daß der Originalstrang beim Kopieren geringfügig modifiziert wird durch Anhängen von Methylgruppen an seine Nukleotide. Diese Technik können wir nicht einsetzen, da wir die Chemie der Nukleotide nicht modellieren. Wir behelfen uns auf eine nicht weniger subtile Art: Im Unterschied zur Wirklichkeit (Doppelhelix) kann man im Modell (DNA_DoubleStrand) einen linken und rechten Strang unterscheiden. Übereinstimmend mit der Modellierung der Polymerase legen wir fest, daß stets der linke Strang als Original gilt, der rechte als die Kopie. Auch die Exonuclease modellieren wir durch ihre Funktion: exonuclease :: DNA_DoubleStrand -> DNA_DoubleStrand exonuclease ([],[]) = ([],[]) exonuclease ([],x) = ([],[]) -- Kopie wird abgeschnitten exonuclease (x,[]) = dnapolymerase x -- Kopie wird verlaengert exonuclease (a:x,b:y) = if b == ac then (a:x,b:y ) else (a:x,ac:y ) where ac = wc_complement a (x,y ) = exonuclease (x,y) Damit erhalten wir z.b. die erwünschte Korrektur des fehlerhaften Doppelstrangs: exonuclease incorrectdoublestrand ==> ([A,C,C,G,A,T],[T,G,G,C,T,A]) Unsere Definition der Exonuclease ist der Natur abgelauscht. Vom Standpunkt des Rechenergebnisses aus betrachtet (man nennt diesen Standpunkt extensional) können wir das Gleiche auch einfacher haben: Verläßt man sich darauf, daß unsere DNA-Polymerase im Modell keine Fehler macht, kann man einfach den kopierten Strang gleich neu polymerisieren. dnacorr :: DNA_DoubleStrand -> DNA_DoubleStrand dnacorr (x,y) = dnapolymerase x Es ist nicht ganz überflüssig, die gleiche Funktion auf verschiedene Weisen zu beschreiben. Daraus ergibt sich die Möglichkeit, das Modell an sich selbst zu validieren. Es muß ja nun die folgende Aussage gelten:

24 2. Modellierung Für alle d::dna_doublestrand gilt dnacorr d == exonuclease d. Außerdem muß die dnapolymerase eine Idempotenzeigenschaft aufweisen: Für alle x::dna gilt: x == z where (x,y) == dnapolymerase x (y,z) == dnapolymerase y Wir formulieren solche Eigenschaften, die wir aus der Wirklichkeit kennen, in der Sprache der Modellwelt. Können wir sie dort als gültig nachweisen, so wissen wir erstens, daß unser Modell im Hinblick auf genau diese Eigenschaften der Realität entspricht. Aber noch mehr: Sofern wir diese Eigenschaften beim Formulieren des Modells nicht explizit bedacht haben, fördert ihr Nachweis auch unser generelles Vertrauen in die Tauglichkeit des Modells. Wir werden später Techniken kennenlernen, wie man solche Eigenschaften nachweist. Fast ohne Ausnahme benutzen alle Lebewesen den gleichen genetischen Code. Bestimmte Dreiergruppen (genannt Codons) von Nukleotiden codieren für bestimmte Aminosäuren. Da es 4 3 = 64 Codons, aber nur 20 Aminosäuren gibt, werden viele Aminosäuren durch mehrere Codons codiert. Einige Codons codieren für keine Aminosäure; man bezeichnet sie als Stop-Codons, da ihr Auftreten das Ende eines Gens markiert. Der genetische Code ist also eine Funktion, die Codons auf Aminosäuren abbildet. (Wir abstrahieren hier davon, daß die DNA zunächst in RNA transkribiert wird, wobei die Base Thymin überall durch Uracil ersetzt wird.) gencode :: Codon -> AminoAcid gencode (A,A,A) = Lys; gencode (A,A,G) = Lys gencode (A,A,C) = Asn; gencode (A,A,T) = Asn gencode (A,C,_) = Thr gencode (A,G,A) = Arg; gencode (A,G,G) = Arg gencode (A,G,C) = Ser; gencode (A,G,T) = Ser gencode (A,T,A) = Ile; gencode (A,T,C) = Ile gencode (A,T,T) = Ile gencode (A,T,G) = Met gencode (C,A,A) = Glu; gencode (C,A,G) = Glu gencode (C,A,C) = His; gencode (C,A,T) = His gencode (C,G,_) = Arg gencode (C,C,_) = Pro gencode (C,T,_) = Leu gencode (G,A,A) = Glu; gencode (G,A,G) = Glu gencode (G,A,C) = Asp; gencode (G,A,T) = Asp gencode (G,C,_) = Ala gencode (G,G,_) = Gly gencode (G,T,_) = Val gencode (T,A,A) = Stp; gencode (T,A,G) = Stp

2.4. Modellierung in der molekularen Genetik 25 gencode (T,G,A) = Stp gencode (T,A,C) = Tyr; gencode (T,A,T) = Tyr gencode (T,C,_) = Ser gencode (T,G,G) = Trp gencode (T,G,C) = Cys; gencode (T,G,T) = Cys gencode (T,T,A) = Leu; gencode (T,T,G) = Leu gencode (T,T,C) = Phe; gencode (T,T,T) = Phe Ein Gen beginnt stets mit dem Startcodon (A,T,G), setzt sich dann mit weiteren Codons fort und endet mit dem ersten Auftreten eines Stopcodons. Die Translation, d.h. die Übersetzung des Gens in das codierte Protein erfolgt am Ribosom. Dies ist ein sehr komplexes Molekül, ein Verbund aus Proteinen und Nukleinsäuren. Wir modellieren es durch seine Funktion: ribosome :: DNA -> Protein ribosome (A:T:G:x) = Met:translate (triplets x) where triplets :: [a] -> [(a,a,a)] triplets [] = [] triplets (a:b:c:x) = (a,b,c):triplets x translate :: [Codon] -> Protein translate [] = [] translate (t:ts) = if aa == Stp then [] else aa:translate ts where aa = gencode t Auch hier haben wir wieder einige Modellierungsentscheidungen getroffen, die man sich klarmachen muß. Dies betrifft die Behandlung inkorrekt aufgebauter Gene, die auch in der Natur gelegentlich vorkommen. Fehlt das Startcodon, wird kein Protein produziert. Ist das Gen unvollständig, d.h. bricht es ohne Stopcodon ab, so ist ein unvollständiges Proteinprodukt entstanden, das entsorgt werden muß. Im Modell ist dies so ausgedrückt: Fehlt das Startcodon, gibt es keine passende Rechenregel für ribosome, und die Rechnung beginnt gar nicht erst. Ist das letzte Triplett unvollständig, bleibt die Rechnung in einer Formel der Art triplets [a] oder triplets[a,b] stecken, für die wir keine Rechenregel vorgesehen haben. Ein Fehlen des Stopcodons wird verziehen. Wer dies nicht will, streicht die erste Regel für translate, so daß ohne Stopcodon die Rechnung am Ende in translate [] steckenbleibt. Eine frühere Entscheidung hat sich hier gelohnt: Da wir den Listentyp polymorph eingeführt haben, können wir hier auch ganz nebenbei Listen von Codons, d.h. den Typ [Codon] verwenden.

26 2. Modellierung Bisher haben wir Vorgänge modelliert, die in der Natur selbst vorkommen. Zum Abschluß nehmen wir den Standpunkt des Naturforschers ein. Heute liefern die großen Sequenzierprojekte dank weitgehender Automatisierung eine Fülle von DNA-Sequenzen immer mehr Organismen. Von einigen ist sogar bereits das komplette Genom bekannt, etwa vom Koli-Bakterium (ca. 3 Millionen Basenpaare) oder der Bäckerhefe (ca. 14 Millionen Basenpaare). Den Forscher interessiert nun unter anderem, welche Gene eine neue DNA-Sequenz möglicherweise enthält. Sequenzabschnitte, die den Aufbau eines Gens haben, nennt man ORFs (open reading frames). Ob es sich bei ihnen tatsächlich um Gene handelt, hängt davon ab, ob sie jemals vom Ribosom als solche behandelt werden. Dies kann man der Sequenz heute nicht ansehen. Wohl aber ist es interessant, in einer neuen DNA-Sequenz nach allen ORFs zu suchen und ihre Übersetzung in hypothetische Proteine vorzunehmen. Wir wollen also für unsere Kollegin aus der Molekularbiologie eine Funktion definieren, die genau dieses tut. Damit ist unsere Aufgabe so bestimmt: Wir gehen von einem DNA-Doppelstrang aus, der zu untersuchen ist. Als Ergebnis möchten wir alle ORFs in übersetzter Form sehen, die in dem Doppelstrang auftreten. Wir wollen diese Aufgabe durch eine Funktion analyseorfs lösen. Schon beim Versuch, den Typ dieser Funktion anzugeben, wird klar, daß die Aufgabe zwar halbwegs ausreichend, aber keineswegs vollständig beschrieben ist. Was genau bedeutet alle ORFs? Weder in der DNA, noch in unserem Modell liegt eine feste Einteilung der Nukleotidsequenz in Codons vor. Das Auftreten einer Dreiergruppe A,T,G definiert implizit die Lage der folgenden Codons. Ein einzelnes Nukleotid kann so drei verschiedenen Leserastern angehören, in denen es jeweils als 1., 2. oder 3. Element eines Codons interpretiert wird. Damit kann ein DNA-Abschnitt überlappende ORFs enthalten. Das gleiche gilt für den Gegenstrang, der dabei in umgekehrter Richtung abzulesen ist. Alle ORFs zu finden ist also etwas komplizierter als es zunächst erscheint. Das führt zu der Frage, wie eigentlich das Ergebnis aussehen soll. Einfach eine Liste aller ORFs, die vorkommen? Oder will man zu jedem ORF auch wissen, in welchem Leseraster auf welchem Strang er liegt? Möchte man gar zusätzliche Informationen erhalten, wie etwa Länge eines ORF und seine Lage relativ zum Anfang der DNA-Sequenz? Schließlich wir wissen ja was unsere Kollegin letzlich interessiert könnte man die hypothetischen Proteine noch mit einer Proteindatenbank abgleichen, um zu sehen, ob ein solches (oder ein ähnliches) Protein an anderer Stelle bereits nachgewiesen wurde... Es ist immer ein gutes Entwurfsprinzip möglicherweise interessante Information, die während der Rechnung anfällt, auch im Ergebnis sichtbar zu machen. Dies gilt hier für die Verteilung der ORFs auf die Leseraster. die Funktionalität eines Entwurfs nicht zu überfrachten. Was gut und logisch einleuchtend durch zwei getrennte Funktionen realisiert werden kann, wird auch getrennt.