9.1 Grundsätzliches Fehlertoleranz vs. Fehlerintoleranz. Testen vs. Verifikation Testen. Verifikation und Test in der SW-Entwicklung

Ähnliche Dokumente
C. A. R. Hoare. An Axiomatic Basis for Computer Programming. Nicolas Schelp. Proseminar Assertions SS 2007

{P} S {Q} {P} S {Q} {P} S {Q} Inhalt. Hoare-Kalkül. Hoare-Kalkül. Hoare-Tripel. Hoare-Tripel. Hoare-Tripel

! 1. Erste Schritte! 2. Einfache Datentypen! 3. Anweisungen und Kontrollstrukturen! 4. Verifikation! 5. Reihungen (Arrays) II.1.4. Verifikation - 1 -

Algorithmen und Programmieren II Programmverifikation {V} P {N}

Verifikation von Programmen

Informatik I - Programmierung Globalübung Hoare-Kalkül. Thomas Weiler. Fachgruppe Informatik RWTH Aachen. T. Weiler, RWTH Aachen - 1 -

WS 05/06 mod Verifikation

2.4 Schleifen. Schleifen unterscheiden sich hinsichtlich des Zeitpunktes der Prüfung der Abbruchbedingung:

4.3 Verifikation von Aussagen über Algorithmen

Verifizierende Testverfahren

Kurs 1612 Konzepte imperativer Programmierung Musterlösung zur Nachklausur am

Beispiel 1 zur Verifikation eines bedingten Anweisung. Hoare-Regel für die bedingte Anweisung. else

Partielle Korrektheit von Programmen. Beispiele an der Tafel

Beispiel 1 zur Verifikation eines bedingten Anweisung. Hoare-Regel für die bedingte Anweisung. Beispiel 2 zur Verifikation eines bedingten Anweisung

Ein Beispielbeweis zur Verifikation des Programms zur Division mit Rest auf der Basis der Hoare-Regeln

Software Entwicklung 2. Formale Verifikation

Kontrollstrukturen -- Schleifen und Wiederholungen

Kapitel 5: Abstrakte Algorithmen und Sprachkonzepte. Elementare Schritte

Informatik II - Tutorium

Formale Programmverifikation. Referentin: Kirsten Hradek

Programmiersprachen. Marco Block. Folieninhalte teilweise übernommen von Prof. Heinz Schweppe (ALP II, SoSe 2008) und Prof. Löhr (ALP II, SoSe 2004)

Grundlagen der Theoretischen Informatik

Algorithmen und Datenstrukturen Korrektheit von Algorithmen

Teil X. Programmverifikation. Spezifikation eines Algorithmus einer Funktion einer Prozedur. Vorbedingungen Parameter Wertebereiche

Korrekte Software: Grundlagen und Methoden Vorlesung 11 vom : Funktionen und Prozeduren

Elementare Konzepte von

Zusammenfassung. Definition. 1 (x i ) 1 i n Sequenz von Registern x i, die natürliche Zahlen beinhalten. 2 P ein Programm. Befehle: 1 x i := x i + 1

4.4 Imperative Algorithmen Prozeduren

11.0 Systematisches Programmierung

1 Funktionale vs. Imperative Programmierung

7.1 Spezifikation mit Vor- und Nachbedingungen

Definition der Hilfsprädikate

EINI LW/WiMa. Einführung in die Informatik für Naturwissenschaftler und Ingenieure Vorlesung 2 SWS WS 14/15

Tutoraufgabe 1 (Hoare-Kalkül):

Tag 3 Repetitorium Informatik (Java)

Warum Programme Verträge schließen sollten

Java 8. Elmar Fuchs Grundlagen Programmierung. 1. Ausgabe, Oktober 2014 JAV8

Mathematische Rekursion

FACHHOCHSCHULE AUGSBURG Hochschule für Technik, Wirtschaft und Gestaltung

Funktionale Programmierung ALP I. µ-rekursive Funktionen WS 2012/2013. Prof. Dr. Margarita Esponda. Prof. Dr. Margarita Esponda

Thomas Gewering Benjamin Koch Dominik Lüke. (geschachtelte Schleifen)

Allgemeine Hinweise: TECHNISCHE UNIVERSITÄT MÜNCHEN. Name Vorname Studiengang Matrikelnummer. Hörsaal Reihe Sitzplatz Unterschrift

Semantik von Programmiersprachen SS 2017

Übung zur Vorlesung Wissenschaftliches Rechnen Sommersemester 2012 Auffrischung zur Programmierung in C++, 1. Teil

Grundbegriffe der Informatik

Statisches Programmverständnis. pk12w16,

Algorithmen & Programmierung. Steuerstrukturen im Detail Selektion und Iteration

3. Anweisungen und Kontrollstrukturen

Einführung in die Informatik 1

Grundlagen der Programmierung Prof. H. Mössenböck. 4. Schleifen

3. Grundanweisungen in Java

zu große Programme (Bildschirmseite!) zerlegen in (weitgehend) unabhängige Einheiten: Unterprogramme

2. Grundlagen. Beschreibung von Algorithmen durch Pseudocode. Korrektheit von Algorithmen durch Invarianten.

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf Seite 1 von 25

Anweisungen zur Ablaufsteuerung

Klassen und Objekte. Klassen sind Vorlagen für Objekte. Objekte haben. Attribute. Konstruktoren. Methoden. Merkblatt

Einführung in die Programmierung II. 3. Kontrollstrukturen

Prof. Dr. Michael Philippsen / Prof. Dr. Herbert Stoyan

C++ Teil 2. Sven Groß. 16. Apr IGPM, RWTH Aachen. Sven Groß (IGPM, RWTH Aachen) C++ Teil Apr / 22

Sequentielle Programme, Hoare-Logik und Dynamische Logik

Kapitel 1. Grundlegendes

Programmieren I. Kapitel 5. Kontrollfluss

Kapitel 5. Programmierkurs. Kontrollstrukturen. Arten von Kontrollstrukturen. Kontrollstrukturen Die if-anweisung Die switch-anweisung

Technische Universität Braunschweig Institut für Programmierung und Reaktive Systeme

Theoretische Informatik SS 03 Übung 3

fl diese Variablen haben jeweils den Wahrheitswert "wahr" oder "falsch", es sind damit boolesche Variablen (Datentyp: bool bzw.

Operatoren für elementare Datentypen Bedingte Anweisungen Schleifen. Operatoren für elementare Datentypen Bedingte Anweisungen Schleifen

Softwaretechnik. Vorlesung 06: Design by Contract (Entwurf gemäß Vertrag) Peter Thiemann SS Universität Freiburg, Germany

Informatik I Tutorium WS 07/08

Einführung in die Informatik Iterationen

(Aufgaben zu Wertzuweisungen siehe Vorlesungsbeilage S. 49)

Schachtelung der 2. Variante (Bedingungs-Kaskade): if (B1) A1 else if (B2) A2 else if (B3) A3 else if (B4) A4 else A

Einführung in die Programmierung Wintersemester 2011/12

4. Ablaufsteuerung (Kontrollstrukturen) 4.1 Anweisungen 4.2 Selektion (bedingte Anweisung) 4.3 Iteration 4.4 Flussdiagramm (Programmablaufplan)

Einführung in die Informatik Iterations

Logik. Ernest Peter Propädeutikum Mathematik Informatik/Wirtschaftsinformatik, Block Aussage

Algorithmen und Datenstrukturen

Vorlesung Programmieren

Theorem Proving. Software Engineering in der Praxis. Prädikatenlogik. Software Engineering in der Praxis Wintersemester 2006/2007

1 Aufgaben 1.1 Umgebungsvariable setzen: CLASSPATH

Resolutionsalgorithmus

Friedrich-Alexander-Universität Erlangen-Nürnberg

Technische Universität Braunschweig Institut für Programmierung und Reaktive Systeme

3.2.6 Sprünge. Hier: Beschränkung auf gute Sprünge wie return break continue. Beachte: Ein Sprung hat keinen Effekt auf die Programmvariablen.

1 Programmierfehler und ihre Behebung

Einführung in die Programmierung für NF. Rückgabewerte, EBNF, Fallunterscheidung, Schleifen

Grundzüge der Wirtschaftsinformatik WS 2002/03. Wiederholung Java. Programmierzyklus. Heiko Rossnagel Problem

Informatik I. 19. Schleifen und Iteration für verlinkte Listen. Jan-Georg Smaus. Albert-Ludwigs-Universität Freiburg. 27.

3. Kontrollstrukturen Grundlagen der Programmierung 1 (Java)

Inhalt Kapitel 2: Rekursion

2 Teil 2: Nassi-Schneiderman

Verlässliche Echtzeitsysteme

Verlässliche Echtzeitsysteme

Objektorientierte Programmierung

Tag 3 Repetitorium Informatik (Java)

Grundlagen der Programmierung

LOOP-Programme: Syntaktische Komponenten

Diskrete Strukturen Kapitel 2: Grundlagen (Beweise)

Das diesem Dokument zugrundeliegende Vorhaben wurde mit Mitteln des Bundesministeriums für Bildung und Forschung unter dem Förderkennzeichen

C++ Teil 4. Sven Groß. 30. Apr IGPM, RWTH Aachen. Sven Groß (IGPM, RWTH Aachen) C++ Teil Apr / 16

Transkript:

Verlässliche Systeme Wintersemester 2016/2017 Fehlertoleranz vs. Fehlerintoleranz Verlässliche Systeme Bisher haben wir Ausfälle der Hardware betrachtet Jetzt: Betrachten Software 9. Kapitel Verifikation von Software Prof. Matthias Werner Professur Betriebssysteme Wiederholung: Fehlerintoleranz Fehler vermeiden Fehlertoleranz Existenz von Fehlern akzeptieren und negative Auswirkungen verhindern/reduzieren Zwei Basisansätze der Fehlerintoleranz bei Software Testen Verifikation WS 2016/17 M. Werner 2 / 41 osg.informatik.tu-chemnitz.de Verifikation und Test in der SW-Entwicklung Testen vs. Verifikation Testen Verifikation Vorstellung des Kunden Formale Spezifikation Fehler Anforderungsspezifikation Programmentwurf Fehler Test Verifikation keine Fehler gefunden korrekt Für einige möglichst gut ausgewählte Testdaten wird das Programm ausgeführt und beobachtet, ob das gewünschte Ergebnis ermittelt wird Nicht alle möglichen Kombinationen von Eingabedaten können getestet werden Keine Gewissheit über die Korrektheit des Programms für die noch nicht getesteten Eingabedaten Aber: auch Anforderungsfehler/ Spezifikationsfehler können evtl. gefunden werden liefert einen mathematischen, formalen Beweis, dass das Programm der Spezifikation gehorcht Anforderungsfehler können nicht gefunden werden Sie werden aber in der Praxis oft doch gefunden, weil das formale Vorgehen präzisere Spezifikationen erzwingt Verifikation sollte im Entwurf und der Implementierung mit eingeplant sein nachträgliche Verifikation ist meist unmöglich Wir betrachten hier Verifikation WS 2016/17 M. Werner 3 / 41 osg.informatik.tu-chemnitz.de WS 2016/17 M. Werner 4 / 41 osg.informatik.tu-chemnitz.de

Semantiken Um über die Korrektheit von Programmen zu urteilen, muss die Programmsemantik formalisiert werden Gemeinhin sind drei Ansätze bekannt: Denotationelle Semantik Semantik eines Programms wird durch eine Funktion zugewiesen; Nutzung von Domainen (Bereichstheorie) Operationelle Semantik Semantik durch Betrachtung von Zustandsübergängen; jeder Schritt wird durch ein Paar (Vorzustand, Folgezustand) beschrieben Axiomatische Semantik Beschreibung der Semantik durch ihre logischen Eigenschaften, wobei im Allgemeinen nur einige Eigenschaften betrachtet werden Wir betrachten axiomatische Semantik Zusicherungen Ziel: Ableitung eines Nachzustandes aus einem Vorzustand Einen exakten Vor- und Nachzustand zu spezifizieren ist meist schwierig Spezifikation einer Menge von Zuständen über Bedingungen (assertions) an die Zustände Diese Bedingungen können unterschiedlich stark sein // { y > 1 } x= y* y; // { x >= 0 } Schwächere Nachbedingung // { y > 1 } x= y* y; // { x > y > 1 } Stärkere Nachbedingung WS 2016/17 M. Werner 5 / 41 osg.informatik.tu-chemnitz.de Verifikation WS 2016/17 M. Werner 6 / 41 osg.informatik.tu-chemnitz.de C.A.R. Hoare Verifikation ist der formale, d.h. mathematische Beweis, dass das Programm die Spezifikation erfüllt, dass es korrekt ist Partielle Korrektheit Ein Programm(teil) ist partiell korrekt, wenn es von einem spezifizierten Vorzustand (Q) die Abarbeitung beginnt, bei einer eventuellen Terminierung einen spezifizierten Endzustand (R) erreicht. Totale Korrektheit Ein Programm(teil) ist total korrekt, wenn es partiell korrekt ist und terminiert. Sir Charles Antony Hoare (besser bekannt als: Tony Hoare) 1934 Informatikprofessor, University of Oxford, später Microsoft Research Cambridge 1980: Turing Award 2011: John-von-Neumann-Medaille Bedeutende Leistungen: Konzept des Monitors Hoare-Kalkül (auch: Floyd-Hoare-Kalkül) CSP (Communicating Sequential Processes) WS 2016/17 M. Werner 7 / 41 osg.informatik.tu-chemnitz.de WS 2016/17 M. Werner 8 / 41 osg.informatik.tu-chemnitz.de

Hoare-Kalkül Formale Präzisierung des Korrektheitsbegriffs Regeln für die Korrektheit einzelner Anweisungstypen Vorwärtsanalyse von imperativen Programmen Ableiten von Aussagen über das Programm aus den Anweisungen heraus in Vorwärtsrichtung Unterschied: Rückwärtsableiten von Aussagen (z.b. für imperative Sprachen: wp-kalkül von Dijkstra) Hoare-Tripel: {Q}P {R} Bedeutung: Wenn vor Ausführung von P die Zusicherung Q galt, dann muss nach Ausführung von P die Zusicherung R gelten Manchmal 1 andere Syntax: Q{P }R Ohne Bezug auf ein konkretes Programm P : {Q}.{R} Spezifikation Aufgabe des Programmierers, ein Programm P zu schreiben, das der Spezifikation genügt 1 z.b. in Hoares Originalartikel WS 2016/17 M. Werner 9 / 41 osg.informatik.tu-chemnitz.de Verifikationsregeln Verifikationsregeln für imperative Programme Imperative Programme Bestehen aus linearen Kontrollstrukturen Korrektheit: Ergibt sich aufgrund der Korrektheit der Teilstrukturen Ein komplexes Programm kann schrittweise durch korrektes Zusammensetzen aus einfacheren Strukturen verifiziert werden (Beweisdekomposition) Verifikationsregeln Zuweisungs-Axiom Sequenz-Regel (Kompositionsregel) Konsequenz-Regel (Verstärkung und Abschwächung) If-Else-Regel (Verzweigungsregel) While-Regel (Schleifenregel) Methodenaufrufregel Anwendung und Einschränkungen Anwendung Zerlegung eines Programms {Q}P {R} in Sequenz von Programmfragmente {Q i }P i {R i } dekomponiert werden Theoretische Einschränkungen Achtung: Das Hoare-Tripel sagt nichts über P /R aus, wenn Q nicht gilt! Praktische Einschränkungen Verifikation (mit Hoare-Kalkül) gelingt i.d.r. nur für kleine Programme Praktischer Einsatz beschränkt sich daher auf (sicherheits)kritische Teile komplexer Programmsysteme, von denen das Funktionieren des restlichen System essentiell abhängt. (Trusted Computing Base) WS 2016/17 M. Werner 10 / 41 osg.informatik.tu-chemnitz.de Schreibweise Allgemeines Format von Regeln Voraussetzung Aussage Aus der Voraussetzung folgt die Aussage (Schlussfolgerung) Eine Aussage, die immer gilt (ohne Voraussetzung) heißt Axiom Aussage WS 2016/17 M. Werner 11 / 41 osg.informatik.tu-chemnitz.de WS 2016/17 M. Werner 12 / 41 osg.informatik.tu-chemnitz.de

Zuweisungsaxiom {R(x e)} x = e; {R} {R(x e)}: Die Vorbedingung entsteht dadurch, dass man die Nachbedingung hernimmt und jedes Vorkommen der Variablen x durch den Ausdruck e ersetzt Dadurch erhält man zu einer Nachbedingung die passende Vorbedingung Kompositionsregel (Sequenzregel) {Q} P 1 {R} {R} P 2 {S} {Q} P 1; P 2 {S} Diese Regel wird benötigt, um aus den Aussagen zu einzelnen Programmteilen Aussagen über zusammengesetzte Programmteile zu gewinnen Q Beispiel: // { x+1 = a} x= x+1; // { x = a } Wenn nach der Zuweisung x = a gilt, dann muss vor der Zuweisung x + 1 = a bzw. x = a 1 gegolten haben P1 R R P2 S Q P1 P2 S WS 2016/17 M. Werner 13 / 41 osg.informatik.tu-chemnitz.de Beispiel: Kompositionsregel WS 2016/17 M. Werner 14 / 41 osg.informatik.tu-chemnitz.de Beispiel: Swap Beweis eines Programmteils, das die Werte zweier Variablen vertauscht // { x+1 = a } x= x+1; // { x = a } // { x = a } x= 2* x; // { x = 2*a } {Q} P 1 {R} {R} P 2 {S} {Q} P 1; P 2 {S} backgroundcolor // { x+1 = a } x= x+1; x= 2* x; // { x = 2*a } 1 // PRE: { y=a x=b } 2 // { y=a x=b } 3 int z=x; 4 // { y=a z=b } 5 // { y=a z=b } 6 x=y; 7 // { x=a z=b } 8 // { x=a z=b } 9 y=z; 10 // POST : { x=a y=b } Das Beweisen geht nicht immer so einfach Identität Zuweisungsregel Identität Zuweisungsregel Identität Zuweisungsregel Komposition Komposition Vor- und Nachbedingungen müssen oft angepasst werden Verzweigungen und Schleifen treten auf WS 2016/17 M. Werner 15 / 41 osg.informatik.tu-chemnitz.de WS 2016/17 M. Werner 16 / 41 osg.informatik.tu-chemnitz.de

Anpassung von Vor- und Nachbedingungen Konsequenzregel Bei der Anwendung der Kompositionsregel stellt man häufig fest, dass die Nachbedingung R von P 1 nicht mit der Vorbedingung R von P 2 übereinstimmt Kann man jedoch R aus R ableiten (R R ), dann ist die Schlussfolgerungskette wieder geschlossen Q Q, {Q } P {R }, R R {Q} P {R} Q P1 R R' Q P1 P2 S Die Konsequenzregel gibt es, um die Übergänge zu beweisen, d.h. um Vor- und Nachbedingungen anzupassen Folgerungen verschiedener Art sein: syntaktisch logisch arithmetisch P2 S WS 2016/17 M. Werner 17 / 41 osg.informatik.tu-chemnitz.de Beispiel für Konsequenzregel Q Q, {Q } P {R }, R R {Q} P {R} WS 2016/17 M. Werner 18 / 41 osg.informatik.tu-chemnitz.de Verzweigungsregel (If-Else-Regel) {B Q} P 1 {R} { B Q} P 2 {R} {Q} if (B) P 1 else P 2; {R} Beide Alternativen müssen die gleiche Nachbedingung haben 1 // { true } 2 // { a=a } 3 // { a*a=a*a } logische Folgerung arithmetische Folgerung 4 x=a* a // Zuweisungsregel 5 // { x=a*a } 6 // { x 0 } arithmetische Folgerung 1 // { true } 2 if (a<0) 3 // { a<0 true } 4 // { -a = a } 5 abs = -a; 6 // { abs = a } 7 else 8 // { a 0 true } 9 // { a = a } 10 abs = a; 11 // { abs = a } 12 // { abs = a } WS 2016/17 M. Werner 19 / 41 osg.informatik.tu-chemnitz.de WS 2016/17 M. Werner 20 / 41 osg.informatik.tu-chemnitz.de

Verifikation von Schleifen Betrachten Beispiel: Berechne x = n 1 i i=0 // { true } // { 0=0 1=1 } int x= 0; int k= 1; // {Q: x=0 k=1 } while (k!=n) { x= x+k; k= k+1; } // {R: x= 1+2+..+(n -1) } Wie kommt man von Vorbedingung Q zur Nachbedingung R? Muss man jeden einzelnen Schleifendurchlauf beweisen? Oder reicht es, den Schleifenrumpf einmal zu beweisen? WS 2016/17 M. Werner 21 / 41 osg.informatik.tu-chemnitz.de Schleifenregel Verifikation von Schleifen (Forts.) Um die Schleife in eine einfache Anweisungssequenz zu zerlegen, könnten wir sie ausrollen : // { 0=0 } int x= 0; // { x=0 } { x +1=0+1 } x= x+1; // { x =0+1} { x +2=0+1+2 } x= x+2; // { x =0+1+2} { x +3=0+1+2+3 }...... //{ x+(n -1)=0+1+2+3+...+( n -1) } x= x+(n -1); // { x =0+1+2+...+( n -1)} Idee: einzelne Zusicherungen für jeden Durchlauf zu einem Ausdruck zusammenfassen Ausdruck gilt bei jedem Schleifendurchlauf Invariante WS 2016/17 M. Werner 22 / 41 osg.informatik.tu-chemnitz.de Schleife Die allgemeine Einsatz der Schleife: {Q} while (B) P ; {R} {I B} P {I} {I} while(b) P ; {I B} Regel nutzt While-Schleife für den Korrektheitsbeweis For-Schleifen können in äquivalente while-schleifen umgeformt werden Keine Beachtung von Break- und Continue-Anweisungen Q I while(b) { I Die Schleife hat also Vor- und Nachbedingungen, die zu der Invarianten passen müssen Wesentlich: Konstruktion der Invarianten I, die vor, während und nach der Schleife gelten muss Aussage der Schleifenregel: Wenn vor jeder Schleifeniteration die Invariante I und die Schleifenbedingung B und nach jeder Iteration die Invariante gilt, so ist die Schleife korrekt und nach Beendigung der Schleife gilt die Schleifenbedingung nicht mehr } P I I B R Anmerkung Wir betrachten hier nur While-Schleifen. Andere Schleifen (repeat...until, for) lassen sich abbilden. WS 2016/17 M. Werner 23 / 41 osg.informatik.tu-chemnitz.de WS 2016/17 M. Werner 24 / 41 osg.informatik.tu-chemnitz.de

Vorgehen Schleife: Beispiel Folgende Schritte werden durchgeführt: 1. Finde eine geeignete Schleifeninvariante I 2. Weise nach, dass die Schleifeninvariante aus der Vorbedingung Q der Schleifenanweisung folgt: Q I 3. Beweise die Invarianz der Invariante: {I B}P {I} 4. Zeige, dass die Invariante stark genug ist, die Nachbedingung zu erzwingen I B R Gegeben sei folgendes Java-Programmstück 2 1 // Calculates the square of a 2 // nonnegative integer number a 3 // {Q: 0 a} 4 y= 0; 5 x= 0; 6 while (y!= a) { 9 } 10 // {R: x = a 2 } 2 Beispiel ist aus OHLBACH und EISINGER WS 2016/17 M. Werner 25 / 41 osg.informatik.tu-chemnitz.de Schritt 1: Invariante 1 // Calculates the square of a 2 // nonnegative integer number a 3 // {Q: 0 a} 4 y= 0; 5 x= 0; 6 while (y!= a) { I I 9 } 10 // {R: x = a 2 } I I Die Invariante I muss gelten: = vor der Schleife = vor jedem Schleifenrumpf = nach jedem Schleifenrumpf = nach der Schleife Identifikation der Invariante Durch Analyse der Schleife: y wird schrittweise erhöht und die Schleife abgebrochen wird, wenn y den Wert a erreicht Außerdem bekannt: bei jedem Durchlauf gilt (nach Zeile 7) x = (y + 1) 2 und somit nach Zeile 8: x = y 2 Wählen daher als Schleifeninvariante: y a x = y 2 WS 2016/17 M. Werner 27 / 41 osg.informatik.tu-chemnitz.de WS 2016/17 M. Werner 26 / 41 osg.informatik.tu-chemnitz.de Schritt 2: Folgerung aus Vorbedingung 1 // Calculates the square of a 2 // nonnegative integer number a 3 // {Q: 0 a} 4 y= 0; 5 x= 0; 6 while (y!= a) { 9 } 10 // {R: x = a 2 } Aufgrund der Vorbedingung des Programmstücks {0 a} und der beiden Zuweisungen (Zeile 4 und 5) findet man als Vorbedingung vor Zeile 6: (0 a) (y = 0) (x = 0) Daraus lässt sich offensichtlich die Schleifeninvariante ableiten: (0 a) (y = 0) (x = 0) (y a) (x = y 2 ) WS 2016/17 M. Werner 28 / 41 osg.informatik.tu-chemnitz.de

Schritt 3: Invarianz gilt Zu zeigen: {I B} P {I} also: // {I B: y a x=y 2 y a} // {I: y a x=y 2 } Dies kann durch zweimalige Anwendung der Zuweisungsregel gezeigt werden: // {I B: y a x=y 2 y a} // {Q5: y+1 a x+2*y+1 = (y+1) 2 } // {Q6: y+1 a x=(y+1) 2 } Schritt 3: Invarianz gilt (Forts.) Jetzt kann gezeigt werden, dass die Gültigkeit Invariante nach dem Schleifenkörper aus ihrer Gültigkeit vor dem Schleifenkörper folgt // {I B: y a x=y 2 y a} // {Q5: y+1 a x+2*y+1 = (y+1) 2 } // {Q6: y+1 a x=(y+1) 2 } // {I: y a x=y 2 } Noch zu zeigen: 1. Aus y a und y a folgt y < a und damit y + 1 a 2. Aus x = y 2 folgt x 2 + 2y + 1 = y 2 + 2y + 1 = (y + 1) 2 // {I: y a x=y 2 } WS 2016/17 M. Werner 29 / 41 osg.informatik.tu-chemnitz.de Schritte 4: Nachbedingung Zu zeigen: Die Invariante (y a) (x = y 2 ) und die Negation der Schleifenbedingung (y a) erzwingen die Nachbedingung D.h., aus (y a) (x = y 2 ) (y a) folgt (x = y 2 ) (y = a) und folglich x = a 2 WS 2016/17 M. Werner 30 / 41 osg.informatik.tu-chemnitz.de Gesamter Beweis // {Q : 0 a} Vorbedingung // {0 a 0 = 0 0 = 0} logische Folgerung 4 y = 0; // {0 a y = 0 0 = 0} Zuweisungsregel 5 x = 0; // {0 a y = 0 x = 0} Zuweisungsregel // {I : y a x = y 2 } arithmetische Folgerung 6 while (y!=a) { // {y a x = y 2 y a} Schleifenregel // {y < a x = y 2 } logische Folgerung // {(y + 1) a x + 2y + 1 = (y + 1) 2 } arithmetische Folgerung // {(y + 1) a x = (y + 1) 2 } Zuweisungsregel // {I : y a x = y 2 } Zuweisungsregel 9 } // {y a x = y 2 (y a)} Schleifenregel // {R : x = a 2 } logische Folgerung WS 2016/17 M. Werner 31 / 41 osg.informatik.tu-chemnitz.de WS 2016/17 M. Werner 32 / 41 osg.informatik.tu-chemnitz.de

Unterprogramme Unterprogramme sind beweistechnisch schwierig Betrachten einfachen Fall: Methode mit einem Wert- und einem Referenzparameter (genauer: call by value return) backgroundcolor, void p(int i, Object o){ // {Q} P // {R} } {Q} P {R} {Q[i e, o r]} p(e, r); {R[o r]} Interpretation: beim Aufruf werden die formalen Parameter i und o durch die aktuellen Parameter e und r ersetzt Diese Substitution überträgt sich dann auf die Zusicherungen Terminierung Bisher: partielle Korrektheit wird bewiesen Für totale Korrektheit muss noch Terminierung bewiesen werden Kritisch bei Rekursion Die Rekursion muss nach einer endlichen Anzahl abbrechen, d.h. die Rekursionsbasis erreichen Schleifen Die Schleifenbedingung muss nach einer endlichen Anzahl von Iterationen false werden Es muss sichergestellt sein, dass auch der Schleifenrumpf terminiert (in jeder Iteration) Bei Objekten (Referen!z) kann der Wert des aktuellen Parameters durch die Methode verändert werden WS 2016/17 M. Werner 33 / 41 osg.informatik.tu-chemnitz.de Terminierungsfunktion WS 2016/17 M. Werner 34 / 41 osg.informatik.tu-chemnitz.de Terminierungsregel Zum Beweis der Terminerung einer Schleife muss eine Terminierungsfunktion τ angeben werden: τ : V N V ist eine Teilmenge der Ausdrücke über die Variablenwerte der Schleife Die Terminierungsfunktion muss folgende Eigenschaften besitzen: Ihre Werte sind natürliche Zahlen (einschließlich 0) Jede Ausführung des Schleifenrumpfs verringert ihren Wert (streng monoton fallend) Die Schleifenbedingung ist false, wenn τ = 0 τ ist obere Schranke für die noch ausstehende Anzahl von Schleifendurchläufen {τ = k}p {τ < k} {τ = 0} B P terminiert while(b) P ; {Terminierung} Es ist also zu zeigen: 1. Streng monotones Fallen von τ 2. Die Implikation der Nichterfüllung der Schleifenbedingung B bei niedrigsten τ 3. Die Terminierung des Rumpfs P Sind diese drei Eigenschaften gezeigt, so terminiert die Schleife WS 2016/17 M. Werner 35 / 41 osg.informatik.tu-chemnitz.de WS 2016/17 M. Werner 36 / 41 osg.informatik.tu-chemnitz.de

Beispiel: Quadratzahl Terminierung bei Rekursion 1 // {Q: 0 a} 2 y= 0; 3 x= 0; 4 while (y!= a) { 5 x= x+2*y+1; 6 y= y+1; 7 } 8 // {R: x = a 2 } Wähle als Terminierungsfunktion τ = a y: 1. τ wird in jedem Durchgang dekrementiert, da y inkrementiert wird und a konstant bleibt. 2. Wenn τ = 0 folgt y = a, d.h. die Schleifenbedingung y a ist falsch 3. Schleifenrumph enthält keine Schleifen/Rekursionen/Gotos... Terminierung trivial Wie bei Schleifen wird eine Terminierungsfunktion τ konstruiert, die mit zunehmender Rekursionstiefe kleiner wird Es muss gelten: 1. Die Werte von sind natürliche Zahlen (inkl. 0) 2. Bei jedem Aufruf der Methode wird der Wert von echt kleiner 3. Abbruch bei (spätestens) τ = 0 erzwungen Beispiel: Fibonacci-Zahlen 1 public static int fib(int n){ 2 if (n<3) return 1; 3 else return (fib(n-1)+fib(n-2)); 4 } In diesem Fall können wir als Terminierungsfunktion τ = n wählen WS 2016/17 M. Werner 37 / 41 osg.informatik.tu-chemnitz.de Probleme bei Terminierung Betrachten folgendes Beispiel: 1 // { x = 4 } 2 while ( x == Summe zweier Primzahlen) x+= 2; 3 // { x > 4 } Terminiert dieses Programm? Goldbachsche Vermutung: Bis heute 1 nicht allgemein bewiesen, aber bis 10 18 geprüft Beweise für Terminierung sind nicht immer möglich! Diese Aussage ist wiederum bewiesen ( Halteproblem) WS 2016/17 M. Werner 38 / 41 osg.informatik.tu-chemnitz.de 9.3 Diskussion 9.3 Diskussion Beweise sind mindestens so kompliziert wie die Programme selbst, so dass auch ein Beweis Fehler enthalten kann Durch Einsatz von Werkzeugen kann die Qualität der Verifikation erheblich gesteigert und der Aufwand erheblich reduziert werden Andere Kalküle lassen sich z.t. besser formalisieren (z.b. λ-kalkül funktionale Programmierung) Einige Eigenschaften, die zur fehlerhaften Diensterfüllung führen können, lassen sich mit dem Hoare-Kalkül nicht beweisen: Nebenläufigkeit Ressourcenverbrauch Zeitverhalten 1 Dezember 2014 WS 2016/17 M. Werner 39 / 41 osg.informatik.tu-chemnitz.de WS 2016/17 M. Werner 40 / 41 osg.informatik.tu-chemnitz.de

9.3 Diskussion Werkzeuge Fortschritte in letzten Jahren Aber: Keine vollautomatischen Beweiser maschinelle Unterstützung beim Beweis Bekanntestes Tool: Isabelle/HOL Sehr(!) komplex Meta-Tool, Sprache/Logik muss beigebracht werden Betrachten Dafny Microsoft Research, http://rise4fun.com/dafny Eigene Sprache, nahe an C#/Pascal Erweitert um Spezifikationskonstrukte Beispiel: Terminierung function fib (n: int): int decreases n; { if n<2 then n else fib(n-2) + fib(n-1) } > Dafny program verifier finished with 1 verified, 0 errors WS 2016/17 M. Werner 41 / 41 osg.informatik.tu-chemnitz.de