ii Sonstiges 1.Auflage 1993 Prof. Dr. Kupka 2.Auflage 1994 überarbeitet und erweitert von Prof. Dr. Ecker 3.Auflage 1997 überarbeitet 4.Auflage 1998 unverändert 5.Auflage 1999 überarbeitet und erweitert An dieser Version haben mitgearbeitet: Informatik I/II Prof. Dr. Kupka Institut für Informatik Technische Universität Clausthal Wintersemester 1998/99, Sommersemester 1999 5. Auflage Stand 27. September 1999 Patrick Bothe Torsten Erkens Martin Herzog Oliver Krüger Stephanie Müller Ulrike Bostelmann Ralf Wolters Silke Schomann Andrea Skala Eva Blunk Katrin Baptist Michael Skubowius Sven Witting Alexander Neid Robert Heine Stephan Mühling Florian Rilke Michael David INHALTSVERZEICHNIS iv 2.5 Inhaltsverzeichnis 2.6 1 Die Entwicklung der Informatik 1 1.1 Historische Wurzeln . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.1.1 Verfahren unabhängig von inhaltlichen Beziehungen . . . 1 1.1.2 Das 17. Jahrhundert: mechanische Automaten und Mechanisierung des Rechnens . . . . . . . . . . . . . . . . . 2 1.1.3 Ab Mitte des 19. Jahrhunderts: Mechanisierung des logischen Denkens, Verknüpfung von Philosophie, Logik, Mathematik und Sprachwissenschaft . . . . . . . . . . . . 2 1.2 Die technologische Entwicklung . . . . . . . . . . . . . . . . . . 4 1.3 Die Entwicklung der Programmierung . . . . . . . . . . . . . . . 7 1.3.1 1. Phase: Entwicklung der Grundtechniken . . . . . . . . 8 1.3.2 2. Phase: Theoretische Fundierung . . . . . . . . . . . . . 9 1.3.3 3. Phase: Rückbesinnung auf die Praxis . . . . . . . . . . 9 1.3.4 4. Phase Paradigmen . . . . . . . . . . . . . . . . . . . . 10 1.4 Anwendungen der Informatik . . . . . . . . . . . . . . . . . . . 11 1.5 Informatik als Wissenschaft . . . . . . . . . . . . . . . . . . . . . 12 2 Elementare Modellbildung 2.1 Einführung . . . . . . . . . . . . . 2.2 Mengen . . . . . . . . . . . . . . . 2.3 Relationen und Funktionen . . . . . 2.3.1 Cartesisches Produkt . . . . 2.3.2 Relationen . . . . . . . . . 2.3.3 Ordnungsrelationen . . . . . 2.3.4 Operationen auf Relationen 2.3.5 Funktionen . . . . . . . . . 2.3.6 Operationen auf Funktionen 2.3.7 Darstellung von Funktionen 2.3.8 Äquivalenzrelationen . . . . 2.3.9 Darstellung von Relationen . 2.4 Beweistechniken . . . . . . . . . . iii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 15 17 23 23 24 25 26 26 27 28 32 32 34 2.7 2.8 3 4 2.4.1 Widerspruchsbeweis . . . . . . . . . . . . . . . . . . . . 2.4.2 Beweis nach dem Prinzip der vollständigen Induktion . . . Werte, Variable und Terme . . . . . . . . . . . . . . . . . . . . . 2.5.1 Werte . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.5.2 Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.5.3 Terme . . . . . . . . . . . . . . . . . . . . . . . . . . . . Aussagenlogik . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.6.1 Boolesche Funktionen . . . . . . . . . . . . . . . . . . . 2.6.2 Aussagenlogische Formeln . . . . . . . . . . . . . . . . . 2.6.3 Konjunktive und disjunktive Normalform . . . . . . . . . 2.6.4 Schaltungstechnik . . . . . . . . . . . . . . . . . . . . . 2.6.5 Aussagenkalkül . . . . . . . . . . . . . . . . . . . . . . . 2.6.6 Die Methode der Wahrheitstafeln . . . . . . . . . . . . . 2.6.7 Der Wang-Algorithmus . . . . . . . . . . . . . . . . . . . 2.6.8 Das Resolutionsverfahren im Aussagenkalkül . . . . . . . Prädikatenlogik . . . . . . . . . . . . . . . . . . . . . . . . . . . Fuzzy-Logik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Prozesse und Systeme 3.1 Prozesse und Ablaufpläne . . . . . . . . . . . 3.1.1 Diskrete Prozesse . . . . . . . . . . . 3.1.2 Sequentielle Prozesse . . . . . . . . . 3.1.3 Syntax-Diagramme . . . . . . . . . . 3.1.4 Der Backus-Naur-Formalismus (BNF) 3.1.5 Grammatik . . . . . . . . . . . . . . 3.1.6 Reguläre Ausdrücke . . . . . . . . . 3.2 Endliche Automaten . . . . . . . . . . . . . 3.3 Graphen . . . . . . . . . . . . . . . . . . . . 3.3.1 Einführende Beispiele . . . . . . . . 3.3.2 Ungerichtete und gerichtete Graphen 3.4 Petri-Netze . . . . . . . . . . . . . . . . . . 3.5 Dynamische Systeme . . . . . . . . . . . . . 34 34 35 35 36 37 39 40 43 46 50 53 56 56 58 61 67 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 69 70 71 72 73 74 77 79 84 84 86 93 111 Problemstrukturen und Problemsolving 4.1 Problembeschreibung und Spezifikation . . . . . . . . . . . . 4.1.1 Anforderungen an die Problembeschreibung . . . . . . 4.1.2 Notation in einer formalen Spezifikationssprache . . . 4.1.3 Formale Spezifikation, Datenspezifikation, Constraint 4.1.4 Einzelprobleme, Problemklassen, Probleminstanzen . 4.2 Problemarten und Darstellung von Problemen . . . . . . . . . 4.3 Techniken und Strategien des Problemlösens . . . . . . . . . . . . . . . . . . . . . . . . 113 114 114 116 116 117 118 122 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . INHALTSVERZEICHNIS 4.4 v 4.3.1 Die analytische Vorgehensweise . . 4.3.2 Die algorithmische Vorgehensweise 4.3.3 Die heuristische Vorgehensweise . . 4.3.4 Allgemeine Strategien . . . . . . . Softcomputing-Ansätze des Problemsolving 4.4.1 Fuzzy-Technik . . . . . . . . . . . 4.4.2 Neuronale Netze . . . . . . . . . . 4.4.3 Evolutionäre Verfahren . . . . . . . 4.4.4 Simulated Annealing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 124 125 126 126 127 127 128 129 7.3.1 7.3.2 7.3.3 8 5 Algorithmen und Programmierung 131 5.1 Übersicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 5.2 Der Algorithmusbegriff . . . . . . . . . . . . . . . . . . . . . . . 132 5.3 Nichtdeterministische Algorithmen . . . . . . . . . . . . . . . . . 134 5.4 Programmierparadigmen und Programmierstile . . . . . . . . . . 138 5.4.1 Das Paradigma der imperativen Programmierung . . . . . 138 5.4.2 Das Paradigma der funktionalen Programmierung . . . . . 143 5.4.3 Das Paradigma der regelbasierten Programmierung . . . . 146 5.4.4 Das Paradigma der logikorientierten Programmierung . . 148 5.4.5 Das Paradigma der objektorientierten Programmierung . . 149 5.5 Grundkonzepte der Programmierung . . . . . . . . . . . . . . . . 150 5.5.1 Zielsetzungen bei der Programmierung . . . . . . . . . . 150 5.5.2 Das Konzept der virtuellen Maschine . . . . . . . . . . . 151 5.5.3 Unterprogrammtechnik . . . . . . . . . . . . . . . . . . . 152 5.5.4 Variable Kontexte und Deklarationen . . . . . . . . . . . 154 6 Information und Nachricht 6.1 Information, Daten und Nachrichten . . . . . . . 6.1.1 Diskretisierung . . . . . . . . . . . . . . 6.1.2 Quantelung . . . . . . . . . . . . . . . . 6.2 Codes und Codierung . . . . . . . . . . . . . . . 6.3 Ein Einblick in die Codierungstheorie . . . . . . 6.4 Huffman-Codierung und arithmetische Codierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 157 161 163 163 169 173 7 Die Von-Neumann-Maschine 7.1 Das grundlegende Konzept . . . . . 7.1.1 Struktur des Speichers . . . 7.1.2 Struktur des Rechenwerks . 7.1.3 Struktur des Leitwerks . . . 7.2 Maschinennahe Programmierung . . 7.3 Darstellung von Zahlen im Rechner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 175 178 180 181 182 186 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . INHALTSVERZEICHNIS vi 9 Nichtnegative ganze Zahlen . . . . . . . . . . . . . . . . 186 Vorzeichenbehaftete ganze Zahlen . . . . . . . . . . . . . 187 Rationale Zahlen und Gleitpunktdarstellung . . . . . . . . 189 Datenstrukturen 8.1 Von Datentypen zu Datenstrukturen . . . . . . . 8.2 Elementare Datenstrukturen . . . . . . . . . . . 8.2.1 Boolean . . . . . . . . . . . . . . . . . . 8.2.2 Character . . . . . . . . . . . . . . . . . 8.2.3 Integer . . . . . . . . . . . . . . . . . . 8.2.4 Natural . . . . . . . . . . . . . . . . . . 8.2.5 Rational . . . . . . . . . . . . . . . . . . 8.2.6 Real . . . . . . . . . . . . . . . . . . . . 8.2.7 Aufzählungstyp . . . . . . . . . . . . . . 8.2.8 Unterbereichstyp . . . . . . . . . . . . . 8.3 Zusammengesetzte Datenstrukturen . . . . . . . 8.3.1 String . . . . . . . . . . . . . . . . . . . 8.3.2 Feld . . . . . . . . . . . . . . . . . . . . 8.3.3 Verbund . . . . . . . . . . . . . . . . . . 8.3.4 Vereinigung . . . . . . . . . . . . . . . . 8.4 Die Speicherstrukturen Stack, Queue und Deque . 8.5 Listen, Mengen und Hash-Tabellen . . . . . . . . 8.6 Rekursive Datenstrukturen und Zeiger . . . . . . 8.6.1 Symbolische Ausdrücke von LISP . . . . 8.6.2 Arithmetische Bäume . . . . . . . . . . . 8.6.3 Der Stack als rekursive Datenstruktur . . 8.6.4 Zeiger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195 195 198 198 200 200 201 201 201 202 203 203 203 204 205 206 206 208 211 211 213 214 215 Kontrollstrukturen 217 9.1 Übersicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217 9.2 Unterprogramme . . . . . . . . . . . . . . . . . . . . . . . . . . 217 10 Programmiersprachen 10.1 Allgemeine Bemerkungen zu Programmiersprachen . 10.1.1 Syntax, Semantik und Pragmatik . . . . . . . 10.1.2 Merkmale und Ausprägungen . . . . . . . . 10.2 Funktionale Programmierung . . . . . . . . . . . . . 10.2.1 Übersicht . . . . . . . . . . . . . . . . . . . 10.2.2 APL . . . . . . . . . . . . . . . . . . . . . . 11 Literatur zu Informatik I und II . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219 . 219 . 219 . 220 . 222 . 222 . 222 229 2 KAPITEL 1. DIE ENTWICKLUNG DER INFORMATIK 1.1.2 Das 17. Jahrhundert: mechanische Automaten und Mechanisierung des Rechnens 1623 Kapitel 1 Wilhelm Schickard (Math. und Astronom), Tübingen, erste bekannte Rechenmaschine, zahnradgesteuert, 6 Stellen 1641 Blaise Pascal (Phil., Math. und Physiker), Paris, erste noch erhaltene Rechenmaschine für 6-stellige Addition Die Entwicklung der Informatik 1674 Gottfried Wilhelm von Leibniz (Phil., Math. und Jurist), Multiplikation und Division auf (konstruierter Rechenmaschine, Gleitschlitten, Staffelwalze 1.1 Historische Wurzeln 1679 Leibniz: binäres Zahlsystem 1774 Philipp Matthäus Hahn (Pfarrer) läßt Rechenmaschinen in Serie bauen 1822 Charles Babbage (engl. Math., Techniker und Org.) entwirft seine ’Difference Engine’, eine 3-stufige, 6-stellige Addiermaschine zur Berechnung von Funktionswerten 1833 Babbage entwirft ’Analytical Engine’, lochkartenprogrammiert, seine ’Programmiererin’: Ada Augusta, Countess of Lovelace ! Universalität des Computers 1886 Hermann Hollerith (amer. Bergwerksing.), Lochkartenmaschine für 11. amer. Volkszählung 1880: 500 Helfer / 7 Jahre 1890: 43 Maschinen und Helfer / 4 Wochen — 1896: Hollerith gründet die Firma Tabulating Machine Company 1911: Firmenverkauf, Firma wird Vorläufer der IBM (1924) Hilfsmittel zum Rechnen systematische Vorgehensweisen 1800 v. Chr. Gebrauch von Rechenbrettern (Abakus in Ägypten) 1700 v. Chr. Papyrus Rhind, Ägypten, enthält die ältesten Rechenaufgaben 400 v. Chr. Griechen und Perser rechnen mit dem Abakus 300 v. Chr. Euklid (griech. Math.) beschreibt in ’Elemente’ mathematische Verfahren, ! Euklidischer Algorithmus 500 n. Chr. In Indien wird das Dezimalsystem erfunden 1.1.1 Verfahren unabhängig von inhaltlichen Beziehungen 1.1.3 Ab Mitte des 19. Jahrhunderts: Mechanisierung des logischen Denkens, Verknüpfung von Philosophie, Logik, Mathematik und Sprachwissenschaft 820 n. Chr. Al-Chowarizmi (persischer Math. und Astronom) schreibt ein Buch über Algebra (nach Titel des Buches) ! ’Algorithmus’ 1202 n. Chr. Leonardo von Pisa, genannt Fibonacci, beschreibt in ’liber abaci’ indische, arabische und eigene Rechenmethoden 1524 n. Chr. Adam Riese veröffentlicht Rechenbuch, dezimal 1 1847 George Boole (engl. Math. und Logiker 1815-1864) beschreibt den Zusammenhang zwischen Logik und Algebra: ’The mathematical analysis of logic, beeing an essay towards a calculus of deductive reasoning’ 1.1. HISTORISCHE WURZELN 1879 3 Gottlob Frege (deutsch. Math. 1848-1918) legt Grundlage für moderne Logik: ’Begriffsschrift, eine der arithmetischen nachgebildete Formelsprache des reinen Denkens’ 1889 Guiseppe Peano (ital. Math. 1858-1932) schreibt ’Aritnetices Principia’ 1913 A. N. Whitehead (1861-1947) und Bertrand Russell (1872-1970, Lit.-Nobelpreis), Grundlagenwerk für Mathematik und Logik: ’Principia Mathematica’ 1928 David Hilbert und W. Ackermann: ’Grundzüge der theoretischen Logik’ 1934 Jacques Herbrand (franz. Philosoph) und Kurt Gödel (Österr. Math. 1906-1978) entwickeln einen mathematischen Funktionsbegriff, der die prinzipelle Leistungsfähigkeit von Rechenmaschinen repräsentiert: ’allgemein-rekursive Funktion’ 1936 Alan M. Turing (engl. Math. 1912-1954) entwickelt ein abstraktes Modell zur Untersuchung von Fragen über die Berechenbarkeit: Turing-Maschine 1936 Alonzo Church (amer. Math. geb. 1903) entwickelt den LambdaKalkül als universelles Berechenbarkeitsmodell, Church’sche These: alle denkbaren Maschinenmodelle beschreiben die gleiche Leistung 1938 S. C. Kleene (engl. Math.) definiert partiell-rekursive Funktionen, welche die Leistungsfähigkeit von Computer exakt beschreiben KAPITEL 1. DIE ENTWICKLUNG DER INFORMATIK 4 1.2 Die technologische Entwicklung Unmittelbar im Anschluß an die theoretischen Entdeckungen begann die Entwicklung und Inbetriebnahme der voll funktionsfähigen, programmierbaren, universellen Rechenmaschinen – der Computer im heutigen Sprachgebrauch. 1938 Konrad Zuse, Bauingenieur, Erfinder und Unternehmer (*1910), stellt einen mechanischen Rechner mit Binärtechnik fertig – die Z1. 1939 Es folgt die Z2 mit elektromechanischem Rechenwerk mit ca. 200 Relais. 1941 Zuses Z3 wird fertig, die erste voll arbeitsfähige, programmgesteuerte Rechenmaschine. Sie wird in der Deutschen Forschungs- und Versuchsanstalt für Luft- und Raumfahrttechnik (DFVLR) eingesetzt. Einige Daten: Rechenwerk: 600 Relais, 2 parallele arithmetische Einheiten für Exponent und Mantisse. Speicher: 1400 Relais für 64 Worte mit je 22 Bit, Zahlendarstellung halblogarithmisch mit einem Bit Vorzeichen, 7 Bit Exponent und 14 Bit Mantisse. Programmsteuerung: 8-Kanal Lochstreifen. Eingabe: spezielle Tastatur. Ausgabe: Resultatanzeige auf Lampenreihen. Multiplikationszeit: 3 Sekunden. Das Original der Z3 verbrannte 1944 in Berlin. Ein Nachbau steht im Deutschen Museum in München. 1944 Howard Hathaway Aiken, amerikanischer Mathematiker (1900–1973), baut mit der Unterstützung von IBM den Großrechner Mark I: 15m lang, 2.5m hoch und 35t schwer. Einige Daten: Relaistechnik, 60 Read-Only-Register, manuell einstellbar. 72 Read-Write-Register für 23-dezimalstellige Zahlen. Mutiplikationszeit: 6 Sekunden. 1945 Konrad Zuse baut die Z4, die bis 1959 in Betrieb ist. 1.2. DIE TECHNOLOGISCHE ENTWICKLUNG 5 1945 John von Neumann, ungarisch amerikanischer Mathematiker, entwickelt ein grundlegendes Konzept für programmierbare Rechner, welches bis heute tragendes Konzept geblieben ist. 1946 J. P. Eckert und J. W. Manchly bauen die ENIAC, die erste elektronische Rechenmaschine. Sie hat 18000 Röhren und eine Multiplikationszeit von 3ms. 1949 Der Engländer M. V. Wilkes baut mit der EDSAC den ersten praktisch verwendbaren Rechner nach dem von-Neumann-Konzept. Einige Daten: 3000 Röhren. Speicher: 512 35-Bit-Worte. Die weitere Entwicklung ist durch gewaltige technische Verbesserungen und durch folgenschwere Erfindungen im Bereich der Programmierung gekennzeichnet. KAPITEL 1. DIE ENTWICKLUNG DER INFORMATIK 6 Die Taktzeit unterschreitet 50 Nanosekunden (10;9 sec). 1977 Hochintegrierte Schaltkreise treiben die Miniaturisierung weiter. Es entstehen die Mikroprozessoren, die das gesamte Rechenwerk auf einem Chip enthalten. 1977 Der Mikroprozessor Z 80 wird herausgebracht, neben ähnlichen Mikroprozessoren, charakterisiert durch 8 bit Wortbreite, 7000 Transistoren integriert, 1 MIPS (Million Instruktionen pro Sekunde) 1985 Es entstehen die Mikroprozessoren 80386 (Intel) und ähnliche: 32 bit Wortbreite, 10 hoch 5 Transistoren integriert, 10 MIPS Die Halbleitertechnologie entwickelt sich exponentiell: Etwa alle 5 Jahre vervierfacht sich die Anzahl der Transistorfunktionen pro Chip. Auch die Verarbeitungsgeschwindigkeit wächst exponentiell. 1996 Der Mikroprozessor Pentium (und ähnliche) tritt auf den Markt: 4 mal 10 hoch 6 Transistorfunktionen, 200 MIPS Parallel zur Chip- und Prozessortechnologie entwickelt sich das Internet. 1955 Die Elektronenröhre wird durch den Transistor abgelöst. Dies führt zur 2. Computergeneration mit kleineren und schnelleren Rechnern. Taktzeiten von 1–10 µsec werden realisiert. Die Speichergröße steigt in den Bereich einiger Tausend. 1958 Mit FORTRAN beginnt die Verbreitung der höheren Programmiersprachen. Es folgen ALGOL und COBOL. 1962 Die Miniaturisierung der Transistoren führt zur 3. Computergeneration. SSI: small scale integration: bis 50 Transistoren pro Chip. MSI: medium scale integration: 50–500 Transistoren pro Chip. Es wird eine Taktzeit von 0.1–1 µsec erreicht. 1969 Das Forschungsnetz ARPANET wird in der US Defense Advanced Researech Project Agency (DARPA) eingeführt 1983 der 1. Januar 1983 gilt als Geburtsstunde des Internet: es erfolgt die Einführung des Protokollstandards TCP/IP für ARPANET und es entstehen die Netzwerkdienste Telnet, E-mail und FTP Es bedeuten TCP: Transmission Control Protocol IP: Internet Protocol Telnet: Dienst für Terminal-Verbindungen zu entfernten Rechnern FTP: Dienst für Datei-Übertragungen 1965 Die Entwicklung von BASIC öffnet für Laien den Zugang zur Programmierung. Es entwickeln sich Techniken des Compilerbaus und der Betriebssysteme. 1986 Es erfolgt die überregionale Ausdehnung des Netzes, 1988 Kanada, 1989 Deutschland 1968 Es entstehen hochintegrierte Halbleiterschaltungen. Sie bilden die Grundlage der 4. Computergeneration. 1991 Der Internetdienst Gopher für die Übertragung von Text, Bild, Ton etc. wird eingeführt LSI: large scale integration: 500–2500 Transistoren pro Chip. VLSI: very large scale integration: über 2500 Transistoren pro Chip. 1993 Das Internet breitet sich in allen Bereichen aus Die Anzahl der Netzknoten verdoppelt sich alle 12 bis 15 Monate. 1.3. DIE ENTWICKLUNG DER PROGRAMMIERUNG 7 1996 Das Netz besitzt 13 mal 10 hoch 6 Knoten, in Europa 3 mal 10 hoch 6 Knoten 1996 Die Internet-Programmiersprache JAVA wird eingeführt. KAPITEL 1. DIE ENTWICKLUNG DER INFORMATIK 8 1.3.1 1. Phase: Entwicklung der Grundtechniken Zeitraum: 50’er-Jahre bis frühe 60’er-Jahre. Generell gilt für die Entwickling seit den 80’er Jahren: Weitere Steigerung der Verarbeitungsgeschwindigkeit. Verringerung der räumlichen Abmessungen (ULSI: ultra large scale integration). Verbilligung und Massenproduktion. Fortschreitende Vernetzung der Computer: globale Verbindungen, extrem hohe Übertragungsraten bei der Verwendung von Lichtleitfasern. Anpassung der Endgerätetechnik an die sensorischen Fähigkeiten der Menschen. Entwicklung von Vektorrechnern und Multiprozessorsystemen 1.3 Die Entwicklung der Programmierung Die technologische Entwicklung eröffnete eine Vielzahl von Möglichkeiten, die Universalität des Computers auszunutzen. Hierzu gehören: die Behandlung von Programmen als Daten. Programme können vom Computer umgeformt, übersetzt, optimiert und sogar aus Beschreibungen hergeleitet werden. Wir unterteilen die Zeit der Entwicklung der Programmierung in folgende Phasen ein: Einführung der symbolischen Maschinensprache: Unterscheidung von internem Code (binär oder hexadezimal) und einem externen Code, der mnemotechnisch aufgebaut ist (z. B. ADD für Additionsbefehl). Entstehen des ersten Assemblers. Zusammenfügen der Zielprogramme unter Anwendung von Symboltabellen und Makrotechnik. Entstehen der ersten höheren Programmiersprachen; die sogenante erste Generation höherer Programmiersprachen. 1954–57 entsteht bei IBM die Sprache FORTRAN (Formula Translation), definiert durch J. W. Backus. FORTRAN wird für lange Zeit die wichtigste Sprache für technisch wissenschaftliche Anwendungen und wird auch heute noch gebraucht und erweitert. 1959–60 entsteht durch ein internationales Autorengremium die Sprache ALGOL, (algorithmic language). Zugleich wird für die exakte Beschreibung der Backus-Naur-Formalismus eingeführt. ALGOL wird zum Grundmodell für allgemeine Betrachtungen der Programmierung. Erst die Nachfolger von ALGOL erfahren größere praktische Bedeutung. 1960 wird COBOL (common business oriented language) definiert, ebenfalls durch eine internationale Organisation. Die Sprache ist geeignet für Anwendungen mit vielen einfachstruktuierten Daten und einfachen Verarbeitungsprozeduren. Im kommerziellen Bereich ist COBOL immer noch die am weitesten verbreitete Sprache. 1962 wird von K. E. Iversan die Sprache APL (a programming language) vorgestellt. Später wird sie von IBM als APL/60 verbreitet. Sie ist eine Dialogsprache, welche direkt interpretiert wird. Ihre von der Mathematik entlehnten Konstruktionen wurden 20 Jahre später zum Vorbild für die sogenannten funktionalen Sprachen. die Simulation eines Computers auf einem anderen und die Simulation einer Sprache in einer anderen. die Umformung in beliebige Datenformen wie Zeichenfolgen, Zahlenfolgen, Bitfolgen, Bild-Matrizen usw. Entstehung von Macros und der Makro-Technik: Abkürzung von Befehlsfolgen durch Pseudobefehle, Abarbeitung erfolgt durch Einsetzen. 1.3. DIE ENTWICKLUNG DER PROGRAMMIERUNG 9 1962 entsteht BASIC (beginners all purpose symbolic instruction code), eine weitere einfache Programmier- und Dialogsprache. 1962 entsteht mit LISP (List processing language) von John McCarthy die erste Sprache der Künstlichen Intelligenz“. Die einzige Datenstruktur ” in LISP ist die Liste. LISP ist die erste voll funktionale Sprache. 10 KAPITEL 1. DIE ENTWICKLUNG DER INFORMATIK 1971 wird die Sprache PASCAL von N. Wirth vorgestellt. Sie korrigiert die übertriebenen theoretischen Ansätze von ALGOL68, realisiert Ideen des strukturierten Programmierens und ist für die Lehre konzipiert. 1978 erfolgt die Verbreitung der Sprache C“ von Kernigham und Ritchie. Die ” Sprache ist eng mit dem Betriebssystem UNIX verbunden und erlaubt eine maschinennahe Programmierung, obwohl es sich um eine höhere Sprache handelt. C wird zu einer wichtigen Implementationssprache. 1.3.2 2. Phase: Theoretische Fundierung Zeitraum: späte 60’er Jahre Theoretische Erforschung der Möglichkeiten der Definition von Sprachen durch Grammatiken und der Übersetzung von Sprachen durch Compiler. Konstruktion von Programmiersprachen mit universellem Anspruch: die zweite Generation höherer Programmiersprachen. 1965 entsteht PL/I (programming language I) bei IBM, im wesentlichen durch Zusammenbringen und Verallgemeinerung von Konzepten aus FORTRAN, ALGOL und COBOL. PL/I erreicht eine sehr weite Verbreitung, wurde meist jedoch nur teilweise implementiert (Implementation sogenannter Subsets). PL/I ist auch die erste Sprache, deren inhaltliche Bedeutung, die Semantik, exakt formal beschrieben wird. Hierzu entwickelt das Wiener IBM-Labor unter H. Zemanek die Vienna-Definition-Language (VDL). 1.3.4 Es kommt die Erkenntnis zum Durchbruch, daß gänzlich andere Programmiervorstellungen zur Programmierung ebenfalls geeignet sind. 1978 verkündet J. W. Backus in seiner berühmten Turing Award Lecture“, ” daß fast alle bisherigen Programmiersprachen, die sogenannten vonNeumann-Sprachen, eigentlich maschinennahe Sprachen sind, und daß wirklich maschinenunabhängige Konzepte, wie man sie z. B. in LISP findet, nötig sind. 1980 erscheint ein Aufsatz von R. Kowalski mit dem Titel Algorithm = Lo” gic + Control“. Hierin wird dafür plädiert, die Ausführungskontrolle aus Algorithmen so weit wie möglich herauszuhalten. Damit wird unter anderem die Programmierung in PROLOG begründet. 1980 wird die bisher letzte große Programmiersprache des von-NeumannPrinzips, ADA (ein Pascal Nachfolger) benannt nach Ada Augusta, der ersten Programmiererin, vorgestellt. 1967 Auf ALGOL60 aufbauend entsteht SIMULA67, eine Simulationssprache. 1968 wird durch eine Arbeitsgruppe der IFIP (International Federation of Information Processing) die Sprache ALGOL68 vorgestellt. Die Sprache besitzt ein perfektes theoretisches Konzept, wurde aber zu spät implementiert und konnte daher nicht in die Praxis eindringen. 4. Phase: Aufkommen der programmiersprachlichen Paradigmen ab 1980 erscheinen in weiterer Verbreitung: Beginn der systematischen Software-Technologie und Aufkommen des structural ” programming“. 1968/69 fanden zwei wichtige NATO-Tagung zu dem Thema statt. Wichtige Ideen stammen von C. A. R. Hoare und E. W. Dijkstra. PROLOG (programming in logic) wird zur zweiten wichtigen Sprache der künstlichen Intelligenz (KI). FP (funktional programming) begründet die neueren funktionalen Sprachen. 1.3.3 3. Phase: Rückbesinnung auf die Praxis Zeitraum: 70’er Jahre. Es entstehen wieder engere Sprachkonzepte mit weniger universellem Anspruch, aber mit besseren Realisierungsmöglichkeiten. Die Softwaretechnologie wird weiterentwickelt, hauptsächlich das Modulkonzept. MIRANDA, HOPE und andere funktionale Sprachen entstehen und verbreiten sich. SMALLTALK wird zur ersten objektorientierten Sprache. 1992 Bertrand Meyer entwickelt die objektorientierte Sprache EIFFEL. 1.4. ANWENDUNGEN DER INFORMATIK 1996 11 Auf C und der objektorientierten Erweiterung C++ setzt die Internetsprache JAVA auf. Weitere Einflüsse auf die Programmierung ergeben sich durch: KAPITEL 1. DIE ENTWICKLUNG DER INFORMATIK 12 zu 3.) Die Kommunikationsleistung des Computers hat sehr große Ähnlichkeit mit der des Menschen, findet aber in streng geregelten Bahnen statt. Sowohl Computer untereinander als auch Computer und Menschen können miteinander im Dialog Informationen austauschen. Hier sind einige wichtige Anwendungen: Vordringen von Architekturen mit Parallelverarbeitung. Entwicklung von Datenbanken und Grafik-Anwendungen wie CAD (Computer-Aided-Design). Entstehen der Multimediatechnik. Problemangepaßte Sprachen mit sehr leistungsfähigen Ausdrucksmitteln 1.4 Anwendungen der Informatik Die Anwendungsmöglichkeiten der Informatik hängen von den stungsmöglichkeiten des Computers ab. Wir müssen dabei unterscheiden: Lei- 1. die Informationsverarbeitungsleistung des Computers, 2. die Speicherleistung des Computers und 3. die Kommunikationsleistung des Computers. zu 1.) Die Informationsverarbeitungsleistung bezieht sich auf die Rechenleistung im engeren und im weiteren Sinn: sie kann dabei folgende Formen annehmen, die ineinander überführt werden können: Informationsverarbeitung auf Zahlen: Rechnen. Informationsverarbeitung auf Texten: Textverarbeitung. Informationsverarbeitung auf Bildmatrizen: Bildverarbeitung. Informationsverarbeitung auf logische Aussagen: Automatische Deduktion in der KI. Datenbanken und Systeme des Information Retrieval (InformationsWiedergewinnung): Anwendungen in Staat, Verwaltung sowie im kommerziellen, technischen und wissenschaftlichen Bereich. Computergraphik: Wiedergabe von Meßwerten, Entwurf von Konstruktionszeichnungen, Kartographie. Bildverarbeitung: Komplexe Meßwerterfassung, automatisches Sehen; Anwendungen in der Medizin und in der Technik. Prozeßautomatisierung und Robotik: Hier geht es um die Automatisierung von chemischen bzw. technischen Produktionsprozessen. Simulation: Die Simulation dient der Gewinnung von Erfahrungen und Vorhersagen durch Experimente, die nach denselben Regeln wie in der Realität im Rechner ablaufen. Expertensysteme: Sie halten Expertenwissen großen Umfangs verfügbar und können dieses mit Hilfe von Methoden des Wissensverarbeitung auf Probleme anwenden. Wichtigste Beispiele sind die Diagnosesysteme in Medizin und Technik, die aus Symptomen sehr präzise auf die Ursachen schließen können. 1.5 Informatik als Wissenschaft Beim Menschen entspricht das Denken dieser Computerleistung. zu 2.) Die Speicherleistung bezieht sich auf die Möglichkeit, große Datenmengen zu speichern und geordnet zu verwalten, so daß auf die darin enthaltenen Informationen gezielt zugegriffen werden kann. Eine Analogie beim Menschen ist das Gedächtnis. Begreift man Informatik als Wissenschaft von Computern, wie das angloamerikanische Wort Computer Science“ nahe legt, so kann man sich schon fra” gen, wie die Beschäftigung mit einem vom Menschen geschaffenen Gerät eine Wissenschaft ergeben kann. Es gibt ja nicht einmal eine Wissenschaft vom Auto. Nun ist aber der Computer, der Gegenstand der Informatik ist, eine viel abstraktere 1.5. INFORMATIK ALS WISSENSCHAFT 13 und grundsätzlichere Angelegenheit als der real käufliche Computer. Bei der abstrakten Computeridee geht es beispielsweise um die Möglichkeiten des Vorwegplanens aller realisierbaren Aktivitäten, um die Ausschöpfung von Informationen und um die Gestaltung beliebiger Kommunikation. In wenigen Jahrzehnten hat die Informatik außer datentechnischen Entwicklungen auch eine stattliche Anzahl geistig-theoretischer Leistungen hervorgebracht: 14 KAPITEL 1. DIE ENTWICKLUNG DER INFORMATIK Theoretische Informatik Automatentheorie, Theorie der Berechenbarkeit, Algorithmentheorie, Theorie der Programmierung, Theorie der Wissensverarbeitung, Theorie formaler Sprachen Komplexitätstheorie, Formale Semantik, Theorie der Systeme und Prozesse, Informations- und Codierungstheorie. Praktische Informatik Die exakte Erfassung aller mit Computern lösbaren Aufgaben (Berechenbarkeit), die Entdeckung konkreter, nicht auf Computern lösbarer Aufgaben (Unberechenbarkeit), die Aufdeckung der Gleichwertigkeit aller prinzipiellen Maschinenkonzepte (Churchsche These), Datenstrukturen Programmier- und Dialogsprachen, Betriebssysteme, Mensch-Maschine-Kommunikation, Algorithmen, Übersetzer, Softwaretechnik, Multi-Media-Systeme. Angewandte Informatik Informationssysteme, Computergraphik, Bildverarbeitung, Robotik, Wissensverarbeitung, Simulation, Textverarbeitung und Büro-Automation Prozeßautomatisierung. Technische Informatik das Auffinden des Zusammenhang zwischen Grammatiken (Sprachdefinition) und Automaten (Übersetzung) (Chomsky-Hierarchie), die präzise Abschätzungen für Zeit- und Speicheraufwand von Programmen (Komplexität) und die Entwicklung von Verfahren, um die Korrektheit von Programmen sicherzustellen (Programmverifikation). Gegenstand der Informatik ist die Verarbeitung von Informationen und alles, was damit in engerem Zusammenhang steht. Ihr zentraler Begriff ist nicht der der Information, sondern der des Algorithmus. Wir unterteilen die Informatik in Theoretische, Praktische, Angewandte und Technische Informatik. Schaltnetze, Schaltwerke, Peripheriegeräte, Hardware-Entwurfstechniken, Rechnerorganisation,´ Prozessoren, Mikroprogrammierung, Rechnerarchitektur, Rechnernetze. Die Informatik steht in enger Beziehung zu vielen anderen Wissenschaften. Die folgende Liste nennt jeweils den Gegenstand gemeinsamen Interesses: Mathematik Physik Maschinenbau Nachrichtentechnik Sprachwissenschaft Psychologie, Physiologie Gesellschaftswissenschaft Wirtschaftswissenschaft Strukturen Prozesse Steuerung, Datenbanken und Graphik Daten Sprache Wahrnehmung Kommunikation Organisation KAPITEL 2. ELEMENTARE MODELLBILDUNG 16 Die Position einer Dame ist ein Wertepaar hx; yi. Um 8 Damen zu unterscheiden, führen für wir 8 Wertepaare hx1 y1i hx2 y2i hx8 y8i ; ; ; ; ; ; ein, abgekürzt: Kapitel 2 hxi yii i = 1 2 ; ; ; ; : : :; 8: Die Bedrohungen lassen sich so ausdrücken: Elementare Modellbildung a) Die Damen zu den Nummern i; j ,i 6= j, liegen in derselben Zeile: yi = y j . b) Sie liegen in derselben Spalte: xi = x j . Wenn eine Aufgabe mit dem Computer gelöst werden soll, so braucht man ein genaues Modell von allen Zusammenhängen, die für die Aufgabe von Bedeutung sind. Hierzu betrachten wir mathematische Hilfsmittel: Mengen, Funktionen, Relationen, Beweistechniken, Grundelemente von Berechnungen: Werte, Variable, Terme, sowie Modelle zur logischen Präzisierung von Sachverhalten: Aussagenlogik, Prädikatenlogik. Zur Veranschaulichung beginnen wir mit einem konkreten Problem als Beispiel. 2.1 Einführung Wir betrachten das 8-Damen-Problem: 8 Damen sind auf einem Spielbrett aus ” 8 8 Feldern so zu positionieren, daß keine eine andere bedroht.“ Alle Begriffe müssen nun exakt modelliert werden: Das Spielbrett wird durch seine Koordinaten x; y 2 f1; 2; 3; 4; 5; 6; 7; 8g modelliert: y: 8 7 6 5 4 3 2 1 x: 1 2 3 15 4 5 6 7 8 c) Sie liegen auf derselben diagonal verlaufenden Linie: jxi ; x j j = jyi ; y j j. Jetzt können wir eine exakte Formulierung des Problems angeben: Gesucht sind für i = 1; : : : ; 8 Wertepaare xi ; yi 2 f1; 2; : : : ; 8g, so daß für i 6= j stets gilt: xi 6= x j ; yi 6= y j ; jxi ; x j j 6= jyi ; y j j : Eine solche Festlegung heißt Spezifikation. In Anlehnung an die sogenannte ZNotation schreiben wir eine solche Spezifikation in der folgenden Form: 8-Damen-Problem xi ; yi : f1; 2; : : : ; 8g; i = 1; 2; : : :; 8 i 6= j =) xi 6= x j ; yi 6= y j ; jxi ; x j j 6= jyi ; y j j Man kann das Problem dadurch vereinfachen, daß man festlegt, die i-te Dame genau in die i-te Zeile zu stellen. Es gilt dann yi = i; i = 1; 2; 3; :::; 8: 8-Damen-Problem xi : f1; 2; : : : ; 8g; i = 1; 2; : : :; 8 i 6= j =) xi 6= x j ; jxi ; x j j 6= ji ; jj Eine Lösung hierfür kann durch ein Programm bestimmt werden. Dazu braucht man noch eine Lösungsidee. In diesem Fall kann man den Computer auch alle Möglichkeiten durchprobieren lassen. Eine heuristische Vorgehensweise liegt vor, wenn ähnliche Überlegungen zugrunde gelegt werden, die der Mensch als Problemlöser anwendet. Ein Programm lohnt sich aber eigentlich nur, wenn man es oft auf verschiedene Daten anwenden kann, d. h. wenn eine Klasse ähnlicher Probleme vorliegt. Aus dem 8-Damen-Problem gewinnen wir das n-Damen-Problem. n ist der Eingabeparameter. Die Spezifikation wird dann so geschrieben: 2.2. MENGEN 17 KAPITEL 2. ELEMENTARE MODELLBILDUNG 18 Eine ausreichende Darstellung wäre jetzt N-Damen-Problem (n) n : N4 xi : f1; 2; : : :; ng; i = 1; 2; : : :; n i 6= j =) xi 6= x j ; jxi ; x j j 6= ji ; jj Dabei bezeichnet N die Menge der natürlichen Zahlen. Die allgemeine Vorgehensweise zum Lösen von Problemen in der Praxis mit Hilfe des Computers ist in Abbildung 2.1 zu sehen. fh1 1i h2 1i h3 1i h4 1i h1 2i h2 2i h3 2i h1 5i h2 5ig ; Die wichtigsten mathematischen Hilfsmittel zur Modellbildung sind die Mengen und die Relationen, zu denen auch die Funktionen gehören. ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; Es genügt die Unterscheidung durch irgendwelche Merkmale vorzunehmen, z. B. fhx 1i hy 1i hm 1i hq 1i h100 2i h1000 2i h35 2i hy 5i h100 5ig ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; oder f1 1 1 1 2 2 2 5 5g ; Mathematische Hilfsmittel ; ; ; ; ; ; ; ; : Wir sagen: Elemente einer Menge besitzen Individualität. Beispiel 2.2.2 Weitere Beispiele für Mengen sind: 2.2 Mengen (a) Die Menge aller von einer Dame auf Position hx; yi bedrohten Felder eines n n - Brettes. In der naiven Mengenlehre wird unter einer Menge eine Gesamtheit von Objekten verstanden. Ein einzelnes Objekt heißt Element der Menge. (b) Die Menge aller Felder auf der Hauptdiagonalen eines n n - Brettes. Beispiel 2.2.1 Wir nehmen als Objekte die Zeichen ’A’,’B’,’C’ und die Zahlen 3,5,9,20. Die daraus gebildete Menge schreiben wir (c) Die Menge der Figuren eines Schachspiels. f0 A0 0 B0 0 C0 3 5 9 20g ; ; ; ; ; ; : Dabei spielt jedoch die Reihenfolge der Niederschrift keine Rolle: f3 9 0 B0 20 0 A0 5 0 C0g ; ; ; ; ; ; bezeichnet dieselbe Menge. Die Menge verändert sich auch dadurch nicht, daß Elemente mehrfach notiert werden: f3,3,9,3g bezeichnet dieselbe Menge wie f3,9g, f9,3g oder f9,9,3,9,9,3,3,9g. Wie modelliert man nun den Inhalt einer Geldbörse? Es seien vorhanden 4 1DM; 3 2DM; 2 5DM: Die Menge f1,1,1,1,2,2,2,5,5g bezeichnet dasselbe wie die Menge f1,2,5g. Man muß daher die Münzen gleichen Wertes individualisieren: h1 1i: Das erste 1 DM - Stück, h2 1i: Das zweite 1 DM - Stück, h3 1i: Das dritte 1 DM - Stück, ; ; ; usw. (d) Die Menge aller möglichen Züge bei einer bestimmten Stellung des Schachspiels. (e) Die Menge aller Primzahlen. Für einige wichtige Mengen gibt es feste Bezeichnungen: f g N =Menge der natürlichen Zahlen = 1; 2; 3; : : : . N0 =Menge der natürlichen Zahlen mit 0 = 0; 1; 2; 3; : : : . R =Menge der reellen Zahlen. I =Menge der abgeschlossenen Intervalle über R. Z=Menge der ganzen Zahlen. Q =Menge der rationalen Zahlen. C =Menge der komplexen Zahlen. f g B =ftrue, falseg = Menge der sogenannten Wahrheitswerte. Wir verwenden folgende Schreibweisen für Aussagen über Mengen: x 2 M: das Objekt x ist ein Element der Menge M. x 62 M: das Objekt x ist kein Element der Menge M. 2.2. MENGEN 19 M1 M2 : M1 ist eine echte Teilmenge von M2 , das heißt alle Elemente von M1 sind auch Elemente von M2 , aber M2 enthält mindestens ein Element, welches nicht Element von M1 ist. M1 M2 : Es gilt M1 M2 oder M1 = M2 . Ferner werden die folgenden Schreibweisen für Mengen verwendet: 1. Auflistung der Elemente, z. B.: f’a’,’e’,’i’,’o’,’u’g , f5 10 15 ; ; ; : : :; 95g, f1; 2; 4; 8; : : :g (falls klar ist, wie die Elemente fortgesetzt werden). KAPITEL 2. ELEMENTARE MODELLBILDUNG 20 nennt man ihn gesellig, sonst ungesellig. Die ungeselligen Einwohner der Stadt bilden einen Club. In dieser Geschichte steckt ein Widerspruch. Gehört der Einwohner, nach dem der Club der Ungeselligen benannt ist, selbst zu diesem Club oder nicht? Wenn ja, so wäre er gesellig, also könnte er nicht zum Club gehören. Wenn nein, so wäre er ungesellig und müßte doch dazu gehören. Die naive Modellierung hat also ihre logische Tücken. Dies gilt genauso für die moderne Mengenlehre, wie das folgende Paradoxon, die sog. Antinomie von Bertraud Russell zeigt: Bilde R 2. Angabe von Eigenschaften der Elemente, z. B.: M = = : fxjx 2 N x 5g; ; dies ist gleichwertig mit M = f1 2 3 4 5g ; ; ; ; : R2R ) R 62 R R 62 R ) R 2 R: Das Paradoxon der Clubs ist übrigens kein Mengenparadoxon, sondern eines der Gesamtmodellierung. Für endliche Mengen M definieren wir jM j=card(M) durch j0/ j = 0 und jfx1; : : : ; xngj (alle xi verschieden)=n. M heißt unendlich, wenn jM j nicht endlich ist. M heißt abzählbar unendlich, wenn man eine Reihenfolge der Elemente von M in der Form M Spätestens hier wird klar, daß es sinnvoll ist, von der leeren Menge zu reden. Z. B. ist fxjx 2 N und x 5 und x 7g die leere Menge, da es kein x 2 N gibt mit x 5 und x 7. Im obigen Beispiel (d) M : sowie fxjE (x)g Dabei beschreibt E (x) eine Eigenschaft von x, z. B.: M fMjM ist Menge und M 62 Mg = Hierzu kann man schließen = ergibt sich in der sogenannten Pattstellung auch die leere Menge. Die leere Menge wird durch 0/ beschrieben, aber auch durch fg (leere Aufzählung). Die Problematik einer naiven Modellierung zeigt das folgende Beispiel, das von Raymond M. Smullyan stammt: Beispiel 2.2.3 Die Einwohner einer Stadt gehören vielen Clubs an, wobei jeder auch mehreren Clubs angehören kann. Jeder Club ist nach einem Einwohner benannt und es gibt zu jedem Einwohner genau einen Club, der nach ihm benannt ist. Ein Einwohner braucht aber nicht dem nach ihm benannten Club anzugehören. Tut er dies, so = fx1 x2 x3 g ; ; ;::: angeben kann. M ist dann unendlich. Beispiel 2.2.4 1. N ist abzählbar unendlich, denn N = f1 2 3 g ; ; ;::: : 2. N0 ist abzählbar unendlich, denn N0 = fx1 x2 x3 g mit xi = i ; 1 N0 = f0 1 2 g ; ; ;::: d. h. ; ; ;::: : ; 2.2. MENGEN 21 KAPITEL 2. ELEMENTARE MODELLBILDUNG 22 Dann wird noch jeweils nz fortgelassen, wenn die dadurch dargestellte Zahl schon vorkam. Dies ergibt also folgenden Anfang der Aufzählung: 3. R ist unendlich, aber nicht abzählbar unendlich. Wir zeigen die letzte Eigenschaft: Dazu nehmen wir an, R sei doch abzählbar unendlich, R = 0; 1; fr1 r2 r3 g ; ; ;::: : Wir schreiben jedes Element ri in der Dezimalschreibweise r1 = : : :; r2 = : : :; 1 1 dk1; dk1;1; : : : ; d21; d11; d01:d; 1 ; d;2 ; : : : 2 2 dk2; dk2;1; : : : ; d22; d12; d02:d; 1 ; d;2 ; : : : = : : :; Wir verwenden die üblichen Operationen auf Mengen: Es gilt r 2 R. Dies beweist man mit Hilfe der genauen Definition von R. Nun müßte r in der Reihe r1 ; r2; : : : vorkommen, etwa r = r j . Dann wäre = : : :; j j j j j d2 ; d1 ; d0 ; d;1; d;2; : : : = r = : : : ; 0; 0; 0; e;1; e;2; : : : 2 0 3 1 1 2 1 3 4 1 4 -2 ::: ::: . % . % ; 12 ; 13 ; 14 #% . % . -1 -1 2 ::: !0 0! #% . % . 2 ::: 2 2 2 3 2 4 ::: . % . % -2 ; 22 ; 23 ; 24 ::: = = B [ A; (A [ B) [ C; A: Potenzmenge: P(A) = fBjB Ag : Statt P(A) schreibt man auch 2A . Ist A endlich und jAj = n, so ist auch P(A) endlich und es gilt 5. Q ist abzählbar unendlich. Eine Abzählfolge ergibt sich wie folgt: Jedes q 2 Q ist durch q = nz ; z 2 Z; n 2 Z, darstellbar. Darauf gründen wir folgende Reihenfolge: 1 0 = A sei eine Menge. Die Potenzmenge zu A ist definiert als j 1 Differenz A ; B von zwei Mengen A und B. Aus einfachen Mengen kann man komplexe Mengen aufbauen: k für alle k gewählt. Dies ist Also d; j = e; j . Es war aber gerade e;k 6= d; k ein Widerspruch. Also war die Annahme, daß R abzählbar unendlich ist, falsch. Das bedeutet, R ist eben nicht abzählbar unendlich. Nenner Zähler 0 Durchschnitt A \ B von zwei Mengen A und B. A[B A [ (B [ C) A[A 0; : : :; 0; e;1; e;2; : : : k für alle k. (als Dezimalbruch r = 0:e;1e;2 e;3 : : :) mit e;k 6= d; k rj Vereinigung A [ B von zwei Mengen A und B. Es gelten die bekannten Rechenregeln für diese Operationen, z. B.: 4. Dazu bilden wir r 1 1 1 1 1 ; ;1; 2; ; ; ; ; ; ; ;2; : : : 2 2 3 4 3 jP(A)j = 2n: Das Cartesische Produkt von Mengen werden wir im nächsten Abschnitt kennenlernen. Im Rechner werden Mengen normalerweise in einer bestimmten Reihenfolge, d. h. als Liste abgelegt. Wir betrachten dazu verschiedene Möglichkeiten. Für jede ist zu überlegen, welcher Aufwand bei Operation auf den Mengen entsteht. Als Operationen ziehen wir in Betracht 1. Test auf Enthaltensein eines Elementes: x 2 M, 2. Hinzufügen eines Elementes: M [fxg und 2.3. RELATIONEN UND FUNKTIONEN 23 3. Entfernen eines Elementes: M ;fxg. 2. (S1 S2 ) S3 ist ein cartesisches Produkt über den beiden Mengen S1 S2 und S3 ; es ist hier also zwischen S1 S2 S3 und S1 (S2 S3 ) zu unterscheiden. a) Ablage als Liste mit möglicher Wiederholung von Elementen: 1. x 2 M: Durchsuchen gegebenenfalls der ganzen Liste nach dem ersten Auftreten des Elementes x erforderlich. 2. M [fxg: Schlichtes Anfügen an die Liste. 3. M ; fxg: Durchsuchen der ganzen Liste auf mehrfaches Vorkommen und Entfernen jedes Elements x. b) Ablage als Liste ohne Wiederholung von Elementen 1. x 2 M?: Durchsuchen gegebenenfalls der ganzen Liste nach dem Auftreten des Elements x erforderlich. Die Gesamtlänge der Liste ist jedoch i.a. kürzer als in der Notation von Teil a). 2. M [ fxg: Erst suchen, ob x schon vorkommt, dann gegebenenfalls an die Liste anfügen. 3. M ;fxg: Durchsuchen bis zum ersten Vorkommen von x, dann wird x entfernt. Später werden wir noch bessere Möglichkeiten der Speicherung kennenlernen, bei denen eine mögliche Ordnung auf den Elementen ausgenutzt wird. 2.3 Relationen und Funktionen 2.3.1 Cartesisches Produkt fhs1 s2 ; ; : : :; Wenn die Mengen Sk alle gleich sind, S1 = S2 = : : : = Sk = S, dann heißt S1 S2 Sk das k-fache cartesische Produkt (von S), in Zeichen Sk . Im Falle k = 1 degeneriert das cartesische Produkt: S1 = S. Gelegentlich wird noch der spezielle Fall des nullstelligen cartesischen Produkts (k = 0) gebraucht: S0 enthalte nur ein Element, das leere Tupel ε (oder:hi); dieses enthält keine Komponenten. ::: Beispiel 2.3.2 a) Felder eines Schachbrettes: fA,. . . ,Hgf1,. . . ,8g. b) Sei Σ ein endliches Alphabet. Die Menge Σi heißt auch Menge der Worte der Länge i. Für die Elemente von Σi ist die kürzere Schreibweise s1 s2 : : : sk anstelle von hs1 ; s2 ; : : : ; sk i üblich. S Anmerkung: Die Menge aller Worte über Σ ist fΣi ji 2 N0 g. Diese enthält auch das leere Wort ε. Für diese Menge wird kurz Σ geschrieben. Spezielle Alphabete sind: B=Menge aller Großbuchstaben (einschl. dem Leerzeichen), Menge Z der Ziffernzeichen. c) Sei VNAME=B20 ,FNAME=B25 ,PLZ=Z5 . Die Tupel des cartesischen Produkts FNAME VNAME PLZ enthalten drei Komponenten, die der Reihe nach für Familienname, Vorname und Postleitzahl stehen. 2.3.2 Relationen Definition 2.3.1 (Cartesisches Produkt) Sei k 2 N. Cartesisches Produkt von S1; S2; : : : ; Sk: S1 S2 : : : Sk := KAPITEL 2. ELEMENTARE MODELLBILDUNG 24 sk ijsi 2 Si ; i = 1; : : : ; kg ; ; : : : ; sk i heißt k-Tupel über S1 ; S2 ; : : : ; Sk . Das cartesische Produkt über S1 ; S2; : : : ; Sk ist also die Menge aller k-Tupel über diesen Mengen. hs1 s2 Beachte: 1. Die Reihenfolge, in der die k Mengen notiert sind, ist relevant. D. h., werden z. B. S1 und S2 vertauscht, dann ergibt sich ein anderes cartesisches Produkt. Eine Teilmenge R von S1 S2 : : : Sk heißt Relation über S1 S2 : : : Sk. Im Falle k = 2 spricht man von einer binären Relation (oder Korrespondenz von S1 nach S2 ). Für R S1 S2 heißt S1 der Definitionsbereich (Urbildbereich, domain, kurz: dom(R) ), und S2 der Bildbereich (Wertebereich, image, range, kurz im(R) ). Für ha; bi 2 R wird auch häufig aRb geschrieben. Wenn R Relation ist und S1 = S2 = : : : = Sk = S, dann heißt R k-näre Relation auf S. Beispiel 2.3.3 Relationen sind: a) Identische Relation auf einer Menge S (Diagonale von S): idS = fha; aija 2 Sg. 2.3. RELATIONEN UND FUNKTIONEN 25 b) Leere Relation zwischen S1 und S2 : 0/ S1 S2 c) Verschiedenheitsrelation auf S: idS = fha; bija; b 2 S; a 6= bg d) Teilmenge der Tupel der Form FNAMEVNAMEPLZ der hier anwesenden Personen Sei S eine Menge, und R eine binäre Relation über S. Dann ist R;1 fha bijhb ai 2 Rg die zu R inverse Relation. ; d) S=fmo,di,mi,do,fr,sa,sog stehe für die Tage der Woche. R beschreibe die Abfolge der Tage: R=f(mo,di),(di,mi),(mi,do),(do,fr), (fr,sa),(sa,so),(so,mo)g. Sei nun R ergänzt um alle Paare ha; bi für die gilt: es existiert ein c; ha; ci 2 R; hc; bi 2 R. Die so erhaltene Relation R ist keine partielle Ordnung, da sie nicht asymmetrisch ist: z. B. sind die Paare (fr,so) und (so,fr) darin enthalten. Eine partiell geordnete Menge (S; R) heißt total geordnet, falls die partielle Ordnung R folgende Eigenschaften hat: für alle a; b 2 S gilt: ha; bi 2 R oder hb; ai 2 R. Einige grundlegende Begriffe bei binären Relationen: KAPITEL 2. ELEMENTARE MODELLBILDUNG 26 = ; 2.3.4 Operationen auf Relationen R heißt symmetrisch, wenn R;1 = R gilt, d. h. aus ha; bi 2 R folgt hb; ai 2 R. R heißt antisymmetrisch, falls R \ R;1 hb; ai 2 R folgt a = b. R heißt reflexiv, falls idS R, d. h. ha; ai 2 R für alle a 2 S. R heißt irreflexiv, falls idS \ R = 0, d. h. ha; ai 2 = R für alle a 2 S. idS gilt, d. h. aus ha bi 2 R und ; R heißt transitiv, wenn für alle a; b; c 2 S gilt: Aus ha; bi 2 R und hb; ci 2 R folgt ha; ci 2 R. 2.3.3 Ordnungsrelationen Eine binäre Relation R über S heißt (partielle) Ordnung (über S) falls R reflexiv, antisymmetrisch und transitiv ist. Das Paar (S; R) heißt dann auch partiell geordnete Menge, oder poset. Beispiel 2.3.4 Partiell geordnete Mengen sind: a) S = N, und R = fhi; jiji jg. b) Sei P(S) die Potenzmenge einer Menge S. Die Relation über P(S) ist reflexiv, antisymmetrisch und transitiv. Dagegen ist die Relation irreflexiv, antisymmetrisch und transitiv. c) Menge I der Intervalle über R, zusammen mit der partiellen Ordnung hI:= f< i1; i2iji1 = [a1; b1]; i2 = [a2; b2], und b1 < a2g. Sei R eine Relation über S1; S2; : : : ; Sk. Für i 2 f1; : : : ; kg ist die i-te Projektion pri : R ! Si definiert durch: pri (hs1 ; : : : ; sk i) = si . Seien R1 und R2 binäre Relationen über Mengen S1 und S2 . Dann sind auch die Vereinigung R1 [ R2 , der Durchschnitt R1 \ R2 , und die Differenz R1 ; R2 Relationen über S1 und S2 . Seien nun Relationen R1 S1 S2 und R2 S2 S3 gegeben. Das Relationenprodukt R1 R2 ist definiert durch R1 R2 = fha; cij9b 2 S2 mit ha; bi 2 R1 und hb; ci 2 R2g Ist spezieller R S S, dann werden mehrfache Relationenprodukte rekursiv definiert: R0 R1 = Rn+1 R+ = R = = = idS ; R; R Rn ; n 2 N; [ R1 [ R2 [ : : : = fRi ji 2 Ng ist die transitive Hülle von R, und R0 [ R+ ist die reflexive, transitive Hülle von R: 2.3.5 Funktionen Eine binäre Relation R über A und B heißt Funktion (von A nach B) falls aus ha; b1i; ha; b2i 2 R die Gleichheit b1 = b2 folgt. Eine Relation mit dieser Eigenschaft heißt auch rechtseindeutig. Üblicherweise wird die Funktionenschreibweise verwendet: fR : A ! B. Anstelle von ha; bi 2 R schreiben wir fR (a) = b oder fR : a 7! b. Für Funktionen gilt R;1 R idB . Wenn idA R R;1 gilt, so heißt R (bzw fR ) total, andernfalls partiell. Für eine totale Funktion fR : A ! B gilt somit dom( fR) = A. R (bzw fR ) heißt surjektiv (oder auf B) wenn R;1 R = idB gilt. 2.3. RELATIONEN UND FUNKTIONEN 27 KAPITEL 2. ELEMENTARE MODELLBILDUNG 28 R (bzw fR ) heißt injektiv (oder 1-1) wenn R R;1 = idA (äquivalent dazu: aus fR (a1 ) = fR (a2 ) folgt a1 = a2 ). R (bzw fR ) heißt bijektiv wenn R injektiv und surjektiv ist. Eine bijektive Funktion von A nach A selbst wird auch Permutation von A genannt. 2.3.6 Operationen auf Funktionen durch ( p1 Dann ist f g: A ! B definiert durch Dann ist g f : A ! C definiert durch (f f : A ! B; g)(a) = f (a) g(a) benutzt man außer der Funktionsschreibweise f (a; b) auch Operatorschreibweisen wie: a f b : Infixschreibweise, z. B. 3j + j7, f ab : Präfixschreibweise, z. B. +j3j7 oder ab f : Postfixschreibweise, z. B. 3j7j+. ! f (a) g(a)) ! x1 ; ; p2 ! x2; : : : ; pn ! xn)(a) = x1 , falls p1(a) =TRUE, x2 , falls p1(a) =FALSE und p2(a) =TRUE, = x3 , falls p1(a) = p2(a) =FALSE und p3(a) =TRUE, .. . 8 > < > : Dabei kürzen wir nur noch den Fall pn =TRUE, ( p1 ! x1 , falls a 2dom(g) , falls a 2 = dom(g); a 2dom( f ): f:AB ! C , falls p(a) = TRUE , falls p(a) = FALSE. und allgemeiner ( p1 f (a) heißen auch n-stellige Funktionen. Dabei ist auch der Sonderfall der 0-stelligen Funktionen f : ! B erfaßt. Statt f (ha1 ; : : : ; ani) schreibt man f (a1 ; : : : ; an). Für zweistellige Funktionen g: A ! Bundp: A ! B Wir schreiben hierfür auch ( p(a) g(a) f : A1 A2 : : : An ! B Dann ist die Funktion ( p ! f ; g) definiert durch ; = Funktionen der Form Seien f , g und p Funktionen gemäß !f g)(a) g( f (a)): Verzweigung: (p Überschreibung: f : A ! Bundg: A ! B: f : A ! Bundg: B ! C: = pn;1 ! xn;1 ; xn) Seien f und g partielle Funktionen gemäß Seien f und g Funktionen gemäß f )(a) ; : : :; ab. Hintereinanderausführung: (g ! x1 ::: , TRUE ! xn ) 2.3.7 Darstellung von Funktionen Wertetabellen: Eine Funktion f : A ! B mit endlich vielen Wertepaaren ha; f (a)i kann in einer Tabelle dargestellt werden, z. B. a 1 2 3 4 f (a) ’xyz’ ’xx’ ’yzy’ ’zzzz’ 2.3. RELATIONEN UND FUNKTIONEN 29 Berechnungsvorschrift Hierbei wird angegeben, wie aus dem Argument a 2 A das Bild f (a) errechnet werden soll. Dies kann durch eine Formel geschehen, z. B. p f (a) = a2 + 7a (1 + 2a)2 Allgemeiner ist die Beschreibung mit Hilfe eines Algorithmus, d. h. einer programmierbaren Berechnungsvorschrift. Beispiel 2.3.5 Euklidischer Algorithmus zur Bestimmung des größten gemeinsamen Teilers: ggT: N N ! N : Für x; y 2 N wird ggT(x; y) wie folgt bestimmt: while x<>y do begin if x > y then x := x-y else y := y-x; ggt(x;y) := x; end. Dies läßt sich auch als eine rekursive Funktionsdefinition schreiben. Wir tun dies in der Form einer Spezifikation in Z-Notation: ggT(x,y) x; y : N x=y ggT(x,y)= x < y x>y !x ! y;x ! x;y Charakterisierung durch Eigenschaften Man kann eine Funktion auch hinreichend beschreiben, ohne eine Berechnungsvorschrift dazu anzugeben. Das folgende Beispiel demonstriert dies für die Funktion ggT: 30 KAPITEL 2. ELEMENTARE MODELLBILDUNG ggT(x,y) x; y : N ggT(x,y)=x ggT(x+y,y)=ggT(x,y) ggT(x,x+y)=ggT(x,y) Es gibt Programmiersprachen, in denen man einige solcher Definitionen auch als eine Art Berechnungsvorschrift hinschreiben kann. Der Übersetzer zur Programmiersprache kann dann automatisch eine Berechnungsvorschrift ableiten. 2.3. RELATIONEN UND FUNKTIONEN 31 KAPITEL 2. ELEMENTARE MODELLBILDUNG 32 2.3.8 Äquivalenzrelationen Eine binäre Relation R über S heißt Äquivalenzrelation (über S) falls R reflexiv, symmetrisch und transitiv ist, d. h. idS R; reales Problem R;1 = R; R R R: Modellierung der Problemstruktur Für jedes a 2 S definieren wir eine Teilmenge aR von S, Erkundung des Loesungsweges fuer die ganze Problemklasse fb 2 Sjha bi 2 Rg aR heißt R-Klasse von a. Statt ha bi 2 R schreibt man oft a b (mod R). Es gilt für alle a 2 S: a 2 aR a b (mod R) genau dann wenn aR = bR aR Modell des Problems = ; : ; ; : Speziell bilden die R-Klassen eine Partition von S, d. h. sie definieren eine Zerlegung von S in paarweise disjunkte Teilmengen (Klassen der Partition). Loesungsverfahren im Modell Beispiel 2.3.6 Programmierung des Loesungsverfahrens k 2 N; für alle m n 2 N0 gelte hm ni 2 R genau dann wenn es ein i 2 N gibt, so daß jm ; nj = ki . Die R-Klassen sind: ; Programm Anwendung des Programms jR = ; f j k + j 2k + j g für j = 0 1 ; ; ;::: ; ; : : :; k;1 (Restklassen modulo k). Loesung im Modell Interpretation reale Loesung 2.3.9 Darstellung von Relationen Abbildung 2.1: Lösen von Problemen mit dem Computer Funktion f : A ! B; R = f f ;1 . Es gilt R ist Äquivalenzrelation auf A. Tabellendarstellung Endliche Relationen lassen sich in Tabellen darstellen, z. B. Person Alter Hans 19 Anna 18 Fritz 21 2.3. RELATIONEN UND FUNKTIONEN 33 Matrixdarstellung Die Mengen A und B seien endlich, jAj = n, jBj = m. Jede Relation R A B läßt sich dann in einem rechteckigen Schema mit n Zeilen, je eine für jedes Element aus A, und m Spalten, je eine für jedes Element aus B, darstellen. Man zeichnet dann ein bestimmtes Zeichen (1 oder +) für das Bestehen der Relation und ein anderes (0 oder ;) für das Nichtbestehen der Relation. Beispiel 2.3.7 ajb bedeute: a ist Teiler von b, a 2 f1; : : : ; 6g, b 2 f1; : : : ; 12g j 1 1 0 0 0 0 0 1 2 3 4 5 6 2 1 1 0 0 0 0 3 1 0 1 0 0 0 4 1 1 0 1 0 0 5 1 0 0 0 1 0 6 1 1 1 0 0 1 7 1 0 0 0 0 0 8 1 1 0 1 0 0 9 10 11 12 1 1 1 1 0 1 0 1 1 0 0 1 0 0 0 1 0 1 0 0 0 0 0 1 Berechnungsvorschrift Genauso wie eine Funktion kann auch eine Relation berechnet werden, z. B. durch einen Algorithmus. Dies wird insbesondere klar durch die Tatsache, daß eine Relation R A B durch eine totale Funktion f:AB ! B dargestellt werden kann: für R gewinnt man f durch die Festlegung f (a; b) = ( ha bi 2 R ! TRUE,FALSE) ; : Umgekehrt wird aus f die Relation R durch ha bi 2 R $ f (a b) = TRUE ; 2.4 Beweistechniken Die Richtigkeit einer mathematischen Aussage kann sich auf zwei Arten ergeben. Sie kann durch Festlegung gegeben sein. Beispiel 2.4.1 Sei M eine Menge und x 2 M. Hier brauchen wir x 2 M nicht weiter zu beweisen. Ist eine Aussage nicht durch unmittelbare Festlegung wahr, so muß sie bewiesen werden, um als wahr zu gelten. Ein direkter Beweis hat die folgende Form: Es gibt Aussagen A1 ; : : : ; An , die durch Festlegung gelten. Durch logisches Schließen wird aus Aussagen A1 ; : : : ; Ak ; k n, jeweils eine neue Aussage Ak+1 gewonnen, solange bis die zu beweisende Aussage Ai erreicht ist. 2.4.1 Widerspruchsbeweis Oft verwendet man keinen direkten Beweis, sondern einen Widerspruchsbeweis. Dieser beruht darauf, daß nicht zugleich eine Aussage und ihr Gegenteil gelten können. Soll man nun aus A1 ; : : : ; An die Aussage B herleiten, so bildet man das Gegenteil B von B und wendet logische Schlußverfahren auf A1 ; : : : ; An ; B an. Sobald eine Aussage zusammen mit ihrem Gegenteil auftritt, hat man B auf der Grundlage von A1 ; : : : ; An bewiesen. Beispiel 2.4.2 Es gibt unendlich viele Primzahlen. Das Gegenteil ist: Es gibt nur endlich viele Primzahlen. Diese seien p1; p2; : : : ; pn. Bilde z = p1 p2 pn + 1. Nach den Regeln über die Teilbarkeit ist z durch keine der Zahlen p1; : : : ; pn teilbar. Also ist z entweder eine Primzahl, oder durch eine Primzahl p teilbar, die zu p1 ; : : : ; pn verschieden ist. Damit haben wir das logische Gegenteil der Aussage p1 ; : : : ; pn ” sind alle Primzahlen“ hergeleitet. Also ist die Annahme falsch und die Aussage Es gibt unendlich viele Primzahlen“ bewiesen. ” ; bestimmt. KAPITEL 2. ELEMENTARE MODELLBILDUNG 34 Charakterisierung durch Eigenschaften Eine indirekte Bestimmung einer Relation ist ebenfalls wie bei Funktionen möglich. 2.4.2 Beweis nach dem Prinzip der vollständigen Induktion Der Induktionsbeweis, genauer Beweis durch vollständige Induktion, ist eine spezielle Methode des logischen Schließens. Man kann auch Methoden des logischen Schließens als Aussagen formulieren und beweisen. Als Beispiel verwenden wir eine Variante der vollständigen Induktion. Betrachte eine Folge von Aussagen A(1); A(2); : : :: 2.5. WERTE, VARIABLE UND TERME 35 Sei A(n) eine Aussage zu n 2 N. Es gelte A(1) und daß aus A(i) für alle i n stets A(n + 1) folgt, n 2 N. Wir können dazu eine Folge von Aussagen E (1); E (2); : : : angeben, für die gilt: Sei E (n) eine Aussage zu n 2 N. Es gelte E (1) und aus E (n) folgt stets E (n + 1), n 2 N, n > 1. Dann gilt E (n) für alle n 2 N. Wir setzen E (n) = Es gilt A(i) für alle i n“ : ” Dann zeigen wir, daß die Schlußweise der Behauptung immer richtig ist: E (1)ist erfüllt. Es gelte E (n), also A(i) für alle i n. Nach Voraussetzung gilt dann A(n + 1) und folglich auch E (n + 1). Das Prinzip der vollständigen Induktion besagt die Gültigkeit von A(i) für alle i 2 N. Dann ist auch E (i) für alle i 2 N richtig. 2.5 Werte, Variable und Terme 2.5.1 Werte Die Elemente von Mengen, die wir zur Modellierung benutzen, nennen wir Werte. Häufig vorkommende Werte sind Aussagenwerte oder boolesche Werte: TRUE, FALSE, natürliche Zahlen bzw. Zahlen aus N0 , ganze Zahlen, reelle Zahlen, rationale Zahlen, komplexe Zahlen, Zeichen eines Alphabets und Worte über Alphabeten. Auch Elemente komplizierter Mengen treten als Werte auf: Paare, n-Tupel, Mengen selbst, Funktionen, Relationen. KAPITEL 2. ELEMENTARE MODELLBILDUNG 36 2.5.2 Variable Eine Variable ist charakterisiert durch einem Namen x, das ist ein Element aus einer Menge von Symbolen, meist ein Wort über einem Alphabet, einem Wertevorrat Y, das ist eine Menge und einer veränderlichen Zuordnung v: x 7! y mit y 2 Y , dabei bedeutet veränderlich, daß während der Verwendung der Variablen verschiedene Zuordnungen x 7! y und auch das Nichtbestehen einer solchen Zuordnung ( undefi” nierte Variable“) in Betracht kommen. Die Festlegung einer Variablen bezüglich ihres Wertevorrats schreiben wir in der Form [d. h. x:Y für alle Zuordnungen v gilt v(x) 2 Y ] oder, falls M eine Obermenge von Y ist (Y M), x:M p(x) für den Fall, daß Y = fy 2 M j p(y)g gilt. Eine solche Festlegung heißt Deklaration der Variablen. Die Festlegung eines Wertes heißt Zuweisung. Sie wird meist in der Form x := y notiert. Danach gilt x 7! y. Diese Schreibweise setzt die Vereinbarung einer Funktion voraus, die die Variablen auf ihre Werte abbildet: Sei N die Menge der Variablennamen und W = [ x2N;x:Y Y: Eine Variablenbelegung ist eine partielle Funktion v: N ! W mit v(x) 2 Y für x : Y : Deklarationen in Programmiersprachen können explizit und implizit sein. Bei der impliziten Deklaration in der Sprache APL wird der Wertebereich aus dem Kontext bei der Benutzung entnommen. Beispiel: X ’A’ (Zuweisung des Zeichens ’A’, zugleich implizite Deklaration X : character) 2.5. WERTE, VARIABLE UND TERME 37 Die Sprache Fortran führt implizite Deklarationen auf der Grundlage von Standards ein z. B. die Verwendung von sofern nichts anderes explizit vereinbart ist. Die Verwendung von Werten erfordert Methoden für ihre Beschreibung und Konstruktion. Wir unterscheiden: Wertebeschreibungen durch sogenannte Konstanten, z. B. 3.14159 = π stellvertretend für eine solche Konstante, Werteberechnungen durch sogenannte Terme z. B. (a + 3b)=17:2 2.5.3 Terme Terme sind formale Ausdrücke, in denen Konstante, Variable und Funktionen vorkommen können, und die die Berechnung von Werten über null oder mehrere Stufen hinweg beschreiben: / .& + a .& 3 Stufe 3 17,2 * .& ; x) 3 ein arithmetischer Term. Beweis: a; c; 99; x und 3 sind arithmetische Terme, (a + c) und (99 ; x) sind arithmetische Terme, (a + c) (99 ; x) ist ein arithmetischer Term; (a + c)(99 ; x) ist damit auch ein arithmetischer Term. 3 Terme werden zunächst als Zeichenreihen oder Strings aufgefaßt. Das ist möglich, wenn man die Konstanten als Beschreibungen von Werten durch Strings auffaßt. Die Struktur von Strings kann anschaulich durch Syntaxdiagramme dargestellt werden. ) ) ) Beispiel 2.5.3 m - bm - cm Variable: - a Stufe 2 Stufe 1 b Beispiel 2.5.2 Sei K=f0,1,: : :,99g und V=fa,b,: : :,zg. Dann ist (a + c) (99 i, j, k für Integer und von x, y, z für Real, KAPITEL 2. ELEMENTARE MODELLBILDUNG 38 .. . - z Stufe 0 m Die folgende exakte Definition beschreibt arithmetische Terme mittels der Funktionen für Addition, Subtraktion, Multiplikation und Division in Operatorschreibweise: Definition 2.5.1 (arithmetischer Term) Sei K 6= 0/ eine Menge von Konstanten und V / K \ V = 0. 6= 0/ eine Menge von Variablen, 1. Eine Konstante k 2 K ist ein arithmetischer Term, die einen Wert bezeichnet (z. B. π : Wert 3:1415 : : :, 3“: Wert 3) ” 2. Eine Variable v 2 V ist ein arithmetischer Term. 3. Sind S und T arithmetische Terme, so auch (S + T ), (S ; T ), (S T ), S=T . Hierdurch wird immer eine unendliche Menge von Termen definiert. 6 .. . - 99 m 6 Term: m- - ( m - 2m - 3m Konstante: -1 - Term - Konstante - Variable m ;m - m - m -+ - 6 6 6 6 - 6 6 - Term m - ) 6 2.6. AUSSAGENLOGIK 39 Dabei unterscheiden wir Boolesche Funktionen sind totale Funktionen f : Bn ! B; n 2 N: elementare Diagramme: Diese enthalten nur Bestandteile in Stringform. Diagramme mit Referenzen: Diese enthalten Stringbestandteile in der Form von Namen, die auf andere Syntaxdiagramme bzw. auf sich selbst verweisen. Letzteres führt auf KAPITEL 2. ELEMENTARE MODELLBILDUNG 40 Diagramme mit Rekursion. Die Auswertung von Termen wird durch eine Funktion evalv : T !W beschrieben, dabei ist v eine Variablenbelegung, T die Menge der Terme und W die Menge aller in Frage kommenden Werte. Eine solche Evaluierungsfunktion ist meistens keine totale Funktion, da Terme wie 1=0 vorkommen können. Die Evaluierungsfunktion wird rekursiv definiert entsprechend dem Aufbau der Terme. Für die vorhin definierten arithmetischen Ausdrücke ergibt sich folgende Definition: Definition 2.5.4 (evalv(t )) Sei val(k) der für k 2 K dargestellte Wert. Dann sei evalv (t ) = ; Beispiel 2.6.1 Beispiele für solche Aussagen sind: Im Garten liegt ein Schatz. Auf dem Mond fliegen Elefanten. Französische Weine schmecken erdig. Gegenbeispiele sind: Der Brocken im Winter. Der erdige Geschmack französischer Weine. Informationstechnische Schaltungen realisieren boolesche Funktionen auf technische Weise. 2 K ! val(t ) t 2 V ! v(t ) t = t1 + t2 ! eval(t1) + eval(t2) t = t1 ; t2 ! eval(t1) ; eval(t2) t = t1 t2 ! eval(t1) eval(t2 ) t1 eval(t1) ) t= ! t eval(t ) (t Was Aussagen über Sachverhalte sind, können wir nur anschaulich an Hand von Beispielen erklären. Sie beziehen sich auf irgendeine Realität“, deren physikali” sche Wirklichkeit uns nicht interessiert. Sie können entweder wahr oder falsch sein, jedoch nicht gleichzeitig ( Prinzip vom ausgeschlossenen Widerspruch“) ” und müssen entweder wahr oder falsch sein ( Prinzip vom ausgeschlossenen Drit” ten“). ; ; ; ; 2.6.1 Boolesche Funktionen der Stelligkeit 0,1,2 2 Nullstellige boolesche Funktionen sind TRUE :! B mit Wert True FALSE :! B mit Wert False : 2 2.6 Aussagenlogik Diese Funktionen benötigen kein Argument. In diesem Abschnitt geht es um die gemeinsame logische Struktur von booleschen Funktionen, Aussagen über Sachverhalte informationstechnischen Schaltungen. Für einstellige boolesche Funktionen f : Möglichkeiten. 1. die Identität: x ! x; x2B B!B existieren genau vier 2.6. AUSSAGENLOGIK 41 KAPITEL 2. ELEMENTARE MODELLBILDUNG 42 2. die Negation: x ! xbzw.:x; dabei gilt: (c) Aus Falschem folgt Wahres: Das ist wahr (d) Aus Falschem folgt Falsches: Das ist wahr x2B x = :x FALSE TRUE x TRUE FALSE Die Fälle 3c und 3d sind etwas überraschend. Daher betrachten wir zwei Beispiele: zu 3c: Aus 4 = 5 folgt 3 = 3: 3. die Konstante TRUE: x ! TRUE ; x 2 B; 4=5 4. die Konstante FALSE: x ! FALSE ; 2. Disjunktion (OR): Symbol: _ 3. Implikation: Symbole: !; ); : zu 3d: Aus 4 = 5 folgt Ich bin der Papst“: ” x 2 B: 4=5 Es gibt genau 16 zweistellige boolesche Funktionen. Hierzu gehören die folgenden: 1. Konjunktion (AND): Symbol: ^ ) 40 = 50 ) 0 = 0 ) 0+3 = 0+3 ) 3 = 3 Wertetabelle: Wertetabelle: Wertetabelle: Wir interpretieren die Funktion wie folgt: (a) Aus Wahrem folgt Wahres: Das ist wahr (b) Aus Wahrem folgt Falsches: Das ist falsch x y x^y T T T T F F F T F F F F ) ) ) ) 5 = 4 ) 5;3 = 4;3 ) 2 = 1 2 = 1 ^ Ich und der Papst sind 2 Ich und der Papst sind eins Ich bin der Papst. Wir beobachten ferner: Wahres kann aus Wahrem wie aus Falschem geschlossen werden. Dies liegt daran, daß man beim logischen Schließen stets Wahres neu einbringen kann und andererseits Voraussetzungen ignorieren darf. Falsches kann nicht aus Wahrem, sondern nur aus Falschem geschlossen werden. Dies ist eine notwendige Eigenschaft des logischen Schließens. x y x_y T T T T F T F T T F F F 5. Äquivalenz: x y xy T T T T F F F T T F F T 6. Antivalenz (exklusives oder): Symbole: ,, Symbole: ,, 6 Wertetabelle: Wertetabelle: x y T T T F F T F F x,y T F F T x y x, 6 y T T F T F T F T T F F F 2.6. AUSSAGENLOGIK 43 7. Sheffer-Funktion (NAND): Symbole: ^,— Wertetabelle: x T T F F y x^y T F F T T T F T x T T F F y x_y T F F F T F F T KAPITEL 2. ELEMENTARE MODELLBILDUNG 44 Formeln können ausgewertet werden auf der Grundlage von Variablenbelegungen v:V ! B. Dabei gilt: evalv (t ) = 8. Peirce-Funktion (NOR): Symbole: _,# Wertetabelle: 2.6.2 Aussagenlogische Formeln Definition 2.6.2 (aussagenlogische Formel) Sei V eine Menge von Variablen. Aus V , B und den genannten Funktionen lassen sich Terme bilden. Diese heißen aussagenlogische Formeln. Die Variablen aus V werden vorzugsweise mit p, q und r bezeichnet. 1. x 2 V ist eine aussagenlogische Formel. 2. TRUE und FALSE sind aussagenlogische Formeln. 3. Sind F und G aussagenlogische Formeln, so auch F , und (F op G) mit op 2 f^; _; ); (; ,;, 6 ; ^; _g. Klammern können anschließend nach folgenden Regeln fortgelassen werden: Betrachtet man (F op G), jedoch nicht als Teil eines anderen Terms, so schreibt man F op G. Statt (F op G) schreibt man F op G. In F , G sowie in F , 6 G lasse ggf. äußere Klammern von F bzw. G weg, 6 “ noch ”)“ vorkommen. wenn in F bzw. in G weder ,“ noch , ” ” In F ) G läßt man ggf. äußere Klammern von F bzw. G weg, wenn in F bzw. G weder ,“ noch , 6 “ noch ”)“ vorkommen. ” ” (t 2 B ! t ; t 2 V ! v(t ); t = s ! evalv (s); t = (r op s) ! evalv (r) op evalv (s)) Dabei ist op wie oben definiert. Eine wichtige Rolle spielen Formeln, deren Auswertung bei jeder Belegung den Wahrheitswert TRUE ergeben. Solche Formeln heißen Tautologien. Die einfachste Art der Überprüfung, ob eine Formel eine Tautologie ist, erfolgt durch Auswertung der Wertetafeln. Man kann aber auch durch Umformung in Formeln mit gleichem Wahrheitswert Tautologien beweisen. Dazu ist folgende Technik nützlich: Sind F, G Formeln, so daß F , G eine (bereits bekannte) Tautologie ist, so kann man in einer Formel H, in der F als Teilformel vorkommt, F durch G ersetzen, ohne daß das Ergebnis der Auswertung dabei verändert wird. Hier sind einige wichtige Tautologien: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. p_ p p^ p p,p p^q , p_q p_q , p^q p ) q , p_q p)q,q) p ( p ^ ( p ) q)) ) q p ) p_q ( p ^ q) ^ r , p ^ (q ^ r) ( p _ q) _ r , p _ (q _ r) p_q , q_ p p^q , q^ p p ^ (q _ r) , ( p ^ q) _ ( p ^ r) p _ (q ^ r) , ( p _ q) ^ ( p _ r) p ) (q ) p) (( p ) q) ) p) ) p Satz vom ausgeschlossenen Dritten (tertium non datur) Satz vom Widerspruch Satz von der doppelten Verneinung Gesetz von de Morgan (I) Gesetz von de Morgan (II) Transformation der Implikation Kontraposition modus ponens disjunktive Abschwächung Assoziativgesetz (I) Assoziativgesetz (II) Kommutativgesetz (I) Kommutativgesetz (II) Distributivgesetz (I) Distributivgesetz (II) Implikative Abschwächung Peirce-Implikation Wir haben Tautologien so definiert, daß sie beim Belegen ihrer Variablen mit beliebigen Werten TRUE oder FALSE immer den Wert TRUE liefern. Wenn nun in 2.6. AUSSAGENLOGIK 45 einer Tautologie eine Variable p an jeder Stelle durch dieselbe Formel F ersetzt wird, so muß daher wieder eine Tautologie entstehen. Beispiel 2.6.3 Aus 16. ergibt sich mit der Ersetzung von q durch p ) q die Tautologie p ) (( p ) q) ) p): Definition 2.6.4 (Substitution) Eine totale Abbildung σ: F ! F heißt eine Substitution, wenn = TRUE und σ(FALSE) = = = σ(t ) (σ(t1 ) Op σ(t2 )) für Op = ; ; ; ; ; 7! f ( p1 ; : : : ; pi;1; T ; pi+1; : : : ; pn) f ( p1 ; : : : ; pi;1; F; pi+1; : : : ; pn)) 8i 1 i n ; = ( pi ^ f ( p1 ^ f ( p1 ; : : :; ; : : :; pi;1; T ; pi+1; : : : ; pn)) _ pi;1; F; pi+1 ; : : : ; pn))8i; 1 i n Man kann also das Argument pi aus f (: : :) herausziehen. Dies gilt für alle pi ; i = 1; 2; : : :; n. Unter Verwendung von ( pi , T ) = pi bzw. ( pi , F ) = pi ergibt sich allgemein der Satz von der disjunktiven Normalform (DNF): 2 f^ _ ) , , 6 ^ _g ; ( pi ( pi : (t 2 B ! t t=q !F t 2V !t t = s ! σFq (s) t = (r Op s) = Wir wollen dabei die Verzweigung der Form ( p 7! a; b) beseitigen. Es gilt: ( p 7! a; b) = ( p ^ a) _ ( p ^ b) für p; a; b 2 B (Beweis durch Vergleich der Wertetafeln). Also gilt: f ( p 1 ; : : : ; pn ) Sind p; q; r; : : : die betrachteten Variablen, so beschreibt σ gerade die Substitution bei der p durch σ( p), q durch σ(q), r durch σ(r) usw. ersetzt wird. Soll nur“ q ” durch eine Formel σ(q) ersetzt werden, so wird für die anderen Variablen σ( p) = p usw. gesetzt. Soll q durch F ersetzt werden, so bezeichnen wir die entsprechende Substitution mit σFq . Dann gilt σFq (t ) Im folgenden geht es um die Darstellung beliebiger boolescher Funktionen f : Bn ! B. Es seien p1; p2; : : : ; pn die n Argumente einer solchen Funktion. Wir betrachten die Abhängigkeit des Wertes f ( p1 ; p2; : : : ; pi; : : : ; pn) von einem einzelnen Argument pi . Da pi 2 B, hat pi den Wert T oder F. Also gilt: FALSE sowie für alle t ; t1; t2 2 F gilt: σ(t ) σ(t1 Op t2) 2.6.3 Konjunktive und disjunktive Normalform f ( p 1 ; : : : ; pn ) Wir wollen diesen Gedankengang formal betrachten. Dazu führen wir die Substitution als eine Abbildung auf der Menge F der Formeln ein. σ(TRUE ) KAPITEL 2. ELEMENTARE MODELLBILDUNG 46 ! (σFq (r) Op σFq (s)) Es gilt nun: Satz 2.6.5 Die Tautologien sind unter Substitution abgeschlossen, d. h. ist t 2 F eine Tautologie und σ eine Substitution, so ist auch σ(t) eine Tautologie. Satz 2.6.6 Jede boolesche Funktion f : Bn ! B ist darstellbar durch: _ xi 2 B f ( p1 ; p2; : : : ; pn) = ^ ( pk , xk ) ^ f (x1 x2 ; ; : : :; xn) k = 1; 2; : : : ; n i = 1; 2; : : :; n (Normalform bedeutet, daß von verschiedenen Darstellungsmöglichkeiten eine ganz bestimmte festgelegt wird.) Erläuterung der Formel: W : Bilde für alle möglichen n-Tupel (x1 ; x2 ; : : : ; xn) 2 Bn den angegebenen Term, und verknüpfe die Terme disjunktiv. V k=1;2;:::;n ( pk , xk ) : Bilde für jede Stelle k des jeweiligen n-Tupels den angegebenen Term, und verknüpfe diese Terme konjunktiv: ( p1 , x1 ) ^ ( p2 , x2 ) ^ : : : ^ ( pn , xn ) Die Umformung läßt sich anschaulicher so darstellen: B xi 2 i=1;2;:::;n (: : :) f ( p 1 ; : : : ; pn ) = = , T ) ^ f (T p2 pn)] _ , F ) ^ f (F p2 pn)] [( p1 , T ) ^ ( p2 , T ) ^ f (T T p3 [( p1 , T ) ^ ( p2 , F ) ^ f (T F p3 [( p1 ; ; : : :; [( p1 ; ; : : :; ; ; ; : : :; ; ; ; : : :; pn)] _ pn)] _ 2.6. AUSSAGENLOGIK = Beweis Bereits bewiesen ist: f ( p 1 ; : : : ; pn ) = 47 , F ) ^ ( p2 , T ) ^ f (F T p3 pn)] _ , F ) ^ ( p2 , F ) ^ f (F F p3 pn)] [( p1 , T ) ^ ( p2 , T ) ^ ( p3 , T ) ^ f (T T T [( p1 ; ; ; : : :; [( p1 ; ; ; : : :; ; W B xi 2 (( pi , xi ) ^ f ( p1 ; : : :; ; Die Anwendung des Satzes ergibt: ; f ( p1 ; p2; : : : ; pn) p4 ; : : : ; pn)] _ = Sei 1 i n und f ( p 1 ; : : : ; pn ) = Dann folgt: f ( p 1 ; : : : ; pn ) = W , x1) ^ f (x1 (( p1 B x1 2 _ V B x1 ;:::;xi 2 k=1;:::;i ( pk _ ^ B x1 ;:::;xi 2 _ ^ ( pk ; p2; : : : ; pn)) , xk ) ^ f (x1 B (( pi+1 , xi 1) ^ f (x1 + = V _ B x1 ;:::;xi+1 2 k=1;:::;i+1 ( pk ; : : :; xi ; xi+1 ; pi+2; : : : ; pn) ::: ::: ::: T T T ::: F F F ::: F _ = (x1 ; x2 ; : : : ; xn ) ; ; ; ;:::; ;:::; 2 Bn ^ ( pk k=1;2;:::;n Beispiel 2.6.9 f ( p; q; r) = ( p _ q) ^ r _ q. Bestimme die disjunktive Normalform. p T T T T F F F F q T T F F T T F F r T F T F T F T F (p _ q) ^ r _ q F F F T F F F T p^q^r p^q^r D. h. die disjunktive Normalform ist ( p ^ q ^ r) _ ( p ^ q ^ r ). , xk ) f (x1 ;x2 ;:::;xn )=T ; : : :; Vollständige Induktion bis i = n liefert den Satz von der disjunktiven Normalform. Konkret ist folgendermaßen vorzugehen: Wähle die (x1 ; x2; : : : ; xn) systematisch (wie in einer Wertetafel): T T T F T T T F T f ( p1 ; p2; : : : ; pn) xi ; xi+1; pi+2 ; : : : ; pn)) , xk ) ^ f (x1 ; ;:::; Es ergibt sich der Satz von der disjunktiven Normalform in vereinfachter Form: Satz 2.6.8 Jede Funktion f : Bn ! B ist darstellbar durch , xk ) Die Anwendung des Distributivgesetzes ergibt: f ( p 1 ; : : : ; pn ) xi ; pi+1; : : : ; pn) k=1;:::;i xi+1 2 ; ; Definition 2.6.7 (Min-Terme) Die verbleibenden, durch Disjunktion verknüpften Terme heißen Min =Terme. Jeder Min-Term ist durch eine Konjunktion von n Gliedern pi bzw. p̄i ; i = 1; 2; : : : ; n dargestellt. ; : : :; ( p1 ^ p2 ^ p3 ^^ pn ^ f (T T T )) _( p̄1 ^ p2 ^ p3 ^^ pn ^ f (F T T )) _( p1 ^ p̄2 ^ p3 ^^ pn ^ f (F T T T )) .. . _ _( p̄1 ^ p̄2 ^ p3 ^^ p̄n ^ f (F F F )) = Die Terme (Konjunktionen), bei denen f (: : :) = F ist, liefern den Wert F (da q ^ F , F); diese Terme können aus der Disjunktion herausfallen (da q _ F , q). Die anderen Terme, bei denen f (: : :) = T ist, können nach der Formel q ^ T , q vereinfacht werden. pi;1; xi ; pi+1; : : : ; pn))8i; 1 i n Speziell für i = 1 heißt das: f ( p 1 ; : : : ; pn ) KAPITEL 2. ELEMENTARE MODELLBILDUNG 48 2.6. AUSSAGENLOGIK 49 3. p _ q = p ^ q, d. h. _ kann durch ^ und : dargestellt werden. Konjunktive Normalform f ( p 1 ; p2 ; : : : ; pn ) _ ( pk , xk ) xn ) 2 Bn | k 1 2 n{z } ^ = KAPITEL 2. ELEMENTARE MODELLBILDUNG 50 (x1 ; x2 ; : : : ; = f (x1 ;x2 ;:::;xn )=F Satz 2.6.14 Die Menge fNANDg = f^g ist funktional vollständig. ; ;:::; Max-Terme Wertetafel für NAND: p q T T T F F T F F Beispiel 2.6.10 Implikation: p1 T T F F p2 T F T F p1 ) p2 T F T T f (x1; x2 ) = F für x1 = F; x2 = T ) f ( p1 ; p2) = ( p1 , F ) _ ( p2 , T ) = p1 _ p2 (nur ein Term, daher kein ^) In disjunktiver Normalform wird die Implikation folgendermaßen dargestellt: ( p1 ^ p2 ) _ ( p1 ^ p2 ) _ ( p1 ^ p2 ) Die Sätze über die Normalform zeigen zusätzlich: Die Operationen _; ^ und : (Negation) reichen aus, um sämtliche booleschen Funktionen darzustellen. Für Schaltungen heißt das: Wenn _; ^ und : geschaltet werden können, kann alles geschaltet werden. Definition 2.6.11 (funktional vollständig) Eine Menge boolescher Funktionen (der Art f : Bn ! B) heißt funktional vollständig, wenn sich jede beliebige boolesche Funktion durch endlichmalige Anwendung von Funktionen dieser Menge darstellen läßt. p^q F T T T Beweis 1. 2. 3. f^ :g ist funktional vollständig. p = p^ p = p^ p p ^ q = p ^ q = p ^ q = ( p ^ q) ^ ( p ^ q) ; 2.6.4 Schaltungstechnik An dieser Stelle soll der Zusammenhang mit der Schaltungstechnik dargestellt werden. Den booleschen Funktionen f : Bn ! B entsprechen Schaltungsgliedern mit n Eingängen und einem Ausgang. Die Schaltzeichen dafür haben die folgende Form: x1 x2 Satz 2.6.12 Die Menge f^; _; :g ist funktional vollständig. xn Erläuterung .. . y (genormt) Beweis siehe Sätze über Normalformen Satz 2.6.13 Die Mengen f^; :g und f_; :g sind funktional vollständig. Beweis 1. 2. f^ _ :g ist funktional vollständig. p ^ q = p _ q, d. h. ^ kann durch _ und : dargestellt werden. ; ; bzw. x1 x2 xn Erläuterung .. . (genormt) e y 2.6. AUSSAGENLOGIK 51 Allgemeiner werden Schaltungsglieder verwendet, welche Funktionen f:B n !B m KAPITEL 2. ELEMENTARE MODELLBILDUNG 52 Der Übertrag der binären Addition wird durch die Konjunktion ’^’ errechnet. Die mehrstellige binäre Addition wird durch stellenweise Anwendung des sogenannten Halbaddierers (HA) realisiert: realisieren. Sie werden mit m Ausgängen gezeichnet. Hier sind die wichtigsten Symbole der Schaltungstechnik nach DIN 40700. x y Operation Schaltzeichen : ^ _ =) ^ _ 1 e u u 1 & e & s = xy Ü = x ^ y & 1 e 1 Abgekürzt ergibt sich ein Schaltungssymbol (nicht genormt): x y e 1 e s Ü HA & Der Volladdierer besitzt noch einen weiteren Eingang für den Übertrag aus der vorherigen Stelle: Man beachte die Systematik mit der Negation bei Eingängen (siehe ’)’) sowie Ausgängen (’:’,’^’, ’_’). Die kurze Inschrift besagt, wieviele der Eingänge (ggf. negiert) 1 (d. h. TRUE) liefern müssen, damit der Ausgang (ggf. vor der Negation) 1 liefert. In der Schaltungstechnik werden die booleschen Werte oft mit 0 (=FALSE) und 1 (=TRUE) bezeichnet. Die Antivalenz ’6,’ entspricht dann der Addition modulo 2 im Dualsystem. Daher wird sie auch mit ’’ bezeichnet. Auf mehrstellige Darstellungen angewendet ergibt sie eine Addition ohne Übertrag, z. B.: x y Ü’ xy x y HA Wegen der Tautologie p q () ( p _ q) ^ p ^ q u u 1 Ü x^y x 3 y3 xn yn e 1 s Beim n-Bit-Volladdierer sind ein Halbaddierer und n-1 Volladdierer seriell (hintereinander) geschaltet: läßt sich die Antivalenz als Schaltung so darstellen & s Ü A Eine mögliche Schaltung hierfür ist die folgende: (x y)Ü’ Ü’ HA (x y)^Ü’ 1101 10111 11010 p q u & pq A Un sn U3 A s3 x2 y2 U2 A s2 x1 y1 U1 HA s1 2.6. AUSSAGENLOGIK 53 Man erkennt, daß Arithmetik auf einfache Weise auf logische Operationen zurückgeführt wird. KAPITEL 2. ELEMENTARE MODELLBILDUNG 54 Dies ergibt die Prämissen: 1. P ^ R =) Q 2.6.5 Aussagenkalkül 2. W Zum Abschluß des Abschnitts über Aussagenlogik besprechen wir formales Schließen und formale Beweise im Aussagenkalkül. Ein formaler Beweis hat folgende Struktur: Gegeben seien n( 1) Aussagen A1 ; : : : ; An , die sogenannten Prämissen, und eine Behauptung B, das sogenannte Theorem. B ist auf der Grundlage von A1 ; : : : ; An beweisbar, wenn 3. R A1 ^ A2 ^ : : : ^ An =) B; bzw. im Fall n = 0 die Formel B allein eine Tautologie ist. Gleichbedeutend damit ist, daß A1 ^ A2 ^ : : : ^ An ^ B eine Kontradiktion ist. Das folgende Beispiel veranschaulicht den Übergang von Aussagen mit realer Bedeutung zu formalen Aussagen. Das sog. Szenario besteht aus möglichen Eigenschaften eines Gegenstandes. Es gelte 4. P 5. W Das Schließen erfolgt jetzt rein formal, d. h. ohne Beachtung der Bedeutung. Was ist nun Schließen? Für den Menschen ist Schließen auf logischer Einsicht auf abstraktem Niveau begründet. Für den Computer beruht Schließen auf systematischen Textumformungen. Hier sind Beispiele von Schlußregeln: 4. Der Gegenstand ist aus Plastik. 5. Der Gegenstand ist ein Würfel. Wir führen jetzt folgende Symbole (Variable) ein: P für: Der Gegenstand ist aus Plastik. R für: Der Gegenstand ist rot. Q für: Der Gegenstand ist ein Quader. W für: Der Gegenstand ist ein Würfel. Resolutionsschluß: p_q p_r q_r Disjunktionsschluß: p p_q Kettenschluß: p =) q q =) r p =) r Konjunktionsschluß: p q p^q modus tollens: q p =) q p 3. Der Gegenstand ist nicht rot. Zu beweisen ist die Aussage: modus ponens: p p =) q q 1. Wenn der Gegenstand aus Plastik ist, ist er ein Quader, es sei denn, er ist rot. 2. Wenn der Gegenstand kein Würfel ist, so auch kein Quader. )Q = Substitution für Tautologien p: p q pr q q ( pr = σr ( p); r 2 V) Wendet man diese Schlußregeln an, so gewinnt man aus gegebenen und bereits hergeleiteten Aussagen weitere Aussagen. Um aus A1 ; : : : ; An die Aussage B zu beweisen wendet man also Schlußregeln auf die jeweils bereits gesicherten Aussagen an, solange bis B hergeleitet ist. Dies ist nichts Anderes, als eine schrittweise Bestätigung der Tautologie A1 ^ : : : ^ An =) B. Wir wenden dies auf unser 2.6. AUSSAGENLOGIK 55 KAPITEL 2. ELEMENTARE MODELLBILDUNG 56 2.6.6 Die Methode der Wahrheitstafeln Beispiel an: 4. P Man bringt die Prämissen A1 ; : : : ; An und das Theorem B in die Form 3. R 6. Konjunktionsschluß P^R 1. P ^ R =) Q modus ponens 7. Q 2. W )Q = 8. W modus tollens Umformung 5. W Der als Umformung bezeichnete letzte Schritt läßt sich auch durch eine weitere Schlußregel A1 ^ : : : ^ An =) B und untersucht, ob diese Formel eine Tautologie ist, anhand der Wahrheitstafeln für die vorkommenden Operationen. Bei k Variablen muß man 2k Varianten der Formel auswerten. 2.6.7 Der Wang-Algorithmus Die Idee dieses Verfahrens beruht auf Umformung von Formeln der Art L1 ^ L2 ^ : : : ^ Ln =) R1 _ R2 _ : : : _ Rm ; welche in der Form L1; L2; : : : ; Ln ;! R1 ; R2; : : : ; Rm p p notiert werden. Man verwendet dabei folgende Tautologien: herleiten. Grundsätzlich ist jede Regel p1 ... pn q anwendbar, d. h. logisch korrekt, wenn p1 ^ : : : ^ pn =) q eine Tautologie ist. Es gibt auch inkorrekte Schlußregeln die ebenfalls Anwendungen besitzen, z. B. als Plausibilitätserklärung. Beispiel 2.6.15 (Abduktionsschluß) Die Abduktion wird häufig im medizinischen Bereich verwendet: p =) q Krankheit ) Krankheitssymptome Krankheitssymptome q p Krankheit Es gibt verschiedene programmierbare Methoden zur Durchführung von Beweisen im Aussagenkalkül: L ^ L0 =) R () L =) R _ L0 , L =) R _ R0 () L ^ R0 =) R, L _ L0 =) R () (L =) R) ^ (L0 =) R), L =) R ^ R0 () (L =) R) ^ (L =) R0 ), L ^ P =) R _ P () textslTRUE : Das Verfahren lautet: 1. Überführe die Problemstellung in die Form A1 ; A2; : : : ; An ;! B; wobei Prämissen und Theorem nur die Verknüpfungen ^; _ und : enthalten dürfen. 2. Falls in der Form L1; L2; : : : ; Ln ;! R1 ; R2; : : : ; Rm ein Li oder Ri negiert ist, so wird es unnegiert auf die andere Seite gebracht. 2.6. AUSSAGENLOGIK 57 KAPITEL 2. ELEMENTARE MODELLBILDUNG 58 3. Steht links eine Konjunktion L1 ^ L2 oder rechts eine Disjunktion R1 _ R2 , so wird daraus L1 ; L2 bzw. R1 ; R2. 1. # 4. Steht links L1 _ L2 oder rechts R1 ^ R2 , so werden jeweils zwei neue Zeilen erzeugt, die die alte ersetzen: : : :; 3.1 # L1 _ L2 ; : : : ;! R wird ersetzt durch : : : ; L1 ; : : : ;! R : : : ; L2 ; : : : ;! R L ;! : : : ; R1 ^ R2 ; : : : wird ersetzt durch L ;! : : : ; R1 ; : : : L ;! : : : ; R2 ; : : : . 4.1 bestätigt 2. . 4.2.1 # & 4.2.2 bestätigt 5.2.1 bestätigt b) Beweisversuch einer Formel, die keine Tautologie darstellt: (p 5. Eine Zeile der Form L1; L2; : : : ; Ln ;! R1 ; R2 ; : : : ; Rm ist bestätigt, wenn es ein Element gibt, daß links und rechts auftritt. Li = R j . 1. 2. 3.1 3.2 4.1 4.2.1 4.2.2 5.2.1 6. Eine Zeile L1 ; L2; : : : ; Ln ;! R1 ; R2 ; : : : ; Rm , die nur noch Variablen als Elemente enthält, ist endgültig nicht bestätigt, wenn 5. nicht vorliegt. Beispiel 2.6.16 ) q) ^ (r ) q)) =) ( p ) r) p _ q r _ q ;! p r (ersetzt durch 2) p _ q r _ q p ;! r (ersetzt durch 3.1,3.2) p r _ p ;! r p (ersetzt durch 4.1) q r _ q p ;! r (ersetzt durch 4.2.1,4.2.2) r _ q p ;! r p (bestätigt) q r p ;! r (ersetzt durch 5.2.1) (endgültig nicht bestätigt) q q p ;! r q p ;! r r (endgültig nicht bestätigt) ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; An dieser Stelle kann das Verfahren abgebrochen werden. a) Beweis der dem Kettenschluß entsprechenden Tautologie: 2.6.8 Das Resolutionsverfahren im Aussagenkalkül Dieses Verfahren basiert auf: (( p 1. 2. 3.1. 3.2. 4.1. 4.2.1. 4.2.2. 5.2.1. & 3.2 ) q) ^ (q ) r)) =) ( p ) r) p _ q; q _ r ;! p _ r p _ q; q _ r; p ;! r p; q _ r; p ;! r q; q _ r; p ;! r q _ r; p ;! r; p q; q; p ;! r q; r; p ;! r q; p ;! r; q (ersetzt durch 2) (ersetzt durch 3.1,3.2) (ersetzt durch 4.1) (ersetzt durch 4.2.1,4.2.2) (bestätigt) (ersetzt durch 5.2.1) (bestätigt) (bestätigt) Anordnung der Formeln als Baum: der Technik des Widerspruchsbeweises: A1 ^ A2 ^^ An ) B genau dann, wenn A1 ^ A2 ^^ An ^ B widersprüchlich ist, der Schlußregel der Resolution: p p q _ _ _ q r r 2.6. AUSSAGENLOGIK 59 und der Darstellung in konjunktiver Normalform KAPITEL 2. ELEMENTARE MODELLBILDUNG 60 4. Der Beweis ist mißlungen, d. h. nicht möglich, wenn keine neuen Resolventen gebildet werden können und nil nicht abgeleitet wurde. K1 ^ K2 ^^ Kn Beispiel 2.6.17 (Kettenschluß) mit sog. Klauseln K der Form K = l1 _ l2 __ lm ; (p wobei die sog. Literale li Variable oder negierte Variable sind. Ziel des Verfahrens ist die Ableitung der leeren Klausel nil, welche den Widerspruch darstellt: der Resolutionsschluß wird auf Klauseln in der Form p p q1 _ q1 _ _ _ r1 _ _ _ _ qn _ qn rm r1 ) q) ^ (q ) r) ) ( p ) r) ergibt umgeformt: (p _ q) ^ (q _ r) ^ ( p _ r) und in konjunktiver Normalform: _ _ (p rm angewendet. Für n = m = 0 ergibt sich 2. Dies belegt, daß die leere Klausel einen Widerspruch darstellt. Man nennt zwei Klauseln (miteinander) resolvierbar, wenn ein Literal unnegiert in der einen und negiert in der anderen vorkommt. Dann kann auf die beiden Klauseln der Resolutionsschluß angewendet werden. Das Ergebnis ist wieder eine Klausel und heißt Resolvente der Ausgangsklauseln. Das Verfahren lautet: 1. Die zu untersuchende Formel A1 ^ A2 ^^ An ^ B 3. 4. f p _ q; q _ r; p; rg. Die beiden ersten Klauseln sind resolvierbar mit p _ r als Resolvente: f p _ q; q _ r; p; r; p _ rg. Resolventenbildung zwischen 3. und 5. Klausel liefert die Resolvente r. f p _ q; q _ r; p; r; p _ r; rg und Resolventenbildung zwischen 4. und 6. Klausel liefert die leere Klausel nil. f p _ q q _ r p r p _ r r nilg. ; p_q & K1 ^ K2 ^^ Km gebracht. Dann wird die Menge aller Klauseln gebildet: ; ; : : :; ; ; ; ; ; Die Bildung der Resolventen kann graphisch wie folgt dargestellt werden: wird in die konjunktive Normalform fK1 K2 : Die Klauselmenge hierzu ist 1. p p leere Klausel nil _ q) ^ (q _ r) ^ p ^ r Kmg p_r . & q_r r . & 2. Die Menge der Klauseln wird vergrößert, indem man zu zwei resolvierbaren Klauseln die Resolvente bildet und zur Menge der Klauseln hinzufügt. Gegenbeispiel: 3. Der Beweis ist gelungen, wenn die leere Klausel abgeleitet wurde. Dies ergibt folgende Klauselmengen: (p ) q) ^ (q ) r) ) (r ) p) : . nil . . p . . . . r 2.7. PRÄDIKATENLOGIK 1. 2. 61 f p _ q; q _ r; p; rg Die beiden ersten Klauseln sind resolvierbar mit p _ r als Resolvente: f p _ q q _ r p r p _ rg ; ; ; ; Neue Resolventen können nicht gebildet werden! KAPITEL 2. ELEMENTARE MODELLBILDUNG 62 Variable: x; y; z Funktionssymbole: hier brauchen wir nur eines: quad für das Quadrat einer Zahl Prädikatssymbole: das sind Symbole für Funktionen mit B als Wertebereich: für: x ist Elefant, ELEPHANT(x) WEISS(x) für: x ist weiß, STADT(x) für: x ist Stadt, HUNDEFÄNGER(x; y) für: y ist Hundefänger in x, für: y ist Hund in x, HUND(x; y) GEBISSEN(x; y) für: x wurde von y gebissen, NAT(x) für: x 2 N, LESS(x; y) für: x < y und für: x > y. GREATER(x; y) 2.7 Prädikatenlogik Während die Aussagenlogik die Grundlage für die Schaltungstechnik liefert, dient die Prädikatenlogik der Hardware- und Softwaretechnik auf höherem Niveau. Wichtige Anwendung sind die Verifikation von Hardware und Software, d. h. die Sicherstellung der Korrektheit, und die Wissensverarbeitung, in der die LogikProgrammierung eine fundamentale Rolle spielt. Es geht hier übrigens um die Prädikatenlogik erster Stufe, auch PL1 genannt. Die mathematische Logik kennt höhere prädikatenlogische Kalküle. Wichtig ist der folgende Unterschied zur Aussagenlogik: Operatoren der Aussagenlogik: Die Quantoren Der Kalkül der Aussagenlogik ist entscheidbar. D. h. es gibt einen Algorithmus, der immer terminiert (d. h. zum Ende kommt) und zu jeder aussagenlogischen Formel feststellt, ob sie unter einer bestimmten Variablenbelegung wahr ist, oder nicht. Der Kalkül der PL1 ist nicht entscheidbar. D. h. es gibt keinen Algorithmus, der immer terminiert und zu einer prädikatenlogischen Formel feststellt, ob sie wahr ist oder nicht. Zur begrifflichen Einführung der Prädikatenlogik betrachten wir Beispiele, für deren Formulierung die Aussagenlogik nicht ausreicht: 1. Es gibt einen weißen Elefanten. 2. Jede Stadt hat einen Hundefänger, der von jedem Hund der Stadt gebissen wurde. 3. Zu jeder natürlichen Zahl x gibt es eine kleinere natürliche Zahl y, deren Quadrat größer als x ist. Zur präzisen Formulierung dieser Beispiele führen wir ein: ; ; ; ; ; ; ; Existenzquantor und Allquantor: 9x 8x : : f (x): es existiert ein x, für welches f (x) gilt. f (x): für alle x gilt f (x). Damit können wir die Beispielaussagen so formulieren: 1. 2. 9x (ELEPHANT(x)^WEISS(x))) (8x (STADT(x) ) (9y HUNDEFÄNGER(x y) ^ (8z HUND(x z) )GEBISSEN(y z))))) (8x (NAT(x) ) (9y NAT(y)^LESS(y x)^GREATER(quad(y) x))))) ( : : : : ; Aber es gilt wenigstens: der Kalkül der PL1 ist semi-entscheidbar (wörtlich: halb-entscheidbar). D. h. es gibt einen Algorithmus, der wahre Formeln in endlicher Zeit erkennt. : ^ _ ) , 6, ^ _ 3. : ; : ; : : ; ; : Für die Definition prädikatenlogischer Formeln benötigen wir zunächst drei variable Mengen, nämlich: eine Menge V von Variablen, eine Menge F von Funktionssymbolen und eine Menge P von Prädikatssymbolen. Fest dagegen sind folgende Mengen eine Menge J = f:; ^; _; ); ,; 6,; ^; _g von Junktoren, eine Menge Q = f9; 8g von Quantoren und 2.7. PRÄDIKATENLOGIK 63 eine Menge H = f(; ); :; ; g von Hilfssymbolen. KAPITEL 2. ELEMENTARE MODELLBILDUNG 64 Zusammenfassen von Quantoren: 9x1 9x2 9xn wird zu 9x1 x2 8x1 8x2 8xn wird zu 8x1 x2 Definition 2.7.1 ((Prädikatenlogische) Terme) Die Menge T der prädikatenlogischen Terme wird induktiv wie folgt gebildet: 1. Jede Variable aus V ist ein Term. 2 F ein n-stelliges Funktionssymbol, so ist Definition 2.7.2 ((Prädikatenlogische) Formel, Syntax) Die Menge FO der prädikatenlogischen Formeln wird induktiv wie folgt gebildet: 1. Die booleschen Werte TRUE und FALSE sind Formeln. 2. Jede Prädikatskonstante, d. h. jedes nullstellige Prädikatssymbol, aus P ist eine Formel. 3. Sind t1; : : : ; tn Terme und ist p 2 P ein n-stelliges Prädikatssymbol, so ist p(t1 ; : : : ; tn) eine Formel. 4. Ist a eine Formel, so auch (:a). 5. Ist a eine Formel und x eine Variable, so sind (9x:a) und (8x:a) Formeln. 6. Sind a; b Formeln, so sind (a ^ b); (a _ b); (a ) b); (a , b); (a 6, b); (a^b) und (a_b) Formeln. Bemerkung Die Bedingungen 1,2,4 und 6 allein definieren die Aussagenlogik; die Mengen F; Q; V , sowie die n-stelligen (n 1) Prädikatensymbole werden dabei nicht verwendet. An Vereinfachung der Notation sei erlaubt: Weglassen von Klammern unter Beachtung der Prioritäten der Bindung: : 9x 8x ^^ __ ) , 6, ; :; ; ; ; : bindet am stärksten, Priorität 4. bindet stark, Priorität 3. bindet geringer, Priorität 2. bindet noch geringer, Priorität 1. bindet am geringsten, Priorität 0. : ; ; : : :; : : ; ; : : :; xn: xn: Beispiel 2.7.3 2. Jede Konstante, d. h. jedes nullstellige Funktionssymbol aus F ist ein Term. 3. Sind t1 ; : : : ; tn Terme und ist f f (t1 ; : : : ; tn) ein Term. : 9x (9y (9z (( p(x y) ^ q(y z)) , ( p(z y) ) r(x)))))) ( : : : ; ; ; kann zu 9x y z ( p(x y) ^ q(y z) , p(z y) ) r(x))) ( ; ; : ; ; ; vereinfacht werden. Damit haben wir den zeichenweisen Aufbau prädikatenlogischer Formeln erklärt, jedoch nicht ihre Bedeutung. Diese hängt von der jeweiligen Interpretation ab, die auch formal definiert werden kann. Definition 2.7.4 (Interpretation einer prädikatenlogischen Formel) Gegeben seien die Mengen V; F; P. Eine Interpretation hierzu ist ein Paar hD; I i, dabei ist D eine nichtleere Menge (Domäne oder Universum genannt) und I eine Abbildung wie folgt: 1. Zu jeder Konstanten c 2 F ist I (c) 2 D. 2. Zu jedem Funktionssymbol f der Stelligkeit n 1 ist I ( f ) eine Funktion I ( f ): Dn ! D. 3. Zu jeder Prädikatskonstanten k 2 P ist I (k) 2 B. 4. Zu jedem Prädikatssymbol p der Stelligkeit n 1 ist I ( p) eine Funktion I ( p): Dn ! B. Auch bei fester Interpretation betrachtet man die Formeln in Abhängigkeit von Variablenbelegungen v:V ! D. Auf den Termen ist dann eine Evaluierungsfunktion evalv: T ! D wie folgt definiert: evalv (t ) = 8 t 2 V ! v(t ) > < t 2 F t nullstellig ! I (t ) (t1 tn) f n-stellig, n 2 N > : t = f! I ( f )(evalv (t1) evalv (tn )) t1 ; ; : : :; ; ; : : :; ; ; : : :; tn Terme 2.7. PRÄDIKATENLOGIK 65 Definition 2.7.5 (Semantik prädikatenlogischer Formeln) Auf den Formeln wird eine Evaluierungsfunktion evallogv: FO definiert: evallog 1. v (a) = a v (k) = I (k) v ( p(t1 ; : : : ; tn )) = I ( p)(evalv (t1 ); : : : ; evalv (tn )) n 1, t1; : : : ; tn Terme evallog 4. für p 2 P, n-stellig, :a) = :(evallogv (a)) v( evallog 5. (a) 9x a)) =TRUE, falls es eine Variablenbelegung v0 gibt, so daß v (( D = N ist die Domäne, I bildet wie folgt ab: I (quad): N ! N mit I (quad)(x) = x2 ; I (NAT): N ! B mit I (NAT)(x) = (x 2 N !TRUE,FALSE) I (LESS); I (GREATER): NN ! B mit I (LESS)(x; y) = (x < y !TRUE,FALSE) und I (GREATER)(x; y) = (x > y !TRUE,FALSE). für k 2 P, nullstellig evallog 3. Die Interpretation ergibt sich aus der verbalen Originalform: für a 2 B evallog 2. ! B wie folgt KAPITEL 2. ELEMENTARE MODELLBILDUNG 66 Semantik von 8x:(NAT(x) ) (9y:NAT(y)^LESS(y; x)^GREATER(quad(y); x)))): Sei v: fx; yg ! N eine beliebige Variablenbelegung; evallog 1. : evallogv0 (a) = T RUE evallogv0 (A) ist; dabei stimmt v0 mit v in allen Variablen (außer eventuell in x) überein. Andernfalls istevallogv ((9x:a)) =FALSE. evallog (b) [x 2. v0 (NAT(x) evallogv0 (a) = T RUE; evallog 3. evallog 6. op b)) = (evallogv (a) op evallogv (b)) für ¯ ; _g op 2 f^; _; ); ,; 6,; ^ Zur Veranschaulichung betrachten wir erneut das Einführungsbeispiel: 8x (NAT(x) ) (9y (NAT(y)^LESS(y x)^GREATER(quad(y) x))))) : : ; ; Hier ist V = fx; yg die Menge der Variable F = fquadg die Menge der Funktionssymbole, quad einstellig P = fNAT,LESS,GREATERg, mit den Stelligkeiten 1 für NAT und 2 für LESS und GREATER. mit T RU E : ) : : :) vereinfacht sich wegen I (NAT)(x) =TRUE zu: 9 v0 ( y:B) =TRUE, v0 (x) =beliebig, so falls ein v00 : fx; yg daß !N evallogv00 (NAT(y) ^ LESS(y; x) ^ : : :) v ((a ( = !N evallogv0 (9y:(NAT(y) ^ : : :)): : dabei stimmt v0 mit v (außer eventuell in x) überein. Andernfalls ist evallogv((8x:a)) =FALSE. falls für jede Variablenbelegung v0 : fx; yg ist dabei eine beliebige natürliche Zahl] evallog 8x a)) =TRUE, falls für jede Variablenbelegung v0 gilt: v (( 8 v (( x:A)) =TRUE, v0 (y) = v(y) gilt: = existiert, mit v00 (x) = T RU E : 4. I (NAT)(y) =TRUE; somit bleibt zu zeigen: evallogv00 (LESS(y; x)) ^ evallogv00 (GREATER (quad(y); x)) = T RU E (dabei ist v00 (x) = v0 (x) beliebig aus den natürlichen Zahlen) evallogv00 (LESS(y; x)) = = = I (LESS)(evalv00 (y); evalv00 (x)) 00 < v00 (x) ! T RU E ; FALSE ) 00 (v (y) < 1 ! T RU E ; FALSE ) = FALSE (v (y) 2.8. FUZZY-LOGIK 67 D. h. die oben angegebene Formel ist nicht mit TRUE evaluierbar. Man kann leicht eine Interpretation angeben, in der die Formel immer TRUE liefert (z. B. D = N ; f1; 2g). Oft betrachtet man auch zu einer Formel alle Interpretationen, unter denen die Formel wahr ist. Dies wollen wir hier nicht weiter betrachten. Die Allgemeingültigkeit einer Formel der PL1 wird so erklärt: Definition 2.7.6 (allgemeingültig) Eine prädikatenlogische Formel a heißt allgemeingültig, falls unter jeder Interpretation und für jede Variablenbelegung v evallogv(a) = T RUE ist. Beispiel 2.7.7 (Allgemeingültige Formeln der PL1) 1. (8x:P(x) ) P(y)) 2. (P(y) ) 9x:P(x)) 3. 4. 5. 6. 9x P(x) , :8x (:P(x))) (8x P(x) , :9x (:P(x))) (:(8x P(x)) , 9x (:P(x))) (:(9x P(x)) , 8x (:P(x))) ( : : : : : : : : Für die Prädikatenlogik gibt es spezielle Verfahren, die die Allgemeingültigkeit feststellen sollen. Ein Beispiel hierfür ist das Resolutionsverfahren der Prädikatenlogik, welches eine Verallgemeinerung des aussagenlogischen Resolutionsverfahrens darstellt und auch Grundlage der Programmiersprache PROLOG ist. 2.8 Fuzzy-Logik Literaturhinweis: Goos, Bd.4, Kap.23: Unscharfe Informationsverarbeitung ¡Text fehlt¿ 68 KAPITEL 2. ELEMENTARE MODELLBILDUNG KAPITEL 3. PROZESSE UND SYSTEME 70 Diskrete Prozesse: Die Zeit wird als (kausale) Reihenfolge der Ereignisse berücksichtigt. Die Ereignisse heißen Aktionen. Beispiel 3.1.4 (Ein Rechenprozeß) ggT zweier Zahlen x; y: x = 18; y = 12 1. Subtrahiere y von x (x = 6; y = 12) 2. Subtrahiere x von y (x = 6; y = 6) 3. Gib x als Resultat aus. Kapitel 3 Prozesse und Systeme Das folgende Programm erzeugt diesen Prozeß: 1. if x = y then Gib x als Resultat aus. 3.1 Prozesse und Ablaufpläne 2. if x > y then Subtrahiere x von y. Definition 3.1.1 (Prozeß) Ein Prozeß ist ein in der Zeit ablaufender Vorgang, der aus Ereignissen zusammengesetzt ist. Es kann sich um einen realen oder virtuellen (gedachten) Prozeß handeln. 3.1.1 Diskrete Prozesse Man unterscheidet: Innere Struktur der Prozesse Zusammenhang der Aktionen: Kontinuierliche Prozesse: Die Zeit wird durch reelle Zahlen gemessen und dargestellt. Die Ereignisse heißen Zustände und werden durch zeitabhängige Funktionen dargestellt. Beispiel 3.1.2 (gedämpfte Pendelschwingung) t Beispiel 3.1.3 (Prozeß zu einem kontinuierlichen dynamischen System) x(t ); y(t ) mit ẋ(t ) = ;x2 (t ) + a y3 (t ); ẏ(t ) = ;y(t ), beginnend mit x(0) = c0 ; y(0) = c0 . 69 zeitliches Nacheinander: dann liegt ein sequentieller Teilprozeß vor unabhängiges Nebeneinander: dann liegt ein nebenläufiger Teilprozeß vor Beispiel 3.1.5 (diskrete Prozesse) Amplitude 3. if x < y then Subtrahiere y von x. rein sequentiell: A ! B ! C ! D ! E nebenläufig mit sequentiellen Teilprozessen: A -B E F ; ; C -D -G @ ; R @ ; @ R @ H Beachte: zeitliche Reihenfolge ist transitiv und irreflexiv, daher sind Zyklen nicht möglich. 3.1. PROZESSE UND ABLAUFPLÄNE 71 KAPITEL 3. PROZESSE UND SYSTEME 72 3.1.2 Sequentielle Prozesse 3.1.3 Syntax-Diagramme Wir betrachten Pläne zur Steuerung solcher Prozesse. Die Pläne enthalten: Syntax-Diagramme sind Pläne zur systematischen Erzeugung von Texten. Bestandteile sind: elementare Aktionen Reihenfolgeangaben Alternativen Text konstante Text-Teile: 1. mit beliebiger endlicher Wahl (Nichtdeterminismus) Verweis auf andere Diagramme bzw. auf dasselbe Diagramm (Selbstreferenz): Name 2. mit Auswahl gemäß Bedingung (Determinismus) Wiederholungen elementare Aktionen Reihenfolge nichtdetermin. Alternative Wiederholung determin. Alternative als Text Textsymbole Reihenfolge der Niederschrift; Verweise Spezialsymbole: z. B. —, 2; oder Spezialsymbole: repeat, while, ( )+,( ) if. . . then. . . Beispiel 3.1.6 (Programm eines sequentiellen Prozesses) x := 1; y := x + 3; (z := x + yjz := 100jz := x + x y); w := 1; (w := w + 1) ; print(x); print(y); print(z); print(w); als Zeichnung graphische Grundsymbole: , gerichtete Pfeile; für die Vorzugs-richtungen ; oft ohne Spitze Linienverzweigung: Name zur Benennung eines Diagrammes und als Referenzen #! * H j H Verbindungslinien mit – Laufrichtung (Pfeil oder implizit nach rechts bzw. nach unten) – Verzweigung – Rückführung Ein Syntaxdiagramm repräsentiert eine Menge von Worten über einem Alphabet, also eine sogenannte formale Sprache. Beispiel 3.1.7 (unendliche formale Sprache) -- c b - d e -6 6 f Linienrückführung: ? X- a Linienverzweigung mit Bedingungen notiert 6 Zur formalen Sprache X gehören z.B.: abc, ade, adee, adeee, adefde Beispiel 3.1.8 (leere formale Sprache) X -? - b X - Y - c ? a - - - e X Y - d 3.1. PROZESSE UND ABLAUFPLÄNE 73 3.1.4 Der Backus-Naur-Formalismus (BNF) Zu einer Beschreibung in BNF gehören: Metasymbole: ::=“, j“ ” ” begriffliche Symbole, sogenannte Nichtterminalsymbole N: Hilfszeichen der Definition, z. B. hZahli, hstatementi. Bestandteile des Textes, sogenannte Terminalsymbole T , z. B.: a, b, c, 0, 1, . . . , ?, [, . . . KAPITEL 3. PROZESSE UND SYSTEME 74 X::=aY j aZ Y::=b j bY Z::=cd j cd j ce j cdZ j ceZ Hierbei sind Terminalsymbole: T = fa,b,c,d,eg und Nichtterminalsymbole: N = fX; hYi; hZig. Der Backus-Naur-Formalismus führt uns zu einem sehr wichtigen Begriff der Theorie der Formalen Sprachen: Die Beschreibung besteht aus Regeln der Form A ::= X1 jX2 j : : : jXn ; n 1; A 2 N ; Xi 2 (T [ N ) Erläuterung: Steht M für eine Menge von Zeichen, dann bezeichnet M die Menge aller Wörter über diesen Zeichen, einschließlich des leeren Wortes. Beispiel 3.1.9 (arithmetische Terme) hTermi ::= (hTermihOpihTermi) j hKonsti j hVariablei hKonsti ::= : : : hVariablei ::= : : : hOpi ::= + j ; j j n Überführung von Syntaxdiagrammen in BNF: 3.1.5 Grammatik Definition 3.1.11 (Grammatik) Eine Grammatik G ist ein Quadrupel G = (VN ; VT ; P; S) wie folgt: VN = Alphabet der Nichtterminalsymbole, VT = Alphabet der Terminalsymbole, VN \ VT = 0/ P = Menge von Ersetzregeln der Form α ! β, wobei α β 2 V , V = VN [ VT S = Startsymbol der Grammatik, S 2 VN Hintereinanderschaltung: bleibt erhalten Verzweigung: Aufteilung in Alternativen : : : j : : : j : : : Linienrückführung: Einführung eines neuen Nichtterminalsymbols Beispiel 3.1.10 (Backus-Naur-Formalismus) - 6 X- a d - c - e 6 -? b 6 X- a - d - c 6 - e 2 V VNV und Ist α 2 VN , so heißt G kontextfrei. - b X::=ab j acd j ace Beispiel 3.1.12 (Darstellung von BNF als kontextfreie Grammatik) X::=aY j aZ Y::=b j bY Z::=cd j ce j cdZ j ceZ Als kontextfreie Grammatik: P = fX!aY,X!aZ,Y!b,Y!bY, Z!cd,Z!ce,Z!cdZ,Z!ceZg VN = fX,Y,Z,g; VT = fa,b,c,d,eg; S =X. 3.1. PROZESSE UND ABLAUFPLÄNE 75 Beispiel 3.1.13 (nicht kontextfreie Grammatik) G = (fX,Y; Sg; fa,b,cg; P; S), P = fS !XYC,Y!ab,Y!bY,Xa!aXb, Xbb!cg 76 KAPITEL 3. PROZESSE UND SYSTEME oder mehrere Nachfolger, die durch Kanten an ihn gebunden sind. Alle Knoten, bis auf den Wurzelknoten, haben genau einen Vorgänger. Aus einer Ableitungsfolge entsteht auf folgende Art ein Ableitungsbaum: Oft verwendet man die Alternativdarstellung : : : j : : : j : : : j : : : auch bei Grammatiken zur Ab-kürzung. Definition 3.1.14 (direkte Ableitung) Eine Grammatik G = (VN ; VT ; P; S) definiert auf V = (VN [ VT ) die sogenannte direkte Ableitung ’)’ als binäre Relation: x ) y gilt genau dann, wenn x = w1 αw2 ; y = w1 βw2 ; w1 ; w2 2 V und (α ! β) 2 P gilt. Definition 3.1.15 (Satzform) Ein Wort w 2 V heißt Satzform (zu G), wenn S ) w gilt. Dabei ist ’)’ die reflexive, transitive Hülle von ’)’, d.h. es ist genau dann S ) w, wenn es eine Folge S = w0 ) w1 ) w2 ) ) wn = w (n 0) gibt. 1. Man notiert einen Wurzelknoten und schreibt daran das Startsymbol S. Definition 3.1.16 (Menge aller Satzformen) Sei G eine Grammatik. Dann ist L(G) die Menge aller Satzformen zu G, welche nur terminale Zeichen enthalten: L(G) = fw j s ) w; w 2 VTg. Beispiel 3.1.17 G = (fSg; fa; bg; fS ! ε; S ! abSg; S); L(G) = fanbn j n 0g. Zur Veranschaulichung des Arbeitens mit Grammatiken führen wir die Begriffe einer Ableitungsfolge und eines Ableitungsbaums ein, den letzteren allerdings nur unter der Einschränkung, daß es sich um eine kontextfreie Grammatik handelt. Zu einer Grammatik G haben wir die Relation ’)’, eigentlich ’)G ’ eingeführt. Dann bezeichnen wir eine Kette gültiger Ableitungsschritte S ) w1 ) w2 ) ) wn als Ableitungsfolge. S ) w bedeutet dann, daß eine solche Folge von S nach w führt (im Falle n = 0 mit S = w). Ist die Grammatik kontextfrei, so wird in jedem Schritt ein Nichtterminalsymbol duch ein Wort aus (VN [ VT ) ersetzt. Dabei spielt es keine Rolle, in welcher Reihenfolge die vorhandenen Nichtterminalsymbole ersetzt werden. Eine reihenfolgeunabhängige Darstellung ergibt sich durch eine zweidimensionale Darstellung durch einen sogenannten Baum: Ein Baum besteht aus Knoten und Kanten und wird von oben nach unten gezeichnet. Es gibt oben einen ausgezeichneten Knoten, den sogenannten Wurzelknoten. Jeder Knoten ist entweder ein Endknoten, auch Blatt genannt, oder er besitzt einen 2. Eine Ableitung A ! α1 α2 : : : αn ; αi 2 (VN [ VT ); i = 1; : : : ; n; n 1, wird so durchgeführt: Von dem mit A beschrifteten Knoten zeichnet man n Kanten für n Nachfolger, die mit α1 ; : : : ; αn beschriftet werden. Eine Ableitung A ! ε wird so durchgeführt, daß von A ausgehend eine Kante zu einem Nachfolger gezeichnet wird, der mit beschriftet wird. Das abgeleitete Wort steht am Schluß in den von links nach rechts zu lesenden Blättern des Baumes. 3.1. PROZESSE UND ABLAUFPLÄNE 77 Beispiel 3.1.18 (zur Grammatik) S !ab,S !aSb,S !AA,A! S S )aSb)aAAb)aASb)aSSb )aaSbSb)aaSbabb)aaabbabb S H a HH S b Q Q A S JJ KAPITEL 3. PROZESSE UND SYSTEME 78 2. Lε = fεg. 3. LRS = LR LS = fvw j v 2 LR; w 2 LSg. A S AA 4. L(R1 j ::: j Rn ) = LR1 [[ LRn . a S b a b AA a b Grammatiken, die nicht kontextfrei sind, werden auch benötigt. Es gibt formale Sprachen mit einem praktischen Hintergrund, die sich sonst nicht durch Grammatiken beschreiben ließen. Ein theoretisches Beispiel für eine formale Sprache, die sich nicht durch eine kontextfreie Grammatik geschreiben läßt, ist die Sprache L = fan bncn j n 1g. Eine weitere Methode, formale Sprachen zu beschreiben, ist durch die sogenannten regulären Ausdrücke gegeben. 3.1.6 Reguläre Ausdrücke 5. LR = (LR ) ; LR+ = (LR )+ . Dabei verwendet man die folgende Definition von ’’ und ’+ ’ für Mengen von Worten: Definition 3.1.19 (regulärer Ausdruck) Gegeben sei ein Terminalalphabet VT . 1. Jedes Symbol a 2 VT ist ein regulärer Ausdruck. 2. Das Symbol 0/ für die leere Sprache ist ein regulärer Ausdruck. 3. Sind R; S reguläre Ausdrücke, so auch RS. (Hierdurch wird Konkatenation ausgedrückt.) 4. Sind R1 ; : : : ; Rn reguläre Ausdrücke, so auch (R1 j tiven). ::: j Rn ), n 2 (Alterna- 5. Ist R ein regulärer Ausdruck, so auch R und R+ (bzw. (R) ; (R)+ ) (Wiederholung). Definition 3.1.21 Sei A ein Alphabet und X X = fw1 : : : wn j wi 2 X ; i = 1; : : : ; n n 0g X + = fw1 : : : wn j wi 2 X ; i = 1; : : : ; n n 1g Reguläre Ausdrücke benötigen keine Nichtterminalsymbole. Definition 3.1.20 Jedem regulären Ausdruck r ist eine Menge Lr VT wie folgt zugeordnet: 1. a 2 VT : La = fag. A .Dann ist Beachte: 0/ = fεg. 3.2. ENDLICHE AUTOMATEN 79 Wir vergleichen die Ausdruckskraft: b 1. Syntaxdiagramme ohne Referenzen = reguläre Ausdrücke, dargestellte Sprachen heißen reguläre Sprachen b KAPITEL 3. PROZESSE UND SYSTEME 80 Ist ein vorgelegtes Wort vollständig zeichenweise gelesen und danach ein Zustand q 2 F erreicht, so hat der EA das Wort akzeptiert. b 2. Syntaxdiagramme mit Referenzen = BNF = kontextfreie Grammatik, dargestellte Sprachen heißen kontextfreie Sprachen ) reguläre Sprachen kontextfreie Sprachen, d.h. die regulären Sprachen sind ein spezieller Fall der kontextfreien. Merke: Klammerstrukturen sind kontextfrei, aber nicht regulär. Wir können uns die Arbeit eines endlichen Automaten so veranschaulichen: Beispiel 3.1.22 (Syntaxdiagramm) XLX = - b a 6 X fanbn j n 1g. 3.2 Endliche Automaten Automaten dienen dem Erkennen und Verarbeiten exakt definierter Strukturen. Definition 3.2.1 (endlicher Automat) Ein endlicher Automat ist ein Quintupel (Q; Σ; δ; q0; F ) wie folgt: Q ist eine endliche Menge sogenannter Zustände Σ ist ein Alphabet q0 2 Q; q0 heißt Anfangszustand δ : Q Σ ! Q ist eine totale Funktion. Sie heißt Transitionsfunktion F Q, F heißt die Menge der Endzustände. Anschaulich: Arbeitsweise eines EA: Der Automat beginnt in Zustand q0. In jedem Schritt wird ein von außen vorgelegtes Zeichen a 2 Σ gelesen und der Zustand q in den neuen Zustand q0 = δ(q; a =) übergeführt. a b c x p q ....... Lesekopf nur Bewegungen nach rechts q q0 , δ , F aktueller Zustand, verändert sich feste Bestandteile Eingabemedium (Band) mit Wort über Alphabet 3.2. ENDLICHE AUTOMATEN 81 Das Transitionsdiagramm eines endlichen Automaten: Zeichne jeden Zustand q als Knoten: q Für jeden Fall qn = δ(qm ; a) zeichne einen Pfeil von qn nach qm und beschrifte ihn mit ’a’. Fasse alle Pfeile zwischen gleichen Knoten zu einem mit Mehrfachbeschriftung zusammen: a q n ;::: - q m e Definition 3.2.3 (erweiterte Transitionsfunktion) Die erweiterte Transitionsfunktion δ wird rekursiv erklärt durch e 2. e δ(q wa) = δ(e δ(q w) a) für alle q 2 Q w 2 Σ a 2 Σ. 1. δ(q; ε) = q für alle q 2 Q. ; ; ; ; ; Satz 3.2.4 Für die von einem endlichen Automaten A erkannte Sprache gilt S(A) = fw 2 Σ j δ(q0 ; w) 2 F g. e Zum Beweis zeigt man für w = a1 : : : an eδ(q0 a1 ; ::: ai ) = qi ; i = 0; : : : ; n: Kennzeichne den Anfangszustand durch einen hereinführenden Pfeil: H H q0 KAPITEL 3. PROZESSE UND SYSTEME 82 Kennzeichne alle Endzustände durch eine doppelte Umrandung: q Außer durch Transitionsdiagramme werden endliche Automaten auch durch Tabellen dargestellt, in denen man zu jedem Zustand und jedem Eingabezeichen den Folgezustand ablesen kann. Zusätzlich müssen noch Anfangszustand und Endzustände gekennzeichnet werden. Beispiel 3.2.5 (Tabelle zu einem EA) ! q0 für q 2 F . q1 q2 q3 q4 q5 2 F q6 Exakte Definition der Arbeitsweise eines endlichen Automaten: Gegeben sei A = Dem Automaten werde ein Wort w = a1 : : : an ; ai 2 Σ; i = 1; : : : ; n vorgelegt. Der Automat durchläuft dann die Zustände q0; q1; : : : ; qn mit (W ; Σ; δ; q0; F ). qi+1 = δ(qi ; ai+1 ); i = 0; : : : ; n ; 1: a q1 q6 q4 q4 q6 q6 q6 b q6 q2 q3 q6 q5 q6 q6 c q6 q3 q6 q3 q6 q6 q6 Ist qn 2 F, so wird w von A akzeptiert, sonst nicht. Das folgende Beispiel zeigt, wie ein erkennender Automat zu einem Verfahren erweitert wird, welches die vollständige Verarbeitung enthält: Definition 3.2.2 (von einem EA akzeptierte Sprache) Die vom endlichen Automaten A akzeptierte (oder: erkannte) Sprache ist l (A) = fw j w 2 Σ; w = a1 : : : an; ai 2 Σ, so daß q1; : : : ; qn existieren mit qi+1 = δ(Qi ; ai+1; i = 0; : : : ; n ; 1 und qn 2 F g. Zu einer kürzeren Beschreibung von L(A) kommen wir mit Hilfe der erweiterten Transitionsfunktion δ : Q Σ ! Q. Beispiel 3.2.6 Es sollen Binärworte zu folgendem Syntaxdiagramm erkannt und zugleich in die dargestellte Zahl umgewandelt werden: e - 0 ? - . ? q - q q - q 1 1 - 0 0 1 2 3 3.2. ENDLICHE AUTOMATEN 83 Das Syntaxdiagramm ist schon ergänzt um die Zustände des endlichen Automaten. Wir zeichnen nun auch den Automaten, notieren aber zusätzlich den jeweils dazugehörigen Verarbeitungsschritt. Dabei ist z den Wert der gerade gelesenen Ziffer (0 oder 1), w der aktuelle Gesamtwert der Binärzahl und d eine Hilfsgröße bei der Berechnung. KAPITEL 3. PROZESSE UND SYSTEME 84 Die Informationen des Diagramms bringt man in praktischen Anwendungsfällen in die Form zweier Tabellen: Zustand 0 1 . sonst Aktion 0 1 . sonst (q)0 1 1 4 4 (q)0 1 1 0 0 4 0 1 1 1 2 1 2 2 3 2 3 3 4 2 4 4 0 4 0 3 3 3 4 3 5 5 0 4 0 4 4 4 4 4 0 0 0 4 0 Die Einträge in der Aktionstabelle bedeuten: 0: “Fehlermeldung” 1: w := z 2: w := 2w + z 3: d := 12 4: w := w + 2 z 5: d := d2 ; w := w + d z 3.3 Graphen 3.3.1 Einführende Beispiele Graphen sind allgemeine mathematische Modelle für “Objekte” und “Verbindungen” zwischen diesen. Anschauliche Definition eines Graphen: Definition 3.3.1 Ein Graph besteht aus Knoten (oder Ecken, eng. ’nodes’ oder ’vertices’) und Kanten (oder Bögen, engl. ’edges’ oder ’arcs’), welche Knoten miteinander verbinden. Knoten und Kanten können noch zusätzlich beschriftet sein. Beispiel 3.3.2 (Transtionsdiagramm eines endlichen Automaten) Beispiel 3.3.3 (Elektrischer Schaltkreis) R1 A R2 B U Ein klassisches Beispiel: Beispiel 3.3.4 (Das Königsberger Brückenproblem) 3.3. GRAPHEN 85 KAPITEL 3. PROZESSE UND SYSTEME 86 Der Graph besteht aus folgenden Teilen: C A D B Knoten: A; B; C; D (Gebiete) Kanten: a; b; c; d ; e; f ; g (Brücken) Die Lösung fand L EONHARD E ULER (1707-1783). Wir werden sie noch kennenlernen. 3.3.2 Ungerichtete und gerichtete Graphen Definition 3.3.5 (ungerichteter Graph) Ein ungerichteter Graph (’undirected graph’) ist ein Tripel G = (K ; B; δ) wie folgt: Gesucht ist ein Weg, der genau einmal über jede der sieben Brücken führt. Als Graph: K ist eine nichtleere Menge, deren Elemente Knoten heißen B ist eine Menge, deren Elemente Kanten oder Bögen heißen δ : B ! ffk1 ; k2g j k1; k2 2 K g ist eine totale Abbildung G heißt endlich, wenn K und B endlich sind. Beim Graphen zum Königsberger Brückenproblem ist z.B. δ(a) = fA; Bg; δ(b) = fA; Bg; δ(c) = fA; Cg: Bemerkung: Sind zwei Knoten höchstens durch einen Bogen miteinander verbunden, so kann man einen Bogen b mit δ(b) identifizieren. Definition 3.3.6 (Schlinge) Eine Kante b mit δ(b) = fkg, d.h. k1 = k2 , heißt Schlinge (’loop’). c C d e b A a B g D f Definition 3.3.7 (Pfad, Zykel) Ein Pfad in einem ungerichteten Graphen G = (K ; B; δ) ist eine Folge b1; : : : ; bn von Kanten (n 0), so daß eine zugehörige Folge k0 ; : : : ; kn von Knoten existiert mit δ(bi ) = fki;1 ; ki g, i = 1; 2; : : :; n. Ein Pfad ist ein Zykel, wenn k0 = kn ist. Definition 3.3.8 (Eulerscher Pfad, Zykel und Graph) Ein Pfad ist ein Eulerscher Pfad, wenn darin jede Kante des Graphen genau einmal vorkommt bzw. ein Eulerscher Zykel, wenn außerdem k0 = kn ist. Ein ungerichteter Graph heißt ein Eulerscher Graph, wenn es darin einen Eulerschen Zykel gibt. Definition 3.3.9 (Hamiltonscher Zykel, Graph) Ein Zykel, der alle Knoten des Graphen genau einmal enthält, heißt ein Hamiltonscher Zykel. Ein ungerichteter Graph heißt ein Hamiltonscher Graph, wenn es darin einen Hamiltonschen Zykel gibt. 3.3. GRAPHEN 87 Beispiel 3.3.10 (Eulerscher Graph, nicht Hamiltonsch) KAPITEL 3. PROZESSE UND SYSTEME 88 Weitere Begriffe zu ungerichteten Graphen: Definition 3.3.12 (azyklisch, zyklisch) Ein ungerichteter Graph, in dem es keinen Zykel gibt, heißt azyklisch, sonst zyklisch. Beispiel 3.3.13 (azyklisch) s3 s u s s s6 u s ;@ @ ; @ 4 ; 2 ; ; ; ; ; ; ; 5 1 ; ; @ ; @ @; A A u u AA @ @ @ u u u u Beispiel 3.3.14 (zyklisch) u u u u u u P BB PP P ; B ; B; Definition 3.3.15 (schlicht) Ein ungerichteter Graph heißt schlicht, wenn er keine Mehrfachkanten enthält, d.h. δ(b1 ) = δ(b2) ) b1 = b2 für alle b1 ; b2 2 B, und keine Schlingen enthält. Beispiel 3.3.11 (Hamiltonscher Graph, nicht Eulersch) s s s s s s ;@ ; ; ; @; ; ; ;@ @ ; ; @ Definition 3.3.16 (zusammenhängend) Ein ungerichteter Graph heißt zusammenhängend, wenn es zu je zwei Knoten einen Pfad gibt, dessen Knotenfolge beide Knoten enthält. Die Relation für Knoten k1 ; k2 k1 y k2 , Es gibt einen Pfad von k1 nach k2 läßt sich leicht exakt beschreiben: Sei k1 ! k2 , Es gibt einen Bogen b mit δ(b) = fk1 ; k2g. Dann ist ’y’ die reflexive, transitive Hülle von ’!’: ’y’=’!’. Folgerung: G ist zusammenhängend genau dann, wenn für k1 ; k2 2 K stets k1 ! k2 gilt. Bemerkung: ! ist eine Äquivalenzrelation, also reflexiv, symmetrisch und transitiv. Sie zerteilt K in Äquivalenzklassen. Ist G zusammenhängend, so gibt es nur eine Äquivalenzklasse. Definition 3.3.17 (Grad) Der Grad eines Knotens ist die Anzahl der darin zusammentreffenden Kanten: γ(K ) = j fb j k 2 δ(b)g j (Anzahl der Elemente einer endlichen Menge). Im gerichteten Graphen: 3.3. GRAPHEN 89 γ+ (k) = j fb j (k; k0) 2 δ(b)g j “auslaufender Knotengrad” γ+ (k) = j fb j (k0 ; k) 2 δ(b)g j “einlaufender Knotengrad” KAPITEL 3. PROZESSE UND SYSTEME 90 Weiter mit ungerichteten Graphen: Satz 3.3.19 (Grad, Eulerscher Graph) Für einen zusammenhängenden ungerichteten Graphen sind folgende Aussagen gleichwertig: 1. Der Graph ist ein Eulerscher Graph. 2. Bei jedem Knoten ist die Anzahl der hinführenden Bögen geradzahlig. 3. Die Menge der Bögen läßt sich auf disjunkte Zykel ohne Kreuzungspunkte aufteilen. Beispiel 3.3.18 (Grad, ungerichteter Graph) Beweis: 1 ) 2 : Ein Eulerscher Zykel geht bei einem Umlauf genauso oft in einen Knoten hinein wie er dort herauskommt und benutzt dabei nie denselben Bogen mehrfach. Also gilt 2. 2 ) 3 : Bilde einen ersten Zykel ohne Kreuzungspunkt, s s s s s @ ; ; R @ ; YH ; H s Da man aus jedem Knoten wieder herauskommt, landet man bei einem solchen: s s * - s s ; ; @ @ ; ; Grad 3 Grad 2 Der Restgraph ist von gleicher Struktur oder leer. 3 ) 1 : Aufbau des Eulerschen Zykels aus der Folgerung: Ein ungerichteter zusammenhängender Graph besitzt einen Eulerschen Pfad genau dann, wenn entweder genau für zwei Knoten die Anzahl der hinführenden Bögen ungeradzahlig ist oder für alle Knoten die Anzahl geradzahlig ist. Anwendung auf das Königsberger Brückenproblem Bemerkung: Hamiltonsche Graphen sind nicht so einfach zu charakterisieren. Definition 3.3.20 (gerichteter Graph) Ein gerichteter Graph ist ein System G = (K ; B; δ0; δ1): K = Menge sogenannter Knoten, nichtleer B = Menge sogenannter Bögen δ0 : B ! K ; δ1 : B ! K 3.3. GRAPHEN 91 Definition 3.3.21 (Pfad, gerichteter Graph) Ein Pfad in einem gerichteten Graphen (K ; B; δ0; δ1 ) ist eine Folge b1; b2; : : : ; bn von Bögen, n 0, so daß eine Folge k0 ; k1 ; : : : ; kn von Knoten existiert mit δ0(bi ) = ki;1 ; δ1 (bi ) = ki ; i = 1; : : : ; n. Definition 3.3.22 (Adjazenzmatrix, gerichteter Graph) Sei G = (K ; B; δ0; δ1) ein gerichteter Graph. Dann heißt die Matrix AG = (ai j ), ai j = (9b 2 B : δ0 (b) = ki ^ δ1(b) = k j ! 1; 0) die Adjazenzmatrix von G. Definition 3.3.23 (Adjazenzmatrix, ungerichteter Graph) Sei G = (K ; B; δ) ein ungerichteter Graph. Dann heißt die Matrix AG = (ai j ), ai j = (9b 2 B : δ(b) = fki ; k j g ! 1; 0) die Adjazenzmatrix von G. Satz 3.3.24 (Adjazenzmatrix, Weglänge) Sei G ein gerichteter Graph ohne Mehrfachkanten und A = (ai j ) die zugehörige Adjazenzmatrix. Ferner sei Ar = Ar;1 A für r 2 und A1 = A. Dann gilt Ar = (r ) (ai j ), (r ) ai j = Anzahl der Wege der Länge r von ki nach k j . Beweis: durch vollständige Induktion Satz 3.3.25 (Adjazenzmatrix, zyklisch / azyklisch) Sei G ein gerichteter Graph, A seine Adjazenzmatrix. Dann gilt: G ist zyklisch , Ar 6= 0 für 1 r n, G ist azyklisch , 9r : 1 r n ^ Ar = 0. Definition 3.3.26 (Graph, vereinfachte Schreibweise) Ein schlichter ungerichteter Graph G = (K ; B; δ) wird vereinfacht geschrieben als G = (K ; E ) mit E = fδ(b) j b 2 Bg, ein schlichter gerichteter Graph G = (K ; B; δ0; δ1 ) in der Form G = (K ; E ) mit E = fδ0 (b); δ1 (b) j b 2 Bg. Definition 3.3.27 (Baum etc.) Ein schlichter, ungerichteter, azyklischer zusammenhängender Graph G = (K ; E ) zusammen mit einem ausgezeichneten Knoten k0 2 K heißt ein Baum mit Wurzel k0. Als Tiefe eines Knotens k bezeichnet man die Länge des Pfades von k0 nach k. Sind zwei Knoten k1; k2 direkt durch einen Bogen verbunden, so heißt der mit der geringeren Tiefe Vorgänger des anderen und der mit der größeren Tiefe Nachfolger des einen. Die Knoten ohne Nachfolger heißen Blätter des Baumes, die anderen heißen innere Knoten. Man zeichnet Bäume mit der Wurzel nach oben und den Nachfolgern jeweils unter den Vorgängern. Klar ist: Jeder Knoten hat höchstens einen Vorgänger. Nur der Wurzelknoten hat keinen Vorgänger. KAPITEL 3. PROZESSE UND SYSTEME 92 Definition 3.3.28 (geordneter Baum) Ein Baum B = ((K ; E ); k0) heißt geordnet, wenn auf den Nachfolgern jedes inneren Knotens eine totale Ordnung festgelegt ist. Beispiel 3.3.29 (geordneter Baum) Ableitungsbäume zu kontextfreien Grammatiken sind geordnete Bäume. Zu S ! AcB; A ! aAb; A ! a; B ! BBb; B ! c kann mat folgenden Ableitungsbaum konstruieren S H A ;@ ; @ c HH H B ;@ ; @ a A b B B b a A b c c ;@ ; @ a Hinweis: Die Knoten sind nicht identisch mit ihren Beschriftungen. Will man den Graphen durch seine Knoten und Kanten beschreiben, so muß man für die Knoten eindeutige Bezeichnungen einführen. 3.4. PETRI-NETZE 93 KAPITEL 3. PROZESSE UND SYSTEME 94 3.4 Petri-Netze Petri-Netze sind Graphen mit 2 Arten von Knoten, bei denen Kanten nur Knoten verschiedener Art verbinden, sog. bipartite Graphen. Sie wurden 1962 von Carl-Adam Petri eingeführt als ein Modell für den Informationsfluß bei der automatischen Verarbeitung von Information. Zu den Ideen von Petri gehören folgende Feststellungen, die zugleich Kritikpunkte in Bezug auf die klassischen Automaten darstellen: T-Elemente: Quadrate, Rechtecke, eckige Formen Kanten: als Linien bzw. Pfeile, wie bei Graphen üblich Informationsverarbeitung erfolgt räumlich und zeitlich verteilt kooperierende nebenläufige Prozesse benötigen Synchronisationsmechanismen Petri-Netze sind besonders gut geeignet für: Synchronisation die Darstellung der Zusammenhänge zwischen Prozessen und Systemen Beispiel 3.4.2 Das linke Netz ist ungerichtet, das rechte ist gerichtet. Definition 3.4.1 Ein Petri-Netz ist ein Graph mit folgenden Eigenschaften: 1. Es gibt zwei Arten von Knoten: S-Elemente (state) und T-Elemente (transition). 2. Es gibt nur Kanten zwischen verschiedenartigen Elementen. 3. Jeder Knoten liegt an mindestens einer Kante. Ein Petri-Netz heißt gerichtet, wenn der Graph gerichtet ist. Definition in formaler Form: Ein Petri-Netz ist ein Graph G (K ; B; δ0; δ1 ) mit folgenden Eigenschaften: 1. K = S [ T ; S \ T = = (K ; B; δ) bzw. Einige Anwendungsarten von Petri-Netzen: 2. δ(b) \ S 6= ; δ(b) \ T 6= für b ; fδ0(b); δ1(b)g 6= für b 2 B 1. Netze aus Instanzen und Kanälen 2 B bzw. 3. es existiert b mit k 2 δ(b) = fδ0(b); δ1 (b)g für alle k fδ0(b) δ1(b)g 6= ; T-Elemente: Instanzen, d. h. informationsverarbeitende Einheiten S-Elemente: Einheiten zur Übertragung und Speicherung von Information. Kanten sind gerichtet: Richtung des Informationsflusses, Bedeutung: lesen, schreiben, . . . Graphische Darstellung: S-Elemente: Kreise, Ellipsen, runde Formen Beispiel 3.4.3 Konfiguration eines Rechnersystems 3.4. PETRI-NETZE 95 seperater gemeinsamer seperater Speicher 1 Speicher Speicher 2 KAPITEL 3. PROZESSE UND SYSTEME 96 Arbeitszustand des Editors Editieren eines Files Loeschen alter Versionen Prozessor 1 Prozessor 2 Kopplungskanal Verlassen des Editors Speicher 3 Einloggen Eingabekanal Ausgabekanal Informieren ueber Files Auftragszustand seperater Ausloggen fehlerhaftes Einloggen E.K. Grundzustand informieren A.K. 3. Netze aus Aufgaben und Mitteln T-Elemente: Auszuführende Aufgaben Multiplexeinheit S-Elemente: Benötigte und produzierte Mittel Kanten: gerichtet, Arbeitsfluß .... Terminals Beispiel 3.4.5 Programmverarbeitung Editieren 2. Zustands-/Vorgangsnetze Programmtext T-Elemente: Vorgänge, welche Zustände verändern Uebersetzen S-Elemente: Zustände Fehlermeldungen lauffaehig. Progr. Kanten:gerichtet, bedeuten Wirkungen Eingabedaten Beispiel 3.4.4 Benutzeroberfläche eines Computersystems Markierte Petri-Netze Ausfuehren Resultatdaten 3.4. PETRI-NETZE 97 Beispiel 3.4.6 Engpaß: Gegeben zwei nebenläufige Abläufe KAPITEL 3. PROZESSE UND SYSTEME 98 Beispiel 3.4.7 Engpaß A1 ;! A2 ;! A3 B1 ;! B2 ;! B3 mit der Bedingung, daß sich A2 und B2 zeitlich gegenseitig ausschließen. Modellierung: A1 ; A2 ; A3; B1 ; B2 ; B3 werden Zustände. Der jeweils gültige Zustand wird markiert durch Zuordnung einer Marke. Es wird ein zusätzlicher Zustand X eingeführt (quasi als Ampel). Es werden 4 Übergänge A1 =A2 ; A2=A3 ; B1 =B2 ; B2 =B3 eingeführt. Diese transportieren Marken von Eingangsplätzen auf Ausgangsplätze: Zwei um 2 Mittel konkurrierende Prozesse Sukzessive Aufnahme von 2 Mitteln bei einem Prozeß Konkurrenz zweier solcher Prozesse M2 Konflikt: t1 , t2 A1 A2 B1 t1 A1 t1 t3 B1 t4 B2 Prozesse A und B konkurrieren um M1 , M2 X B2 t3 t4 A3 t2 M2 t2 A2 A0 B 0 B3 Das sog. Schalten oder Feuern einer Transition t: t kann schalten, wenn alle hineinführenden Stellen markiert sind, evtl. spielen Marken auf den nachfolgenden Stellen noch eine Rolle (siehe unten). Schalten bedeutet Entfernen der Marken im Vorbereich und Hinzufügen von Marken im Nachbereich. Es kann vorkommen, daß verschiedene schaltbereite Transitionen sich gegenseitig behindern, sei es durch Entziehen von Marken im gemeinsamen Vorbereich oder, wie wir sehen werden, im Nachbereich. Wir modellieren zunächst die sog. Bedingungs-/Ereignis-Netze (B/E-Netze): Eine Transition kann nur schalten, wenn alle Stellen des Vorbereich markiert sind und keine Stelle des Nachbereichs markiert ist. M1 M2 A0 t2 t1 A1 A2 t4 t3 A3 t5 A4 Sukzessive Aufnahme zweier Mittel 3.4. PETRI-NETZE 99 Formale Beschreibung des Schaltens eines B/E-Netzes: und eine Anfangsmarkierung M0 : S ! f0; 1g Definiere Vor- und Nachbereich eines Knotens: x 2 S [ T; x = fyj9b 2 B : δ0 (b) = y ^ δ1(b) = xg; x = fyj9b 2 B : δ0 (b) = x ^ δ1(b) = yg: t 2 T ist schaltbereit bei Markierung M (s 2 t ) M (s) = 1) ^(s 2 t ) M (s) = 0) Markierung nach Schalten von t: (S; T ; B; δ0; δ1 ) Mt (s) = KAPITEL 3. PROZESSE UND SYSTEME 100 Wir führen jetzt auch paralleles Schalten ein: Zwei schaltbereite Transitionen, die sich gegenseitig nicht behindern, können gleichzeitig schalten. dies gilt auch für n unabhängige schaltbereite Transitionen. Beispiel 3.4.8 Hier ist paralleles Schalten möglich: 2 t ^ s 2 t ! 0 s 2 t ^ s 2 t ! 1 s 2 t ^ s 2 t ! 1 s 2 t ^ s 2 t ! M (s)) (s = ; A B C D ; = = ; = Schalten bei Stellen-/Transitionsnetzen mit/ohne Kapazitätsbeschränkung. Spezialfall beim Schalten einer Transition: t s Nach der bisherigen Definition kann t bei keiner Markierung schalten. Da man solche Situationen berücksichtigen will, formulieren wir die Schaltregel neu: Einen Transition ist schaltbereit, wenn 1. alle Stellen des Vorbereichs markiert sind und 2. alle Stellen des Nachbereichs, die nicht zum Vorbereich gehören, nicht markiert sind. Das Schalten erfolgt dann so: 1. alle Stellen des Vorbereichs, die nicht auch zum Nachbereich gehören, werden unmarkiert 2. alle Stellen des Nachbereichs werden markiert. E Wir haben dann elementare Transitionen: A, B, C, D, E parallele Transitionen: AjjB, AjjD, CjjB, CjjD. Der gesamte Systemzustand wird durch die Markierung des Netzes wiedergegeben (bei bekannter Struktur des Netzes). Formel: Mi : S ! f0; 1g zum Zeitpunkt i, oder Mi = f< s; Mi (s) > js 2 Sg. Definition 3.4.9 Sei P ein markiertes Petri-Netz mit einer Markierung M0 und M die Menge aller von M0 aus erreichbaren Markierungen von P. Dann wird der zugehörige Markierungsübergangsgraph G wie folgt gebildet: G ist ein gerichteter Graph. Die 3.4. PETRI-NETZE 101 Markierungen Mi 2 M bilden die knoten des Graphen. markierungen, die durch Schaltung ineinander übergehen, werden durch gerichtete Kanten verbunden. Die Kanten werden mit den zugehörigen Transitionen, elementaren oder parallelen, verbunden. Beispiel 3.4.10 zum Petri-Netz von oben: KAPITEL 3. PROZESSE UND SYSTEME 102 Schaltgraph oder Folgengeflecht des Petri-Netzes bei vorgegebener Anfangsmarkierung. Zu Beispiel von oben: B. 1 B. 2 A.1 A A||B A.2 ... A.n C.2 C.n A Bildungsregeln: Knoten = Instanzierungen von Transitionen gerichtete Kanten = Weitergabe der Schaltbereitschaft Im folgenden werden einige Begriffe zur Charakterisierung verschiedener markierter Petri-Netze eingeführt. usw. Beispiel 3.4.11 Ein weiteres Beispiel ist: Definition 3.4.12 Alle Markierungen, die von einer bestimmten Markierung M aus erreichbar sind, bilden eine Markierungsklasse von M. Alle Markierungen in der Markierungsklasse von M bilden die Knoten des Markierungsübergangsgraphen mit M als Startmarkierung. A B D.1 B C.1 B B. 3 C D Definition 3.4.13 Der Nebenläufigkeitsgrad einer Markierungsklasse ist die Maximalzahl elementarer Transitionen, die im Markierungsübergangsgraphen parallel vorkommen. zugehoeriger Markierungsuebergangsgraph: C B B||C A C B D C||D Beispiel 3.4.14 Der Markierungsübergangsgraph von oben hat Kantenbeschriftungen A, B, C, D, BjjC, CjjD. Also ist der Nebenläufigkeitsgrad der Markierungsklasse der Anfangsmarkierung gleich 2. Start C D Bemerkung: auch als Petri-Netz auffaßbar! Eine weitere Sichtweise: die Struktur des Prozesses, bestehend aus den Transitionen: Der folgende Begriff unterscheidet zwischen markierten Netzen, die leichter und solchen die schwerer zu durchschauen sind. Definition 3.4.15 Eine Markierung M heißt eine sichere Markierung, wenn für alle Markierungen ihrer Markierungsklasse gilt: Sind alle Stellen des Vorbereichs einer Transition markiert, so ist die Transition schaltbereit, d. h. die Ausgangsstellen, soweit nicht Eingangsstellen, sind unmarkiert. Andernfalls heißt die Markierung unsicher. 3.4. PETRI-NETZE 103 Beispiel 3.4.16 Das linke Netz ist sicher markiert, das rechte unsicher. KAPITEL 3. PROZESSE UND SYSTEME 104 Sei dies die Anfangsmarkierung: A F F C B W S S W D H E H F Wir analysieren jetzt die Arbeitsfähigkeit von Netzen. Definition 3.4.17 Eine Transition heißt tot bei einer gegebenen Markierung, wenn sie bei keiner Markierung der zugehörigen Markierungsklasse schaltbereit ist. Dieselben Prozesse erzeugt: Beispiel 3.4.18 Bei dieser Markierung ist keine Transition tot, schaltet D, so sind B, A und D tot. Schaltet danach E abwechselnd mit F, so ist keine weitere Transition tot. Sobald C schaltet, sind alle Transitionen tot. C E A B C D F E F Definition 3.4.20 Eine Transition ist bei einer Markierung lebendig (eigentlich müßte es ’unsterblich’ heißen), wenn es in der zugehörigen Markierungsklasse nur solche Markierungen gibt, von denen aus die Transition schaltbereit werden kann. Ist eine Transition bei der Anfangsmarkierung tot, so kann sie samt den damit verbundenen Kanten gestrichen werden, ohne daß sich die Prozesse ändern. Beispiel 3.4.19 (aus dem vorherigen Beispiel entwickelt) Beispiel 3.4.21 Die beiden Vierjahreszeiten haben nur lebendige Transitionen, auch das folgende Netz: 3.4. PETRI-NETZE 105 1. Es gibt Transitionen unter vorgegebenr Markierung, die weder tot noch lebendig sind: Sie können noch mal dran kommen, aber es ist möglich, daß sie in die Situation ’tot’ geraten. H F 2. Es gibt Markierungen, die weder tot noch lebendig sind: Es gibt lebendige Transitionen, aber dies sind nicht alle. W Tote Markierungen unterscheiden sich anschaulich oft wie folgt: Es gibt Endsituationen, denen eine Entscheidung vorausgeht, einen Prozeß zu beenden. Es gibt ferner Verklemmungen, die auf ungünstigen Entscheidungen bei Konflikten beruhen und aus Anwendersicht vermieden werden sollten. Eine formale Unterscheidung hierfür gibt es bislang nicht. S Im folgenden Netz ist nur G nicht lebendig: C F KAPITEL 3. PROZESSE UND SYSTEME 106 E G Beispiel 3.4.24 Beispiele für Verklemmungen H Bsp. 1: V Definition 3.4.22 Ein Petri-Netz heißt lebendig markiert, wenn darin alle Transitionen lebendig sind. Die Markierung heißt dann lebendige Markierung. S R Folgerung: Ein Petri-Netz ist höchstens dann lebendig markiert, wenn alle Knoten im Markierungsübergangsgraphen herausgehende Kanten besitzen. Natürlich ist diese Bedingung nicht hinreichend, wie das letztgenannte Beispiel zeigt. W V R V R||V R S W S Start Endsituation V Verklemmung W R Definition 3.4.23 Eine Markierung heißt tot, wenn es dazu keine schaltbereite Transition gibt. Folgerung: Tote Markierungen sind im Markierungsübergangsgraphen durch Knoten ohne herausführende Kanten charakterisiert. Veranschaulichung: tot lebendig Transition kommt nie wieder dran kann immer wieder dran kommen Markierung nichts geht mehr alle Transitionen können immer wieder dran kommen Man mache sich folgendes klar: Bsp. 2: c a c Verklemmung a b d c b d a Verklemmung 3.4. PETRI-NETZE 107 KAPITEL 3. PROZESSE UND SYSTEME 108 Beispiel 3.4.25 Beispiel zu Vergröberung/Verfeinerung Man kann verklemmungsfreieErsatznetze bilden: Bsp. 1: Bsp. 1: ZR R R S Sp V U EAI W E A E A Bsp. 2: feines Netz grobes Netz Bsp. 2: a c A A C b d Wir wenden uns noch einmal den nichtmarkierten Netzen zu. Wir betrachten folgende Arten von Netztransformationen: Vergröberung: Fortlassen von Detail-Information über die Struktur. Verfeinerung: hinzufügen struktureller Information. Faltung: Eine spezielle Form der Vergröberung. Abwicklung: Eine spezielle Form der Verfeinerung. Dabei wird sich folgendes ergeben: Vergröberung und Verfeinerung sind die Umkehrung voneinander, ebenso Faltung und Abwicklung. Hieran können wir die Definition der Begriffe Prozeßnetz und Systemnetz anschließen. Zunächst definieren wir als Hilfsbegriffe transitionsberandete und stellenberandete Teilnetze. B C D feines Netz grobes Netz Definition 3.4.26 Sei P ein Petri-Netz mit Knotenmenge K und 6= X K. X bildet zusammen mit allen Kanten, die Knoten aus X verbinden, ebenfalls ein Petri-Netz. Dieses heißt transitionsberandet, wenn in P alle Knoten aus X, die mit einem Konten aus K n X verbunden sind, T-Knoten sind, es heißt stellenberandet, wenn alle Knoten aus X, die mit einem Knoten aus K n X verbunden sind, S-Knoten sind. Beispiel 3.4.27 Dialog mit einem Rechner 3.4. PETRI-NETZE Benutzeraktion 1 109 Eingabe 1 Rechneraktion 1 Zustand 1 Eingabe 2 Rechneraktion 2 Zustand 2 Rechneraktion 3 Zustand 3 Ausgabe 2 Benutzeraktion 3 Eingabe 3 Ausgabe 3 Zustand 4 Durch Faltung entsteht ein Netz für ein Dialog-System: Eingabekanal Benutzer Rechner Ausgabekanal KAPITEL 3. PROZESSE UND SYSTEME Definition 3.4.28 Durch eine Vergröberung werden n 0 disjunkte transitions- bzw. stellenberandete Teilnetze durch je eine einzige Transition bzw. Stelle ersetzt. Die umkehrung heißt Verfeinerung. Definition 3.4.29 Eine Vergröberung heißt Faltung, wenn zwei direkt durch eine Kante verbundene Knoten dabei getrennt bleiben, d. h. nicht demselben Teilnetz angehören, welches durch einen Knoten ersetzt wird. Die Umkehrung heißt Abwicklung. Ausgabe 1 Benutzeraktion 2 110 Speicher Definition 3.4.30 Ein gerichtetes Petri-Netz ohne Zyklen heißt Prozeßnetz. Entsteht hieraus durch Faltung ein weiteres Netz, so ist dieses ein zugehöriges Systemnetz. Aus dem Systemnetz entstehen durch Abwicklung (verschiedene) Prozeßnetze. 3.5. DYNAMISCHE SYSTEME 3.5 Dynamische Systeme (Text fehlt) 111 112 KAPITEL 3. PROZESSE UND SYSTEME 114 KAPITEL 4. PROBLEMSTRUKTUREN UND PROBLEMSOLVING Schwierigkeiten der Darstellung Techniken und Strategien des Problemlösens Kapitel 4 Problemstrukturen und Problemsolving Problembeschreibung und Spezifikation Anforderungen an die Problembeschreibung Allgemeine Strategien Softcomputing-Ansätze des Problemsolving Fuzzy-Technik Neuronale Netze Evolutionäre Verfahren Notation in einer formalen Spezifikationssprache In diesem Kapitel befassen wir uns mit möglichen Aufgabenstellungen für den Computer, d.h. für automatische Problemlösungen, und mit Beschreibungen von Problemen. Probleme sind in diesem Zusammenhang nichts Anderes als Aufgabenstellungen. Formale Spezifikation, Datenspezifikation, Constraint Beispiel: Sortieren Einzelprobleme, Problemklassen, Probleminstanzen Constraintprobleme Optimierungsprobleme Constraint-Optimierungsprobleme Beispiel: Rucksack-Problem Heuristischer Weg 4.1 Problembeschreibung und Spezifikation Beispiel: Traveling-Salesman-Problem Algorithmischer Weg Beispiele Beispiel: n-Damen Analytischer Weg Mathematisch exakte Beschreibung und formale Spezifikation Problemarten und Darstellung von Problemen 4.1.1 Anforderungen an die Problembeschreibung Eine Problembeschreibung muß klar und verständlich sein. Einfache Probleme lassen sich in natürlicher Sprache so beschreiben. Bei komplexen Problemstellungen kommt man meistens nicht ohne Formaln aus, d.h. Teile der Beschreibung sind exakt abgefaßt, natürlich mathematisch exakt. Wir beschreiben auch einfache Probleme mathematisch exakt, erstens zur Einübung in die Methoden, zweitens aber auch im Hinblick darauf, daß exakte Beschreibungen notwendig sind, um später von Programmen beweisen zu können, daß sie das Problem lösen. Mathematisch exakte Beschreibungen von Anforderungen heißen formale Spezifikationen. Beispiel 4.1.1 Bestimme zu einer natürlichen Zahl n die kleinste Primzahl, die größer als n ist.“ ” Wahl der Darstellung 113 4.1. PROBLEMBESCHREIBUNG UND SPEZIFIKATION 115 Diese Beschreibung ist exakt und verständlich. Eine mathematisch exakte Beschreibung ist die folgende: Gegeben: n 2 N Gesucht: m 2 N mit prim(m) ^ (m > n) ^8 p : ( prim( p) ^ p > n) ! p m Man benötigt hierzu prädikatenlogische Formeln und setzt die darin vorkommenden Prädikate >, und prim als gegeben voraus. Wir können aber auch prim durch eine eigene Spezifikation beschreiben: Spezifikation prim(x): Gegeben: x 2 N Gesucht: b 2 fT RUE ; FALSE g mit b = (8y : teiler(y; x) ! y = 1 _ y = x) ^ x > 1 Auch teiler(x; y) (d.h. y ist Teiler von x) können wir weiter erklären, und zwar entweder durch eine neue Spezifikation: 116 KAPITEL 4. PROBLEMSTRUKTUREN UND PROBLEMSOLVING 4.1.2 Notation in einer formalen Spezifikationssprache In den sogenannten formalen Spezifikationssprachen wird noch stärker festgelegt, wie Spezifikationen zu schreiben sind. Wir betrachten Beispiele in Anlehnung an die Sprache Z: Beispiel 1 n:N m:N prim(m) ^ (m > n) ^ (8 p : (( prim( p) ^ p > n) ! p m)) prim(x) x:N b:B b = (8y : ((9z : (y z) = x) ! y = 1 _ y = x) ^ x > 1) Eine solche Beschreibung besteht aus drei Teilen: 1. Spezifikationskopf: Eine Überschrift oder eine Funktion mit Argumenten 2. Eine Datenspezifikation für die Eingabeparameter 3. Eine Datenspezifikation für das Resultat Spezifikation teiler(x; y): Gegeben: y; x 2 N Gesucht: b 2 fT RUE ; FALSE g b = 9z : y z = x oder durch direktes Einfügen: Der Teil 2 kann fehlen, etwa wenn wir im Beispiel 1 den Parameter n durch die Konstante 50 ersetzen. Beispiel 2 m:N prim(m) ^ (m > 50) ^ (8 p : (( prim( p) ^ p > 50) ! p m)) Spezifikation prim(x): 4.1.3 Formale Spezifikation, Datenspezifikation, Constraint Gesucht: b 2 fT RUE ; FALSE g mit Jede Datenspezifikation besteht aus einer oder mehreren Variablendeklarationen vi : Di mit Wertebereichen Di und gegebenenfalls einer einschränkenden Formel, welche ein Constraint genannt wird. Gegeben: x 2 N b = 8y : ((9z : (y z) = x) ! y = 1 _ y = x) Wir können natürlich in der allerersten Aufgabenstellung auch prim direkt ersetzen. Dies erschwert aber die Lesbarkeit. Hinzu kommt, daß wir an zwei Stellen die Ersetzung vornehmen müßten, also die Beschreibung unnötig länger machen würden. Beispiel 4.1.2 (Sortieren) Gegeben: ein Vektor (Array) A mit reellen Komponenten a1 ; : : : ; an. Gesucht: eine Umsortierung der Komponenten a01 ; : : : ; a0n, so daß a01 a02 : : : a0n. Mathematisch exakter ist folgende Formulierung: 4.1. PROBLEMBESCHREIBUNG UND SPEZIFIKATION 117 Gesucht ist eine Permutation (a01 ; : : : ; a0n) von (a1 ; : : : ; an), so daß a01 0 : : : an . 4.2 Problemarten und Darstellung von Problemen Die formale Beschreibung lautet jetzt so: Sortieren(a1 ; : : : ; an) ai : R; i = 1; : : : ; n ai : R; i = 1; : : : ; n (a01 ; : : : ; a0n ) 2 perm(a1 ; : : : ; an ) ^ ( j k ) a0j a0k ) Die Menge perm(a1 ; : : : ; an) aller Permutationen von a1 ; : : : ; an kann man auch auf der Grundlage der folgenden rekursiven Mengendefinition spezifizieren: 1. (a1 ; : : : ; an) 2 perm(a1 ; : : : ; an) 2. (b1 ; : : : ; bi; bi+1 ; : : : ; bn) 2 perm(a1 ; : : : ; an); 1 (b1 ; : : : ; bi+1; bi ; : : : ; bn ) 2 perm(a1 ; : : : ; an ). i n ; 1 ) Bei aller Vielfalt der in der Praxis auftretenden Probleme treten doch immer wieder Probleme ähnlicher Art auf, die dann eine ähnliche Behandlung erfordern. Die folgenden Problemarten werden im Bereich des Problemsolving, einem Zweig der sogenannten Künstlichen Intelligenz, der auch im dazu benachbarten Bereich des sogenannten Operations Research, einem Bindeglied zwischen Mathematik und Wirtschaftswissenschaften, modelliert und systematisch analysiert. a) Constraint Probleme (auch Erfüllungsprobleme) Diese haben folgende abstrakte Form: Gegeben: 4.1.4 Einzelprobleme, Problemklassen, Probleminstanzen Jetzt soll schärfer zwischen Einzelproblem und allgemeineren Klassen von Problemen unterschieden werden. Beispiel 4.1.3 Folgendes sind Einzelprobleme, erkennbar daran, daß sie ohne veränderliche Eingabe formuliert werden können: a) Bestimme die Fakultät von 5, d.h. 1 2 3 4 5 b) Sortiere den Array (10 7 3 6 8 2) Für solche Probleme braucht man keine öfter zu benutzenden Programme, z.B. wird a) gelöst“ durch die Anweisung: ” Schreibe 120“ ” und b) durch Schreibe (2 3 6 7 8 10)“. ” Probleme mit veränderlichen Eingabeparametern heißen Problemklassen. Beispiel 4.1.4 a) Bestimme die Fakultät von n b) Sortiere den Array (a1 ; : : : ; an) Ein Einzelproblem aus einer Klasse heißt eine Probleminstanz dieser Klasse. KAPITEL 4. PROBLEMSTRUKTUREN UND PROBLEMSOLVING 118 n Variablen x1 ; : : : ; xn; x 1, n Wertebereiche D1 ; : : : ; Dn, so daß gilt: xi : Di m Constraints, das sind logische Formeln c1 (x1 ; : : : ; xn); : : : ; cm(x1 ; : : : ; xn), in denen die Variablen alle oder zum Teil vorkommen. Gesucht: n Werte a1; : : : ; an; ai 2 Di , so daß c1 (a1 ; : : : ; an) = : : : = cm (a1 ; : : : ; an) = T RUE Beispiel 4.2.1 (n-Damen) Auf einem n n-Schachbrett sind n Damen so zu verteilen, daß sich keine zwei Damen gegenseitig bedrohen, d.h. keine gemeinsame Zeile oder Spalte besetzen und auch nicht diagonal benachbart sind. n Variablen: x1 ; : : : ; xn (xi entspricht der Figur in Zeile i) n Wertebereiche: Di = D = 1; : : : ; n. Folgende Constraints: xi 6= x j für i 6= j, das sind n2 = n(n2;1) Constraints. (Bedeutung: nicht in derselben Spalte) i + xi 6= j + x j für i 6= j, i ; xi 6= j ; x j für i 6= j, das sind n(n ; 1) Constraints. (Bedeutung: nicht diagonal benachbart) Hier ist eine formale Spezifikation dazu: N ; Damen(n) n:N n4 xi : f1; 2; : : : ; ng; i = 1; 2; : : :; n i 6= j ) x1 6= x j ^ i + xi 6= j + x j ^ i ; xi 6= j ; x j ; 4.2. PROBLEMARTEN UND DARSTELLUNG VON PROBLEMEN 119 Weitere Beispiele zu Constraint-Problemen: b) Optimierungsprobleme Die abstrakte Form ist die folgende: Gegeben: Beispiel 4.2.2 (Kryptoarithmetik) Es handelt sich um Rätsel-Aufgaben wie SEND +MORE MONEY n Wertebereiche D1 ; : : : ; Dn eine Abbildung f : D1 : : : Dn ! R Gesucht: Darstellung als Constraint-Problem: Variable: fS; E ; N ; D; M ; O; R; Y g = V n Werte a1 ; : : : ; an; ai 2 Di , so daß f (b1 ; : : : ; bn) f (a1 ; : : : ; an) für alle bi 2 Di Wertebereiche: f0; 1; : : : ; 9g (Spezialfall Minimierungsproblem) Constraints: bzw. u= 6 v für alle verschiedenen u v 2 V 103 S + 102 E + 103 M + 102 O = 104 M + 103 O + 102 N f (b1 ; : : : ; bn) f (a1 ; : : : ; an) für alle bi 2 Di ; + + + 10 N 10 R 10 E + + + D E Y ähnliche Aufgaben: KAPITEL 4. PROBLEMSTRUKTUREN UND PROBLEMSOLVING 120 HEMD+HOSE=JACKE ROAD+CROSS=DANGER Beispiel 4.2.3 (Graphenfärbung) Gegeben sei ein Graph G = (V; E ) (jedes e 2 E hat die Form fv1 ; v2g; v1; v2 2 V ) und eine natürliche Zahl k; 1 k jV j. Gesucht ist eine Abbildung f :V ! f1 ; : : :; kg mit f (u) 6= f (v), falls fu; vg 2 E Variable: Knoten Wertebereiche: f1; : : : ; kg für alle Constraints: u 6= v für alle fu; vg 2 E (Die Standard-Constraint-Formulierung benötigt die Funktion f nicht!) Dieses Problem ist aus zwei Gründen wichtig: 1. Es ist eine abstrakte Form vieler praktischer Probleme. 2. Es gehört zu den Problemen, die in der Informatik als sehr schwierig erkannt wurden (für k > 2). (Spezialfall Maximierungsproblem) Man kann Minimierungsprobleme in Maximierungsprobleme umwandeln und umgekehrt. Ein Spezialfall ist die ganzzahlige Optimierung mit f : D1 : : : Dn ! N oder ! Z. Beispiel 4.2.4 (Travelling-Salesman-Problem) Gegeben seien n Städte“ 1; 2; : : :; n (vereinfacht für s1 ; s2 ; : : : ; sn ) und Distanzen ” di j 2 N1 (= f1; 2; : : :g) für alle i; j 2 f1; : : : ; ng; i 6= j, wobei di j = d ji gilt. Gesucht ist die kürzeste Rundtour durch alle Städte, wobei jede Stadt genau einmal zu besuchen ist. Darstellung in der Standard-Form: ein Wertebereich D = perm(1; : : : ; n), Abbildung f : D ! N, f (i1 ; : : : ; in) = n;1 ∑ dikik +1 + din i1 k=1 als zu minimierende Funktion. Dieses Problem ist für die Praxis von großer Bedeutung. Es ist ein sehr schwieriges Problem unter der Zielsetzung, in annehmbarer Zeit eine Lösung zu ermitteln. c) Constraint-Optimierungsprobleme Die beiden vorher genannten Problemarten treten jetzt kombiniert auf. Gegeben: 4.2. PROBLEMARTEN UND DARSTELLUNG VON PROBLEMEN 121 122 n Variable x1 ; : : : ; xn ; n 1, Beispiel 4.2.6 (n-Damen) Das Constraint i 6= j ) xi 6= x j ^ i + xi 6= j + x j ^ i ; xi 6= j ; x j n Wertebereiche D1; : : : ; Dn mit xi : Di , wird überführt in die zu minimierende Funktion f : f1; : : : ; ng n ! N, m Constraints ck (x1 ; : : : ; xn); k = 1; : : : ; m, f (x1 ; : : : ; xn) = jf(i; j)j(i < j) ^ (xi = x j _ i + xi = j + x j _ i ; xi = j ; x j )gj. eine Abbildung f : D1 : : : Dn ! R 3. Eine Optimierungsbedingung läßt sich durch eine logische Formel, also durch ein Constraint ersetzen. Gesucht: n Werte a1 ; : : : ; an; ai 2 Di , so daß ck (a1 ; : : : ; an) = T RUE für k = 1; : : : ; m und f (b1 ; : : : ; bn) f (a1 ; : : : ; an) (bzw. ) für alle bi 2 Di , die auch die Bedingung ck (b1 ; : : : ; bn) = T RUE ; k = 1; : : : ; m erfüllen. Beispiel 4.2.5 (Rucksackproblem) Es geht darum, eine optimale Auswahl von Gegenständen in einen Rucksack zu packen, ohne dessen Kapazität zu überschreiten. Für die n Objekte sind Werte vi 2 N und Kapazitätsanteile ki 2 N gegeben. Die Kapazität des Rucksacks wird als K 2 N angegeben. Optimal ist die Auswahl mit maximalem Wert. Die drei vorgestellten Problemarten sind untereinander austauschbar, man kann also die Problemart wählen. Hierfür sind in der Praxis die Verständlichkeit der Darstellung und die Wahl der Lösungsverfahren ausschlaggebend. Folgendes sind die wichtigsten Überlegungen hierzu: 1. In Constraint-Optimierungsproblemen lassen sich die Constraints durch Umdefinition der Wertebereiche eliminieren. KAPITEL 4. PROBLEMSTRUKTUREN UND PROBLEMSOLVING Diese Umformung hat mehr prinzipiellen Charakter und ist nicht so sehr von praktischer Bedeutung. Zum Schluß dieses Abschnittes sei darauf hingewiesen, daß das Auffinden einer Darstellung zu einem gegebenen Problem sich bereits schwierig gestalten kann. Dies ist insbesondere dann der Fall, wenn das Problem sich auf anschauliche Vorstellungen stützt, deren abstrakte Komplexität dem Betrachter nicht bewußt ist. Beispiel 4.2.7 (Pentominos) Hier handelt es sich um eine Legespiel, also die Überdeckung von Flächen mit vorgegebenen Spielsteinen unterschiedlicher Form. 4.3 Techniken und Strategien des Problemlösens Dieser Abschnitt soll einen Einblick in die grundsätzlichen Vorgehensweisen beim Lösen von Problemen mit Hilfe des Computers geben. Hierauf basieren unter anderem die Technik des strukturierten Programmierens Methoden der kombinatorischen Optimierung und des Operations Research Methoden der Künstlichen Intelligenz Wir stellen drei prinzipiell unterschiedliche Ansätze vor: Zum Constraint-Optimierungsproblem mit x1 ; : : : ; xn; D1; : : : ; Dn; c1(xi ); : : : ; ck (xi ); f ergibt sich folgendes reines Optimierungsproblem: x; D = f(a1 ; : : : ; an) 2 D1 : : : Dnjc j (a1 ; : : : ; an) = T RUE ; j = 1; : : : ; kg; f . 2. Zu reinen Constraint-Problemen lassen sich Funktionen konstruieren, welche ihr Minimum dort annehmen, wo die Constraints erfüllt sind. 1. Die analytische Vorgehensweise: Diese Methode stützt sich auf das abstrakte, mathematische Problemverständnis. 2. Die algorithmische Vorgehensweise: Im Vordergrund steht der Prozeß der Problemlösung. Durch geschickte Zerlegung des Prozesses gewinnt man eine Darstellung des Lösungsprozesses. 4.3. TECHNIKEN UND STRATEGIEN DES PROBLEMLÖSENS 123 Es werden Erfahrungen bei der Lösung von Problemen eingesetzt. 4.3.1 Die analytische Vorgehensweise Es wird eine umfangreiche Problemanalyse vorgenommen. Dabei können sich Hinweise auf eine besonders günstige Lösungskonstruktion ergeben, oder es läßt sich sogar mathematisch eine Formel für die Lösung herleiten. Beispiel 4.3.1 (Fibonacci-Zahlen) Welches ist die n-te Zahl der Folge y 1 + 0; 5x y 6 ; 2x y Eine mathematische Analyse ergibt mit x1 = Beispiel 4.3.3 (Lineare Optimierung) Minimiere f (x1 ; : : : ; xn), so daß gi (x1 ; : : : ; xn ) 0; i = 1; : : : ; k, mit linearen Funktionen f ; gi . Beispiel: y 0 (d.h. ;y 0) f ib(i + 2) = f ib(i + 1) + f ib(i)? ; ; Benutze die n = 5-Lösung erst auf den 5 5-Feldern des 25 25-Brettes und in jedem der besetzten Felder noch einmal. f (x; y) = 3x + 2y = min! f ib(0) = f ib(1) = 1, f ib(n) = Beispiel: n = 5 / n = 25: x 1 (d.h. 1 ; x 0) f ib(n); n = 0; 1; 2; : : :, x2n+1 x2 KAPITEL 4. PROBLEMSTRUKTUREN UND PROBLEMSOLVING 2. Gewisse Lösungen für n lassen sich auf n2 ausdehnen. 3. Die heuristische Vorgehensweise: x1n+1 x1 124 p 1 1 2+2 5; x2 = 1 2 p 1 ;2 5 Durch Einsetzen wird dieses Ergebnis leicht bestätigt. Man braucht also nicht alle Glieder der Folge bis zum n-ten Element zu errechnen. Beispiel 4.3.2 (n-Damen) Eine Analyse zeigt, daß man aus Lösungen für bestimmte n Lösungen für andere n konstruieren kann: 1. Hat man eine Lösung für n, bei der die Hauptdiagonale nicht belegt ist, so kann man diese zu einer Lösung für n + 1 erweitern. Beispiel: n = 4 / n = 5: 111111 000000 000000 111111 000000 111111 y=6-2x 000000 111111 000000 111111 000000 111111 000000 111111 000000 111111 000000 111111 000000 111111 0000000000 1111111111 000000 111111 0000000000 1111111111 y=1+0,5x 000000 111111 0000000000 1111111111 000000 111111 0000000000 1111111111 000000 111111 0000000000 1111111111 000000 111111 0000000000 1111111111 000000 111111 0000000000 1111111111 000000 111111 0000000000 1111111111 000000 111111 0000000000 1111111111 000000 111111 0000000000 1111111111 000000 111111 000000 111111 000000 111111 000000 111111 1111 0000 0000 1111 0000 1111 0000 1111 x Die mathematische Analyse ergibt: Man braucht die optimale Lösung nur unter den Eckpunkten zu suchen (! Simplex-Verfahren). 4.3.2 Die algorithmische Vorgehensweise 11 00 00 11 00 11 Es wird versucht, den Lösungsweg auf die Lösung von Teilproblemen zurückzuführen. Erreicht man dabei am Ende triviale Teilprobleme, so läßt sich der gesamte Lösungsprozeß hinschreiben. Der wichtigste Fall ist die rekursive Rückführung auf dasselbe Problem. 4.3. TECHNIKEN UND STRATEGIEN DES PROBLEMLÖSENS 125 Beispiel 4.3.4 (Sortieren) Sortieren(a1 ; : : : ; an) läßt sich erreichen durch 1. Sortieren von (a1 ; : : : ; ai ); (i n 2) 126 KAPITEL 4. PROBLEMSTRUKTUREN UND PROBLEMSOLVING 4.3.4 Allgemeine Strategien Ebenfalls aus Erfahrungen stammen die allgemeinen Strategien des Problemsolving. Sie rücken bestimmte Betrachtungsweisen in den Vordergrund. 2. Sortieren von (ai+1 ; : : : ; an) Vorwärts- und Rückwärts-Strategie 3. Zusammenmischen der sortierten Listen Sind eine Anfangs- und eine Endsituation gegeben und ein verbindender Weg mit Zwischenschritten gesucht, so konzentriert sich die Vorwärts-Strategie auf den Weg vom Anfang her, die Rückwärts-Strategie auf den Weg vom Ende her. Beispiele: Logisches Schließen, Planungen Das Verfahren wird rekursiv angewendet. Beispiel dazu: Sortiere(7 1 5 8 6 2 4 3 9). Diese Vorgehensweise führt zu einer schnellen Programmierung durch den Benutzer, ergibt aber auch ein recht gutes Verfahren. Beispiel 4.3.6 (Erkennen eines Wortes zu einer gegebenen Grammatik) Hier spricht man auch von der Top-Down-Methode: Start beim Startsymbol S, Ableitungsschritte bis zum Wort w, und von der Bottom-Up-Methode: Start mit w und Rückwärts-Ableitungsschritte bis S. 4.3.3 Die heuristische Vorgehensweise Generate & Test Wenn die analytische Vorgehensweise höchstens zu aufwendigen Lösungen führt, die auf dem Computer eine zu hohe Rechenzeit erfordern (etwa astronomisch hoch) und auch die algorithmische Vorgehensweise keine zusätzlichen Einsichten liefert, bleibt folgender Ausweg: Man führt eine systematische Suche nach der Lösung durch und setzt allgemeine Erfahrungen ein, um den Aufwand dabei zu vermindern. Eventuell verzichtet man auch auf exakte oder optimale Lösungen und begnügt sich mit Approximationen. Beispiel für eine heuristische Technik, die Aufwand spart, aber zur optimalen Lösung führt: kürzester Weg im 8er-Puzzle. Die heuristische Technik lautet: unter den möglichen Schritten wähle man einen solchen, für den die durchgeführten Schritte plus die Anzahl der noch falschen Positionen am geringsten ist. Mann kann diese Heuristik noch verbessern. Beispiel für eine heuristische Technik für Optimierungsprobleme, die Aufwand spart, aber nicht das Optimum liefert: Man erzeugt erst Lösungskandidaten, von denen man vermutet, daß sie eine Lösung darstellen könnten, und testet aus, ob sie tatsächlich die Bedingungen an eine Lösung erfüllen. Die Strategie ist für Constraint-Probleme geeignet, nicht für Optimierungsprobleme. Exhaustive Search Diese Strategie kann aus der vorherigen hergeleitet werden, indem der Wertebereich voll durchsucht wird. Damit lassen sich nun auch Optimierungsprobleme lösen, im Allgemeinen aber nur mit einem zu hohen Aufwand. Es gibt viele Strategien auf ähnlich abstrakter Ebene. Sie gehören zum Wissensbestand der Künstlichen Intelligenz beziehungsweise der Wissensverarbeitung. 4.4 Softcomputing-Ansätze des Problemsolving Die Greedy-Heuristik Baue die Lösung schrittweise auf. Wähle dabei in jedem Schritt die Alternative, die aus momentaner Sicht am günstigsten erscheint. Beispiel 4.3.5 (Travelling-Salesman-Problem) Beginne in 1. Wähle stets die nächstgelegene Stadt unter den noch vorhandenen. Man kann zeigen, daß dabei die optimale Tour eventuell nicht erreicht wird. Die Bezeichnung Softcomputing bezieht sich auf Methoden, die wie die FuzzyTechnik diskrete Unterscheidungen wie 0 oder 1, FALSE oder T RU E, durch glättende Übergänge zu ersetzen versuchen. Im Wesentlichen handelt es sich dabei um die Anwendung Neuronaler Netze die Fuzzy-Technik und 4.4. SOFTCOMPUTING-ANSÄTZE DES PROBLEMSOLVING 127 evolutionäre Verfahren Es haben sich folgende weitgehend gemeinsame Ideen als entscheidend für den Erfolg der Methoden herausgebildet: Black-box“-Lösungen ” Analogien zu natürlichen Systemen Kontinuierliche Daten Vage Werte Probabilistische Werte Holistische Problemsicht Die herkömmlichen Methoden heißen, bezogen auf die Informatik, symbolorientiert. Aus der Sicht der aufgezählten Ideen betrachten wir die wichtigsten Ansätze: 128 KAPITEL 4. PROBLEMSTRUKTUREN UND PROBLEMSOLVING das gewünschte Verhalten des Netzes. Am Ende weiß man - im Erfolgsfall - daß das Netz in Einzelfällen wie gewünscht funktioniert, aber nicht im Detail, warum es funktioniert. Dies ist offensichtlich eine Systemkonstruktion als Blackbox“” Lösung. Das natürliche Vorbild der Neuronalen Netze ist das Gehirn bei Mensch und Tier. Die darauf basierende Systembeschreibung führt zunächst zu kontinuierlichen Daten, die aber diskretisiert werden. Es gehört zum typischen Verhalten Neuronaler Netze, auf geringe Abweichungen bei Eingabedaten, stetig und weitgehend unempfindlich zu reagieren. Die Werte brauchen daher nur vage vorzuliegen. Es gibt darüber hinaus spezielle Fuzzy-Versionen Neuronaler Netze. Man spricht hierbei von der Neuro-Fuzzy-Technik. Probabilistische Werte treten nur in bestimmten Situationen auf, etwa wo eine willkürliche Entscheidung vorzunehmen ist. Betrachtet man jedoch Netze, die bei Eingabe oder Verarbeitung von Informationen Störungen unterworfen sind, so treten systematisch probabilistische Werte auf. Das Verhalten Neuronaler Netze wird durch Systemgleichungen beschrieben, - es sind ja dynamische Systeme - im kontinuierlichen Fall sind dies Differentialgleichungen, im diskreten Fall Iterationsgleichungen. Dies belegt die holistische Sicht. 4.4.1 Fuzzy-Technik Ein Fuzzy-System wird aus Komponenten für Fuzzyfizierung, Regelanwendung und Defuzzyfizierung konstruiert. Dabei bezieht sich die Blackbox-Idee auf die einzelnen Regeln. Ein Whitebox-Ansatz würde aus der Aufgabenstellung heraus die Regeln begründen. Die Analogie zu natürlichen Systemen bezieht sich auf das Lernen der Regeln und die Struktur der Regeln, dies geschieht nämlich ähnlich wie beim Menschen oder bei Tieren. Im Vordergrund der Technik stehen die Fuzzy-Werte, also die vagen Werte. Dadurch entstehen intern kontinuierliche Daten. Probabilistische Werte spielen in der Fuzzytechnik keine Rolle. Eine holistische (ganzheitliche) Systemsicht liegt der Begründung der Regeln zugrunde: Das System als Ganzes zeigt das durch die Regeln formulierte Verhalten. 4.4.2 Neuronale Netze Soll ein künstliches Neuronales Netz zur Lösung bestimmter Aufgaben gebildet werden, so legt man eine bestimmte Struktur der Neuronen und ihrer synaptischen Verbindungen zugrunde und betrachtet die Gewichte mi j zu den Synapsen zwischen Neuronen xi und y j als noch zu bestimmende Parameter. Durch Trainieren des Systems sorgt man dafür, daß sich solche Werte mi j einstellen, die das Netz zu seiner Aufgabe befähigen. Es erfolgt also ein ständiges Anpassen an 4.4.3 Evolutionäre Verfahren Die natürliche Evolution dient hier als Vorbild, um Lösungen ohne analytische Konstruktion als Blackbox-Lösungen zu gewinnen. Ein evolutionäres Verfahren stellt ein Suchverfahren für ein gewünschtes Konstrukt dar, bei dem viele Approximationen simultan betrachtet werden und schrittweise verbessert werden. Wir nehmen als Beispiel die Lösung eines Problems, wie beispielsweise des Travelling-Salesman-Problems. Es wird eine sogenannte Population von N Rundtouren gebildet (N passend, für die Wahl dieses Parameters wie auch anderer braucht man Erfahrungen). Jedem Individuum der Population wird eine Fitneß als Qualitätsmaß zugeordnet (Länge der Tour). Die Population wird nun in vielen diskreten Schritten so fortentwickelt, daß die Wahrscheinlichkeit eines Individuums zu überleben oder Nachkommen zu erzeugen mit seiner Fitneß korreliert ist. Nachkommen entstehen durch Mutation sowie durch Kreuzung. Dabei werden die Individuen durch sogenannte Chromosomen beschrieben, auf die sich die genannten genetischen Operatoren anwenden lassen. Man erwartet, daß die Populationen gegen Populationen mit Individuen hoher Fitneß konvergieren und dadurch Lösungen liefern. 4.4. SOFTCOMPUTING-ANSÄTZE DES PROBLEMSOLVING 129 4.4.4 Simulated Annealing Bei dieser Methode handelt es sich um ein Suchverfahren, bei dem nach einem der Physik entnommenen Vorbild Approximationen für eine Problematik ermittelt werden. Anders als bei Evolutionären Verfahren wird aktuell immer eine Approximation behandelt. Von der momentanen Approximation ausgehend sucht man eine andere per Zufall aus der Nachbarschaft aus - man muß also vorher definieren, wie die Approximationen untereinander benachbart sind - und macht mit dieser weiter, falls keine Verschlechterung der Approximation eintritt. Bei einer Verschlechterung entscheidet man zufällig mit vorgegebener Wahrscheinlichkeit, ob die Approximation genommen wird oder nicht. Dabei gilt: Je geringer die Verschlechterung ∆ ist, um so höher ist die Wahrscheinlichkeit der Annahme, und je weiter die Zeit“ des Iterationsverfahrens fortgeschritten ist, um so geringer wird ” (bei gleichem ∆) die Wahrscheinlichkeit der Annahme. Die Analogie zur Physik ist die folgende. Ein physikalisches System, wie zum Beispiel eine Metallschmelze, durchläuft einen Prozeß, bei dem mit fortschreitender Zeit die Temperatur T und ebenfalls die Energie des Systems abnimmt, jedoch kann die Energie auch um ∆ zunehmen, jedoch mit einer Wahrscheinlichkeit e;k T (k eine Konstante) ∆ Diese Formel wird beim Simulated Annealing ( annealing“ = Erstarrung einer ” Schmelze) auch verwendet. Der Energie entspricht das Bewertungsmaß für die Approximationen derart, daß niedrige Energie mit einer guten Bewertung korrespondiert. Beim Travelling-Salesman-Problem und ähnlichen Problemen der kombinatorischen Optimierung gilt Simulated Annealing zur Zeit als ein sehr erfolgreiches Suchverfahren. 130 KAPITEL 4. PROBLEMSTRUKTUREN UND PROBLEMSOLVING KAPITEL 5. ALGORITHMEN UND PROGRAMMIERUNG 132 5.2 Der Algorithmusbegriff Kapitel 5 Algorithmen und Programmierung Der klassische Algorithmusbegriff geht auf Donald Knuth zurück und stellt eine Präzisierung intuitiver Begriffe wie Rezept“, Prozeß“, Methode“, Technik“, ” ” ” ” Prozedur“ und Routine“ dar. präziser: ” ” Definition 5.2.1 (Algorithmus) Ein Algorithmus ist ein ein endlich beschriebener abstrakter Handlungsplan für die diskrete Informationsverarbeitung, der die Eigenschaften der Endlichkeit (der Ausführung), der Bestimmtheit, der Funktionalität und der Effektivität besitzt. nach D.E. Knuth: 5.1 Übersicht Der Algorithmusbegriff Algorithmus nach Knuth, Eigenschaften Verzicht auf Terminierungseigenschaft erster Überblick über Kontrollstrukturen mathematische Sicht: berechenbare Funktionen Hinweis auf Turing-Maschinen und λ-Kalkül Nichtdeterministische Algorithmen Verzicht auf Bestimmtheit Finiteness (Endlichkeit) ”An algorithm must always terminate after a finite number of steps.” (sonst: ’computational method’) Definiteness (Bestimmtheit) ”Each step of an algorithm must be precisely defined; the actions to be carried out must be rigorously and unambiguously specified for each case.” Input/Output (Funktionalität) ”An algorithm has zero or more inputs. i.e. quantities which are given to it initially before the algorithm begins. These inputs are taken from specified sets of objects. An algorithm has one or more outputs, i.e. quantities which have a specified relation to the inputs.” Effectiveness (Effektivität) ”All of the operations to be performed in the algorithm must be sufficiantly basic that they can in principle be done exactly and in a finite length of time by a man using pencil and paper.” Erläuterungen und Bemerkungen: Motivation nichtdeterministische Lösungswege nichtdeterministische Resultate Programmierung nach Floyd Ausführungsarten Realisierung des Nichtdeterminismus 131 Zur Endlichkeit: Wir wissen aus theoretischen Untersuchungen, daß man einem Programm grundsätzlich nicht immer ansehen kann, ob seine Ausführung endlich ist oder nicht. Eine Beschränkung von Programmen auf solche, deren Endlichkeit garantiert werden kann, würde die Mächtigkeit des Computers erheblich einschränken. Zur Bestimmtheit: Diese Forderung schließt Nichtdeterminismus aus. Sie sichert die logische Eindeutigkeit der Programmschritte. Zur Funktionalität: 5.2. DER ALGORITHMUSBEGRIFF 133 Hiermit wird im Grunde gefordert, die Aufgaben eines Algorithmus zu spezifizieren. Zur Effektivität: Es gibt mathematisch exakte Definitionen, die nicht effektiv ausführbar sind, da nur endlich viele Ausführungsschritte erlaubt sind. Beispiel: limn!∞ fi für Ausdrücke fi. Effektivität ist nicht zu verwechseln mit Effizienz. Letztere zielt auf einen im Verhältnis zur Leistung möglichst geringen Aufwand an Zeit bzw. an Speicher. Verlangt man von den Eigenschaften, die für einen Algorithmus gefordert werden, die Nachprüfbarkeit, so muß auf die Endlichkeit verzichtet werden. Knuth hatte hierfür die Bezeichnung ’computational method’ vorgeschlagen. Im InformatikHandbuch definiert Pomberger den Algorithmus so: Ein Algorithmus ist eine präzise, d.h. in einer festgelegten Sprache abgefaßte, ” endliche Beschreibung eines schrittweisen Problemlösungsverfahrens zur Ermittlung gesuchter Größen aus gegebenen Größen, in dem jeder Schritt aus einer Anzahl ausführbarer eindeutiger Aktionen und einer Angabe über den nächsten Schritt besteht. Ein Algorithmus heißt abbrechend, wenn er die gesuchten Größen nach endlich vielen Schritten liefert, andernfalls heißt der Algorithmus nicht abbrechend.“ Die Forderung der Bestimmtheit kann abgeschwächt werden, indem für einzelne Schritte endlich viele präzise definierte Alternativen zugelassen werden. Dies kann – muß aber nicht – die Funktionalität verletzen. Diese muß dann ersetzt werden durch relational festgelegte Beziehungen zwischen Eingaben und Ausgaben. Wir werden dies ausführlicher diskutieren in dem Abschnitt über nichtdeterministische Algorithmen. Ein erster Überblick über Kontrollstrukturen Nach dem vorangehenden gehören zu einem Algorithmus Einzelschritte, deren Verhältnis zueinander durch den Algorithmus ebenfalls festgelegt sein muß. Da die Ausführung einen diskreten Prozeß ergibt, kommen hierfür die Techniken zur Planung diskreter Prozesse in Frage: sequentielle Ausführung parallele Ausführung. ggf. mit Synchronisierung Alternativen, und zwar deterministisch (mit einer Bedingung) bzw. nichtdeterministisch 134 KAPITEL 5. ALGORITHMEN UND PROGRAMMIERUNG Wiederholung, z.B. in Form von Schleifen Eine weitere, bisher nicht erwähnte Technik ist hinzuzunehmen: dies ist die Unterprogrammtechnik Man kann in einen Algorithmus einen anderen als Zulieferer einbauen. Bei Programmen spricht man dann von einem Unterprogramm. Die Unterprogrammtechnik dient der besseren Übersicht, dem schnelleren Programmieren und der geschickteren Programmentwicklung, sie erhöht aber nicht die Mächtigkeit der Programmierung. In der Programmierung heißen die genannten Techniken Kontrollstrukturen. Die Algorithmusdefinitionen sind, so wie sie im vorangehenden Text gegeben wurden, nicht im mathematisch-theoretischen Sinne präzise. Die funktionalen Abbildungen, die durch Algorithmen realisiert werden, sind aber – noch vor Fertigstellung des ersten universellen Computers – mathematisch exakt beschrieben worden. Es gibt hierzu u.a. die folgenden Ansätze (vgl. die historische Übersicht in 1.1): partiell-rekursive Funktionen f: Nk ! N; k 0, mathematisch definiert Turingberechenbare Funktion, definiert mit Hilfe von Turing-Maschinen λ-berechenbare Funktionen, definiert mit Hilfe des λ-Kalküls von A. Church 5.3 Nichtdeterministische Algorithmen Beim Lösen von Problemen stoßen wir auf folgende Tatsachen: 1. Oft führen sehr viele verschiedene Programme, die sich gerade in den Kontrollstrukturen unterscheiden, zu demselben Endergebnis. Im Hinblick auf das Ergebnis ist also eine genaue Festlegung der Reihenfolge einzelner Schritte nicht wichtig. Beispiel 5.3.1 Sortieren von ai ,. . . ,an Die folgenden nichtdeterministischen Anweisungen reichen aus: Solange i,j existieren mit 1 i < j n, so daß ai > a j , vertausche die beiden Elemente. 5.3. NICHTDETERMINISTISCHE ALGORITHMEN 135 Oder: Solange i,j existieren mit 1 i, i+1 = j < n, so daß ai > a j , vertausche die beiden Elemente. (2 = nichtdeterministische Alternative) Hier ist nur blinder Nichtdeterminismus möglich. Wir erweitern das Beispiel: x := 2; y := 3; z := x + y 2 x * y; if prim(z) then success drucke z; 2. Oft möchte man nur eine von mehreren als gleichwertig angesehenen Lösungen haben und sich im Programm dafür nicht festlegen. Beispiel 5.3.2 Gesucht ist eine Primzahl < 20. Eine spezielle Aufgabe ergibt sich, wenn wir, etwa für statistische Experimente, Zufallszahlen programmieren sollen. In den obigen Fällen wie in diesem benötigt man nichtdeterministische Programme und – dem zugrunde liegend – Algorithmen. Wir definieren einen nichtdeterministischen Algorithmus wie folgt: Es handelt sich um einen endlich beschriebenen abstrakten Handlungsplan für die diskrete Informationsverarbeitung, der die Eigenschaften der Bestimmtheit für endlich viele Alternativen, der Relationalität in Bezug auf die Ausgaben und der Effektivität besitzt. Je nachdem, ob auch Endlichkeit vorliegt, heißt der nichtdeterministische Algorithmus abbrechend (terminierend) oder nichtabbrechend. Bei der Ausführung nichtdeterministischer Algorithmen (natürlich nur für die nichtdeterministischen Verzweigungen) unterscheiden wir drei Fälle: 1. Blinder Nichtdeterminismus: Es wird mit Hilfe einer geeigneten Zufallsmethode irgendeine der Alternativen ausgewählt. 2. Anglischer Nichtdeterminismus: Es wird versucht, die Auswahl so zu treffen, ein im Algorithmus vorgesehenes Erfolgsereignis eintritt bzw. Mißerfolgsereignis nicht eintritt, falls dies möglich ist. Gedanklich kann dies durch richtiges Raten erfolgen, praktisch durch Wiederholung des gesamten Ablaufs oder durch parallele Aufspaltung des Ausführungsprozesses. 3. Dämonischer Nichtdeterminismus: Dabei wird ein Mißerfolgsereignis angestrebt, ein Erfolgsereignis vermieden. Beispiel 5.3.3 x := 2; y := 3; z := x + y 2 x * y; drucke z; KAPITEL 5. ALGORITHMEN UND PROGRAMMIERUNG 136 else failure; Jetzt sind alle drei Ausführungsarten möglich. Das Erfolgsereignis success tritt ein, wenn prim(z) = TRUE, das Mißerfolgsereignis failure tritt ein, wenn prim(z) = FALSE. Also gilt: Blinder Nichtdeterminismus liefert 5 oder 6. Anglischer Nichtdeterminismus liefert 5. Dämonischer Nichtdeterminismus liefert 6. Ergänzend sei noch auf die statistische Variante der Ausführung hingewiesen: Dabei kommt es jetzt darauf an, für eine häufige Ausführung des Programms festzulegen, wie die einzelnen Entscheidungen verteilt sein sollen. Ein wichtiger Fall ist die Gleichverteilung. Ein Programm enthalte eine nichtdeterministische Alternative mit n Möglichkeiten ai . Bei mehreren Ausführungen dises Programms erwartet man dann etwa gleichviele Varianten für jede der Alternativen. Sind dies X Ausführungen, so nennen wir Xn den Erwartungswert für jede der Alternativen. Jede Alternative ai wird dann mit der Wahrscheinlichkeit pi = 1n ausgeführt. Jetzt wird auch klar, was eine Ausführung mit der Wahrscheinlichkeit p, 0 p 1, bedeutet, wie sie beim Simulated Annealing vorkommt: Bei X Ausführungen ist der Erwartungswert der betreffenden Variante X*p. Programmieren nichtdeterministischer Algorithmen nach R. Floyd: Man verwendet sog. prozedurale Techniken für deterministische Algorithmen, etwa Flußdiagramme oder Sprachen ähnlich C oder PASCAL, und zusätzlich choice(n): als Integer-Funktion, die eine Integer-Zahl aus 1 bis n auswählt success: als Erfolgsereignis failure: als Mißerfolgsereignis Es wird angelicher Nichtdeterminismus unterstellt. Beispiel 5.3.4 “6 aus 49“ 5.3. NICHTDETERMINISTISCHE ALGORITHMEN for j := 1 to begin a[j] := for k := 1 to if a[k] = a[j] end. 137 6 do choice(49); j - 1 do then failure KAPITEL 5. ALGORITHMEN UND PROGRAMMIERUNG 138 5.4 Programmierparadigmen und Programmierstile Programmiersprachliches Paradigma: Modellvorstellung für die Abarbeitung von Programmen, welche die Einzelheiten der Programmierung bestimmt. Beispiel 5.3.5 Sortieren von a[1],. . . ,a[n] Programmierung: for k := 1 to n do begin j := choice (n - k + 1); x := a[k]; a[k] := a[k + j - 1]; a[k + j - 1] := x; end; for k := 1 to n - 1 do if a[k]> a[k + 1] then failure. Beispiel 5.3.6 Gleichung erfüllen x := choice(100); if x * x * x - 5 * x * x - x + 105 = 0 then success. Der Vorgang der Entwicklung und Niederschrift von Programmen, das sind sprachlich abgefaßte Algorithmen im erweiterten Sinn. Programmierstile sind teils von Paradigmen geprägt, teils folgen sie allgemeineren Strategien für die Entwicklung und Niederschrift von Programmen. Wir befassen uns zunächst mit verschiedenen Paradigmen: imperative oder prozedurale oder Von-Neumann-Programmmierung funktionale Programmierung regelbasierte Programmierung Logikprogrammierung objektorientierte Programmierung Realisierung des Nichtdeterminismus in der Praxis 5.4.1 Das Paradigma der imperativen Programmierung Es gibt die folgenden Möglichkeiten: Jeder elementare Schritt der Abarbeitung ist eine Zuweisung eines Wertes an eine Variable. Die Reihenfolge der Schritte ergibt sich aus den verwendeten VonNeumann‘schen Kontrollstrukturen, dies sind physikalischer Zufallsgenerator: Das Ereignis hängt von veränderlichen Außenfaktoren ab. Pseudozufallsgenerator mit vorgegebener Verteilung: Es wird programmtechnisch eine scheinbar zufällige Folge von Zahlen erzeugt, so daß eine vorgeschriebene Verteilung (z.B. Gleichverteilung) möglichst gut eingehalten wird. In Programmiersprachen gibt es hierzu oft eine Standard-Funktion ’random’. Man kann sich leicht überlegen, wie man die Ausführung mit Wahrscheinlichkeit p programmiert, wenn man eine Pseudozufallsfunktion ’random’ zur Verfügung hat, die näherungsweise gleichverteilte Zahlen erzeugt(!). Sequenzen, deterministische Alternativen und Schleifen. Eventuell tritt noch die parallele bzw. nebenläufige Ausführung hinzu, sowie eine Unterprogrammtechnik. 5.4. PROGRAMMIERPARADIGMEN UND PROGRAMMIERSTILE 139 Aus diesen Vorgaben ergeben sich folgende konkret festzulegende Sprachanteile für die imperative Programmierung: Werte der Variablen: dies definiert die sog. Datenstruktur Zuweisung und andere Anweisungen Sequenzen und Nebenläufigkeit Weitere Strukturen werden später erklärt. Zuweisung und andere Anweisungen Abstrakt, und etwas allgemeiner als die meisten Programmiersprachen, vereinbaren wir die simultane Zuweisung v1 ; v2; : : : ; vn := e1 ; e2; : : : ; en . Alternativen: einseitige, zweiseitige, mehrseitige Schleifen: Sprünge, Zählschleifen, unbeschränkte Schleifen Unterprogrammtechnik KAPITEL 5. ALGORITHMEN UND PROGRAMMIERUNG 140 Dabei sind die vi entweder einfache Variable, bezeichnet durch Namen, z.B. x, alpha, wert3, anzahl alt, Datenstrukturen Man legt nicht nur die Mengen der Werte fest, die benutzt werden sollen, sondern zugleich die Operationen, die darauf angewendet werden sollen. Beides definiert dann eine Datenstruktur. Es gibt zusätzliche Operationen, die eine Datenstruktur in eine andere abbilden. Hier werden im folgenden die nachstehend aufgeführten Datenstrukturen verwendet. Name Werte Operationen boolean TRUE, FALSE :; ^; _; !; ; 6 character ’a’,. . . ,’Z’,’0’,. . . ,’9’ =, 6=; <; >; ; u. Sonderzeichen (Ergebnis boolean) (alle geordnet) integer f;Nmin; ;Nmin+1; : : : ; Nmaxg +, -, *, div (ganzzahl. Division), mod (Modulrest), " (Exponentiation), =, 6=; <; >; ; (mit Ergebnis boolean) natural f 0, 1, . . . , Nmaxg Operationen von Integer real rationale und +, -, *, /," (mit Ergebnis real); darstellungsabhängige Werte =, 6=; <; >; ; (mit Ergebnis boolean) zwischen ;Rmin undRmax string Folgen aus character k (Konkatenation), length mit Länge 0 (ergibt natural) array r-dimensionale Anordnung Zugriff auf ein Element von Werten eines bestimmten durch nachgestelltes [i1,. . . ,ir ] Typs, r 1 oder indizierte Variable, bezeichnet durch einen Namen für eine ArrayVariable und einen nachfolgenden Indexausdruck, z.B. x[17], vector[i - 1], M[i,k], ggf. auch y[i][k] usw. Die Ausdrücke auf Indexposition werden als Terme mit Operationen zu ’integer’ gebildet. Danach ist z.B. möglich x[3 * k - m * (n + 2)]. Die Ausdrücke ei sind ebenfalls als Terme zu bilden mit den Operationen, die zu dem Typ passen, z.B. für eine integer-Variable: x := (z div 3) * 7 + 1 für eine boolean-Variable: b := p ^: q. Die Zuweisungen einer simultanen Zuweisung sind streng simultan auszuführen: x, y := y, x vertauscht die Werte. Dies gilt nicht für die Sequenz x := y; y := x . Wir vereinbaren noch weitere elementare Aktionen, die – wie die Zuweisung – Anweisungen heißen: Die Sprunganweisung goto <Marke>. Diese bezieht sich darauf, daß vor jede Anweisung im Programm eine oder mehrere Marken gesetzt werden können: 5.4. PROGRAMMIERPARADIGMEN UND PROGRAMMIERSTILE < 141 Marke > : < Anweisung > KAPITEL 5. ALGORITHMEN UND PROGRAMMIERUNG 142 if fi Ausdruck> then < Anweisung1> else < Anweisung2 > < bzw. < Marke1 > < Marken > : < Anweisung >. Die Sprunganweisung wird zur Realisierung bestimmter Schleifen verwendet. Die Eingabeanweisung lautet Wertn >:<Anweisungn > else <Anweisungn+1 > endcase n 1. mit nicht indizierten Variablen vi , Die Ausgabeanweisung out e1 ; : : : ; en mit Ausdrücken (Termen) e1; : : : ; en; n 1. Die Erfolgsanweisung success sowie die Mißerfolgsanweisung failure für nichtdeterministische Programmierung nach Floyd. Dann werden auch Aufrufe von choice in der Form choice(< natural >) zugelassen. Ein solcher Aufruf ist ein Ausdruck vom Typ natural. Sequenzen und Nebenläufigkeit Wir schreiben Sequenzen als Aufreihung mit Trennzeichen ’;’ : a1 ; a2; : : : ; an (a1 ; a2; : : : ; an) geschrieben. Alternativen Die einseitige Alternative lautet Ausdruck > then mit optionalem else-Teil und Abkürzungen wie Wert1 >; <Wert2 >; : : : :<Anweisung>. < Die Ausführung beruht auf der Auswertung von <Ausdruck> und der durch den erhaltenen Wert gesteuerten Ausführung einer der Anweisungen. Schleifen Mit Hilfe von Marken, die eindeutig gesetzt sein müssen, und Sprunganweisungen, können Schleifen (in einem eher unstrukturierten Programmierstil) geschrieben werden. Die Zählschleife werde so geschrieben: for <Variable >=<Anfangswert> by <Inkrement> to < Endwert> until <Ausdruck> do <Anweisung> od mit folgenden Varianten: ’= <Anfangswert>’ ist optional und implizit ’=1’, ’by ist optional und implizit ’by 1’, ’until <Ausdruck>’ ist optional und implizit ’until FALSE’. Laufvariable und Werte sind entweder vom Typ integer oder vom Typ real. Der Typ von <Ausdruck> ist boolean. Die unbeschränkte Schleife lautet Nebenläufigkeit wird in der Form < case < Ausdruck > of <Wert1 >:<Anweisung1 >; .. . < in v1 ; v2; : : : ; vn if Die mehrseitige Alternative hat die Form while < Anweisung > fi Dabei muß < Ausdruck > einen booleschen Wert liefern. Als < Anweisung > kommen die elementaren Anweisungen sowie die durch die Kontrollstrukturen definierten zusammengesetzten Anweisungen in Frage. Die zweiseitige Alternative lautet Ausdruck> do < Anweisung> od. < Hierbei ist <Ausdruck> vom Typ boolean. Als Erweiterung benutzen wir die unbeschränkte Schleife mit mehreren Ausgängen: do < <Anweisung1 > ; exit <Ausdruck1 >; : : : ; Anweisungn >; exit <Ausdruckn+1 > od 5.4. PROGRAMMIERPARADIGMEN UND PROGRAMMIERSTILE 143 Die Schleife wird verlassen, wenn ein exit mit einem booleschen Ausdruck erreicht wird, dessen Wert gerade TRUE ist. Das Paradigma der imperativen Programmierung beherrscht weitgehend die Programmierpraxis. Dem Paradigma folgen die maschinennahen Sprachen, die frühen sog. höheren Programmiersprachen wie FORTRAN, ALGOL, PL/I, COBOL sowie die Sprachen PASCAL, C und viele andere. in x,y; u := x2 ; y; v := x + y3 ; z := u3 + u2 v + 2 u v + v2; out z Das Programm wird stärker funktional, wenn die Ergebnisformel hinter out steht und möglichst wenige Anweisungen davor vorkommen: in x,y; u := x2 ; y; v := x + y3 ; out u3 + u2 v + 2 u v + v2 5.4.2 Das Paradigma der funktionalen Programmierung Während bei der imperativen Programmierung Aktionen, meist Zuweisungen, durch Kontrollstrukturen verknüpft werden, stehen bei der funktionalen Programmierung die folgenden Überlegungen im Vordergrund: Man kann die verbleibenden Zuweisungen ebenfalls aufgeben und die Ausdrücke für u und v in die Ergebnisformel einsetzen. Dann ist aber die Auswertung sehr ineffizient. Hier ist eine Formulierungsalternative für den Ergebnisausdruck: 1. Das gewünschte Ergebnis wird als ein komplexer Ausdruck in Abhängigkeit von den Eingaben formuliert, sozusagen als Formel (ergebnis = ) f(: : :,eingaben,: : :) 2. Um eine solche Formel bilden zu können, muß man oft Funktionen vorweg definieren. Das funktionale Programm enthält dann Funktionsdefinitionen neben Funktionsanwendungen (= Applikationen, daher spricht man auch von applikativen Sprachen). Beispiel 5.4.1 Sei x ein Array der Länge n. Wir wollen die Summe der Quadrate der Elemente bilden. In imperativer Programmierung: in x; sum := 0; for i to out sum KAPITEL 5. ALGORITHMEN UND PROGRAMMIERUNG 144 u3 + u2 v + 2 u v + v2 where u == x2 ; y; v == x y3 Darin können die Angaben hinter where als Gleichungen angesehen werden. Diese (auf Landin zurückgehende) Technik läßt sich direkt in die Technik des λKalküls umformen: (λu(λv(u3 + u2 v + 2 u v + v2))) bedeutet: die Formel hat u und v als Parameter. Diese Formel wird jetzt angewandt auf x2 - y für u und x y3 für v: (((λu(λv(u3 + u2 v + 2 u v + v2)))x2 ; y)x y3 Definition: mit Parametern u,v Anwendung In vollständiger λ-Notaion sieht sieht auch der arithmetische Ausdruck anders aus, z.B. schreibt man n do sum := sum + x[i]*x[i] od; In der Sprache APL (A Programminglanguage, von K.E. Iverson, ca. 1961) kann dies funktional programmiert werden: x 2 (Eingabe von x) + / x * x (komponentenweise Multiplikation, dann Aufsummierung) Beispiel 5.4.2 Wir gehen aus von folgendem imperativen Programm: (+ (a b c)) statt (a + b + c). Auf dem λ-Kalkül basiert die funktionale Programmiersprache LISP. Beispiel 5.4.3 Es soll die Fakultät programmiert werden. Nach dem imperativen Paradigma bietet sich eine Zählschleife an: 5.4. PROGRAMMIERPARADIGMEN UND PROGRAMMIERSTILE 145 in n; i,s := 0,1; for j to n do s := 1; for i to n do s := s * i od; out s Bemerkung: Die simultanen Zuweisungen lauten sequentialisiert so: i := 0; s := 1 und i := i + 1; s := s * i Man findet hierfür auch eine Formulierung im λ-Kalkül und in LISP. Wir wollen uns jedoch stattdessen zwei Formulierungen in moderneren funktionalen Sprachen ansehen: In FP (nach J.W. Backus) wird die Funktion ’fakultät’ zusammenkomponiert: fak = if null then 1 else mult [id,fak pred] mult :< x; y > = x * y ’:’ kennzeichnet die Anwendung. Verwendet werden die Funktionen null : x = if x = 0 then TRUE else FALSE id : x = x, 1 : x = 1 pred : x = if x = 0 then 0 else x - 1 ’’ bezeichnet die sequentielle Verknüpfung von Funktionen, [: : : ; : : :]die parallele. Damit ergibt sich z.B. mit [id, fak pred]: 3 = <3, fak : pred : 3 >: fak : 3 = if null : 3 then 1 : 3 else mult : < 2, fak : pred : 3> = mult : <3, fak : 2> Zwischenrechnung ergibt fak : 2 = : : : = mult : <2, fak : 1>, fak : 1 = : : : = mult : <1, fak : 0>, fak : 0 = if null : 0 then 1 : 0 else : : : = 1 : 0 = 1, also fak : 1 = mult : < 1; 1 > = 1 * 1 = 1, fak : 2 = mult : < 2; 1 > = 2 * 1 = 2, fak : 3 = mult : < 3; 2 > = 3 * 2 = 6. KAPITEL 5. ALGORITHMEN UND PROGRAMMIERUNG 146 Die Technik erscheint uns deswegen ungewohnt, weil in der Definition die Parameter eliminiert sind. In noch moderneren Sprachen wie MIRANDA werden die Parameter (wieder) mitgeführt: fac 0 = 1 fac (n + 1) = (n + 1) * fac n Hier ist noch eine weitere Formulierung in MIRANDA, bei der die whereKonstruktion sich auf eine verwendete Funktion bezieht: fac n = product [1...n] where product [ ] = 1 product (a : x) = a*product x Dabei gilt: [ ] steht für die leere Liste, a: [b c: : :d]= [a b c: : :d], [a: : :b] = [a, a+1, : : :, b]. Es zeigt sich, daß funktionale Formulierungen oft die Datenstruktur einer Liste benötigen. 5.4.3 Das Paradigma der regelbasierten Programmierung Die Grundoperationen hierbei sind Anwendungen vorgegebener Regeln, die im Prinzip die Form Muster vorher ! Muster nachher haben. Ein Programm besteht dann aus einer im Prinzip ungeordneten Menge von Regeln fL1 ! R1 ; L2 ! R2 ; : : : ; Ln ! Rn g. Die Ausführung erfolgt auf einer Datei, die zu Beginn aus den Eingabedaten und zum Schluß aus den Ergebnisdaten besteht. Die Ausführung folgt dabei dem folgenden Schema, welches RAC (Recognize-Act-Cycle) genannt wird: 5.4. PROGRAMMIERPARADIGMEN UND PROGRAMMIERSTILE 147 KAPITEL 5. ALGORITHMEN UND PROGRAMMIERUNG 148 5.4.4 Das Paradigma der logikorientierten Programmierung Es existiert noch eine anwendbare Regel nein Ende p(t1; : : : ; tn). ja Dabei ist p ein n-stelliges Prädikatssymbol und t1; : : : ; tn sind prädikatenlogische Terme. Regeln in PROLOG sind Formeln Auswahl und Anwendung einer anwendbaren Regel Beispiel 5.4.4 Fakultät: fak 0 fak n Ein Programm besteht aus Fakten und Regeln, d. h. prädikatenlogischen Aussagen. Ziel der Anwendung des Programms ist es, eine als Aussage formulierte Eingabe, eine sogenannte Anfrage an das System, zu bestätigen. Die Ausführung ist dann eine Kette logischer Schlußfolgerungen. Die wichtigste Logiksprache ist PROLOG (Programming in Logic). Fakten in PROLOG sind Formeln p(t1; : : : ; tn) ! 1 where n > 0 ! n*fak(n-1) Hier muß eine Regel ggf. innerhalb eines Datums angewendet werden: fak 3 ) 3*fak 2 ) 3*2*fak 1 ) 3*2*1*fak 0 ) 3*2*1*1 ) 6 Soll das Muster der Regel das volle Datum abdecken, so kann man wie folgt programmieren: fak n ! [0 1 n] [i k n] where i<n [n k n] ! k ! [i+1 k*(i+1) n] Beispiel 5.4.5 Sortieren: In INTRAN (Sprachprojekt an der TU Clausthal) läßt sich folgendes Programm schreiben: forms X,Y : real ; A,B : row real rules [A X Y B] where X>Y ! [A Y X B]. Hierin sind A,B als Sequenzen (row) von real-Zahlen definiert, wobei leere Sequenzen erlaubt sind. Regelbasierte Sprachen finden hauptsächlich in der künstlichen Intelligenz Anwendung. Beispiele sind STRIPS und OPS 5. q1 (: : :); q2 (: : :); : : : ; qn(: : :) Hierin treten rechts ebensolche Formeln auf, die durch Anwendung von Prädikatssymbolen auf Terme entstehen. Sie sind konjunktiv verknüpft, d.h. das Komma steht für ’^’. Eine Anfrage lautet ?-r1 (: : :); : : : ; rk (: : :). Ein nichtnummerisches Beispiel 5.4.6 vater(max,emil). vater(emil,fritz). vater(fritz,hugo). rothaarig(fritz). rothaarig(max). vorfahr(x,y) vater(x,y). vorfahr(x,y) vorfahr(x,z),vater(z,y). (vater von max ist emil) Frage: Gibt es jemanden, der einen rothaarigen Vorfahren besitzt und selbst Vorfahre eines Rothaarigen ist? ?- vorfahr(x,y),rothaaig(y),vorfahr(z,x),rothaarig(z). Die Abarbeitung erfolgt so, daß versucht wird, die Anfrage zu bestätigen. Dabei wird eine durch Fakten bestätigte Formel entfernt (TRUE ^ Rest = Rest) und Substitutionen (z.B. max für x) werden gemerkt. Anwendungen von Regeln führen zu entsprechenden Ersetzungen. Die Anfrage wird von links nach rechts gelesen und 5.4. PROGRAMMIERPARADIGMEN UND PROGRAMMIERSTILE 149 die (bekannten) Aussagen des Programms von oben nach unten. Läßt sich die Formel nicht mit den bereits gewählten Aussagen bestätigen, so werden solange neue Versuche gestartet, bis die Herleitung gelingt oder alle vorgesehenen Möglichkeiten erschöpft sind. Dieses Durchprobieren erfolgt mittels Backtracking. Formal liegt ein Widerspruchsverfahren vor, bei dem der sog. Resolutionsschluß angewendet wird. Das Ergebnis heißt entweder ‘nein‘ oder ‘ja‘, wobei im letzten Fall die Variablensubstitutionen angegeben werden, die den Schluß ermöglichen. Im Beispiel: ja: x = emil. KAPITEL 5. ALGORITHMEN UND PROGRAMMIERUNG 150 5.5 Grundkonzepte der Programmierung Man kann die Programmierung als eine Ingenieurstätigkeit ansehen, die sich jedoch nicht auf physikalische oder chemische sondern auf abstrakte Prozesse bezieht, die es zu planen gilt. Damit wird klar, daß hier sowohl Zielvorstellungen als auch Modelle und Konzepte eine wichtige Rolle spielen. 5.5.1 Zielsetzungen bei der Programmierung Korrektheit 5.4.5 Das Paradigma der objektorientierten Programmierung Die Grundideen der objektorientierten Programmierung lassen sich etwa wie folgt skizzieren: Es gibt sog. Objekte, welche wie die Objekte der realen Welt statische Informationen und dynamische Aktivitäten verknüpfen. Beispiel: Ein Kreis besitzt die statischen Informationen Koordinaten des Mittelpunkts: x,y Radius: r Bei kleinen Programmen reicht hierzu in der Praxis eine sorgfältige Analyse zusammen mit einigen Tests. Bei großen Programmen benötigt man ein ganzes Bündel von ineinandergreifenden Maßnahmen: Dazu können wir ihn mit Aktivitäten ausstatten: Radius verändern um Faktor: f Mittelpunkt verschieben: dx, dy Die Objekte gehören sog. Klassen an. Es gibt Klassenhierarchien, in denen Informationen vererbt werden können. Die Objekte können ggf. auch Nachrichten austauschen. Zum Beispiel kann ein Objekt ein anderes Objekt veranlassen, eine seiner Aktivitäten (diese heißen Methoden) auszuführen. Die Informationsverarbeitung erfolgt dann durch koordinierte Zusammenarbeit von Objekten. exakte Spezifikation der Aufgabenstellung (schwierig!) exakte Spezifikation der Semantik der Sprache (existiert meist, wird aber selten gelesen) formale Korrektheitsbeweise (schwierig, Theorie und Praxis klaffen hier noch weit auseinander) unterstützende Software für die Korrektheit (fehlt weitgehend) systematische Tests (in der Praxis vorhanden) Transparenz der Programme nötig: siehe unten Programmierkonzepte, die die Fehleranfälligkeit herabsetzen: strukturiertes Programmieren, objektorientierter Entwurf transparentes Sprachkonzept Transparenz (der Programme, für die Sprache sei diese vorausgesetzt) Man sollte die folgenden Maßnahmen anwenden: Dokumentation des Programmentwicklungsprozesses Mnemotechnik zur Verbesserung der Selbstdokumentation 5.5. GRUNDKONZEPTE DER PROGRAMMIERUNG 151 Problemangepaßte Strukturen von Daten und Operationen verwenden: hierzu gibt es z. B. die höheren und abstrakten Datenstrukturen Systematischer Programmentwicklungsprozeß: Techniken hierfür vermittelt das Gebiet des Software-Engineering Effizienz Die Zielsetzung der Effizienz betrifft die ökonomische Nutzung der Ressourcen Zeit und Speicher. Für die theoretischen Analysen stellt die Komplexitätstheorie Hilfsmittel bereit. Praktische Analysen können direkt erkennbare Verbesserungen im Einzelfall aufzeigen. Systematische Messungen zur Überprüfung sind notwendig. Anpaßbarkeit, Wiederverwendbarkeit Es ist wichtig, die Verwendung der Programme für etwas veränderte Aufgaben vorzusehen. Hierfür kann es nützlich sein, die Aufgabenstellung gleich etwas abstrakter zu fassen und durch Parameter auf den konkreten Fall abzustimmen. 152 KAPITEL 5. ALGORITHMEN UND PROGRAMMIERUNG Turing-Programme (siehe Theoretische Informatik I und II). Unseren Computern etwas ähnlicher ist der Universal Calculator. Dieser besitzt z. B. Anweisungen der Art x(i) := 0, x(i) := x(i) + 1, x(i) := x(i) - 1, x(i) := x(j). (siehe ebenfalls Theoretische Informatik I und II). 5.5.3 Unterprogrammtechnik Die Unterprogrammtechnik gehört zu den fundamentalen Ideen der Programmierung. Prinzip der Arbeitsteilung Programmteile für Teilaufgaben werden aus dem Gesamtprogramm herausgelöst. Die einzelnen Teilprogramme können von verschiedenen Personen programmiert werden. Dazu sind exakte Schnittstellendefinitionen notwendig. Unterprogramme als Konsequenz des Algorithmusbegriffs Algorithmen sind bereits intuitiv (siehe Algorithmusbegriff nach D. E. Knuth) so definiert, daß ganze Algorithmen innerhalb anderer Algorithmen wie elementare Schritte auch vorkommen können. In der exakten Berechenbarkeitstheorie wird dies noch deutlicher. Offene Unterprogrammtechnik, Makrotechnik 5.5.2 Das Konzept der virtuellen Maschine Die großen Erfolge, welche die Software-Entwicklung verzeichnet, gründen zu einem erheblichen Teil auf dem Konzept der virtuellen Maschine. Eine reale Maschine, also ein Computer, hat eine feste Maschinensprache. Eine virtuelle Maschine existiert zunächst nur gedanklich, wird aber durch Simulation auf einer realen Maschine so realisiert, daß sie für den Programmierer real wirkt. Die Programmiersprache der virtuellen Maschine kann weitgehend frei gewählt werden. Darin liegt gerade der Vorteil, den die Programmiersprachen bieten. Virtuelle Maschinen und Programmiersprachen sind also zueinander duale Konzepte. Wenn wir in C oder in PASCAL programmieren, so beziehen wir uns auf die virtuellen Maschinen C-Maschine, PASCAL-Maschine. Reale Maschinen (natürlich nur Computer) sind universelle Maschinen, bis auf die Tatsache, daß sie nur einen endlichen Speicher besitzen. Die Universalität sichert zu, daß jede andere informationsverarbeitende Maschine darauf simuliert werden kann. Auch für theoretische Untersuchungen benötigt man virtuelle Maschinen. Das bekannteste Beispiel ist diue Turing-Maschine. Ihr entspricht die Sprache der Die älteste Unterprogrammtechnik ist die Makrotechnik oder auch Technik der offenen Unterprogramme genannt. Ein Makro ist eine Befehlsfolge. Diese kann auch parametrisiert sein. Makros besitzen eine Aufrufform, z. B. ein Name zusammen mit den Parametern. Die Ausführung eines Makros erfolgt durch Ersetztechnik. Die zugehörige Befehlsfolge, der sog. Rumpf des Makros, wird, ggf. mit den mitgegebenen Parametern als Text in die Befehlsfolge des Hauptprogramms eingefügt. Dann wird die Ausführung des Hauptprogramms fortgesetzt. Geschlossene Unterprogramme Die heute vorherrschende Unterprogrammtechnik ist die der geschlossenen Unterprogramme. Wie die Makros besitzen auch diese eine Aufrufform mit Parametern und einen Rumpf. Virtuell gesehen erfolgt aber die Ausführung auf einer separaten Maschine. Der Rumpf wird also nicht in das aufrufende Programm eingefügt. Die separate Maschine zur Ausführung des Unterprogramms wird auf der realen Maschine nur simuliert. Die Begriffe Hauptprogramm (aufrufendes Programm) 5.5. GRUNDKONZEPTE DER PROGRAMMIERUNG 153 und Unterprogramm (aufgerufenes Programm) sind natürlich relativ. Die Rolle der Parameter ist komplexer als es auf den ersten Blick scheint. Es gibt hierzu spezielle Parameterauswertungs-Mechanismen (call by value, call by name, call by reference, call by need etc.). In imperativen (d. h. Von-Neumann-) Sprachen unterscheidet man Unterprogramme, die aus Sicht des Hauptprogramms Anweisungen darstellen, diese heißen meist Prozeduren, und solche, die aus Sicht des aufrufenden Programms Ausdrücke darstellen. Letzteres sind Funktionsunterprogramme und sollten nur einen Wert abliefern. Verändern sie auch noch den Programmzustand, so spricht man von einem Seiteneffekt. Eine transparente Programmierung sollte nur seiteneffektfreie Funktionen verwenden. Standardunterprogramme gehören zur Implementation einer Sprache. – die while-Schleife. Es ist wichtig zu wissen, daß diese Strukturen völlig ausreichen. Sprünge sind zum Beispiel entbehrlich. Aus der Theorie weiß man, daß es zu jedem Programm mit beliebigen Sprüngen (vom sog. Label-Typ) ein Programm nach Dijkstra gibt. Allerdings läßt sich dieses nicht systematisch aus dem anderen herstellen. Diese Resultate sind das Ergebnis der sog. gotoKontroverse unter den Informatikern. Modulares Programmieren Hier tritt die Arbeitsteilung stärker in den Vordergrund. Aus dem Teilprogramm wird der Modul. Dieser faßt zusammengehörige Deklarationen und Anweisungen in einer Einheit zusammen. Es erfolgt eine Unterteilung in modulinterne und modulexterne Information. Das verbergen der modulinternen Information heißt Information-Hiding. Die modulexterne Information wird auch Schnittstelle genannt Programmierung im Großen Das Schreiben kleiner Programme ist relativ leicht. Man führt die Lösung einer gestellten Aufgabe auf die Ausführung einiger elementarer Schritte zurück. Bei großen Programmen zeigt sich, daß erstens das Auffinden einer algorithmischen Lösung nicht so einfach ist und zweitens die Transparenz des entstehenden Programms schwerer zu erreichen ist. Zur Lösung dieses generellen Problems haben sich - historisch gesehen in der nachstehenden Reihenfolge - die folgenden Techniken entwickelt: KAPITEL 5. ALGORITHMEN UND PROGRAMMIERUNG 154 Objektorientierte Programmierung Die Weiterentwicklung der Moduln zu Einheiten, die sowohl statische als auch dynamische Informationen tragen und in hierarchischen Klassen organisiert sind, führt zur objektorientierten Programmierung. Die inzelnen Moduln bzw. Objekte tauschen Botschaften untereinander aus. Strukturiertes Programmieren Hierbei nimmt man eine systematische Zergliederung der Aufgabe vor, nämlich – sequentiell: Zerlege die (Teil-)Aufgabe in Teile, die nacheinander gelöst werden können. – alternativ: Zerlege die (Teil-)Aufgabe in Teile, die Alternativen darstellen. – rekursiv, iterativ: Stelle die (Teil-)Aufgabe als Wiederholung von Aufgaben dar. Aus diesen Vorstellungen entwickelten Dijkstra und andere Informatiker in den 70er-Jahren Kontrollstrukturen für imperative Programmiersprachen. Der sog. Dijkstra-Typ für Programmiersprachen sieht demnach folgende Kontrollstrukturen vor: – die Sequenz (durch ’;’ ausgedrückt) – die Alternative (if - then - else) 5.5.4 Variable Kontexte und Deklarationen Befehle werden durch Niederschriften, also durch Texte, dargestellt. Generell unterscheidet man bei Zeichen (in der Zeichenlehre, das heißt in der Semiotik) deren Syntax, Semantik und Pragmatik: Die Syntax bezieht sich auf die Zeichen selbst, die Semantik auf die Bedeutung und die Pramatik auf alle Beziehungen in der Realität. Geht man von einem syntaktischen Zeichen aus (das wir uns jetzt am besten als eine Folge von Symbolen vorstellen), so hängt dessen Semantik von einem jeweils gültigen Kontaxt ab. Z. B. benötigt der Befehl x := y +1 als Kontext die Wertze von x und y sowie die Vereinbarung, was ’+’ bedeutet. In Programmiersprachen dien die Deklarationen zur Festlegung von Kontexten. Durch Deklarationen können zum Beispiel folgende Informationen festgelegt werden: Variable Typen und Datenstrukturen Operationen und Operatoren 5.5. GRUNDKONZEPTE DER PROGRAMMIERUNG Prioritäten zwischen Operationen Resultate (insbesondere in sog. deklarativen Sprachen) Moduln und Objekte. 155 156 KAPITEL 5. ALGORITHMEN UND PROGRAMMIERUNG KAPITEL 6. INFORMATION UND NACHRICHT 158 benötigen immer eine Vereinbarung. Diese nennen wir Kontext. Die Darstellungen der Information können konkret und materiell sein wie z. B. eine Verkehrsampel, aber sie können auch selbst abstrakt sein. Buchstaben und Zahlen sind z. B. abstrakt, ebenso Worte und Sätze. Die Immateriellität der Information hat weitreichende Konsequenzen insbesondere Kapitel 6 Information und Nachricht die leichte Transportierbarkeit, die beliebige Kopierbarkeit und die Speicherbarkeit auf unterschiedliche Arten. Information und Entscheidung bedingen einander Der Begriff der Information wird auch in der Informatik meistens nur intuitiv verstanden. Die Notwendigkeit einer mathematischen Präzisierung trat zuerst bei dem Problem der Übertragung von Informationen auf. In diesem Kapitel wird dieser Aspekt der Information näher untersucht. 6.1 Information, Daten und Nachrichten Bereits vor der Entwicklung der Informationsverarbeitung durch den Computer trat der Begriff der Information im natürlichen Sprachgebrauch auf. Wir betrachten einige wichtige Eigenschaften der Information: Information bezieht sich auf Sachverhalte In den DIN-Festlegungen ist dies durch folgende Erklärung ausgedrückt: Infor” mation ist Kenntnis von Sachverhalten“. Zum Beispiel enthält der Satz Auf dem ” Brocken liegt Schnee.“ eine Information, die sich auf einen konkreten Sachverhalt bezieht, der etwas mit dem Harz und den dortigen Witterungsbedingungen zu tun hat. Es ist offenkundig, daß eine solche Information zutreffend sein kann. Information ist abstrakt, immateriell und bedarf einer Darstellung Die Information ist weder mit dem Sachverhalt identisch noch mit der speziellen Form, in der sie beschrieben wird. Sie existiert nur als Objekt einer geistigen Vorstellungswelt. Gleiches gilt ja für die Zahlen. Auch diese sind abstrakt und von speziellen Darstellungen zu unterscheiden. Die römische Zahldarstellung VII und die arabische Darstellung 7 stellen die gleiche abstrakte Zahl dar. Darstellungen 157 Beim planmäßigen Handeln gründen sich Entscheidungen auf Information. Aber umgekehrt ist auch Information das Ergebnis realer oder ideeller Entscheidungen. Hiervon machen wir z. B. Gebrauch, wenn wir Information durch Fragen ermitteln, deren Beantwortung Fallunterscheidungen herbeiführen. So kann man z. B. mit n Ja-Nein-Fragen 2n verschiedene Sachverhalte unterscheiden. Zugleich erhalten wir hier einen Hinweis auf die notwendige Form der Informationsdarstellung: die durch 2n Ja-Nein-Fragen ermittelte Information benötigt mindestens n Angaben, mit denen sich jeweils Ja und Nein unterscheiden lassen, d. h. n Bit. In der Informationstheorie, die genauer eine Informationsübertragungstheorie (englisch: Mathematical Theory of Communication) ist, bezeichnet man die Angabe der zur Darstellung notwendigen Anzahl von Bits als Informationsgehalt. Hierauf werden wir am Ende dieses Kapitels genauer eingehen. Für die Verarbeitung von Information ist diese Sichtweise nicht besonders geeignet. Hingegen läßt sich die intuitive Auffassung von Information unabhängig von dem Ansatz der Informationstheorie formalisieren: Definition 6.1.1 (Beschreibung, Bedeutung) Gegeben sei eine Menge S von Sachverhalten, eine Menge Z von Zeichen und eine Menge K von Kontexten, d. h. Vereinbarungen, so daß jedes k 2 K eine Relation :k auf Z S festlegt; z :k s heiße z bedeutet s im Kontext k“. ” Dabei soll stets gelten: z :k s ^ z :k s0 ) s = s0 (Eindeutigkeit bei gegebenem Kontext): Für z :k s heißt hz; ki 2 Z K eine Beschreibung von s 2 S und s heißt Bedeutung von z im Kontext k. 6.1. INFORMATION, DATEN UND NACHRICHTEN 159 Bemerkung: Wir lassen auch zu, daß Z eine Teilmenge von S ist, das heißt, Zeichen können eventuell auch als Sachverhalte angesehen werden. Dann gibt es die Möglichkeit, daß ein Zeichen die Bedeutung eines anderen Zeichens darstellt. Intuitiv stellen zwei Paare hz; ki; hz0 ; k0i die gleiche Information dar, wenn sie Beschreibungen desselben Sachverhalts sind. Hierauf gründet sich die folgende Definition von Information. 160 KAPITEL 6. INFORMATION UND NACHRICHT Zeichenvorrat ( character set“) ” Darunter versteht man eine endliche Menge von verschiedenen Elementen, die der Informationsdarstellung dienen soll. Zeichen ( character“) ” So nennt man ein Element aus einem Zeichenvorrat. Definition 6.1.2 (Darstellung) Sei x ein Sachverhalt. Dann heißt die Klasse aller Beschreibungen hz; ki von x die x zugeordnete Information Ix, in Formeln: Ix = fhz; ki j z :k xg. Jedes Paar hz; ki mit z :k x heißt eine Darstellung von Ix . Bemerkung: Informationen sind auf diese Weise als Äquivalenzklassen von Beschreibungen gleicher Bedeutung erklärt. Hierzu gibt es in der Mathematik eine Analogie. Kardinalzahlen sind als Äquivalenzklassen von Mengen gleicher Mächtigkeit definiert. Auf diesem Zusammenhang hat der Erkenntnistheoretiker G. Klaus zuerst hingewiesen. Er definiert Information als Äquivalenzklasse von Signalen gleicher Bedeutung, in Formeln etwa Ix = fz j z : xg. Hierbei treten also Kontexte nicht auf. Hier sind einige Beispiele für Kontexte und Beschreibungen: x = x + 1 :FORTRAN Erhöhung des Wertes von x um 1“ ” x := x + 1 :PASCAL Erhöhung des Wertes von x um 1“ ” Summe der Elemente 1, 2, 3“ + / 1 2 3 :APL ” Wir stellen die Sprechweisen zu der Relation ’:’ noch einmal zusammen: A :k B heißt A bedeutet B im Kontext k A trägt die Information IB (d. h. die Information über B) im Kontext k. hA ki ist eine Beschreibung von B hA ki ist eine Darstellung der Information IB. ; ; Soweit haben wir prinzipiell geklärt, was Informationen sind und wie sie dargestellt werden können. Der nächste Schritt besteht darin, eine systematische Darstellung von Informationen zu modellieren. Hierbei werden die Begriffe und Definitionen der Norm DIN 44300: Informationsverarbeitung - Begriffe“ zugrunde ” gelegt. Alphabet Dies ist ein Zeichenvorrat mit definierter Reihenfolge der Elemente. Bemerkung: In der theoretischen Informatik wird Alphabet oft nur als Zeichenvorrat definiert, ohne Ordnung. Unäre, binäre, ternäre, . . . , n-äre Informationsdarstellungen Dies sind Darstellungen auf der Basis von 1, 2, 3, . . . , n Zeichen. Beispiel 6.1.3 unäre Darstellung: lll. . . l, d. h. die Zahl n 2 N wird durch n Striche dargestellt. binäre Darstellung: 0,1,10,11,110,. . . d. h. das Alphabet besteht aus 2 Zeichen ternäre Darstellung wie der Morsecode mit Zeichen für “kurz“,“lang“ und “Pause“ Es folgen weitere grundlegende Begriffsdefinitionen: Ein Binärzeichen (binary element, binary digit, abgekürzt BIT) ist ein Zeichen eines binären Zeichenvorrats. Ein Wort (word) ist eine endliche Folge von Zeichen. Ein Symbol ist ein Wort, welches eine Bedeutung trägt. Zum Beispiel ist in der deutschen Sprache das Wort Bergspitze“ ein Symbol, die Zeichenfolge ergsp“ ” ” hingegen nicht. Man beachte, daß der Begriff Wort“ hier anders ist als üblicher” weise in der deutschen Sprache verwendet wird. Informationsdarstellungen auf der Basis von Symbolen heißen diskrete Informationsdarstellungen, solche auf der Basis von physikalischen Vorgängen heißen analoge Informationsdarstellungen. Die zugehörigen Informationen heißen dann diskrete bzw. analoge Information. Daten (data, Singular:Datum, data item) sind Informationsdarstellungen zum Zweck der Informationsverarbeitung. 6.1. INFORMATION, DATEN UND NACHRICHTEN 161 KAPITEL 6. INFORMATION UND NACHRICHT 162 W Nachrichten (messages) sind Informationsdarstellungen zum Zweck der Informationsübertragung. Kombinierte Begriffe sind: Digitale (oder diskrete) Daten, digitale (=diskrete) Nachrichten, analoge Daten und analoge Nachrichten. 6.1.1 Diskretisierung In der Praxis besteht oft das Problem, analoge Informationsdarstellungen in diskrete Darstellungen derselben Information oder einer annähernd gleichen Information umzuwandeln. Für die mathematische Modellbetrachtung ersetzen wir analoge Darstellungen durch Funktionen f : D ! W . Siehe hierzu die folgenden Visualisierungen: W D D Eine gerasterte Bildfunktion bezieht sich auf endlich viele Bildpunkte: W = Schwärzungsgrade D a) Darstellung im Koordinatensystem b) Darstellung als Bildfunktion Die Diskretisierung besteht aus zwei Schritten: 1. Die Rasterung bewirkt eine Diskretisierung des Definitionsbereiches D Ist die Rasterung fein genug und f auf bestimmte Art zusammengesetzt, so entsteht durch die Rasterung kein Informationsverlust. Dieser Sachverhalt wird in präziser Form ausgedrückt durch das Abtasttheorem: Sei f : R ! R aus Schwingungen mit Grenzfrequenz νG zusammengesetzt, Zν G f (t ) = (a(ν) cos(2πνt ) + b(ν) sin(2πνt ))dν: 0 2. Die Quantelung bewirkt eine Diskretisierung des Wertebereiches W . Rasterung Die Rasterung ersetzt D durch einen diskreten Bereich, aufgebaut aus gleichgroßen Grundeinheiten. Rasterung von f : R ! R ergibt eine durch eine Treppenfunktion darstellbare Funktion: Ist dann das Abtastintervall ts durch ts 2ν1 beschränkt, so ist f (t ) diskret darG stellbar durch ∞ f (t ) = ∑ n=;∞ f (nts ) sin( πt ts ; nπ) πt ts ; nπ : Hierzu gibt es mehrdimensionale Verallgemeinerungen. 6.2. CODES UND CODIERUNG 163 Die Bedingung ts 2ν1 läßt sich anschaulich noch anders lesen: G Dem Zeitintervall ts des Abtastens entspricht eine Abtastfrequenz νs Bedingung lautet dann = 1 . Die ts KAPITEL 6. INFORMATION UND NACHRICHT 164 2. Codierung der Ziffern in einem binären Graycode: das ist ein Binärcode fester Länge, bei dem sich benachbarte Ziffern genau in einem Bit unterscheiden: νG 2νG 0 1 0000 0001 d.h. um die Funktion durch regelmäßiges Abtasten voll zu erfassen, muß die Abtastfrequenz mindestens das Doppelte der Grenzfrequenz νG betragen. 2 3 0011 0010 00 01 11 10 Die Quantelung ersetzt W durch einen diskreten Bereich. Bei Begrenzung der Werte ergibt sich eine endliche diskrete Menge. Bezogen auf W = R unterscheidet man Quantelung auf Mitte Intervalle werden auf die Intervallmitte abgebildet (Bild a) Quantelung auf Seite Intervalle werden auf einen Intervallrand abgebildet (Bild b) W W a) 6 7 8 0101 0100 1100 9 1101 Die Systematik ergibt sich aus der folgenden Darstellung: 6.1.2 Quantelung 4 5 0110 0111 00 01 0 1 7 6 8 9 11 2 5 10 3 4 3. Der Morsecode verwendet die Zeichen “ (kurz), binär codiert als 01, ” -“ (lang), binär codiert als 0111, und ” Lücke“, binär codiert als 000. ” Es werden die Zeichen eines Alphabets aus Buchstaben und Ziffern codiert. Die Codewörter besitzen unterschiedliche Länge. Sie können in einem sog. Codebaum dargestellt werden; siehe dazu die folgende Darstellung für die Buchstaben: b) ; 6.2 Codes und Codierung Beispiel 6.2.1 1. Codierung der natürlichen Zahlen im Dualsystem 0 1 2 0 1 10 3 11 4 5 100 101 H E Ein Code ist eine Vorschrift, die den Zeichen eines Zeichenvorrats eindeutig die Zeichen eines anderen Zeichenvorrats zuordnet. Vereinfacht nennt man auch die Bildmenge selbst den Code. Besteht die Bildmenge aus Binärworten, so liegt ein Binärcode (binary code) vor. I S ; V F ; U ; Ü L T ; A R ; Ä P ; W ; J B N D ; XC ; ; K ; Y Z M G ; ; Q Ö O ; CH 4. Der Fernschreibercode CCIT-2 ist für 5-Kanal-Lochstreifen ausgelegt. Mit Hilfe der beiden Umschaltzeichen 6.2. CODES UND CODIERUNG Buchstabenumschaltung Ziffern-/Zeichenumschaltung 165 j - j können Codewörter doppelt belegt werden. 5. Der IBM-Lochkartencode stellt Zahlen, Buchstaben und Sonderzeichen durch Löcher in 12 möglichen Positionen (Reihen 0-9 und 2 Überlochreihen) dar. Eine Lochkarte enthält 80 Spalten, kann also bis zu 80 Zeichen aufnehmen. 6. Der ISO-7-Bit-Code ist ein internationaler Binärcode für die rechnerinterne Darstellung von Ziffern, Buchstaben, Sonder- und Steuerzeichen (z. B. Backspace, Line-Feed,...). Siehe dazu DIN66003. 7. Der Strichcode oder Balkencode, mit dem Waren gekennzeichnet werden, codiert Ziffern, beim Code EAN-8 sind es 8 Ziffern, mit je 7 Bit, die durch weiße bzw. schwarze Streifen dargestellt werden, so daß sich häufende Einsen zu breiteren schwarzen Streifen führen. Damit der Code in jeder Richtung gelesen werden kann, gibt es einen Rechtscode und einen Linkscode für jede Ziffer. Es werden dann die linken 4 Ziffern im Linkscode, die rechten 4 Ziffern im Rechtscode dargestellt. Wir betrachten nun allgemein die Codierung von Texten, also von Worten“ über ” dem Originalzeichenvorrat. Es ist klar, daß man die Codewörter der Einzelzeichen zusammenfügt. Dabei entsteht jedoch das Problem der eindeutigen Decodierung, z. B. kann im Beispiel a) die Bitfolge 0 jj 0 als 0110“ oder als 030“ oder 06“ ” ” ” etc. interpretiert werden. Folgende Lösungen des Problems werden angeboten: feste Codelänge, d. h. feste Länge der Codewörter, Codierung von Trennzeichen (Lücke), dabei ist Bedingung, daß der Code des Trennzeichens dieses eindeutig aus dem Gesamttext identifiziert, Fano-Bedingung : Kein Codewort ist Anfang eines Anderen. Die Praxis benötigt Codes mit Möglichkeiten zum Erkennen und Beseitigen von Fehlern: Ein Fehlererkennungscode liegt vor, wenn nicht alle Wörter der Bildmenge ausgenutzt werden. Damit ist in der deutschen Sprache z. B. Bqum“ als fehlerhaft ” erkennbar. Ein Fehlerkorrekturcode liegt vor, wenn es zu gewissen fehlerhaften Worten der Bildmenge nächstgelegene Codewörter gibt, etwa Baum“ zu Bqum“. ” ” Als Maß für die Abweichung bei Binärworten dient der Hamming-Abstand (signal-distance), der die Anzahl der unterschiedlichen Bits angibt. KAPITEL 6. INFORMATION UND NACHRICHT 166 Man spricht von einem binären Fehlererkennungscode bei Hammingabstand 2 für die Codewörter und von einem binären Fehlerkorrekturcode bei Hammingabstand 3. Fehlererkennungscodes gewinnt man auf einfache Weise durch hinzufügen von Prüfzeichen bzw. Prüfbits. Fehlererkennende und -korrigierende Codes Annahme: Datenworte haben feste Länge von m Datenbits 2 f0; 1g. Zur Korrektheitsprüfung werden weitere r 1 Bits benutzt. Für ein Datenwort sind somit n = m + r Bits vorgesehen. Von den insgesamt 2m+r verschiedenen Worten sind 2m gültig“. Ziel ist die Erkennung oder sogar Korrek” tur von ungültigen Worten. (a) Paritätsbit: r = 1 Sei im folgenden m = 8, die Datenbits seien a7 ; a6; : : : ; a0, und das Paritätsbit sei a8 , a8 = a7 : : : a0: Damit ist die Erkennung von 1-Bit Fehlern möglich: wenn a8 a7 : : : a0 = 0, dann liegt kein Fehler vor, andernfalls ist das Wort fehlerhaft. Fehlerkorrektur ist hier nicht möglich. Definition 6.2.2 (Hammingdistanz) (b) Fehlerkorrektur: Seien w1 ; w2 Worte derselben Länge n über f0; 1g. Die Hammingdistanz h(w1 ; w2 ) ist definiert als die Anzahl Binärstellen, in denen sich w1 und w2 unterscheiden; mit anderen Worten: H (w1; w2 ) = Anzahl ’1’ in w1 w2; wobei w1 w2 die komponentenweise EXOR Operation bedeutet. Beispiel 6.2.3 n = 8; w1 = 01011011; w2 = 01110011 ) w1 w2 = 00101000 ) h(w1 ; w2) = 2 6.2. CODES UND CODIERUNG 167 Bemerkung Im Falle (a) (Paritätsbit) haben korrekte Worte w1 ; w2 eine Hamming- Distanz h(w1 ; w2 ) 2, da mindestens zwei Bits geändert werden müssen, um w2 aus w1 zu erhalten. Allgemein gilt: Bei fehlererkennenden Codes muß die Hamming Distanz zwischen je zwei korrekten Worten mindestens 2 sein. Ein Code mit Hamming Distanz 3 dagegen erlaubt Fehlerkorrektur. Sei w ein korrektes Codewort und x ein Wort, das von w nur in einer Binärstelle differiert (1-Bit Fehler). D. h. h(w; x) = 1. Dann gilt: 8w0 6= w; w und w0 korrekt, gilt:h(w; w0 ) 3. Aus h(w; x) = 1 folgt daher: 8w0; w0 korrekt, gilt:h(w0 ; x) 2. Ziel: wenn x gegeben ist, bestimme das zugehörige (korrigierte) Wort w. Korrektur von Einzel-Bit-Fehlern in Worten der Länge m Wähle die Anzahl r zusätzlicher Binärstellen so, daß im Fehlerfall eindeutig festgestellt werden kann, welche der m + r Stellen falsch ist, und der korrekte Fall erkannt wird. Es sind also m + r + 1 verschiedene Möglichkeiten zu unterscheiden. Mit r zusätzlichen Binärstellen sind 2r verschiedene Bitmuster zur Fehlerkorrektur möglich. Folglich muß gelten: 2r m + r + 1: Beispiel 6.2.4 m = 4 ) r = 3 nötig Originalcode sei b1b2 b3 b4 b1 b2 b3 c123 Konstruiere 3 weitere Bits c123 ; c234; c134 , so daß b2 b3 b4 c234 b1 b3 b4 c134 jeweils Fehlererkennungscodes sind. Ist dann eines der Bits b1 b2 b3b4 c123 c234 c134 falsch, so kann erkannt werden, welches dies ist. Beispiel 6.2.5 m = 8 ) r = 4. Seien c0 ; c1; c2; c3 die Fehlerkorrekturbits. ci wird in Position 2i des m + r-Bitwortes eingefügt, i = 0; : : : ; 3: c0 c1 x1 c2 x2 x3 x4 c3x5 x6 x7 x9 = y1 y2 y3y4 y5 y6 y7 y8 y9 y10 y11 y12 : Dabei soll gelten: KAPITEL 6. INFORMATION UND NACHRICHT 168 y1 wird geprüft von c0 y2 wird geprüft von c1 y3 wird geprüft von c0 und c1 y4 wird geprüft von c2 y5 wird geprüft von c0 und c2 etc. y12 wird geprüft von c2 und c3 Allgemein wird yi geprüft von den Prüfbits c α1 ; : : : ; cαk wobei ∑kj=1 2α j = i. Anders ausgedrückt: y1 (bzw. c0 ) führt Paritätsprüfung durch für y 1 y3 y5y7 y9 y11 , y2 (bzw. c1 ) führt Paritätsprüfung durch für y 2 y3 y6y7 y10 y11 , y4 (bzw. c2 ) führt Paritätsprüfung durch für y 4 y5 y6y7 y12 , y8 (bzw. c3 ) führt Paritätsprüfung durch für y 8 y9 y10y11 y12 , Es werden nun Fehlerbits e0 ; e1; e2; e3 definiert: e0 := y1 y3 y5 y7 y9 y11 e1 := y2 y3 y6 y7 y10 y11 e2 := y4 y5 y6 y7 y12 e3 := y8 y9 y10 y11 y12 Das Wort y1 : : : y12 ist korrekt genau dann wenn e0 = e1 = e2 = e3 = 0. Im Fehlerfall gibt j = ∑3i=0 ei 2i die fehlerhafte Binärstelle an. Beispiel 6.2.6 Dem Datenwort 01101110 wird das Codeworty1 : : : y12 =110011011110 zugeordnet (die Korrekturbits ci sind kursiv angegeben). Wenn durch einen Übertragungsfehler das Wort 110011111110 gelesen wird, erhält man:e0 = 1; e1 = 1; e3 = 0. Somit ist die Stelle j = 20 + 21 + 22 = 7 fehlerhaft, und y7 wird zu 0 korrigiert. 6.3. EIN EINBLICK IN DIE CODIERUNGSTHEORIE 169 6.3 Ein Einblick in die Codierungstheorie KAPITEL 6. INFORMATION UND NACHRICHT 170 Fall b) k gleichwahrscheinliche Zeichen, k beliebig. Die Codierungstheorie befaßt sich mit Problemen und Methoden der Übertragung von Informationen. Dabei wird das folgende Modell zugrunde gelegt: Eine Nachrichtenquelle, der Sender, erzeugt in einem sequentiellen Prozeß Zeichen eines Zeichenvorrats. Diese werden in codierter Form über einen Übertragungskanal an einen Empfänger geleitet, wobei jedoch durch Störungen, die auf den Kanal einwirken können, die Nachrichten verfälscht werden können, siehe die folgende Abbildung: Jedes Zeichen xi tritt mit der Wahrscheinlichkeit pi = 1 k auf. Definition 6.3.2 (Entscheidungsgehalt) Als Maß der Information eines Zeichens xi oder gleichbedeutend als Entscheidungsgehalt des Zeichens xi bezeichnet man die Zahl mi := log2 k = ; log2( pi). Die Maßeinheit ist das Bit. Man beachte, daß mi im allgemeinen keine ganze Zahl ist. Störung Fall c) Der allgemeine Fall: k Zeichen xi , jedes Zeichen xi hat die Wahrscheinlichkeit pi , so daß ∑ki=1 pi = 1 gilt. Empfänger Sender Übertragungskanal Abb.: Modell der Nachrichtenübertragung Typische Fragestellungen sind die nach der Größe des Kanals, etwa gemessen in Bits pro Zeiteinheit, nach dem Einfluß der Codierung und der Abhängigkeit von Störungen. Die Nachrichtenquelle wird charakterisiert durch die Wahrscheinlichkeiten, mit der die jeweiligen Zeichen erzeugt werden. Fall a) k gleichwahrscheinliche Zeichen mit k = 2n . Diese lassen sich durch n Binärentscheidungen identifizieren, wie der nachfolgende Entscheidungsbaum illustriert: fa b c d e ; ; ; ; ; f ; g; hg fa b c d g c b fa bg fc d g 6= c 6 a = =c =a fcg fd g fag fbg ; ; ; ; ; 2. ϕ(2) = 1: dies ist eine Normierung auf Binärentscheidungen. f fe f g hg g fe f g 6 e = gfg hg6= g = =e feg f f g fgg fhg ; ; Diese Definition, die wir hier durch Verallgemeinerung eines überschaubaren Falles (k = 2n, pi = 2;n) gewonnen haben, läßt sich auch systematisch begründen. Dies sei hier für beliebiges k, mit pi = 1k skizziert: Man sucht ein Maß ϕ: N ! R, so daß der Entscheidungsgehalt nach einer Unterteilung in n gleichwahrscheinliche Fälle gerade um ϕ(n) zunimmt. Dann läßt sich festlegen: 1. ϕ(1) = 0: keine echte Unterteilung. e d Definition 6.3.3 Als Maß der Information eines Zeichens xi , welches mit der Wahrscheinlichkeit pi auftritt, d. h. als Entscheidungsgehalt von xi bezeichnet man mi := ; log2 pi . ; ; 3. ϕ(n m) = ϕ(n) + ϕ(m): Eine Aufspaltung in n und dann in m Alternativen ergibt insgesamt n m Alternativen. dt ; Definition 6.3.1 (Maß der Information) Als Maß der Information mi für ein Zeichen xi , i = 1; : : : ; k, bezeichnen wir die Anzahl der notwendigen binären Entscheidungen zur Identifikation des Zeichens, welche in diesem speziellen Fall (k=2n, alle Zeichen gleichwahrscheinlich) mit der Zahl der notwendigen Bits einer Binärdarstellung übereinstimmt: Es gilt mi := n = log2 k. (n) dt dt dt dt dt dt dt m) (m) +ϕ(m) (m) dt +ϕ(n dt dt (m) dt +ϕ(n) dt dt dt dt 4. ϕ(n) > ϕ(m) für n > m: Der Zugewinn an Entscheidungsinformation ist größer bei mehr Alternativen. 6.3. EIN EINBLICK IN DIE CODIERUNGSTHEORIE 171 Hieraus kann man mathematisch herleiten:ϕ(n) = log2 n. Dieses Resultat erklärt, weshalb das Maß für den Entscheidungsgehalt logarithmisch ist. Für den allgemeinen Fall wird weiterhin definiert: Definition 6.3.4 (mittlerer Entscheidungsgehalt) Der mittlere Entscheidungsgehalt einer Nachrichtenquelle, auch Entropie der Quelle genannt, ist H = ∑ni=1 pi (; log2 pi ). H gibt die mittlere Länge in Bit an, die zur Codierung der Zeichen der Quelle nötig ist. Definition 6.3.6 (mittlere Wortlänge) Das Zeichen xi der Quelle sei mit Ni Bit codiert, i = 1; : : : ; n. Dann ist L = ∑ni=1 pi Ni die mittlere Wortlänge. Es gilt dann das -hier nicht bewiesene- Codierungstheorem von Shannon: Es gilt: (a) H L (b) Durch Codierung von Zeichengruppen ist es möglich, L ; H beliebig klein zu machen. Beispiel 6.3.5 a) Der Würfel mit xi = i; i = 1; 2; : : :; 6; pi = 16 ; mi = log2 6 2:585 für alle i, also auch H 2:585. Zur Codierung sind also 3 Bit erforderlich. b) Totowürfel mit x1 = 1; x2 = 2; x3 = 3; p1 = 12 ; p2 = 13 ; p3 = 16 . Dabei ist m1 = 1; m2 = log2 3 1:585 und m3 = log2 6 2:585. Es folgt H KAPITEL 6. INFORMATION UND NACHRICHT 172 = 1 1 1 1 1 1 log 2 + log2 3 + log2 6 + 1:585 + 2:585 = 1:448 2 2 3 6 2 3 6 Welche Werte kann nun H annehmen, wenn nur die Zahl n der Zeichen festliegt? Der geringste mittlere Entscheidungsgehalt liegt vor, wenn sicher ist, daß immer nur dasselbe Zeichen x1 gesendet wird: p1 = 1; p2 = : : : = pn = 0. Hierfür kann H gemäß der Formel nicht direkt ausgerechnet werden, da ; log2 0 nicht existiert. Hier hilft eine Grenzwertbetrachtung: Definition 6.3.7 (Redundanz) L ; H heißt Redundanz der Quelle. Beispiel zur Verminderung der Redundanz durch Codierung von Zweiergruppen: Wir haben bereits gesehen, daß für den Totowürfel H 1:448 gilt: Zeichen Wahrscheinlichkeit Entscheidungsgehalt 1 1 1“ 2 ” 1 1:585 2“ 3 ” 1 3“ 2:585 6 ” Hierzu wählen wir als Codierung folgende Zuordnung: lim p (; log2 p) p!0 = lim 1 i!∞ 2i 1 (; log2 21i ) = ilim i = 0 !∞ 2i : Da auch 1 (; log2 1) = 0 ist, ergibt sich H=0. Der größte Wert für H ergibt sich bei gleichen Wahrscheinlichkeiten: n H = 1 1 ∑ n (; log2 n ) = log2 n: i=1 Wir vergleichen jetzt für den allgemeinen Fall die Entropie H mit der mittleren Wortlänge einer beliebigen konkreten Codierung: Zeichen Binärcode Länge 1“ 0 1 ” 10 2 2“ ” 3“ 11 2 ” Man beachte, daß hierfür die Fano-Bedingung erfüllt ist. Für die mittlere Wortlänge L gilt: L = 12 1 + 13 2 + 16 2 = 1:5. Jetzt codieren wir Zweiergruppen. Die Wahrscheinlichkeit für ein Paar xi x j ist pi p j . Für die neuen Zeichen ergibt sich ein Code entsprechender Redundanz durch aneinanderfügen: Auf die neuen Zeichen bezogen ist H 2 1:448 = 2:896 und L=3. Der verbesserte Code erreicht L=2.97: 6.4. HUFFMAN-CODIERUNG UND ARITHMETISCHE CODIERUNG Zeichen 11“ ” 12“ ” 13“ ” 21“ ” 22“ ” 23“ ” 31“ ” 32“ ” 33“ ” Wahrscheinlichkeit Code 1 1 00 22 1 1 010 2 3 1 1 011 2 6 1 1 100 3 2 1 1 1010 3 3 1 1 1011 3 6 1 1 110 62 1 1 1110 63 1 1 1111 66 173 verbesserter Code 00 010 011 100 101 1101 1100 1110 1111 6.4 Huffman-Codierung und arithmetische Codierung (Text fehlt) 174 KAPITEL 6. INFORMATION UND NACHRICHT KAPITEL 7. DIE VON-NEUMANN-MASCHINE 176 – Jeder Algorithmus im Knuth’schen Sinne ist auf der Maschine ausführbar, auch jede ’computational method’ bis zu einem äußerlich erzwungenem Abbruch. – Für Baueinheiten ist die Universalität nicht realisierbar, da sie einen unendlich großen Speicher benötigen würde. Die Universalität begründet die Mächtigkeit und vielseitige Einsetzbarkeit des Computers. Der unendliche Speicher wird durch Soeicher approximiert, die für konkrete Probleme groß genug sind. Kapitel 7 Die Von-Neumann-Maschine Dies ist zu einer wichtigen Voraussetzung für die Software-Technik geworden: Auch Programme werden einer vielfältigen Informationsverarbeitung unterworfen. Für den Compiler ist ein Programm zum Beispiel ein Satz von Eingabedaten. 7.1 Das grundlegende Konzept Das dem modernen Computer im wesentlichen zugrunde liegende Konzept wird nach John von Neumann bezeichnet, der dieses Konzept 1944 in seinem EDVACReport beschrieben hat. Nach diesem Konzept wurde 1946 die ertste Rechenmaschine mit Elektronenröhren gebaut, die ENIAC. Dasselbe Konzept liegt aber auch der Z§ von Konrad Zuse, gebaut 1941, und der Mark I von H.H. Aiken, gebaut 1944, zugrunde. Hier sei auch noch auf ein immer noch interessantes Buch von John von Neumann hingewiesen: The Computer and the Brain, Yale University Press, Inc., New Haven, 1958, Deutsche Übersetzung: Die Rechenmaschine und das Gehirn, Oldenbourg, München, 1960 In der Norm DIN 44300 Geräte der Computertechnik unterscheidet man Funktionseinheiten, die durch Aufgabe und Wirkung beschrieben sind, und Baueinheiten, welche physikalische Gebilde darstellen. Die Von-Neumann-Maschine ist ein Konzept für eine Funktionseinheit. Dieses beruht auf den folgenden Grundprinzipien: Ein Nachteil dieser Arbeitsteilung ist der sog. Von-Neumannsche Flaschenhals: Alle zu verarbeitenden Daten müssen vom Speicher zum Rechenwerk transportiert werden. Dies hat auch Auswirkungen auf die Von-NeumannProgrammierung in höheren Sprachen: Dem Transport entspricht die Zuweisung. Komplexe Vorgänge müssen bis auf elementare Zuweisungen heruntergebrochen werden. Wir betrachten jetzt die funktionalen Einheiten: – Es wird eine einheitliche Struktur der Elemente vorgesehen:k Speicherzellen gleicher Größe, z. B. Binärworte der Länge m. Prinzipielle Gleichheit von zu verarbeitenden Daten und Steuerdaten (Daten und Programmen) – Die Zellen werden linear angeordnet und adressiert. Mit binären Adressen 0...0 bis 1...1 als n-Bit-Worte lassen sich k = 2 hoch n Zellen adressieren. Funktionale Arbeitsteilung – Der Zugriff auf Inhalte wird nur über die Adresse realisiert. Bei sog. assoziativen Speichern wird über den Inhalt zugegriffen. 175 Speicher – Dieser ist für die zu verarbeitenden Daten und die Steuerdaten. Universalität: für alle denkbaren Programmieraufgaben geeignet Universalität: Funktionale Arbeitsteilung: 0.Universelle Maschine 0.0 Speicher 0.1 verarbeitende Instanz 0.1.0 Ein/Ausgabewerk 0.1.1 Prozessor 0.1.1.0 Leitwerk 0.1.1.1 Rechenwerk Wir diskutieren diese Prinzipien im Detail: Prinzipielle Gleichheit der Daten: Rechenwerk 7.1. DAS GRUNDLEGENDE KONZEPT 177 KAPITEL 7. DIE VON-NEUMANN-MASCHINE 178 Dieses heißt auch ALU (arithmetical logical unit) und ist der Ort für arithmetische und logische Operationen auf den Worten, die als Speicherzelleninhalte vorkommen. Die Zellen in der ALU heißen Register. verarbeitende Instanz Leitwerk, Eingabekanal Ausgabekanal auch Steuerwerk oder Befehlswerk genannt, englisch Control Unit (CU). Die Aufgaben betreffen die Verarbeitung von Steuerdaten: – Entschlüsselung von Befehlen, – Organisation und Veranlassung der Ausführung von Befehlen, – Organisation des Befehlszyklus: nächsten Befehl ermitteln oder Beenden. Speicher Abbildung 7.2: Ausgliederung des Speichers Ein-/Ausgabewerk Dieses organisiert den Datenfluß von und nach außen. EK Wir betrachten die funktionale Arbeitsteilung jetzt aus der Sicht der (unmarkierten) Petri - Netze. Die sog. Netze aus Instanzen und Kanälen (NIK’s) sind ein Darstellungs- und Analysehilfsmittel für funktionale Einheiten. Zur Detaillierung wird die Operation der Verfeinerung (Gegenrichtung: Vergröberung) eingesetzt. EA Werk Rechenwk. Leitwerk Kommunikationskanal Maschine Eingabekanal AK Speicher Ausgabekanal Abbildung 7.1: Der Computer als verarbeitende Instanz Beachte: In Petri - Netzen gibt es Verbindungen nur zwischen verschiedenartigen Elementen (S - Elemente, rund, bzw. T - Elemente, eckig gezeichnet). HIER ZEICHNUNG SEITE 122:Aufspaltung des Kommunikationskanals: In der Praxis verwendet man andere Darstellungen, z.B. die folgende ”Bus - orientierte”Darstellung: Abbildung 7.3: Funktionale Aufspaltung der verarbeitenden Instanz 7.1.1 Struktur des Speichers 2n Zellen je m Bit adressiert von 0 bis 2n ; 1. Der Speicher hat ein n - Bit Datenregister DAR und ein Datenregister DR von m Bits: Schema: Um Vorgänge im Detail beschreiben zu können führen wir eine Notation ein: ROM = Read Only Memory RAM = Random Access Memory < a > oder C(a): 7.1. DAS GRUNDLEGENDE KONZEPT 179 KAPITEL 7. DIE VON-NEUMANN-MASCHINE 180 bestehend. 0; x ! a: Transport des zu kurzen Wortes x an die Stelle a unter Auffüllung mit Nullen von links. Abbildung fehlt! Execute(b): Ausführung des Befehls, der durch das Binärwort b dargestellt wird. Jetzt können wir den Zugriff auf den Speicher so beschreiben: Sei x eine Speicheradresse. Gesucht ist < x >: 1. x ! DAR 2. << DAR >>! DR aus DR kann der Inhalt weiter transportiert werden, z.B. in ein Register der ALU. Abbildung 7.4: Bus - orientierte Darstellung 7.1.2 Struktur des Rechenwerks DAR: n DR: m 0: m Das Rechenwerk enthält Register für Binärwerte. Als Beispiel wählen wir folgende einfache Registerstruktur: Ein Hauptregister, Akkumulator (AC) genannt, der Länge m, ein Hilfsregister, Multiplikanden / Quotientenregister MQ genannt, der Länge m, ein 1 - Bit Register OV zur Anzeige des arithmetischen Überlaufs, zwei Indexregister IX, IY der Länge n für Adreßarithmetik: Schema: 2^n-1: m Abbildung 7.5: Speicherstruktur AC: m MQ: m Inhalt von a, wobei a ein Registername oder eine Adresse ist. OV: 1 x ! a: Transport des Wortes x an Register oder Adresse a. IX: n IY: n xk::: j : binäres Teilwort des Wortes x, nämlich aus den Bits der Positionen k bis j Abbildung 7.6: Struktur des Rechenwerks 7.1. DAS GRUNDLEGENDE KONZEPT 181 KAPITEL 7. DIE VON-NEUMANN-MASCHINE 182 Heutige Prozessoren besitzen Rechenwerke aus 32, 64, 128 oder mehr gleichartigen Registern. OP ADR m Abbildung 7.8: Einadreßbefehle 7.1.3 Struktur des Leitwerks Das Leitwerk enthält ein Register IR (instruction register) für Befehlsworte und eines für Adressen von Befehlen PC (program counter). OP ADR ADR m Schema: Abbildung 7.9: Zweiadreßbefehle 1. Befehlsholphase : << PC >>! IR PC: n 2. Decodierungsphase : < IR > wird entschlüsselt. IR: m 3. Operandenholphase : Notwendige Operanden werden in das Rechenwerk geholt Abbildung 7.7: Struktur des Leitwerks Die Arbeitsweise des Leitwerks ist die folgende: Zu Beginn steht die Adresse des Startbefehls im PC. Mittels dieser Adresse wird der Befehl selbst in das IR geholt und dort entschlüsselt. Im PC wird weiter gezählt. Darstellung eines einfachen Befehlszyklus: 1. << 2. < PC >>! IR PC > +1 ! PC 3. Execute(< IR >); falls dieses keinen Abbruch hervorruft, weiter bei 1. Das Leitwerk interpretiert die Worte in seinem IR als Befehlsworte. Hier sind mögliche Strukturen für Befehlsworte: Man benötigt einen Operationscode (OP) für den Befehl selbst sowie 0, 1 oder mehr Adressen (ADR), auf denen ggf. der Befehl arbeiten soll. Einadreßbefehle haben die Form 4. Ausführungsphase : Verknüpfung der Operanden etc. 5. Rückschreibphase : Rückspeicherung der Resultate in dafür bestimmte Speicherstellen oder Register 6. Adressierungsphase : Bestimmung der Adresse des nächsten Befehls. 7.2 Maschinennahe Programmierung Wir unterscheiden folgende Hauptgruppen von Befehlen: 1. Transportbefehle: für den Transport von Teilworten, Worten und Wortgruppen zwischen Zellen des Speichers oder des Rechenwerks. 2. Umwandlungsbefehle: Für arithmetische und logische Operationen. 3. Programmablaufbefehle: Dies sind Befehle, die den Ablauf steuern (z.B. Sprungbefehle). Zweiadreßbefehle haben entsprechend die Form Mit k Bits im Operationsteil lassen sich 2k Befehle identifizieren. Heute unterteilt man den Befehlszyklus in die folgenden 6 Phasen: Im folgenden konstruieren wir für das im vorigen Abschnitt eingeführte Schema eines klassischen Rechners einen Satz von Maschinenbefehlen. Jeder Befehl hat die Struktur 7.2. MASCHINENNAHE PROGRAMMIERUNG OP 183 SPEC Abbildung 7.10: Befehlsstruktur mit einem Operationsteil OP und einem Spezifikationsteil SPEC, der oft aber nicht immer - eine Adresse darstellt. Die Befehle werden nicht in interner binärer Codierung, sondern in einer externen Codierung angegeben, die besser lesbar ist. 184 Befehlsgruppe Transportbefehle OP LAC SAC LMQ SMQ LIX LIY RT RT RT RT RT RT RT RT Umwandlungsbefehle ADD Beispiel: LAC a (für ´Load Accumulator with the content of a´). Die Wirkung wird in der oben eingeführten Notation beschrieben, für LAC a z.B. durch < a >! AC KAPITEL 7. DIE VON-NEUMANN-MASCHINE Programmablaufbefehle SPEC a a a a a a AQ QA AX AY QX QY XA YA a SUB a MUL a AND OR NOT SEZ SHL SHR CSL CSR JMP JLE JEQ JOV STP NOP a a beliebig beliebig k k k k a a a a beliebig beliebig Wirkung < a >! AC < AC >! a < a >! MQ < MQ >! a a ! IX a ! IY < AC >! MQ < MQ >! AC < AC >m;n+1:::m ! IX < AC >m;n+1:::m ! IY < MQ >m;n+1:::m ! IX < MQ >m;n+1:::m ! IY 0; < IX >! AC 0; < IY >! AC < AC > + < a >! AC (1 ! OV bei Overflow) < AC > ; < a >! AC (1 ! OV bei Overflow) < AC > < a >! AC ; < a >! MQ (1 ! OV bei Overflow) < AC > ^ < a >! AC (bitweise) < AC > _ < a >! AC (bitweise) : < AC >! AC (bitweise) 0:::0 ! AC < AC >k +1:::m ; 0 ! AC 0; < AC >1:::m;k ! AC < AC >k +1:::m ; < AC >1:::k ! AC < AC >m;k +1:::m ; < AC >1:::m;k ! AC a ! PC Wenn < AC > 0, dann a ! PC Wenn < AC >= 0, dann a ! PC Wenn < OV >= 1, dann a ! PC; 0 ! OV Halt keine Operation Hier ist ein Beispielprogramm, welches zugleich den Speicher für Befehle und Daten zuweist. Hier ist eine Tabelle solcher Befehle: Aufgabe: Addition von 3 Zahlen, s = x1 + x2 + x3 : 7.2. MASCHINENNAHE PROGRAMMIERUNG 185 Bereich Adresse Wort Erläuterung Befehle 0 LAC 5 x1 ! AC 1 ADD 6 x1 + x2 ! AC 2 ADD 7 x1 + x2 + x3 ! AC 3 SAC 8 x1 + x2 + x3 ! 8 => S < 4 STP 0 Halt Daten 5 x1 1. Argument 6 x2 2. Argument 7 x3 3. Argument 8 s Resultat KAPITEL 7. DIE VON-NEUMANN-MASCHINE 186 - Bedingung). 2. Indirekte Adressierung: Statt der wechselnden Adresse wird ein Speicherplatz a angegeben, an dem die eigentliche Adresse gespeichert ist. Die Veränderung der Adresse erfolgt dann an dieser Stelle. Man braucht dazu einen erweiterten Befehlscode, z.B. so, daß zu jedem Befehl XXX ein Befehl XXXI existiert, so daß XXXI a so wirkt wie XXX < a >. Wir haben hier eine weitere Notationsvereinbarung verwendet: > s < für Adresse von s. Diese Notation macht nur Sinn, wenn die Adresse eindeutig ist. Beispiel 2: Maximum von 2 Zahlen (m = max(x1 ; x2)): Bereich Adresse Wort Befehle 0 LAC 8 1 SUB 9 2 JLE 5 3 LAC 8 4 JMP 6 5 LAC 9 6 SAC 10 7 STP 0 Daten 8 x1 9 x2 10 m Erläuterung x1 ! AC x1 ; x2 ! AC Sprung zu 5, falls x1 x2 falls x1 > x2 : x1 ! AC falls x1 > x2 : Sprung nach 6 falls x1 x2 : x2 ! AC < AC >!> m < Halt 1. Argument 2. Argument Resultat Wir betrachten nun den Fall, daß Befehle in einer Schleife mehrfach verwendet werden sollen, aber jeweils mit verändertem Spezifikationsteil. Dieser Fall tritt z.B. auf, wenn eine variable Anzahl von Zahlen addiert werden soll. Es gibt hierzu besondere Adressiertechniken: 1. Programmierung der Adresse: Die jeweils aktuelle Adresse wird vor Verwendung des Befehls in diesen eingebaut. Wegen der Universalität des Computers ist diese Verarbeitung von Befehlsworten möglich, sie ist aber auch umständlich und etwas undurchsichtig. Außerdem verletzt sie eine wichtige praktische Bedingung, nämlich, daß ein Programm nach Ablauf unverändert sein sollte (´reentrant´ 3. Adreßmodifikation Die zu verwendende Adresse wird aus der angegebenen und einer weiteren Indexinformation zusammengesetzt. Ein Befehl XXX a soll dann interpretiert werden als XXX < i > +a. i könnte dabei ein Indexregister sein. Beispiel: Das Voranstellen eines Befehls MOD IX (Modifizierung mit Indexregister IX) bewirkt, daß im unmittelbar nächsten Befehl XXX a als XXX < IX > +a ausgeführt wird. 7.3 Darstellung von Zahlen im Rechner Wir betrachten die üblichen binären Darstellungen von Zahlen in Maschinenworten. 7.3.1 Nichtnegative ganze Zahlen Mit m Bits lassen sich die Zahlen 0 bis 2m ; 1 durch die Worte 0...00, 0...01, 0...10, ... ..., 1...11 darstellen. Der Zahlenwert eines Wortes b1:::bm (bzw. bm :::b1) ist dann ;1 m;1 i i ∑m i=0 bm;i 2 (bzw. ∑i=0 bi+1 2 ). 7.3. DARSTELLUNG VON ZAHLEN IM RECHNER 187 7.3.2 Vorzeichenbehaftete ganze Zahlen Von m Bits kann man eines für das Vorzeichen verwenden (0 für +, 1 für ;) und die restlichen m ; 1 Bits für den Absolutbetrag, dessen Werte von 0 bis 2m;1 ; 1 reichen. Damit werden die Zahlen von ;(2m;1 ; 1) bis (2m;1 ; 1) dargestellt. Die Zahl 0 hat dabei zwei Darstellungen: 0|0...0 und 1|0..0. Der Nachteil dieser Darstellung erweist sich erst in der Arithmetik: Man braucht dann einen eigenen Subtraktionsbefehl außer dem Additionsbefehl. Einerkomplement Bei der Darstellung im Einer-Komplement wird für positive Zahlen nur der Bereich bis 2m;1 (binär 01...1) verwendet, die darüber liegenden Zahlen werden für negative Zahlen verwendet. Dabei wird ;x = (2hochm) ; 1 ; x gesetzt. Damit ist zum Beispiel ;0 = 2m ; 1 ;1 = 2m ; 2 ;2 = 2m ; 3 binär 11....11 binär 11....10 binär 11....01 Zum Vergleich: +0 +1 +2 wird dargestellt durch 00....0 wird dargestellt durch 00....1 wird dargestellt durch 00...10 Man erhält also ;x durch bitweise Invertierung von +x. Zweierkomplement Heute weitgehend üblich ist die Darstellung im Zweierkomplement. Dabei gilt ;x = 2m ; x: Dies hat zur Folge, daß die negative Null herausfällt: 2m hat schon eine Stelle zuviel. Es gelten folgende Darstellungen: ;1 = 2m ; 1 ;2 = 2m ; 2 binär 11....1 binär 11....0 Hier sind Addition und Subtraktion identisch: Beispiele: KAPITEL 7. DIE VON-NEUMANN-MASCHINE 188 +2 = 0010 +5 = 0101 --------+7 = 0111 +2 = 0010 -5 = 1011 ---------3 = 1101 -2 = 1110 +5 = 0101 --------+3 = 0011 -2 = 1110 -5 = 1011 ---------7 = 1001 Bei den letzten beiden Beispielen tritt ein Überlauf auf, der aber ignoriert werden kann. Ob eine Überschreitung des Zahlbereichs aufgetreten ist, wird separat geprüft. 7.3. DARSTELLUNG VON ZAHLEN IM RECHNER 189 7.3.3 Rationale Zahlen und Gleitpunktdarstellung Um gebrochene Zahlen und auch Zahlen in verschiedenen Größenordnungen (wenigstens angenähert) darstellen zu können, verwendet man GleitpunktZahlensysteme: Eine Zahl x wird in die Form x = (-1) hoch v mal y mal b hoch e gebracht. Dabei gilt 0 ¡= y ¡ 1. b ist die Basis des Exponenmten, meist ist b = 2. Auch b = 2 hoch k für k ¿ 2 kommt vor. Dargestellt werden dann - das Vorzeichen v: 0 oder 1 - die Mantisse y als Binärbruch 0.y(1) y(2) . . . - der Exponent e. Schema: v e Anschaulich ist klar: Wir können die Mantisse durch Einschieben von r*i Nullen hinter dem sog. Radixpunkt verkleinern und den Exponenten entsprechend vergrößern. Beispiel 7.3.2 Im oben erläuterten ’single format’ kann die Zahl 0.75 wie folgt dargestellt werden: v = 0, e = 0 y = 0.7510 = 0.110: : : 02 (dargestellt durch 12710 = 011111112) (dargestellt durch 110: : : 00) d.h. es ergibt sich das folgende Binärwort y Beispiel 7.3.1 Beispiele für in der Praxis vorkommende Wortlängen: 0 01111111 110: : : 00 (zu Basis b = 2) 32 bit: 1 Bit für v, 8 Bit für e, 23 Bit für y 64 bit: 1 Bit für v, 11 Bit für e, 52 Bit für y (’single format’ und ’double format’ der Norm IEC 559 9 1989) Der Exponent e wird wie folgt dargestellt: Beträgt die Länge k bit, so werden dadurch die nichtnegativen Zahlen 0 bis 2k;1 direkt dargestellt. Sei d die direkt dargestellte Zahl. Dann ist Stellen: 1 Alternativen sind 8 v = 0, e = 1, 0 10000000 0110: : : 00 v = 0, -(2k;1 - 1) bis 2k;1 e = 2, y = 0.01875, d.h. ohne Vorzeichen darstellen. Spart man die Bitmuster 0: : :00 und 0: : :01 aus, so reicht der Bereich von -(2k;1 -3) bis 2k;1 für k = 8, also von -125 bis 128, für k = 11 von -1021 bis 1024. Bevor wir das Aussehen der Mantisse erörtern, müssen wir über die Mehrdeutigkeit der Darstellung sprechen: Gilt x = (-1)v ybe mit b = 2i , so gilt auch e y = 0.0375, d.h. Man kann damit für e Werte von x = (-1)vyee mit y = y*b;r , 23 oder e = d - (2k;1 - 1). e KAPITEL 7. DIE VON-NEUMANN-MASCHINE 190 e e = e + r. 0 10000001 00110: : : 00 Eindeutigkeit der Darstellung wird für x 6= 0 erreicht durch die sog. Normalisierungsbedingung b;1 y < 1. Dies bedeutet: Gilt b = 2i , so müssen die i ersten Bits der Mantisse von i Nullen verschieden sein, für i = 1 heißt das: das erste Bit muß gleich 1 sein. Diese Darstellungen heißen normalisierte Gleitpunktzahlen . Ist die Bedingung nicht erfüllt, so spricht man von denormalisierten Gleitpunktzahlen. Für b = 2 und x = 0 ist bei normalisierten Gleitpunktzahlen das erste Bit der Mantisse redundant. Es wird dann eventuell nicht mehr dargestellt. Die Zahl 0.75 würde dann wie folgt dargestellt: 7.3. DARSTELLUNG VON ZAHLEN IM RECHNER 191 KAPITEL 7. DIE VON-NEUMANN-MASCHINE 192 0 01111111 10: : : 00 if x = y then: : : 0 und Sind y1,: : : 0,y p die Bits der Mantisse (y1 für b = 2 eventuell gar nicht dargestellt und implizit = 0), dann gilt if x - y = 0 then: : : 0 x = (-1)v be ∑ y j b; j . p j=1 Auch e läßt sich durch die bits d1 : : : 0dk der Darstellung d = e +(2k;1 - 1) ausdrücken: e = -2k;1 + 1 + ∑ bk;1 d j . k zu unterschiedlichen Resultaten führen können. Der letztgenannte Punkt führt uns zu den Überlegungen zur Arithmetik der Gleitpunktzahlen. Hierfür gelten die folgenden Überlegungen: j=1 Folgende Tatsachen folgen aus den Darstellungen: Es werden nur endlich viele Zahlen dargestellt. Die kleinste und die größte darstellbare Zahl sind aus den Darstellungsparametern errechenbar. Gemäß der Darstellung lassen sich Additionen und Subtraktionen nur nach Anpassung des Argumentes mit kleinerem Exponenten durch Denormalisierung durchführen. Beispiel 7.3.4 (Basis b = 1) Die Intervalle zwischen benachbarten darstellbaren Zahlen wachsen, wenn der Absolutbetrag der Zahl wächst. x1 = 16, x2 = 0.75 Es soll x1 + x2 gebildet werden. Es ist e1 = 5, e2 = 0, Die Lücken rechts und links der 0 sind relativ groß bei normalisierten Gleitpunktzahlen. y1 = 0.12 , y2 = 0.112 Die Darstellung von x2 wird denormalisiert zu Variiert man bei fester Gesamtwortlänge die Bitlänge von Exponent und Mantisse, so ergeben sich prinzipiell folgende Möglichkeiten: Mehr Bits für den Exponenten bedeuten einen größeren Zahlbereich und eine genauere Darstellung der Zahlen ’rechts’ und ’links’ der 0. Mehr Bits für die Mantisse bedeuten eine größere Genauigkeit. Es gibt normalisierte Gleitpunktzahlen, die verschieden sind, deren Differenz aber als normalisierte Zahl nur durch 0 approximiert werden kann. Daraus folgt z.B. daß die Abfragen Ist das Ergebnis nicht exakt darstellbar, so wird es gerundet. x = (-1)v y be Nur ganze Zahlen und gebrochene Dualzahlen werden exakt dargestellt. Zur Darstellung anderer Zahlen innerhalb des überhaupt darstellbaren Bereichs wird gerundet, und zwar auf einen der beiden benachbarten Werte, bei optimaler Rundung auf den nächstgelegenen Wert. Eine einfache Rundungstechnik besteht im Abstreichen überzähliger Bits (’truncation’). Beispiel 7.3.3 Man berechne die Nachbarn von 1, 4 und 16 in der ’single-format’- Darstellung, normalisiert mit impliziter erster Mantissenstelle. Wird der Zahlbereich der darstellbaren Zahlen durch das Ergebnis einer Operation nach außen überschritten, so liegt ein Overflow-Fehler vor. Dieser löst i.a. einen Alarm aus. e’2 = 5, y’ = 0.00000112 Die Summe hat dann die Darstellung e3 = 5, y3 = 0.10000112 Bei der Multiplikation werden die Exponenten addiert, bei der Division subtrahiert. Die Mantissen werden multipliziert bzw. dividiert. Das Resultat der Mantissen muß ggf. angepaßt werden. 7.3. DARSTELLUNG VON ZAHLEN IM RECHNER Beispiel 7.3.5 x1 = 10, x2 = 0.75, 193 x3 = x1*x2. Es ist y1*y2 = 0.0112 , e1 + e2 = 5. Daraus wird errechnet e3 = 4, y3 = 0.112 Es können Ergebnisse arithmetischer Operationen auftreten, die in der Darstellung auf 0 gerundet werden. Dann spricht man von Underflow. Es wird aber mit dem Approximationswert 0 weitergerechnet. Die Ungenauigkeit von Ergebnissen nach Rundung bewirkt, daß einige Rechengesetze außer Kraft gesetzt werden, z.B. : Beispiel 7.3.6 Assoziativgesetze: (a + b) + c = a + (b + c) (a * b) * c = a * (b * c) Distributivgesetz: a * (b + c) = a * b + a * c. 194 KAPITEL 7. DIE VON-NEUMANN-MASCHINE KAPITEL 8. DATENSTRUKTUREN 196 Gründen. In den Programmiersprachen erfüllen die Datentypen mehrere Funktionen: 1. Unterscheidung der Daten nach vorgegebenen Typen, ausgehend von Kapitel 8 Datenstrukturen 8.1 Von Datentypen zu Datenstrukturen In der Anfangszeit der Programmierung waren Datenstrukturen gänzlich unbekannt. Man kannte nur Algorithmen und Zahlen. Komplexe Datenstrukturen wurden erst mit einer höheren Problemorientierung und immer komplexeren Aufgaben für Computer erforderlich. Hierbei ergaben sich die Datenstrukturen direkt aus der Struktur der Probleme. Sie werden durch den Definitions-/Wertebereich einerseits und die Operationen andererseits festgelegt. Die Verwendung von Variablen in von-Neumann-Programmen erfordert die Festlegung von Typen, um den Wertebereich zu bestimmen. Dies ist nötig, um den notwendigen Speicher abzuschätzen und die Laufsicherheit von Programmen zu gewährleisten. Falls der Benutzer sich an die Vereinbarungen nicht hält, wird dies automatisch entdeckt. Dabei sieht die Deklaration, d. h. die Festlegung des Types einer Variablen zum Beispiel folgendermaßen aus: x : N (x ist eine Variable, deren Wert eine natürliche Zahl sein soll). Sind solche Vereinbarungen vor dem Programmaufruf getroffen, kann die korrekte Verwendung von Funktionen überprüft werden. Funktionen erhalten Signaturen, die denen der Mathematik ähnlich sind: f : A 7! B entspricht der Signatur f A7!B oder f (A) = B usw. Hierbei sind A und B genau festgelegte Datenstrukturen. Von Beginn an wurden unterschieden: Zahlen, Zeichen und logische Werte, auch boolesche Werte genannt. Aus der Berechenbarkeitstheorie wissen wir, daß es völlig ausreichend ist, mit nur einem dieser 3 Typen zu arbeiten. Die Unterscheidung erfolgt aus praktischen 195 Fixpunktzahlen oder Integer Gleitpunktzahlen oder Real Gleitpunktzahlen doppelter Genauigkeit oder Double Zeichen oder Character logische Werte oder Boolean Zeichenfolgen oder String Felder (Folgen gleichartiger Daten) oder Array 2. Zuordnung von Variablennamen und Datentypen: dies erfolgt durch Deklaration, z.B. in der Form n : integer st : string allgemein < name >: < typ > Dies ermöglicht: passende Speicherzuteilung Sicherheit gegen Irrtümer des Programmierers bei der Benutzung der Variablen sprachliche Formulierungen für den Zugriff auf die einzelnen Daten 3. Strukturierung größerer Datenmengen: Aus der Sicht der Speicherung wurden dazu Felder als Datentypen entwickelt. Es handelt sich dabei um parametisierte Datentypen. Parameter sind dabei der Elementtyp, die Dimension und Ausdehnung in jeder Dimension bzw. die Indizierung in jeder Dimension. Höherdimensionale Felder, d.h. ab Dimension 2 (für Matrizen) sind nicht durch den realen Speicher motiviert, der ja linear ist, sondern durch die Organisationsform der Daten, wie sie sich aus der Anwendung ergibt. 8.1. VON DATENTYPEN ZU DATENSTRUKTUREN 197 Beispiel 8.1.1 array [1 : : : 100; ;10 : : : 10] o f real array [50 : : : 99] o f boolean Neben die Felder traten als komplexere Datentypen zunächst die Records, auf deutsch: Verbunde. Darin werden Daten auch unterschiedlichen Typs zu einer Einheit zusammengefaßt, z.B. Name (als String), Alter (als Integer), Postleitzahl (als Integer), Wohnort (als String). Datentypen sind im wesentlichen als Mengen aller ihrer Werte definiert: boolean: fTRUE, FALSEg character: fa,b,c,. . . g 8.2 Elementare Datenstrukturen Eine Datenstruktur wird durch eine Menge von Objekten und eine Menge von Funktionen beschrieben. Hierbei erfolgt die exakte Festlegung syntaktisch durch Konstanten- und Funktionsbeschreibungen, semantisch durch die inhaltliche Definition der Objekte und Funktionen. Als Hilfsmittel zur Beschreibung bzw Definition verwendet man Semantikdiagramme (=Signaturdiagramme), Signaturen, Spezifikationen und als rein mathematische Hilfsmittel die Algebren. 8.2.1 Boolean Boolean ist die Datenstruktur der booleschen Werte. Wertemenge: usw. dabei stellt der Verbund ein cartesisches Produkt A1 Ak dar. Felder sind Mengen von Abbildungen von der Menge der Indizes in eine Grundmenge: jedes Element eines Feldes vom Typ array [50. . . 99] of boolean ist eine Abbildung f : f50 : : : 99g ! fT RUE ; FALSE g Mit dem Begriff Datenstrukturen verbindet sich die Vorstellung, daß diese nicht nur durch Mengen von Werten definiert sind, sondern auch durch typische Funktionen oder Operationen auf diesen Werten. Zur Beschreibung der Datenstrukturen gehören daher die Beschreibung der Wertemengen der Datenstrukturen evt. die Beschreibung weiterer Wertemengen die syntaktische Beschreibung der Funktionen durch Festlegung von Definitions- und Wertebereichen; dabei wird einer Funktion f : A1 An 7! B die sogenannte Signatur f A1 ;::: ;An 7!B zugeordnet. die semantische, d.h. inhaltliche Beschreibung der Funktionen Aus den Typbezeichnungen der Wertemengen und den Signaturen der Funktionen wird jeweils die Signatur der Datenstruktur gebildet. KAPITEL 8. DATENSTRUKTUREN 198 Funktionen: B = fT RU E ; FALSE g mit der Typbezeichnung boolean (kurz: bool) Eine mindestens funktional vollständige Menge boolescher Funktionen, z.B. die folgende : not : B 7! B ^; _; ,: BB 7! B Die Semantik der Funktionen wird durch die bekannten Wertetabellen der Aussagenlogik definiert. Wir führen nun zu boolean die zugehörige Signatur der Datenstruktur ein. Definition 8.2.1 Die Signatur einer Datenstruktur ist ein Paar hS; F i, wobei S eine Menge sogenannter Sorten ist und F eine Menge von Funktionen. Jeder Funktion aus F ist eine Stelligkeit n zugeordnet, im Sinne von f (s1 ; : : : ; sn) 7! sn+1 , d. h. Funktion f erhält n Argumente der Sorten s1 ; : : : ; sn und liefert Resultat der Sorte sn+1 . Im Fall von Boolean sieht die Signatur folgendermaßen aus: Signatur von Boolean: < fBg; fnot B7!B ; ^BB7!B ; _BB7!B ; ,BB7!B g > Besser lesbar sind oft die Signatur-Diagramme: Dies sind unmarkierte PetriNetze mit Mehrfachkanten, in denen die S-Elemente die Sorten darstellen, die T-Elemente die Funktionen und die verbindenden Pfeile den Informationsfluß bei den Funktionen. 8.2. ELEMENTARE DATENSTRUKTUREN 199 Signaturdiagramm von boolean: KAPITEL 8. DATENSTRUKTUREN 200 8.2.2 Character Character ist die Datenstruktur für einen vorgegebenen Zeichensatz A, z. B.: bool Eine Algebra ist eine mathematische Struktur, welche z. B. Gruppe, Ring, Körper verallgemeinert, zugleich aber Datenstrukturen der Informatik erfaßt. Genaueres gehört in das Gebiet der Theoretischen Informatik. A = fa b c ; ; z 0; 1; : : :; ?; j; &; : : :g ; : : :; ; Wertemenge: A, geordnet Funktionen: succ : A 7! A, partielle Funktion, z. B. succ(a)=b pred :A 7! A, partielle Funktion, z. B. pred(b)=a =: A A 7! B 8.2.3 Integer Dies ist die Datenstruktur der ganzen Zahlen. Sie ist in zwei Versionen unterteilt. Bei der ersten ist die Wertemenge unendlich, angelehnt an die Menge der ganzen Zahlen in der Mathematik (Bezeichnung: Z). Die zweite Version hat eine eingeschränkte Wertemenge, das bedeutet, daß in dieser Datenstruktur nur die ganzen Zahlen enthalten sind, die sich gemäß einer Vorschrift auf einer Maschine darstellen lassen (Bezeichnung: ZM). Hierbei kann die Wertemenge nicht unendlich sein, was sich aus der Speicherbegrenzung ergibt. Funktionen: +, -, *, /, div, mod, = Fkt. Z ZM + * / div mod = total total total partiell partiell partiell total partiell partiell partiell partiell partiell partiell total Spezifikation: Typ Integer Hilfssorten: Funktionen: Axiome: boolean Z7! Z +: Z ZM ZM 7! ZM usw. x+y = y+x x + (y + z) = (x + y) + z usw. Bemerkung: Auf ZM sind die Axiome z. T. dadurch verletzt, daß Bereichsüberschreitungen vorkommen können, so könnte z. B. x + (y + z) definiert sein, aber x + y und (x + y) + z nicht. 8.2. ELEMENTARE DATENSTRUKTUREN 201 8.2.4 Natural Funktionen: Dies ist die Datenstruktur für die natürlichen Zahlen. In der Praxis ist diese jedoch meistens nur durch Einschränkung der Datenstruktur Integer realisiert. Spezifikation KAPITEL 8. DATENSTRUKTUREN 202 Typ: nat Hilfssorten: boolean Funktionen: 0 :7! nat, succ: nat 7! nat, +; ;; ; div; mod ; =; 6=; ; <; ; >, usw. Axiome: x+0 = x x + succ(y) = succ(x + y) x0 = 0 x succ(y) = x + (x y) .. . ;; ; =; oft auch spezielle Funktionen: exp; sin; cos; : : : +; <; = Axiome: siehe Mathematik, z. B. x (y + z) = x y + x z; usw. . . . Funktionen in RM weichen im allgemeinen von den Funktionen in R ab. M z. B.: x; y 2 RM, falls x + y 2 = R , dann Ersatz durch eine Approximation. R0 ;; ;; ;; ;; ; ; ; ; I @ ; ; @ exaktes Resultat ;; approximiertes Resultat rechts oder links davon 8.2.5 Rational Rational ist die Datenstruktur der rationalen Zahlen, die erst in neueren Programmiersprachen üblich geworden ist. Wertemenge: Q = f xy jx; y 2 ZM; y 6= 0g Funktionen: +; ;; ; = : QQ 7! Q rat : Z7! Q (Einbettung der ganzen in die rationalen Zahlen) =; 6=; <; ; >; : QQ 7! B Hilfssorten: ZM; B Die Semantik der Operationen ist aus der Mathematik bekannt. Auch durch Im” plementation“ definierbar: Darstellung von x 2 Q durch ein Paar hy; zi (in PASCAL: record); so normiert, daß y, z teilerfremd sind. Jede Funktion kann jetzt programmiert werden. hy zi + hy0 z0i=ˆ yz + yz0 = y zz + zy0 z 0 ; 0 ; 0 ) Axiome: i. a. falsch! Stattdessen: Abschätzungsregeln über Rundungsfehler“ ” Hinweis: bei normalisierter Zahldarstellung (Mantisse genügt Bedingung: 1>m 1 ; B mit B als Basis der Zahldarstellung) gibt es folgenden Fall: x 6= y; aber x ; y = 0 Folgerung: if x = y = 0 then . . . // if x = y then . . . : verschiedene Wirkung! ; 8.2.7 Aufzählungstyp (enumeration type) anschließend kürzen (ggT berechnen). Beispiel: 8.2.6 Real Real ist die Datenstruktur der reellen Zahlen. Wertemenge: R = f Menge der reellen Zahlen (Mathematik)g, bzw. RM = eine endliche Einschränkung davon, auf rationalen Zahlen basierend! RM Q Wochentag: So, Mo, Di, . . . , Sa 1 2 3 7 Wertemenge: hx1 ; : : : ; xni, endliche geordnete Menge von Symbolen xi 2 A , A ein Alphabet Funktionen: succ; pred ; =; auch < endlich beschreibbar: succ(x1 ) = x2 ; succ(x2 ) = x3; : : : ; succ(xk;1 ) = xk (succ(xn )nicht definiert) 8.3. ZUSAMMENGESETZTE DATENSTRUKTUREN 203 8.2.8 Unterbereichstyp KAPITEL 8. DATENSTRUKTUREN 204 Testoperationen = (string; string) Text fehlt hier Die Datenstruktur der Aufzählungstypen wurde durch PASCAL eingeführt. Verwendung in Programmiersprachen Unterscheide Standardtypen (gemäß Sprachbeschreibung vorgegeben) von benutzerdefinierten Typen (in der Sprache definierbar). Beispiel: Typen zu REAL: Standardtypen mit festgelegter Genauigkeit benutzerdefinierte Typen mit anderer Genauigkeit (z. B. ADA) 9 > > = > > ; < (i) Auffüllen nicht benutzter Stringpositionen mit speziellen Zeichen: Zur Verarbeitung von Zeichenketten über einem Alphabet A, geordnet. String wird in Abhängigkeit von A gebildet: parametrisierte Datenstruktur, z. B. String of char, String of boolean, . . . Operationen zur Konstruktion ε() : string : erzeugt einen leeren String : erzeugt einen String aus einem Zeichen ι(char) : string (string; string) : string : Konkatenation von Strings x= a b c d $ $ $ $ $ $ $ $ $ y= u v w $ $ $ $ $ $ $ $ $ $ xy = a b c d u v w $ $ $ $ $ $ konstante Länge n (ii) Direkte Längenangabe: x= 4 a b c d 8.3 Die zusammengesetzten Datenstrukturen String, Feld, Verbund und Vereinigung 8.3.1 String : bool : bool String ist eine dynamische Datenstruktur im folgenden Sinn: Der benötigte Speicherplatz ist variabel. Es können auch Strings fester Länge verwendet werden, auf denen sich dann auch Strings kürzerer Länge speichern lassen, wenn zusätzlich die verwendete Stringlänge codiert werden kann: Funktionen bleiben erhalten (bis auf Genauigkeit der Resultate) Benutzerdefinierte Typen sind oft Einschränkungen von Standardtypen (subtype). Beispiel: Typ [1..100] als Untertyp von Integer. (string; string) usw. 8.3.2 Feld Datenstruktur zur Speicherung gleichartiger Daten und Zugriff über Indizes Indizes sind Elemente einer geordneten elementaren Datenstruktur, ausgenommen real, vorzugsweise integer. 1-dimensionale Felder: Typbezeichnung: Typ der Indizes: Typ der Elemente: array index elem Operationen zur Konstruktion: Zugriffsoperationen create(): array: access(string; nat ) : char : Zugriff auf n-tes Zeichen length(string) : nat : Zugriff auf Länge des Strings erzeugt ein Feld bei vorgegebener Indexmenge, aber noch ohne Einträge assign(array,index,elem): array: Eintrag eines Elementes 8.3. ZUSAMMENGESETZTE DATENSTRUKTUREN 205 Zugriffsoperation: access(array,index): elem: Zugriff auf ein Element KAPITEL 8. DATENSTRUKTUREN 206 Definition 8.3.3 (record) Gegeben seien k Typen m1 ; : : : ; mk und k Namen für Selektoren S1; : : : ; Sk . Die daraus gebildete Struktur eines Verbundes werde mit record(S1 : m1 ; : : : ; Sk : mk ) Beispiel 8.3.1 Typbezeichnung in Pascal: bezeichnet. Jeder konkrete Verbund enthält (bis zu) k Komponenten der Typen m1 bis mk , auf welche mit den Selektoren S1 bis Sk zugegriffen wird. array[index] of elem array[1..100] of real Programmiersprachliche Notation: Es handelt sich also um einen parametrisierten Datentyp. Übliche Schreibweisen: a[i]:=e a[i] statt a:=assign(a,i,e) statt access(a,i). Mehrdimensionale Felder: Indexmenge ist ein Cartesisches Produkt mehrerer Komponenten, z. B. I = I1 I2 I3 konkret beispielsweise array[1..100,0..30,-20..20] of elem. Dies kann identifiziert werden mit array[I1] of array[I2] of array[I3] of elem. Das gibt Anlaß auf weitere Zugriffe: Bei 2-dimensionalen Feldern auf Zeilen, auf Spalten und auf Teilfelder. Entsprechend verallgemeinert für höhere Dimensionen Beispiel 8.3.2 (Notationsbeispiele) a[3,] : 2-dimensionales Feld, 3. Zeile a[,5] : 2-dimensionales Feld, 5. Spalte a[4..17] : 1-dimensionales Feld, Elemente 4 bis 17 8.3.3 Verbund Mit ’Verbund’ oder englisch ’record’ bzw. ’structure’ wird die folgende zusammengesetzte Datenstruktur bezeichnet: Es werden Komponenten i. a. verschiedener Arten zusammengefügt. Der Zugriff erfolgt dann über spezielle Namen für diese Komponenten. Diese heißen Selektoren. r: record S1: m1; . . . Sk: mk; end; Zugriff auf i-te Komponente: r.Si Mathematisch betrachtet entspricht der Verbund dem Cartesischen Produkt. 8.3.4 Vereinigung Die Vereinigung von Datenstrukturen mit der Bezeichnung union (in Pascal durch varianten Record realisiert) entspricht der mengentheoretischen Vereinigung. Die wesentlichen Operationen sind die Injektion (i1; : : : ; ik ), die Projektion (p1; : : : ; pk) und der Typtest (test1; : : : ; testk). Programmiersprachliche Notation in PASCAL: r: record case FALL of 1: (S1: m1,...,Sl: ml); 2: ... . . . k: ... end end; 8.4 Die Speicherstrukturen Stack, Queue und Deque Diese Speicherstrukturen dienen dem Abspeichern unter bestimmten speziellen Zugriffsbedingungen. Dabei wird ein Typ für die zu speichernden Elemente zugrundegelegt. 8.4. DIE SPEICHERSTRUKTUREN STACK, QUEUE UND DEQUE 207 LIFO-Prinzip: Last-In-First-Out. Nach diesem Prinzip arbeitet der Stack push top - KAPITEL 8. DATENSTRUKTUREN 208 1. top(push(e,s))=e 2. pop(push(e,s))=s (!) 3. empty(create)=TRUE pop 4. empty(push(e,s))=FALSE. FIFO-Prinzip: First-In-First-Out. Dieses Prinzip charakterisiert die Queue, eine Warteschlange. head append Für die Datenstrukturen queue und deque wird entsprechend verfahren. Realisierung einer Queue als Array. Bei Zugriff auf die Elemente mod-Funktion verwenden. Dabei ist darauf zu achten, daß das Ende der Queue nicht den Anfang einholt (=) Queue Overflow). tail 8.5 Listen, Mengen und Hash-Tabellen LIFO/FIFO-Kombination: Diese seltener erwähnte Struktur heißt doubleended-queue oder kurz Deque und kann wahlweise wie ein Stack oder eine Queue benutzt werden. appendl headl appendr - headr taill tailr Für jede dieser Strukturen führen wir eine Operation create ohne Parameter ein, welche eine leere Struktur der jeweiligen Art erzeugt, sowie eine Testfunktion empty. Damit ergeben sich die folgenden Signaturen mit elem als Parameter für den Elementtyp stack, genauer stack of elem: create(): stack push (elem, stack): stack pop (stack): STACK (!) top (stack): elem empty (stack): bool Hierzu gehören die folgenden Axiome: Listen Listen sind eigentlich eine Verallgemeinerung von Strings, wobei statt char ein allgemeiner Typ elem zugelassen wird. Wir formatieren die Listen aber so, daß auch die Speicherstrukturen Stack, Queue und Deque darin sichtbar werden: create(): list appendr(list, elem): list appendl(list, elem): list concat(list, list): list headr(list): elem headl(list): elem tailr(list): list taill(list): list length(list): nat access(list, nat): elem empty(list): bool equal(list, list): bool 8.5. LISTEN, MENGEN UND HASH-TABELLEN 209 Diese Struktur heißt list of elem. Wir erklären die Semantik direkt mit Hilfe der Repräsentation der Listen durch Tupel he1 ; : : :; eni; n 0; appendr(he1 ; : : : ; eni; e)=he1 ; : : : ; en; ei appendl(he1 ; : : : ; eni; e)=he; e1; : : : ; en i card(set): nat = : (set,set): bool Die Semantik ergibt sich aus den bekannten mengentheoretischen Operationen. concat(he1 ; : : : ; eni; he01 ; : : : ; e0mi)=he1 ; : : : ; en; e01; : : : ; e0mi Hashorganisation (gestreute Speicherung) headr(he1 ; : : : ; eni)=en Prinzip: Eine Hash-Tabelle steht für die Aufnahme von m 2 N Records zur Verfügung. Die Position, in der der Satz gespeichert wird, wird aus dessen Schlüssel berechnet. Sei S die Menge aller möglichen Schlüsselwerte, und h: S 7! f0; : : : ; m ; 1g eine Funktion ( Hash-Funktion“) ” Vorgehen: Der erste Satz (mit Schlüssel s1 ) wird in die Position h(s1 ) gespeichert, der zweite nach h(s2 ), usw. Dabei können Kollisionen auftreten: wenn h(si ) = h(s j ) ist. Für die Kollisionsbehandlung gibt es mehrere Verfahren: headl(he1 ; : : : ; en i)=e1 tailr(he1; : : : ; eni)=he1 ; : : : ; en;1i taill(he1 ; : : : ; eni)=he2 ; : : : ; eni access(he1 ; : : : ; eni; i)=ei ; 1 i n length(he1 ; : : : ; eni)=n empty(he1 ; : : : ; eni)=(n = 0 7! T RUE ; FALSE) (n = m ^ ei = e0i für alle i 7! Mengen Definition 8.5.1 (set of elem) Eine Menge vom Typ set of elem ist eine Menge fe1 ; : : : ; eng mit e1 ; : : : ; en 2 E, wobei E die Menge der Elemente vom Typ elem ist. Darauf sind folgende Operationen definiert: create(): set append(set,elem): set \(set,set): set : (set,set): bool create = hi equal(he1 ; : : : ; en i; he01 ; : : : ; e0mi)= T RU E ; FALSE) [(set,set): set 2 : (elem,set): bool mit Elementen ei vom Typ elem: KAPITEL 8. DATENSTRUKTUREN 210 1. re-hashing: statt nur einer Hashfunktion sind m unterschiedliche Funktionen h0 ; : : : ; hm;1 gegeben. Bei Kollisionen wird die nächste Hashfunktion genommen. Beispiel 8.5.2 gegeben h0 = h: S 7! f0; : : : ; m ; 1g hi (s) = (h(s) + i) mod m. 2. Überlaufliste“: Im Falle der Kollision wird der neue Satz in einer Liste ein” getragen. Im Falle des Aufsuchens muß diese Liste ggf durchsucht werden (zeitaufwendig, da sequentielles Durchsuchen). 3. m Überlauflisten: bei jedem Element der Hash-Tabelle kann eine Liste beginnen. Diese nimmt alle Überlaufsätze mit gleichem Hash-Wert auf. Hash-Tabelle mit m Überlauflisten 8.6. REKURSIVE DATENSTRUKTUREN UND ZEIGER 0 Schlüssel Schlüssel Schlüssel Schlüssel Schlüssel 211 nil 1 i KAPITEL 8. DATENSTRUKTUREN 212 Dabei wird das Cartesische Produkt nicht assoziativ und natürlich auch nicht kommutativ verstanden, d. h. wir unterscheiden hu hv wii von hhu vi wi nil ; ; ; ; und hu vi von hv ui. ; m-1 nil Forderungen an die Hashfunktion h: sie soll möglichst gut streuen“, damit ei” ne gleichmäßige Belegung der Hash-Tabelle mit möglichst wenig Kollisionen erreicht wird. Zeitaufwand für die Operationen: Aufsuchen,Einfügen und Löschen jeweils ein Hashzugriff und im Kollisionsfall ggf. weitere Zugriffe. Vorteile des Hashings: bei guter Streuung sehr schnell; Nachteil: sortiertes Ausgeben aller Sätze ist nicht möglich. 8.6 Rekursive Datenstrukturen und Zeiger Die bisherigen Konstruktionen von zusammengesetzten Datenstrukturen ermöglichten die Bildung neuer Datenstrukturen auf der Grundlage bereits bekannter Datenstrukturen. Es ist aber auch möglich und in manchen Anwendungen sinnvoll, neue Konstruktionen von vornherein in dieselbe Bildung einzubeziehen, die auf bereits bekannte Strukturen angewandt wird. Dies führt zu rekursiven Definitionen. Wir betrachten solche rekursiven Datenstrukturdefinitionen auf zwei Stufen: ; Was bedeutet nun eine solche rekursive Definition? Wir können sie auch so formulieren: 1. Ein Atom a 2 A ist ein symbolischer Ausdruck, d. h. A S. 2. Sind S1 , S2 symbolische Ausdrücke, so auch das Paar hS1 ; S2i, d. h. S S S. 3. Dies sind alle Möglichkeiten, symbolische Ausdrücke zu konstruieren. Man kann nun zeigen, daß dann folgendes gilt: S = A [ [A A] [ [A (A A)] [ [(A A) A] [ [A (A (A A))] [ : : : Zur Veranschaulichung stellt man die Elemente von S auch als Binärbäume dar: s 2 A hat die Form: ȧ s 2 A A hat die Form: a1 1. Stufe: Rekursive Mengendefinition 2. Stufe: Ausstattung der Struktur mit Operationen 8.6.1 Symbolische Ausdrücke von LISP Die funktionale Sprache LISP (List Processing) von John McCarthy gründet sich auf die folgende Definition: Sei A eine vorgegebene Menge sogenannter Atome. Dann ist die Menge S der symbolischen Ausdrücke über A definiert durch S = A (Initialisierung), S = A [ [S S]. a2 a1 s 2 A [A A] hat die Form: a2 a3 Zu geeigneten Operationen kommt man durch folgende Überlegungen: Konstruktion der Komponenten: A braucht nicht konstruiert werden, da diese Menge vorgegeben ist S S muß aus S konstruiert werden: Dazu wird die Operation cons: S S 7! S, cons(u v) = hu vi ; ; 8.6. REKURSIVE DATENSTRUKTUREN UND ZEIGER 213 eingeführt. Zugriff auf Komponenten: KAPITEL 8. DATENSTRUKTUREN 214 Beispiel 8.6.2 arithmetische Bäume der Tiefe 0 auf A hat man direkten Zugriff auf S S hat man Zugriff durch car: S 7! S, car(hu; vi) = u, cdr: S 7! S, cdr(hu; vi) = v. a Test auf Zugehörigkeit zu einer Komponente: Test auf Gleichheit: Dieser wurde von McCarthy nur für Atome festgelegt: 8.6.2 Arithmetische Bäume Wir gehen von einer Datenstruktur operand und einer Datenstruktur operator aus, so daß jedes Element vom Typ operator sich auf zwei Elemente vom Typ operand anwenden läßt. Beispiel 8.6.1 Die Namen a; b; c; d ; e; : : : und die Zahlen aus Z bilden den Typ operand. Die Symbole +; ;; ; = bilden den Typ operator. Für die rekursive Mengendefinition sei A die Menge der Operanden, P die Menge der Operatoren. Dann wird die Menge B der arithmetischen Bäume erklärt durch B = A[BPB Hierbei bedeute B P B die Menge der Tripel hb; p; b0i, b; b0 2 B, p 2 P. B enthält demnach Elemente a 2 A Elemente ha; p; a0i, a; a0 2 A, p 2 P Elemente hha; p; a0i; p0 ; ai usw. + 2 b * c b 4 17 3 * s 2 A wird durch atom: S 7! B getestet; s 2 S S wird durch die Negation zu atom getestet. Hieraus ist ein Gleichheitstest für Elemente aus S programmierbar! - + 1 (Die Bezeichnungen sind historisch; man könnte sie durch left und right ersetzen) eq: A A 7! B . -2 a a 5 * 100 c Als Operatoren können wir hierzu anführen: operation: B P B 7! B, operation(b1; p; b2) = hb1 ; p; b2i leftoperand: B 7! B, leftoperand(hb1; p; b2i) = b1 rightoperand: B 7! B, rightoperand(hb1; p; b2i) = b2 operator: B 7! B, operator(hb1; p; b2i) = p basicoperand: B 7! B , basicoperand(b) = (b 2 A 7!TRUE, FALSE ) 8.6.3 Der Stack als rekursive Datenstruktur Sei nil ein spezielles Element und E die Menge der Daten eines Typs elem. Dann sei S = fnil g[ S E mit folgenden Operationen 7 S, create = nil ! push: S E 7! S, (wie cons bei LISP) pop: S 7! S, (wie car) create: 8.6. REKURSIVE DATENSTRUKTUREN UND ZEIGER 215 top: S 7! E, (wie cdr) empty: S 7! B, (wie atom) Bei der Implementation rekursiver Datenstrukturen tritt das folgende Problem auf: Wird eine Variable des betreffenden Typs definiert, so ist der Speicherbedarf immer noch variabel. 8.6.4 Zeiger (Referenzen, Access-Typen (so in Ada), Pointer) Motivation aus den rekursiven Datenstrukturen heraus: Der Speicherplatz für ein Datum einer rekursiven Datenstruktur ist unbeschränkt groß (z. B. beliebig große Bäume). Für eine geordnete Speicherverwaltung ist eine feste Speicherplatzgröße nützlich. Prinzip: Zu jedem Typ wird ein Typ ref t (Bezeichnung nach ALGOL 68) definiert. Ein Datum vom Typ ref t ist eine Speicheradresse zu einem Datum vom Typ t. Anwendung auf LISP: Vorgegeben: Typ atom. Definiere neuen Typ s zusammen mit ref s s = union(atom,record(car: ref s,cdr: ref s)). Anwendung auf arithmetische Bäume: b = union(operand,record(left: ref b,op: operator,right: ref b)) Zeiger allgemein: Man kann auch ohne rekursive Konstrukte Zeiger zur Adressenverwaltung einführen. Unterscheide: Typ-unabhängige Zeiger, maschinennah, jede Adresse zuweisbar, Typ: pointer. Typ-abhängige Zeiger, ref t zu jedem t. Für die Festlegung von t unterscheidet man zwei Fälle: t beliebig: ermöglicht z. B. Typen real, ref real, ref ref real, . . . , refn real, n 0: ALGOL 68; schwer zu programmieren. t einschränken auf nicht-ref-Typen. 216 KAPITEL 8. DATENSTRUKTUREN 218 Kapitel 9 Kontrollstrukturen call-by-reference: Der Parameter dient zur Übergabe einer Adresse. Zu Beginn des Ablaufes des Unterprogrammes wird die Adresse aus dem aktuellen Parameter ermittelt. Dieser muß so beschaffen sein, daß er eine Adresse liefern kann (also z. B. kein Ausdruck, sonst gibt es einen Fehler). Bei Abarbeitung des Rumpfes wird an jeder Stelle, an der der formale Parameter auftritt, diese Adresse verwendet. Wird der Inhalt der Adresse während der Abarbeitung des Unterprogrammes verändert, so bleibt dieser Wert auch nach der Beendigung des Unterprogrammes erhalten (Effekt nach außen). call-by-name: 9.1 Übersicht KAPITEL 9. KONTROLLSTRUKTUREN Darstellungsform, syntaktisch und semantisch Ausdruck und Anweisung Sequenz und Nebenläufigkeit Der Parameter dient zur Übergabe einer Formel. Zu Beginn des Ablaufes des Unterprogrammes erfolgt keine Auswertung dieses Parameters. Erst bei Erreichen des formalen Parameters bei Abarbeitung des Rumpfes erfolgt eine unmittelbares Einsetzen des aktuellen Parameters, und dies jedes Mal neu. Eventuell keine Auswertung, wenn bei Ablauf der Parameter nicht erreicht wird. Bei Mehrfachauswertung ineffizient, dies ist jedoch für verzögerte Auswertung (’lazy evaluation’) nützlich. Diese Parameterübergabe ist heute nur noch theoretisch wichtig, da sie relativ schwer nachvollziehbar ist und hohe Anforderungen an einen Compiler stellt. Eingeführt wurde diese Parameterübergabe durch die Programmiersprache ALGOL60. Alternativen: einseitig, zweiseitig, mehrseitig Schleifen zur Iteration unbeschränkte Schleifen und Sprünge call-by-need: legt nur fest, daß Auswertung der Parameter erst erfolgt, wenn er benutzt wird; heute: in funktionalen Sprachen 9.2 Unterprogramme in-Parameter: sofortige Auswertung; i. a. wird Wert erwartet (anderes aber nicht ausgeschlossen); im Rumpf keine Zuweisung darauf Bei den Parametern eines Unterprogrammes unterscheiden wir zwischen verschiedenen Arten des Aufrufs: out-Parameter: sofortige Auswertung; Adresse erwartet; im Rumpf muß Zuweisung darauf vorkommen call-by-value: in/out-Parameter sofortige Auswertung; Adresse erwartet; zu Beginn wird Wert transportiert; Rückgabe eines Wertes erwartet Unterprogramme Der Parameter dient der Übergabe eines Wertes (wertfähige Ausdrücke: z. B. 3, a+b, . . . ). Zu Beginn des Ablaufes des Unterprogrammes wird der aktuelle Parameter ausgewertet. Der ermittelte Wert wird dann im Rumpf an jeder Stelle verwendet, an der der formale Parameter auftritt. Zuweisungen an den formalen Parameter sind entweder unzulässig (Fehler) oder werden als Zuweisung an eine (lokale) Variable des Unterprogrammes angesehen, ohne Effekt nach außen. 217 Besonderheiten: Funktionen als Parameter bzw. Unterprogramme als Parameter) eigentlich call-by-value unter folgender Philosophie: Funktionen und Programme sind Werte vom Typ ’function’ bzw. ’program’; falls Funktionen mit Typen ausgestattet sind, dann gehört zur Spezifikation evtl. auch die Spezifikation von deren Parametern ! Signaturen von Funktionen, z. B. f(real, integer, boolean):integer KAPITEL 10. PROGRAMMIERSPRACHEN 220 Zielsetzung, Realisierung, Nutzung, Wirkung, Nebenwirkung, : : : insbesondere: Kapitel 10 Programmiersprachen 10.1 Allgemeine Bemerkungen zu Programmiersprachen Sprachfamilien alles was mit dem Erlernen der Sprache zusammenhängt Implementationsprobleme (;! Compilerbau) 10.1.2 Merkmale und Ausprägungen Mächtigkeit (Ausdruckskraft) exakte Beschreibbarkeit eines Problems, Problem der Semantik 10.1.1 Syntax, Semantik und Pragmatik Syntax Lebenszyklus einer Sprache: Entwurf, Implementierung, Wartung, Standardisierung, Verbreitung, : : : relative Beurteilung Vergleiche Mächtigkeit von Sprachen mit goto und von Sprachen mit Dijkstra-Kontrollstrukturen: L ist mindestens so mächtig wie L0 : L L0 absolute Beurteilung Mächtigkeit der vollen Berechenbarkeit (alle partiell-rekursiven Funktionen oder alle primitivrekursiven Funktionen sind programmierbar). Bei Datenbanksprachen kommen weitere Maße hinzu. legt die Programmiersprache als formale Sprache fest: Alphabet A, L 2 A so als reine Textsprache. Allgemeiner: Handlungssprache, z. B. Manipulation am Bildschirm. Der Fall L endlich ist selten (z. B. Aufzählung). Im allgemeinen wird L unendlich sein, wenigstens im Prinzip (Konsequenz der Schachtelung). Die Beschreibung von unendlichen formalen Sprachen erfolgt durch Grammatiken oder äquivalente Konstrukte. Ziel ist es, die syntaktische Struktur so zu erklären, daß darauf die Erläuterung der Semantik (=Bedeutung) aufgebaut werden kann. Semantik (z. B. APL: interaktive Sprache und funktionaler Programmierstil, hier gemischt mit imperativen Stil) Festlegung der Bedeutung: praktisch: funktionale Semantik: Bedeutung = Funktion zwischen Eingaben und Ausgaben. auch: Bedeutung auf Maschinenebene 219 Determinismus theoretisch: Es gibt viele Konzepte des Nichtdeterminismus: choice, success, failure, guarded commands,: : : operationale Semantik: Bedeutung = Abläufe auf einer realen oder virtuellen Maschine. Pragmatik Die reale Seite der Sprache: Interaktivität Nur wenige Sprachen verwenden systematisch nichtdeterministische Konstrukte. Alle Sprachen erlauben aber stillschweigend Random-Funktionen. Es handelt sich hierbei aber nur um Pseudozufallsfunktionen —Pseudo-Nichtdeterminismus. Prozeduralität 10.1. ALLGEMEINE BEMERKUNGEN ZU PROGRAMMIERSPRACHEN221 KAPITEL 10. PROGRAMMIERSPRACHEN 222 Ein Programm ist um so stärker prozedural, je präziser es seinen Ablauf direkt beschreibt. Das Sortierproblem ist ein gutes Beispiel hierfür. Die Festlegung, die Elemente eines (endlichen) Feldes in eine aufsteigende Reihenfolge zu bringen, ist logisch klar genug, um sie automatisch ausführen zu lassen. Man könnte ein Programm geringer Prozeduralität also etwa so formulieren: – Verwendung möglichst vieler oder möglichst weniger globaler Variablen Beispiel 10.1.1 function sort (a: array[1. . . n]): array[1. . . n]; – häufige Verwendung von Sprüngen – starke/schwache Modularisierung – Vermeidung von Seiteneffekten – Ausnutzung und Bevorzugung von Seiteneffekten – Vermeidung von Sprüngen begin Beispiele für nicht imperative Programmiersprachen: b: array[1. . . n]; b = permutation(a) ^ 1 i n-1=) b[i]b[i-1]; – Verwendung von Mengen (z. B. SETL) – Verwendung von prädikatenlogischen Formeln result b; – deklarative Beschreibung des Programmierzieles end – Verwendung von Zugriffsmustern (z. B. f(n+1)=n*f(n)) Entscheidend für die Ausführbarkeit ist die Existenz eines allgemeinen Mechanismus, der die Lösung schrittweise konstruiert. Ein stärker prozedurales Programm entsteht, wenn wir die Lösung in PASCAL oder einer anderen imperativen Sprache beschreiben. Dann werden die Lösungsschritte einzeln und in ihrer Reihenfolge festgelegt notiert. Von R. Kowalski, der PROLOG entwickelt hat, stammt die Formulierung Algorithm = Logic + Control Diese Formel soll folgendes aussagen: Zur Festlegung eines Algorithmus gehört die logische Festlegung seines Resultats und unabhängig davon eine Ausführungskontrolle. Vereinfachend spricht man von prozeduralen und nichtprozeduralen Programmen. Letztere vermeiden Kontrollangaben so weit wie möglich. Von den beiden Formulierungen 10.2 Funktionale Programmierung 10.2.1 Übersicht APL LISP MIRANDA Grundlage λ-Kalkül Hinweis: Auf der Homepage von Michael David ist weiteres Material zu diesen Themen verfügbar. sortiere a[1. . . n] 10.2.2 APL und sortiere a[1. . . n] durch Einsortieren von unten nach oben ist die erste am geringsten prozedural. Wir ordnen sie aber beide als nichtprozedural ein. Stil bezeichnet eine allgemeine Vorgehensweise, die bei der Programmierung bevorzugt wird. Beispiele bei imperativen Programmiersprachen: APL (=A Programming Language) ist eine Programmiersprache die circa 1960 von K. E. Iverson entworfen wurde und ein wichtiger Vorläufer der modernen funktionalen Sprachen (MIRANDA) ist.. Sie ist hoch interaktiv und beruht auf der Idee, mathematische Konzepte in der Programmierung besser auszunutzen. APL liegt die funktionale Programmieridee zugrunde, und ist eine sehr redundanzarme Programmiersprache, d. h. der Source-Code ist sehr kurz, dafür aber sehr kryptisch. 10.2. FUNKTIONALE PROGRAMMIERUNG 223 Datentypen APL unterscheidet nur zwei elementare Datentypen: Skalare und Felder. Skalare sind Typen der Dimension 0, die entweder numerisch oder literal sein können (literal=character). Dabei schließt der numerische Typ ’boolean’ ein: 0 für false und 1 für true. Felder sind Typen beliebiger Dimension, die ebenso entweder numerisch oder literal sind. Deklarationen sind in APL nicht nötig, da der Interpreter sich immer den richtigen Typ heraussucht. Zum Beispiel ist bei der Zuweisung x 3 4 5 klar, daß es sich bei x um ein numerisches Feld handelt. Ebenso x ’a’: literaler Skalar. APL kennt aber Generierungsoperatoren für Felder: z. B. ι5 b = KAPITEL 10. PROGRAMMIERSPRACHEN 224 Fast jede beliebige Folge von Zeichen und Operatoren ist gültig. Es darf nur ganz rechts kein Operator stehen. Der Operatorenfundus in APL ist reichhaltig, da alle Operatoren mit 2 Argumenten auch mit 1 Argument verwendet werden. Hier eine kleine Übersicht: 1 2 3 4 5 oder 3 3 ρ0 1 00 = b @1 1 0 0 1 0 1 0 1 A APL kennt keine Verbunde und keine Zeiger! Ausdrücke APL unterscheidet zwischen elementaren und zusammengesetzten Ausdrücken. Elementare Ausdrücke sind Konstanten, Variablen und niladische Operatoren (Operatoren ohne Argumente). Zusammengesetzte Ausdrücke sind monadische Operatoren (Operatoren mit einem Argument, wie z. B. ι5) und dyadische Operatoren (Operatoren mit zwei Argumenten, wie z. B. a ρ b) Dabei gilt für die Auswertung immer: Rechts hat Vorrang vor links! b D + X C + X B + X A in APL =D + C X + B X2 + A X 3 Die Regeln der Klammerung gelten wie gewöhnlich. Kombinationen aus Rechenschritten und Zuweisungen sind erlaubt: 3+X Y +1 0a 1a 2a 3a 4a 5a 6a 7a 1 ; a2 sin a cos a tan p 2a a ;1 sinh a cosh a tanh a ; + p ;1 a arcsin a ;2 a arccos a ;3 a p arctan a ;4 a a2 + 1 ;5 a arcsinh a ;6 a arccosh a ;7 a arctanh a Wird dabei ein Operator, der für einen Skalar definiert ist, auf ein Feld angewendet, erfolgt die Ausführung komponentenweise. Bei der Operatoranwendung zwischen zwei Feldern wird auf gleichen Positionen entsprechend verknüpft. Desweiteren gibt es in APL den sogenannten Reduktionsoperator, dabei wird eine Operation für 2 Operanden auf n Operanden (n 0) ausgedehnt. Seine Anwendung auf ein Feld sieht allgemein so aus: b op/X =x1 op x2 op : : : op xn Beispiele für Reduktionsoperatoren sind: b Summenbildung +== z. B. Z a+b a;b ab ab ab a~b adb abb ajb a!b na Arithmetische Operatoren dyadisch monadisch Summe +a Identität Differenz ;a Negation Produkt a Signum Quotient a Reziprokwert ab a ea loga b ~a ln a Maximum da aufrunden Minimum ba abrunden Rest b=a ja Betrag b !a Fakultät a Kreisfunktionen a π a ; =b Bilden einer alternierenden Summe = 10.2. FUNKTIONALE PROGRAMMIERUNG 225 =b Produktbildung d =b Maximumsbildung ∇ SPHERE R [1] SURF 4 R R [2] VOL SURF R 3 [3] ∇ = = Weitere dyadische Operatoren in APL: Durch A # B werden die ersten A Elemente aus B gestrichen. Durch A=B (A und B Vektoren gleicher Länge, wobei A ein boolescher Vektor ist) werden die Elemente aus B gestrichen, die in A mit 0 besetzt sind. Kontrollstrukturen Text fehlt Programmieren in APL APL unterscheidet grob zwischen zwei Modi: dem Tischrechnermodus oder Direktmodus und dem Funktionsdefintionsmodus. Im Tischrechnermodus werden alle Eingaben sofort ausgewertet und das Resultat auf dem Bildschirm angezeigt. Beispiel 10.2.1 KAPITEL 10. PROGRAMMIERSPRACHEN 226 Dabei ist [n] die Eingabeaufforderung des Computers für die n-te Zeile der Funktion. Abschluß einer Prozedur oder Funktion ist ebenfalls wieder ∇. Ein Prozeduraufruf ist jetzt zum Beispiel SPHERE 1.2 Ein- und Ausgaben werden in APL über die Zeichen oder 0 realisiert. Dabei unterscheidet APL zwischen der Ein- und Ausgabe numerischer oder literaler Skalare und Felder. Für literale Skalare und Felder muß anstelle von das Zeichen 0 verwendet werden. Ein Ausgabe bewirkt folgender Ausdruck: hexpressioni Eine Eingabe verlangt der Interpreter immer dann, wenn das Symbol oder 0 in einem Ausdruck auftaucht. Ausnahme ist natürlich der Ausdruck für eine Ausgabe. Beispiel 10.2.3 Ausgabe Eingabe Ausgabe ι3 1 2 3 x ι3 2 3 4 x+1 +/’e’=’eintext’ 2 Der Funktionsdefinitionsmodus dient zur Programmierung komplexerer Funktionen oder Prozeduren in APL. Allen Funktions- oder Prozedurvereinbarungen steht das Zeichen ∇ voran. Beispiele für Funktions- oder Prozedurköpfe sind: ∇F X ∇X FY ∇R F X ∇R F ∇R X FY ∇ F X; U;V Dabei ist F der Funktionsname, R das Resultat und X ; Y übergebene Parameter. Beispiel 10.2.2 (Eine Prozedur in APL) : : Eingabe X 1+ 3 ι4 X +2 8 9 10 11 Sprünge werden in APL mit Hilfe der Zeilennummern oder Labeln (Textmarken) realisiert. Dabei werden konkret die folgenden Befehle verwendet: ! hlabeli ! hscalar expressioni Falls statt einem Skalar ein Feld auftritt, wird an die Stelle gesprungen, die in der ersten Komponente des Feldes angegeben ist. ! 0 wird als Ende der Funktion interpretiert. Ebenso wird bei einem Sprung auf eine nicht existierende Zeilennummer verfahren. Falls als Sprungziel ein leerer Vektor angegeben ist, wird der Befehl einfach ignoriert. Die Funktionsabarbeitung wird fortgesetzt. Beispiel 10.2.4 ! (A = B; A < B; A > B)=2 7 11 10.2. FUNKTIONALE PROGRAMMIERUNG Programmbeispiele Beispiel 10.2.5 (Fakultätsberechnung ohne Verwendung des Operators) ∇Z FAC N [1] ! 4 ι N = 0 [2] Z N FAC N ; 1 [3] ! 0 [4] Z 1 [5] ∇ Beispiel 10.2.6 (Berechnung der Fibonacci-Zahlen) [1] [2] [3] [4] X Y ∇F Z X Y Z Y ∇ 1 X +Y Beispiel 10.2.7 (Berechnung der Fibonacci-Zahl N) [ 1] [ 2] [ 3] [ 4] [ 5] [ 6] [ 7] [ 8] [ 9] [10] [11] [12] [13] ∇ FIB N X Y 1 ! (N = 0; N = 1; N > 1)=3 3 5 1 !0 K 2 Z X +Y X Y Y Z ! (K = N )=12 K K +1 !6 Y ∇ 227 228 KAPITEL 10. PROGRAMMIERSPRACHEN 230 KAPITEL 11. LITERATUR ZU INFORMATIK I UND II – Kupka, I.: Informatik I & II, WS 92/93, SS 93, erstellt von Michael Frank, Thomas Klein, Torsten Hiddessen, Jens Rehaag – Ecker, K.: Informatik I & II, WS 97/98, SS 1998, erstellt von, Thomas Klein, Michael Frank, Andreas Schlechte – Siehe Titelseite, erstellt von siehe Titelseite Kapitel 11 Literatur zu Informatik I und II Nachschlagewerke: – Informatik Rechenberg, Pomberger: Informatik-Handbuch, Hanser, 1997, DM 98,– Mathematik und Informatik: Zeidler (Hrsg.): Teubner-Taschenbuch der Mathematik, Teil I, 1996, Teil II, 1995, Teubner Verlag – Wirtschaftsinformatik: Zilahi-Szabo: Kleines Lexikon der Informatik, Oldenbourg Verlag, 1995 Monographien: – Arbib, M. A., Kfoury, A. J., Moll, R. N.: A Basis for Theoretical Computer Science, Springer, 1981 – Dewdney, A. K.: Der Turing Omnibus, Eine Reise durch die Informatik mit 66 Stationen, Springer 1995 – Goos, G.: Vorlesungen über Informatik, Band 1: Grundlagen und funktionales Programmieren, 2. Auflage, Springer, 1997 – Goos, G.: Vorlesungen über Informatik, Band 2: Objektorientiertes Programmieren und Algorithmen, Springer, 1997, (2. Auflage 1999) – Goos, G.: Vorlesungen über Informatik, Band 3: Berechenbarkeit, formale Sprachen, Spezifikationen, Springer, 1997 – Goos, G.: Vorlesungen über Informatik, Band 4: Paralleles Rechnen und nicht-analytische Lösungsverfahren, Springer, 1998 – Harel, D.: The Science of Computing, Exploring the Nature and Power of Algorithms, Addison-Wesley, 1989 Skripte: 229