TEUBNER-TEXTE zur Informatik Band 34 Christoph Walther Semantik und Programmverifikation TEUBNER-TEXTE zur Informatik Herausgegeben von Prof. Dr. Johannes Buchmann, Darmstadt Prof. Dr. Udo Lipeck, Hannover Prof. Dr. Franz J. Rammig, Paderborn Prof. Dr. Gerd Wechsung, Jena Ais relativ junge Wissenschaft lebt die Informatik ganz wesentlich von aktuellen Beitragen. Viele Ideen und Konzepte werden in Originalarbeiten, Vorlesungsskripten und Konferenz berichten behandelt und sind damit nur einem eingeschrankten Leserkreis zuganglich. Lehr bOcher stehen zwar zur VerfOgung, k6nnen aber wegen der schnellen Entwicklung der Wis senschaft oft nicht den neuesten Stand der Entwicklung wiedergeben. Die Reihe TEUBNER-TEXTE zur Informatik 5011 ein Forum fOr Einzel- und Sammelbeitrage zu aktuellen Themen aus dem gesamten Bereich der Informatik sein. Gedacht ist dabei insbe sondere an herausragende Dissertationen und Habilitationsschriften, spezielle Vorlesungs skripten sowie wissenschaftlich aufbereitete Abschlussberichte bedeutender Forschungs projekte. Auf eine verstandliche Darstellung der theoretischen Fundierung und der Perspek tiven fOr Anwendungen wird besonderer Wert gelegt. Das Programm der Reihe reicht von klassischen Themen aus neuen Blickwinkeln bis hin zur Beschreibung neuartiger, noch nicht etablierter Verfahrensansatze. Dabei werden bewusst eine gewisse Vorlaufigkeit und Un vollstandigkeit der Stoffauswahl und Darstellung in Kauf genommen, weil so die Lebendig keit und Originalitat von Vorlesungen und Forschungsseminaren beibehalten und weiterge hende Studien angeregt und erleichtert werden k6nnen. TEUBNER-TEXTE erscheinen in deutscher oder englischer Sprache. Christoph Walther Semantik und Programmverifikation Teubner B. G. Teubner Stuttgart· Leipzig· Wiesbaden Die Deutsche Bibliothek - CIP-Einheitsaufnahme Ein Titeldatensatz fOr diese Publikation ist bei der Deutschen Bibliothek erhaltlich. Prof. Dr. rer. nat. habil. Christoph Walther Studium der Informatik an der Universitat Karlsruhe und an der Technischen Universitat Wien. AnschlieBend an der Universitat Karlsruhe Wissenschaftlicher Angestellter, Promotion, Hochschulassistent und Habilitation. Seit 1990 Professor fUr Informatik an der Technischen Universitat Darmstadt. Arbeitsschwerpunkte und -interessen: Automatisches Beweisen, Maschinelle Lernverfahren fOr Beweis systeme, Semantik, Beweisverfahren und Systeme zur Programmverifikation und zum Nachweis der Sicher he it und Verlasslichkeit von Kommunikationsprotokoilen. 1. Auflage November 2001 Aile Rechte vorbehalten © B. G. Teubner GmbH, Stuttgart/Leipzig/Wiesbaden, 2001 Der Verlag Teubner ist ein Unternehmen der Fachverlagsgruppe BertelsmannSpringer. Das Werk einschlieBlich aller seiner Teile ist urheberrechtlich geschOtzt. Jede Verwertung auBerhalb der engen Grenzen des Urheberrechtsgesetzes ist ohne Zustimmung des Ver lags unzulassig und strafbar. Das gilt insbesondere fOr Vervielfaltigungen, Obersetzun gen, Mikroverfilmungen und die Einspeicherung und Verarbeitung in elektronischen Systemen. www.teubner.de Die Wiedergabe von Gebrauchsnamen, Handelsnamen, Warenbezeichnungen usw. in diesem Werk berechtigt auch ohne besondere Kennzeichnung nicht zu der Annahme, dass solche Namen im Sinne der Warenzeichen- und Markenschutz-Gesetzgebung als frei zu betrachten waren und daher von jedermann benutzt werden dOrften. Umschlaggestaltung: Ulrike Weigel, www.CorporateDesignGroup.de Gedruckt auf saurefreiem und chlorfrei gebleichtem Papier. ISBN-13: 978-3-519-00336-6 e-ISBN-13: 978-3-322-86768-1 DOl: 10.1007/978-3-322-86768-1 Vorwort Ein zentrales Problem der Informatik ist der Nachweis der Korrektheit von Pro grammen, d.h. der Nachweis, daB Programme auch das tun, was der Programmierer beabsichtigt. Dieser Nachweis - also die Programmverijikation - muB durch einen formalen (mathematischen) Beweis erbracht werden: (1) Mit Definition der Semantik einer Programmiersprache (d.h. der Defmi tion der Bedeutung der Ausdrticke der Sprache) konnen Programmen Formeln der mathematischen Logik zugeordnet werden. (2) Durch Formeln der mathematischen Logik wird formal spezijiziert, was ein Programm leisten solI. (3) Damit kann das Verifikationsproblem, d.h. der Nachweis, daB ein Pro gramm die Spezijikation auch erfollt, auf ein Beweisproblem zurUckgefiihrt werden, und somit sind zu dessen Losung bekannte Resultate der Formalen Logik und des Automatischen Beweisens verwendbar. Am Beispiel einer einfachen funktionalen Programmiersprache, der Sprache !fP, werden in diesem Buch Grundlagen der Semantik, der Spezijikation und der Ve rijikation von Programmen vorgestellt. Zur Definition von!fP und zur Formu lierung von Aussagen fiber Programme dieser Programmiersprache verwenden wir Grundbegriffe der Formalen Logik, die zusammen mit dem erforderlichen mathematischen Rfistzeug in Kapitel 1 wiederholt werden. In Kapitel 2 wird dann die Programmiersprache !fP eingefiihrt sowie deren operationale und de notationale Semantik defmiert und verglichen. Hierbei handelt es sich urn Stan dardstoff aus dem Gebiet der Semantik von Programmiersprachen, erlautert anhand der Programmiersprache !fP. Kapitel 3 behandelt schlieBlich die Verifikation von !fP-Programmen, also den Nachweis der Terminierung sowie 6 Vorwort Beweistechniken zum Nachweis der partiellen Korrektheit von !fP Programmen. * Erganzende, vertiefende und weiterfiihrende Literatur wird im Literaturverzeichnis angegeben. Das vorliegende Buch ist aus der erstmalig im Wintersemester 1995/96 an der Technischen Universitat Darmstadt gehaltenen Vorlesung Semantik und Pro grammverifikation entstanden. Ich danke zahlreichen Horem der Vorlesung fiir kritische und konstruktive Kommentare sowie meinen Mitarbeitem, Herrn Dipl. Inform. Matthias Bormann und Herrn Dr. Jiirgen Giesl, die beim Korrekturlesen oft Fehler bemerkten, die dann noch rechtzeitig behoben werden konnten. Trotzdem wird das Buch immer noch nicht fehlerfrei sein, fiir entsprechende Hinweise bin ich daher dankbar. Zu guter Letzt danke ich der CA Computer Associates GmbH, die mit ihrer Anzeige ein preiswerteres Erscheinen dieses Buches ermoglichte. Darmstadt, im Juli 2001 Christoph Walther • Ein Auszug aus Kapitel 3 erschien in: "C. Walther Criteria/or Termination. In "Intellectics and Computational Logic: Papers in Honor of Wolfgang Bibel", S. Holldobler (Hrsg.), Kluwer Academic Publishers, 1999,361-386". Inhaltsverzeichnis 1 F ormale Grundlagen .................................... 9 1.1 Syntax der Pradikatenlogik 1. Stufe ........................ 10 1.2 Semantik der Sprache 1. Stufe ............................ 20 1.3 Fundierte Mengen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 23 1.4 Konstruktion fundierter Mengen . . . . . . . . . . . . . . . . . . . . . . . . .. 31 1.5 Konfluente Relationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 2 Funktionale Programme ................................. 39 2.1 Die Programmiersprache:FP ............................. 41 2.2 Operationale Semantik von:FP ........................... 48 2.3 Denotationale Semantik von:FP .......................... 62 2.4 Aquivalenz von operationaler und denotationaler Semantik . . .. 94 2.5 Erweiterung von:FP urn Datenstrukturen ................... 105 2.6 Altemativen der Parameterubergabe . . . . . . . . . . . . . . . . . . . . . .. 119 2.7 Elimination von gegenseitiger Rekursion . . . . . . . . . . . . . . . . . .. 128 3 Verifikation funktionaler Programme ...................... 139 3.1 Terminierung funktionaler Programme ..................... 140 3.2 Normal- und Tail-Rekursive Funktionsprozeduren . . . . . . . . . .. 165 3.3 Spezifikation funktionaler Programme. . . . . . . . . . . . . . . . . . . .. 177 3.4 Semantik der Spezifikationssprache . . . . . . . . . . . . . . . . . . . . . .. 185 3.5 Beweise zur partiellen Korrektheit. . . . . . . . . . . . . . . . . . . . . . .. 188 3.6 Grenzen der formalen Verifikation ........................ 193 3.7 Korrektheitsbeweise durch Induktion . . . . . . . . . . . . . . . . . . . . .. 200 Literaturverzeichnis .................................... 208 Sachverzeichnis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210 1 Formale Grundlagen In diesem Kapitel werden diejenigen formalen Grundbegriffe eingefuhrt, die in den nachfolgenden Abschnitten erforderlich sind. Wir verwenden Konzepte der sortierten Pradikatenlogik erster Stufe, urn funktionale Programme zu defi nieren, ihre Semantik zu formalisieren und Korrektheitsaussagen tiber diesen Programmen zu formulieren. Abschnitte 1.1 und 1.2 behandeln Syntax und Semantik der Pradikatenlogik, also Standardstoff, wie er in gangigen Einfuhrungstexten zur Mathematischen Logik und zum Automatischen Beweisen zu finden ist. Da Programmiersprachen tiblicherweise verschiedene Datentypen, wie etwa narurliche Zahlen, Listen von narurlichen Zahlen, Baumstrukturen u.s.w., ken nen, verwenden wir eine sortierte pradikatenlogische Sprache. Die Sortensym bole dienen dabei als Namen fur die jeweiligen Datentypen. Eine sortierte Spra che bzw. eine Programmiersprache mit Datentypen ist theoretisch nicht erfor derlich, aber fur die Anwendung in vielfacher Hinsicht sehr praktisch. Dies gilt sowohl fur die Pradikatenlogik, als auch fur Programmiersprachen. In den Abschnitten 1.3 und 1.4 behandeln wir mit fundierten Mengen das zentrale mathematische Konzept zur rekursiven Definition von Funktionen und zum Beweis von Eigenschaften so1cher Funktionen durch das Induktionsprinzip. Abschlie13end betrachten wir in Abschnitt 1.5 konjluente Relationen, mit de nen indeterministische Ableitungsprozesse elegant formuliert werden konnen. C. Walther, Semantik und Programmverifikation © B. G. Teubner GmbH, Stuttgart/Leipzig/Wiesbaden 2001 10 1 Formale Grundlagen 1.1 Syntax der Pradikatenlogik 1. Stufe Definition 1.1.1 (Sorten und sortenindizierte Mengen) Sei Seine nicht-leere Menge von Sortensymbolen, d.h. eine Menge von Namen fUr Mengen, und sei M irgendeine nicht-leere Menge. Dann bezeichnet 2M die Potenzmenge von M und M* die Menge aIler endlichen Folgen (oder Zeichen reihen) von Elementen aus M, einschlieBlich der leeren Folge A. Wir verwenden if als Abkiirzung fUr M*\{A}. Fiir eine S-indizierte Familie von Mengen M= (Ms)SES und ein W=Sl ... SkES* bezeichnet Mw die Menge aIler endlichen Folgen ml ... mkEM* mit mjEMsj fUr 19:sk, und wir definieren Mt..={A}. Wir nennen eine Abbildung j:M-+N mit M=(Ms)SES und N=(Ns)SES sortener haltend (engl. sort preserving) und schreiben j:M-+sN, gdw. j(Ms)cNs fUr jedes SES. Jede Abbildung j:M-+sN kann als Homomorphismus zu einer Abbildung j:Mw-+Nw erweitert werden, d.h. j(A)=A und j(ml ... mlwl)=j(ml) .. .j(mlwl) fUr aIle WES+ und aIle ml ... mlwIEMw. Dabei ist Iwi die Lange der Folge w. {M-+N} be zeichnet die Menge aIler (totalen) Abbildungen j:M-+N. • Definition 1.1.2 (Sortenindizierte Signaturen) Eine S-sortierte Signatur L=(Lw,s)WES*,SES ist eine S+ -indizierte Familie von paarweise disjunkten Mengen. Jedes fELw,s ist ein Funktionssymbol mit Rang WS, Stelligkeit W und Sorte s. Die Elemente von Lt..,s hei13en auch Konstanten der Sorte s. List eine Teilsignatur von L', kurz LCL', gdw. Lw,sCL'w,s fUr aIle WES* und aIle s ES. Wir unterteilen j"ede S-sortierte Signatur L in einen Konstruktorteil LC und einen Dejinitionsteil Ld. LCi st eine Teilsignatur von L mit Lt..,sCL\'s fUr alle s ES. Die Elemente von LCw erden Konstruktorfunktionssymbole oder auch Kon struktoren genannt. Ld ist eine Teilsignatur von L mit Ldw,s=Lw,s \ LCw,s fUr aIle wES* und aIle SES Die Elemente von Ld hei13en dejinierte Funktionssymbole oder kurz dejinierte Symbole. • Definition 1.1.3 (Terme) Sei L eine S-sortierte Signatur und o/=(o/S)SES eine S-indizierte Familie nicht leerer, paarweise disjunkter und unendlicher Mengen mit o/nL=0. Die Ele mente von o/s hei13en Variable der Sorte s. Fur SES bezeichnet ty(L,o/)s die Men ge aIler Terme der Sorte s (iiber Lund 0/). ty(L,o/)s ist die kleinste Teilmenge von (LUo/)* mit 1.1 Syntax der Priidikatenlogik 1. Stufe 11 (i) o/s c I]l~, o/)s und (ii) jt* E ty(~,o/)s, wennfE~w,s und t*E ty(~,o/)w fUr ein WES*. ty(~)s steht fUr ty(~,0)s und bezeichnet die Menge aller variablenfreien Ter me (der Sorte s) oder auch die Menge aller Grundterme (der Sorte s). ty(~,o/) = (ty(~'o/)S)SES ist die Menge aller Terme (uber ~ und 0/) und ty(~)=eT(~)S)SES be zeichnet die Menge aller Grundterme. Eritsprechend ist q'(~C)s die Menge aller Konstruktorgrundterme der Sorte s und q'(~C)=(q'(~C)s)ses ist die Menge aller Konstruktorgrundterme (beliebiger Sorte). Ein Term t heillt j-Term, gdw. t=jt* fUr ein fE~w,s und ein t*Eq'(~,o/)w. ~(t)c~ ist die Menge aller Funktionssymbole in t und ~(T)=UtET~(t) fUr T cq'(~,o/). o/(t)co/ ist die Menge aller Variablensymbole in t. FUr Tcq'(~,o/) de finieren wir O/(T)=UtET o/(t). Ein Term q ist ein Teilterm (Unterterm, Sub term) von t, kurz q"5r!, gdw. t=q oder t=jtl ... t und q ist Teilterm von ti fUr ein ti mit IgS.n. Ein Teilterm q von t n ist echt, kurz q<qf, gdw. q#. q ist ein direkter Teilterm von t gdw. t=jtl ... t und n q=ti fUr ein ti mit IgS.n. • Terme sind Zeichenreihen uber (~uo/), die gewissen Forderungen genugen. Ubliche Schreibweisen verwenden (formal uberflussige) Klammem und Kom mata, urn die Lesbarkeit nicht zu erschweren, also etwa j(a,g(g(b))) anstatt faggb. Wir werden nachfolgend beide Schreibweisen verwenden. Terme und Operationen auf Termen lassen sich gut durch gewisse Baurne veranschaulichen: Ein Termbaum TB(t) fUr einen Term t besteht lediglich aus einem mit t markierten Wurzelknoten, falls tE(~Uo/). Filr t=jtl ... tn (mit n~l) ist die Wurzel W von TB(t) mitfmarkiert und what n Nachfolgerknoten WI, ... ,Wn, wobei jeder Knoten Wi der Wurzelknoten des Termbaums TB(ti) fUr den Term ti ist, vgl. Bild 1.1.I(i). Der Wurzelknoten W eines Teiltermbaums TTB(t) fUr einen Term t ist mit t markiert. Der Wurzelknoten ist der einzige Knoten von TTB(t), falls tE(~Uo/). FUr t=jtl ... tn (mit n~l) hat W n Nachfolgerknoten WI, ... ,Wn, wobei jeder Knoten Wi der Wurzelknoten des Teiltermbaums TTB(ti) fUr den Term ti ist, vgl. Bild 1. 1. 1 (ii).