Verifikation Verifikation There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult. • Ziele C.A.R. Hoare • Hoare-Kalkül Software wird zur Benutzung freigegeben, nicht wenn sie nachweislich korrekt ist, sondern wenn die Häufigkeit, mit der neue Fehler entdeckt werden, auf ein für die Geschäftsleitung akzeptables Niveau gesunken ist. • Invarianten • Terminierung David L. Parnas c LETTMANN 2003/04 Modellierung — Verifikation V-1 c LETTMANN 2003/04 Aufgaben bei der Programmierung Modellierung — Verifikation V-2 Algorithmus und Programm • Spezifikation Was soll das Programm eigentlich leisten? Was soll gemacht werden? nach Duden - Informatik: • Implementierung Wie soll etwas gemacht werden? Unter einem Algorithmus versteht man eine Verarbeitungsvorschrift, die so präzise formuliert ist, dass sie von einem mechanisch oder elektronisch arbeitenden Gerät durchgeführt werden kann. Aus der Präzision der sprachlichen Darstellung des Algorithmus muss die Abfolge der einzelnen Verarbeitungsschritte eindeutig hervorgehen. . . . Algorithmus: • Korrektheit Berechnet das Programm auch das, was es soll? Arten von Fehlern ∗ syntaktische Fehler ∗ semantische Fehler Programm Terminierung Formulierung eines Algorithmus und der zugehörigen Datenbereiche in einer Programmiersprache. Wird das Programm auch mal fertig? Testen Während Algorithmen relativ allgemein beschrieben werden können und an keine formellen Vorschriften gebunden sind, müssen Programme wesentlich konkreter sein: Überprüfung der Korrektheit einer Implementierung für endlich viele Eingaben Verifikation Nachweis, dass eine Implementierung fehlerfrei macht, was eine Spezifikation vorschreibt. • Komplexität Wie gut ist das Programm eigentlich? • Sie sind im exakt definierten und eindeutigen Formalismus einer Programmiersprache verfasst. • Sie nehmen Bezug auf eine bestimmte Darstellung der verwendeten Daten. • Sie sind auf einer Rechenanlage ausführbar. Zeit, Platz, Struktur Ein und derselbe Algorithmus kann in verschiedenen Programmiersprachen formuliert werden; er bildet eine Abstraktion aller Programme, die ihn beschreiben. c LETTMANN 2003/04 Modellierung — Verifikation V-3 c LETTMANN 2003/04 Modellierung — Verifikation V-4 Arten von Programmen Semantik formaler Sprachen • imperativ (prozedural) z.B. Pascal • Übersetzersemantik x:= 1; Bedeutung wird durch Übersetzer (Compiler) bestimmt. • funktional z.B. Lisp • Operationale Semantik (defun fibonacci (schrittzahl) (cond ((= schrittzahl 0) 1) ((= schrittzahl 1) 1) ((> schrittzahl 1) (+ (fibonacci (- schrittzahl 1)) (fibonacci (- schrittzahl 2)))) ) ) Bedeutung wird durch Abläufe in einer abstrakten Maschine (einem Automaten) bestimmt. • Denotationelle Semantik Bedeutung wird durch eine Funktion f : E → A definiert, die die Eingangszustände E auf die Ausgangszustände A abbildet. • Axiomatische Semantik Bedeutung wird durch Axiome in Form von Voraussetzungen und Ergebniszusicherungen bestimmt. • deklarativ z.B. Prolog member(X,[X|T]). member(X,[H|T]) :- member(X,T). • objektorientiert z.B. Java class Xyz extends Uvw implements Abc { ... } Verifikation angepasst an Programmierparadigma Wir betrachten hier nur ein Beispiel für eine einfache imperative Programmiersprache. c LETTMANN 2003/04 Modellierung — Verifikation V-5 c LETTMANN 2003/04 Zusicherungen Modellierung — Verifikation V-6 Spezifikation Die Spezifikation eines Programms P besteht aus • Zusicherungen sind (mathematische) Formeln, die Aussagen über die (Werte der) Variablen in einem Programm darstellen. • Zusicherungen enthalten Programmvariablen als freie Identifikatoren. 1. einer prädikatenlogischen Formel ϕ in den Eingabevariablen des Programms, die Vorbedingung (precondition) von P genannt wird, • Zusicherungen sind gültig, falls sie in jedem an der entsprechenden Stelle möglicherweise auftretenden Zustand erfüllt sind (Floyd/Hoare). 2. einer prädikatenlogischen Formel ψ in den Ausgabevariablen des Programms, die Nachbedingung (postcondition) von P genannt wird. Man kann Zusicherungen als (formale) Kommentare in Programmen ansehen. ϕ und ψ sind Zusicherungen für das Programm P . ϕ beschreibt die erlaubten Eingaben des Programms; ψ beschreibt, welches Ergebnis für diese Eingaben berechnet werden soll. Während die Gültigkeit von ϕ als gegeben angenommen wird, wollen wir uns von der Gültigkeit von ψ überzeugen. Beispiel: Spezifikation eines Programmes zur Fakultätsberechnung Vorbedingung: { n ∈ Z n ≥ 0 } Nachbedingung: { y = n! } Anstelle von ϕ verwendet man auch die Bezeichnung {V } und anstelle von ψ verwendet man {N }, um anzudeuten, dass es sich um Mengen von Aussagen handelt, die insgesamt den Zustand beschreiben. c LETTMANN 2003/04 Modellierung — Verifikation V-7 c LETTMANN 2003/04 Modellierung — Verifikation V-8 Verifikation auf Basis axiomatischer Semantik Eine einfache imperative Programmiersprache (1) Variable und Ausdrücke Zwei Teilbeweise sind für den Nachweis der (totalen) Korrektheit eines Programms P nötig: • Integer-Variable Variable zur Aufnahme von Ganzzahl-Werten (i) Partielle Korrektheit • Integer-Expressions Wenn das Programm P terminiert, so transformiert P jeden Zustand, in dem V gilt, in einen Zustand, in dem N gilt. Arithmetische Ausdrücke mit Ganzzahl-Ergebnissen bestehend aus Zahl-Konstanten, Integer-Variablen und einfachen arithmetischen Operationen (+, −, ∗, /, ...) Schreibweise: {V }P {N } (ii) Terminierung • Boolean-Expressions Das Programm P terminiert. Boolesche Ausdrücke aus arithmetische Ausdrücken mit Vergleichsoperatoren (<, >, =, ≤, ...) und den Booleschen Konnektoren (, , ). Axiomatische Semantik: Die Semantik wird durch ein Axiom {V }S{N } für jede ausführbare Anweisung S der verwendeten Programmiersprache definiert. (Hoare, 1969) c LETTMANN 2003/04 Modellierung — Verifikation V-9 c LETTMANN 2003/04 Modellierung — Verifikation Eine einfache imperative Programmiersprache (2) Anweisungen (Statements) V-10 Ein Programmbeispiel Spezifikation: Vorbedingung: {x, y ∈ N} Nachbedingung: {b = x + y} • Zuweisung Variable := Integer-Expression ; • Bedingte Anweisung Programm P : einseitig if Boolean-Expression then Anweisung begin zweiseitig a := x; if Boolean-Expression then Anweisung else Anweisung b := y; while a > 0 do begin • Schleife a := a − 1; while Boolean-Expression do Anweisung b := b + 1; • Anweisung end Zuweisung Bedingte Anweisung Schleife begin Anweisungsliste end end Vereinbarungen • Anweisungsliste • Die Eingabewerte für das Programm werden in speziellen Variablen übergeben. Diese Varibalen verändern wir nicht im Programm. Anweisung Anweisungsliste Anweisung Ein Programm besteht aus einer Anweisung (meist in Form eines durch begin und end gebildeten Block von Anweisungen). c LETTMANN 2003/04 Modellierung — Verifikation V-11 • Das Ergebnis der Programmes wird in einer der Variablen gespeichert. c LETTMANN 2003/04 Modellierung — Verifikation V-12 Imperative Programmierung Verifikation auf Basis von Zusicherungen Die Spezifikation eines Programmes beschreibt • Zustandsorientierte Programmierung • in der Vorbedingung eine Abstraktion des (für das Programm relevanten Teil des) Zustands vor der Programmausführung und • Zustand = aktuelle Belegung aller Variablen (auf abstraktem Niveau: kein Systemstack, etc.) an einer Stelle im Programm • Ausführung von Instruktionen verändert Variablenbelegungen. • Aus der Beschreibung des Zustands vor einer Instruktion läßt sich der Zustand nach der Instruktion ableiten. • Jede Anweisung kann einzeln betrachtet werden. • Zusicherungen basieren auf Zuständen. • Zusicherungen abstrahieren so weit, dass alle Zustände erfasst sind, die an einer Stelle möglich sind. Analog zur Spezifikation des gesamten Programmes bezeichnen wir als • in der Nachbedingung eine Abstraktion des (für den Programmbenutzer relevanten Teil des) Zustands nach der Programmausführung. Durch die Verifikation eines Programmes mit einer vorgegebenen Spezifikation werden die Zusicherungen vor und nach jeder Anweisung des Programmes untersucht. • Wie verändert eine Anweisung den Zustand und damit die Zusicherung? Für jede Anweisung gibt es eine eigene Verifikationsregel. • Welcher Nachfolgezustand ergibt sich aus einem Zustand? Wie sah der Vorgängerzustand einer Zustands aus? • Vorbedingung einer Anweisung Jede Anweisung wird einzeln verifiziert. eine Zusicherung vor der Ausführung der Anweisung und als • Der Nachfolgezustand der einen Anweisung ist der Vorgängerzustand der nächsten Anweisung und damit die Nachbedingung der einen die Vorbedingung der nächsten Anweisung. • Nachbedingung einer Anweisung eine Zusicherung für den aus der Vorbedingung durch Ausführung der Anweisung resultierenden Zustand. Anweisungsblöcke werden durch zusammenpassende Einzelschritte verifiziert. Die Verifikation eines Programmes ist die Erstellung eines Beweises der Korrektheit eines Programmes unter Verwendung von akzeptierten Regeln, die für die verwendete Programmiersprache erstellt wurden. c LETTMANN 2003/04 Modellierung — Verifikation V-13 c LETTMANN 2003/04 Modellierung — Verifikation Hoare-Formeln Hoare-Regel für eine Anweisung {V }S{N } Voraussetzung 1 ... Voraussetzung n Schlussfolgerung Eine Hoare-Formel besteht aus Zusicherungen V und N und einer Anweisung S und steht für die folgende Aussage: Für jeden (Ausgangs-)Zustand, für den vor Ausführung der Anweisung S die Zusicherung V gilt, gilt bei Terminierung der Ausführung von S für den Folgezustand die Zusicherung N . V-14 Voraussetzungen sind (meistens) Hoare-Formeln der Form Vorbedingung Anweisung Nachbedingung V heißt auch Vorbedingung, N Nachbedingung der Anweisung S. und die Schlussfolgerung hat ebenfalls die Form Vorbedingung Anweisung Nachbedingung Die Anweisung S kann ein komplexes Programmstück sein! Anwendung der Hoare-Regel Wenn die Voraussetzungen der Hoare-Regel erfüllt sind (i.e. die entsprechenden Hoare-Formeln bereits hergeleitet sind), dann kann für eine Anweisung wie in der Schlussfolgerung der Regel von einer vorhandenen Vorbedingung wie in der Regel auf eine Nachbedingung wie in der Regel geschlossen werden, also die Hoare-Formel der Schlussfolgerung hergeleitet werden, falls die Anweisung terminiert. Die Anweisung in der Schlussfolgerung ist aus den Anweisungen in den Voraussetzungen zusammengesetzt. c LETTMANN 2003/04 Modellierung — Verifikation V-15 c LETTMANN 2003/04 Modellierung — Verifikation V-16 Hoare-Kalkül Verifikation im Hoare-Kalkül System von Regeln für (einfache) imperative Sprachen, das die Ableitung von Nachbedingungen von Programmen bei gegebenen Vorbedingungen erlaubt. • Regeln, die von der Programmiersprache abhängig sind: Eine Verifikation eines Programmes P ist eine Folge von Hoare-Formeln, deren letzte die Form {V }P {N } hat, wobei V die Vorbedingung des Programmes ist und N die Nachbedingung. Jede Hoare-Formel der Liste ergibt sich durch Anwendung einer Hoare-Regel, für die sämliche Hoare-Formeln in der Voraussetzung bereits vorher in der Liste enthalten sind. z.B. Regeln für Zuweisung Diese Regeln legen die Semantik der Programmiersprache fest. Falls das Programm P terminiert, folgt die Korrektheit des Programmes. Die Terminierung ist Vorasusetzung in jeder Hoare-Formel. • Regeln, die von der Programmiersprache unabhängig sind: z.B. Abschwächungsregeln Durch die Schachtelungsmöglichkeit der Anweisungen (Schleifen, bedingte Anweisungen) ist die Liste der Hoare-Formeln eine Darstellung einer baumartigen Verknüpfung von Anwendungen von Hoare-Regeln. Aufgrund der engen Verflechtung mit den Anweisungen des Programmes kann man die Hoare-Formeln einer Verifikation in das Programm integrieren. c LETTMANN 2003/04 Modellierung — Verifikation V-17 c LETTMANN 2003/04 Modellierung — Verifikation Darstellung als Baum Ein Verifikationsbeispiel a:=x; A Spezifikation: Vorbedingung: {x, y ∈ N} Nachbedingung: {b = x + y} b:=y; A C1 {x, y ∈ N} begin {x, y ∈ N} → {x, y ∈ N x = x} a := x; {x, y ∈ N a = x} → {x, y ∈ N a = x y = y} b := y; {x, y ∈ N a = x b = y} → {x, y ∈ N a + b = x + y a ≥ 0} while a > 0 do begin {x, y ∈ N a + b = x + y a ≥ 0 a > 0} → {x, y ∈ N a − 1 + b + 1 = x + y a − 1 ≥ 0} a := a − 1; {x, y ∈ N a + b + 1 = x + y a ≥ 0} b := b + 1; {x, y ∈ N a + b = x + y a ≥ 0} end {x, y ∈ N a + b = x + y a ≥ 0 a ≤ 0} → {x, y ∈ N a + b = x + y a = 0} → {x, y ∈ N b = x + y} end {x, y ∈ N b = x + y} → {b = x + y} c LETTMANN 2003/04 Modellierung — Verifikation V-18 a:=a-1; A C1 C1 b:=b+1; A S S C2 L S B C2 {V} P {N} • Der Beweis, der hinter der Verifikation steht, bildet eine Baumstruktur. • Eine Verifikation eines Programmes wird sequentiell am Programm orientiert vorgenommen. von vorn nach hinten: Hoare-Kalkül von hinten nach vorn (weakest precondition): Dijkstra V-19 c LETTMANN 2003/04 Modellierung — Verifikation V-20 Hoare-Regel für die Zuweisung A: Abschwächungsregeln (1) − {N [x/e]} x := e; {N } {P } → {P } {P } S {Q} {P } S {Q} C1 : Beispiele: {x + 1 = a} x := x + 1; {x = a} ist eine Verifikation der Anweisung x := x + 1; mit der Spezifikation {V } = {x + 1 = a} und {N } = {x = a}. {x, y ∈ N a = x y = y} b := y; {x, y ∈ N a = x b = y} C2 : {P } S {Q } {Q } → {Q} {P } S {Q} P ist eine Abschwächung der Zusicherung P , d.h. P ist semantische Folgerung von P , P |= P . Q ist eine Abschwächung der Zusicherung Q , d.h. Q ist semantische Folgerung von Q , Q |= Q. Beispiel: {x, y ∈ N a = x} → {x, y ∈ N a = x y = y} b := y; {x, y ∈ N a = x b = y} → {x, y ∈ N a + b = x + y a ≥ 0} ist eine Verifikation der Anweisung b := y;. • Die Zuweisungsregel legt die Semantik der Zuweisung fest. ist eine Verifikation der Anweisung b := y;. • Die Zuweisungsregel ordnet jeder Nachbedingung eine schwächste Vorbedingung (weakest precondition (wp)) zu. • Die Zuweisungsregel führt die Semantik der Zuweisung auf die Semantik der Substitution in der Prädikatenlogik zurück. • Da die Zuweisungsregel keine Voraussetzungen hat, bezeichnet man sie auch als Axiom. c LETTMANN 2003/04 Modellierung — Verifikation V-21 Abschwächungsregeln (2) {P } → {P } {P } S {Q} {P } S {Q} C1 : C2 : c LETTMANN 2003/04 Modellierung — Verifikation V-22 Anwendung der Zuweisungsregel (1) A: {P } S {Q } {Q } → {Q} {P } S {Q} − {N [x/e]} x := e; {N } Von der Nachbedingung zur Vorbedingung (rückwärts): • Die Abschwächungsregeln verändern nur die Zusicherungen, z.B. • Nachbedingung N ist bekannt. • Ersetze alle Vorkommen von x in N durch e. • Ergebnis ist die schwächste Vorbedingung N [x/e]. Einzelne Teile der Zusicherung können weggelassen werden, wenn sie mit dem Rest konjunktiv verknüpft sind. {Q1 Q2 } → {Q1} Beispiele: Folgerungen aus der Zusicherung können explizit hinzugenommen werden. {Q1 (Q1 ⇒ Q2)} → {Q1 (Q1 ⇒ Q2) Q2} Tautologische Aussagen können hinzugenommen werden. {Q} → {Q x = x} Zusätzliche Anforderungen können disjunktiv zur Zusicherung hinzugenommen werden. {Q1} → {Q1 Q2} • Die Abschwächungsregeln setzen voraus, dass das entsprechende Programmstück bereits verifiziert wurde. c LETTMANN 2003/04 Modellierung — Verifikation V-23 { x := 27; {x, y ∈ N a = x b = y} } { y := x; {x, y ∈ N a = x b = y} } { x := x + 1; {x, y ∈ N a = x b = y} } { y := x + y; {x, y ∈ N a = x b = y} } c LETTMANN 2003/04 Modellierung — Verifikation V-24 Anwendung der Zuweisungsregel (2) A: Anwendung der Zuweisungsregel (3) − {N [x/e]} x := e; {N } A: Von der Vorbedingung zur Nachbedingung (vorwärts): − {N [x/e]} x := e; {N } Von der Vorbedingung zur Nachbedingung (vorwärts): Fall 1: x kommt in e nicht vor Fall 2: x kommt in e vor • Vorbedingung V ist bekannt • Vorbedingung V ist bekannt • Schwäche Vorbedingung V ab: • Schwäche Vorbedingung V ab: Eliminiere alle Vorkommen von x in V . (Erzeuge neue Vorkommen von e, z.B. e = e.) Wandle alle Vorkommen von x in V in Vorkommen von e um. Ergebnis ist (abgeschwächte) Vorbedingung V . Ergebnis ist (abgeschwächte) Vorbedingung V . • Ersetze in V MANCHE Vorkommen von e durch x. • Ersetze in V ALLE Vorkommen von e durch x. • Ergebnis ist die Nachbedingung V . • Ergebnis ist die Nachbedingung V . Beispiele: Beispiele: {x, y ∈ N a = x} →{ →{ x := 27; { } {x, y ∈ N a = x} →{ →{ y := x; { c LETTMANN 2003/04 {x, y ∈ N a = x} →{ x := x + 1; { } } } } } } } Modellierung — Verifikation {P } S1 {Q} {Q} S2 {R} {P } S1 S2 {R} } {x, y ∈ N a = x} →{ y := x + y; { V-25 c LETTMANN 2003/04 Hoare-Regeln für Anweisungslisten S: } B: Modellierung — Verifikation V-26 Verifikation eines Programmes • Gegeben ist eine Spezifikation mit Vorbedingung {V } und Nachbedingung {N } sowie ein Programm P . {P } S {Q} {P } begin S end {Q} • P bestehe nur aus einer Folge von Zuweisungen. Vorgehen im Hoare-Kalkül • Die Regeln legen fest, wie Listen von Anweisungen ausgeführt werden. • Die Strukturierung der Programme durch begin und end sorgt für eine eindeutige Aufteilung eines Programmes in Anweisungen. Aus Sicht der Verifikation wäre sie nicht erforderlich, da die Struktur des Programmes im Verifikationsbeweis festgelegt wäre. • Die Blockung von Anweisungen erfodert keinen zusätzlichen Verifikationsaufwand. 1. Ergänze {V } als Vorbedingung vor dem Programmtext. 2. Je nach Programmanweisung verfahre folgendermaßen: (a) begin Kopiere die Vorbedingung dieser Zeile als ihre Nachbedingung. (b) end Kopiere die Vorbedingung dieser Zeile als ihre Nachbedingung. (c) Zuweisung x := e; Wende Abschwächungsregeln und Zuweisungsregel auf die Vorbedingung so an, wie es die Zuweisung erfordert (Fall 1: x kommt in e nicht vor; Fall 2: x kommt in e vor). 3. Versuche durch Anwendung von Abschwächungsregeln auf die Nachbedingung der Anweisungen die Nachbedingung {N } der Spezifikation zu erreichen. c LETTMANN 2003/04 Modellierung — Verifikation V-27 c LETTMANN 2003/04 Modellierung — Verifikation V-28 Beispiel zur Verifikation eines Programmes Beispiel zur Struktur des Beweises zur Verifikation Spezifikation: Der Beweis wird folgendermaßen veranschaulicht: Vorbedingung: {x, y ∈ N} Nachbedingung: {b = x + y} (1) (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) • Die Liste der Hoare Formeln wird unteeinander in der Tabelle angegeben. { begin { →{ a := x; { →{ b := y; { →{ b := b + a; { end { →{ • Die Listenelemente sind durchnummeriert (a-z). } } } • Die Hoare-Formeln werden durch Referenz auf die Zeilennummern in dem durch Zusicherungen ergänzten Programm angegeben ((1) - (9999)). } } • Es wird die angewendete Regel angegeben und die Hoare-Formeln, die ihre Voraussetzung bilden. } } } } } • Beim Aufschreiben eines Programmes wird jede Anweisung in einer neuen Zeile begonnen. Nr. a. b. c. d. e. f. g. h. i. j. Hoare-Formel (4)(5)(6) (3)(5)(6) (7)(8)(9) (6)(8)(9) (4)(5)(8)(9) (10)(11)(12) (9)(11)(12) (4)(5)(8)(11)(12) (2)(3)(5)(8)(11)(13)(14) (2)(3)(5)(8)(11)(13)(15) Regel nach Zuweisungsregel A nach Abschwächungsregel C1 für a nach Zuweisungsregel A nach Abschwächungsregel C1 für c nach Sequenzenregel S für b,d nach Zuweisungsregel A nach Abschwächungsregel C1 für f nach Sequenzenregel S für e,g nach Sequenzenregel S für h nach Abschwächungsregel C2 für i Dieser Beweis zeigt nur die partielle Korrektheit, d.h. es muss zusätzlich gezeigt werden, dass das Programm terminiert. • Die Zeilen im Programm werden so eingerückt, dass die Schachtelung der Anweisungen erkennbar ist. • Die Zusischerungen werden in das Programm eingefügt. • Die Einrückung der Zusicherungen erfolgt so, dass sie auf gleicher Höhe mit den zugehörigen Anweisungen stehen. c LETTMANN 2003/04 Modellierung — Verifikation V-29 c LETTMANN 2003/04 Modellierung — Verifikation V-30