Modelchecking zur Qualitätssicherung von Komponentensystemen Autor: C Technische Universität Berlin Fakultät IV Institut für Informatik Softwaretechnik Seminar Komponenten und Verteiltheit Abstract. In der heutigen Zeit wird unser Leben viel von Computersystemen beeinflusst. Daher ist es wichtig, dass Softwaresysteme fehlerfrei ablaufen. Solche Fehler können große wirtschaftliche Folgen haben oder sogar Menschenleben gefährden. Es gibt viele Verifikationstechniken um die Korrektheit von Softwarekomponenten zu prüfen, zum Beispiel Testen, Simulation, Modelchecking und deduktive Methoden. In diesem Seminararbeit wird auf Modelchecking näher eingegangen. Modelchecking ist ein Verfahren für die automatische Verifikation von Softwaresystemen, welches die Korrektheit des Systems bezüglich der Spezifikation feststellt oder ein Gegenbeispiel liefert. Der Modelcheckingprozess besteht aus drei Phasen. Die Modellierungsphase, Spezifikationsphase und Verifikationsphase. In der Modellierungsphase wird vom Entwurf aus ein Transitionssystem erzeugt. Die Kripke-Struktur ist ein häufig eingesetztes Transitionssystem beim Modelchecking. In der Spezifikationsphase werden die Eigenschaften angegeben, die das System überprüfen soll. Diese Eigenschaften werden in einer geeigneten Art und Weise formuliert. Eine Möglichkeit der Spezifikation ist die temporale Logik. In der Verifikationsphase wird ein Algorithmus angewendet, welches mit dem entworfenen Modell und der erstellten Formel die Menge der Zustände berechnet, die die gegebene Formel erfüllen. Das Problem bei Modelchecking ist die Zustandsexplosion, denn mit Modellierung von komplexen Systemen kann die Anzahl der Zustände exponentiell wachsen. Um dieses Problem zu bekämpfen werden Techniken wie Abstraktion, Komprimierung und Reduktion eingesetzt. Key words: Model Checking, Temporale Logik, Kripke-Struktur, Komponenten, Verifikation 2 1 1.1 C: Modelchecking zur Qualitätssicherung von Komponentensystemen Einleitung Motivation In der heutigen Zeit wird unser Leben viel von Computersystemen beeinflusst: Im Verkehr, Gesundheit, Medien, etc. Daher ist es wichtig, dass Softwaresysteme fehlerfrei ablaufen. Solche Fehler können groe wirtschaftliche Folgen haben oder sogar Menschenleben gefährden. Es gibt viele Verifikationstechniken um die Korrektheit von Softwarekomponenten zu prüfen, zum Beispiel Testen, Simulation, Modelchecking und deduktive Methoden. In diesem Seminararbeit wird auf Modelchecking näher eingegangen. 1.2 Die verschiedenen Verifikationstechniken In Simulation und Testen werden Tests ausgeführt, bevor das System genutzt werden kann. Bei der Simulation wird mit ein Modell gearbeitet. Das Testen wird auf dem eigentlichen Produkt ausgeführt. In beiden Methoden werden Signale an gewissen Stellen des Systems eingegeben und die Resultate werden ausgewertet. Für sehr groe Systeme können diese Methoden sehr kostenaufwendig sein und diese Methoden schlieen die Existenz eines Fehlers nicht aus, weil nur für bestimmte Testflle die Anwesenheit der Fehler überprft werden. Das beweißt nicht die Abwesenheit eines Fehlers im System. In Deduktive Methoden werden eine Menge von Axiomen und Beweisregeln verwendet, um die Korrektheit eines Systems zu prüfen. Da dieses Verfahren sehr zeitaufwendig ist und nur von Experten ausgeführt werden kann, findet diese Anwendung nur in hoch sensitiven Systemen statt, zum Beispiel in Sicherheitsprotokollen. Der Vorteil an diese Verifikationstechnik ist, dass auch Systeme mit unbegrenzten Zustandsräumen behandeln werden können. In Methode des Model Checking werden nebenläufige Systeme mit endlichen Zustandsraum betrachtet. Die Einschränkung auf den endlichen Zustandsraum hat den Vorteil, dass die Verifikation vollautomatisch ausgeführt werden kann. Dieses Verifikationstechnik untersucht den Zustandsraum des Systems und entscheidet, ob die Zustände des Systems die Anforderung erfüllen. Wenn die Anforderung nicht erfüllt ist, liefert diese Methode ein Gegenbeispiel. Die vollautomatische Ausführung und das Liefern eines Gegenbeispiels sind die Vorteile des Model Checkings. Im nächsten Abschnitt wird Model Checking näher erläutert. 2 2.1 Model Checking Einleitung Modelchecking ist ein Verfahren für die vollautomatische Verifikation von Softwaresystemen, welches die Korrektheit des Systems bezüglich der Spezifikation feststellt oder ein Gegenbeispiel liefert. Der Modelcheckingprozess besteht aus drei Phasen. Die Modellierungsphase, Spezifikationsphase und Verifikationsphase. In der Modellierungsphase wird vom Entwurf aus ein Transitionssystem C: Modelchecking zur Qualitätssicherung von Komponentensystemen 3 erzeugt. Die Kripke-Struktur ist ein häufig eingesetztes Transitionssystem beim Modelchecking. In der Spezifikationsphase werden die Eigenschaften angegeben, die das System überprüfen soll. Diese Eigenschaften werden in einer geeigneten Art und Weise formuliert. Eine Möglichkeit der Spezifikation ist die temporale Logik. In der Verifikationsphase wird ein Algorithmus angewendet, welches mit dem entworfenen Modell und der erstellten Formel die Menge der Zustände berechnet, die die gegebene Formel erfüllen. Der Ablauf der drei Phasen wird in diesen Seminararbeit zum besseren Verständnis am Beispiel eines Mikrowellensystems durchgeführt. Definition: “Model checking is an automatic technique for verifying finite state concurrent systems.”(Clarke, Grumberg, Peled [1]) Definition: Model Checking ist eine vollautomatische Prüfung eines Modells M (eine Systembeschreibung, z.B. durch endliche Automaten) gegen eine Formel f (Spezifikation, z.B. durch temporale Logiken): s ∈S | M, s |= f, wobei S die Menge der Zustände in M beschreibt. 2.2 Modellierung Um das system zu modellieren wird ein Transitionssystem (Zustandsübergangsgraph) verwendet. Das für Model Checking oft verwendete Transitionssystem ist die Kripke-Struktur. Kripke-Struktur: Die Kripke-Struktur M=(S, S0 , R, L) ist ein gerichteter Graph und ein Vier-Tupel mit: - S : eine endliche Menge von Zuständen, - S0 ⊆ S : eine Menge von Anfangszuständen, - R ⊆ S × S : eine totale Übergangsrelation, - L: S → 2AP : eine Labelfunktion, die einen Zustand s auf AP abbilden, die in s ∈ S gelten. Dabei sei AP eine Menge von atomare logische Aussagen. In der Modellierungsphase wird das Komponentensystem in ein Transitionssystem überführt. Die Modellierung soll hier an einem Beispiel einer Mikrowelle gezeigt werden. Anhand einer verbalen Beschreibung kann aus dem Verhalten der Mikrowelle ein Transitionssystem angegeben werden. Das Transitionssystem kann auch aus den Quellcode der Komponente erstellet werden, was im Grunde auch nichts anderes ist, als die Beschreibung des Verhaltens. In der Mikrowelle können vier Operationen durchgefhrt werden. Das sind Starten der Mikrowelle (Start), Schließen der Tür (Close), Vorgang des Aufwärmens (Heat) 4 C: Modelchecking zur Qualitätssicherung von Komponentensystemen und Zurücksetzen der Mikrowelle (Error). Daraus ergeben sich vier atomare Ausdrücke AP = {Start, Close, Heat, Error}. Um den Umfang nicht zu sprengen, wird die detailliertere Beschreibung des Verhaltens der Mikrowelle gespart. Die Kripke-Struktur M=(S, S0 , R, L) für die Mikrowelle sei gegeben durch: • S = {s0 ,s1 ,s2 ,s3 ,s4 ,s5 ,s6 } • s0 sei der Startzustand • R = {(s0 ,s1 ),(s0 ,s2 ),(s2 ,s0 ),(s3 ,s0 ),(s1 ,s4 ),(s4 ,s1 ), (s4 ,s2 ),(s3 ,s2 ),(s3 ,s3 ),(s2 ,s5 ),(s5 ,s6 ),(s6 ,s3 )} •L= L(s0 ) = {Start, Close, Heat, Error} L(s1 ) = {Start, Close, Heat, Error} L(s2 ) = {Start, Close, Heat, Error} L(s3 ) = {Start, Close, Heat, Error} L(s4 ) = {Start, Close, Heat, Error} L(s5 ) = {Start, Close, Heat, Error} L(s6 ) = {Start, Close, Heat, Error} Die grafische Darstellung dieser Kripke-Struktur ist in der folgenden Abbildung zu sehen. C: Modelchecking zur Qualitätssicherung von Komponentensystemen 5 Fig. 1. Grafische Darstellung der Kripke-Struktur der Mikrowelle.(Clarke, Grumberg, Peled [1]) 2.3 Spezifikation Nach der Modellierungsphase werden die Eigenschaften definiert, die das System erfüllen soll. Diese Eigenschaften werden in einer Formel der Temporalen Logik formuliert. Die Temporale Logik ist eine Erweiterung der Aussagenlogik um Operatoren mit denen die zeitlichen Zusammenhänge dargestellt werden können. Es gibt viele verschiedende Arten von Temporalen Logiken, zum Beispiel LTL (Linear Time Logic), CTL (Computation Tree Logic) und CTL*. Dabei sind LTL und CTL spezielle Teilmengen von CTL*. Im folgenden wird CTL* näher vorgestellt. Syntax und Semantik von CTL* Die Syntax von CTL* ist wie folgt aufgebaut: α ::= p | q |... (atomare Ausdrücke) ¬ α | α ∨ β | α ∧ β |... (boolesche Operatoren) Xα | Fα | Gα | αUβ | ...(temporale Operatoren) Eα | Aα | (Pfadquantoren/modallogische Operatoren) 6 C: Modelchecking zur Qualitätssicherung von Komponentensystemen Fig. 2. Ausdrucksmächtigkeiten. Mit hilfe der temporalen Aussagen können Aussagen α über die Zeitspanne getroffen werden: • X(next time) bedeutet, dass eine Aussage α im nächsten Zustand erfüllt ist. • F(in the future) bedeutet, dass eine Aussage α irgendwann in einem Zustand erfüllt ist. • G(globally) bedeutet, dass eine Aussage α in jedem Zustand erfüllt ist. • U(until) bedeutet, dass eine Aussage α in jedem Zustand entlang eines Pfades erfüllt ist bis die Aussage β in einem Folgezustand auftritt. Die Pfadquantoren sagen folgendes aus: • E (exists) bedeutet, dass eine Aussage α entlang mindestens eines Pfades erfüllt sein muss. • A (always) bedeutet, dass eine Aussage α entlang aller Pfades erfüllt sein muss. Die nachfolgende Abbildung zeigt Beispiele der Kombinationen von Operatoren. EFP bedeutet , dass mindestens in einem Pfad (E : exists) irgendwann C: Modelchecking zur Qualitätssicherung von Komponentensystemen 7 (F: in future) in einem Zustand der Ausdruck P erfüllt ist. EGP bedeutet, dass mindestens in einem Pfad (E : exists) immer (G : globally) der Ausdruck P entlang eines Pfades erfüllt ist. AFP bedeutet, dass der Ausdruck P entlang aller Pfade (A : always) irgendwann (F: in future) in einem Zustand erfüllt ist. AGP bedeutet, dass der Ausdruck P entlang aller Pfade (A : always) in jedem (G : globally) Zustand erfüllt ist. Fig. 3. Kombinationsmöglichkeiten der Operatoren In CTL* gibt es zwei arten von Formeln. Die Zustandsformel und die Pfadformel. Zustandsformeln sind Formeln, die in einem Zustand erfüllt sind und Pfadformeln sind Formeln, die entlang eines Pfades erfüllt sind. Zustandsformeln: φ sei eine Menge von atomaren Aussagen. • Wenn p ∈ φ, dann ist p eine Zustandsformel. • Wenn f und g Zustandsformeln sind, dann sind es auch ¬f, f ∨ g und f ∧ g. • Wenn f eine Pfadformel ist, dann sind E f und A f Zustandsformeln. 8 C: Modelchecking zur Qualitätssicherung von Komponentensystemen Pfadformeln: • Wenn f eine Zustandsformel ist, dann ist f auch eine Pfadformel. • Wenn f und g Pfadformeln sind, dann sind es auch ¬f, f ∨ g, f ∧ g, Xf, Ff, Gf und f U g. Die Semantik von CTL* wird in Beziehung zu den Kripke-Strukturen beschrieben. M sei eine Kripke-Struktur mit M=(S,S0 ,R,L). Wenn f eine Zustandsformel ist, dann bedeutet M,s |= f, dass f im Zustand s die Kripke-Struktur M hält. Wenn f eine Pfadformel ist, dann bedeutet M,π |= f, dass f entlang des Pfades π die Kripke-Struktur M hält. Die Bedeutung von |= ist wie folgt definiert: Dabei gilt f1 und f2 sind Zustandsformeln und g1 und g2 sind Pfadformeln. π i bedeutet, dass der erste Zustand auf dem Pfad π der Zustand si ist. • M, s |= p ⇔ p ∈ L(s) • M, s |= ¬f1 ⇔ M, s 2 f1 • M, s |= f1 ∨ f2 ⇔ M, s |= f1 oder M, s |= f2 • M, s |= f1 ∧ f2 ⇔ M, s |= f1 und M, s |= f2 • M, s |= E g1 ⇔ es existiert ein Pfad π von s, so dass M, π |= g1 • M, s |= A g1 ⇔ für jeden Pfad π, startend bei s gilt M , π |= g1 • M, π |= f1 ⇔ s ist der erste Zustand von π und M, s |= f1 • M, π |= ¬g1 ⇔ M, π 2 g1 • M, π |= g1 ∨ g2 ⇔ M, π |= g1 oder M, π |= g2 • M, π |= f1 ∧ f2 ⇔ M, π |= g1 und M, π |= g2 • M, π |= X g1 ⇔ M, π 1 |= g1 • M, π |= F g1 ⇔ es existiert ein k ≥ 0, so dass M, π k |= g1 • M, π |= G g1 ⇔ für alle i ≥ 0 gilt M, π i |= g1 • M, π |= g1 U g2 ⇔ es existiert ein k ≥ 0, so dass M, π k |= g2 gilt und für alle 0 ≤ j ¡ k gilt M, π i |= g1 C: Modelchecking zur Qualitätssicherung von Komponentensystemen 9 Um Formeln in CTL* darzustellen reichen folgende fünf Operatoren aus: ¬, ∨, X, U, E. Die Umformungsregeln für die anderen Operatoren sind: • f ∧ g ≡ ¬(¬f ∨ ¬g) • f R g ≡ ¬(¬f U ¬g) • F f ≡ True U f • G f ≡ ¬F ¬f • A f ≡ ¬E ¬f Der Beweis dieser Äquivalenzen wird hier nicht durchgeführt. In Bezug auf das Mikrowellenbeispiel findet durch das Ausführen verschiedener Tätigkeiten ein Übergang in einen anderen Zustand statt. Auf Basis der in der Modellierungsphase aufgestellten Kripke-Struktur für die Mikrowelle können mit Hilfe der Temporalen Logik CTL* Aussagen formuliert werden, die das System erfüllen soll. Mögliche Anforderungen wären: • Immer nur dann, wenn die Tür geschlossen ist und auf Start gedrückt wird, kann das Essen erhitzt werden. ⇔ AG ((Close ∧ Start) → AF Heat) • Immer, wenn die Tür nicht geschlossen ist und auf Start gedrückt wird, dann kann das Essen nicht erhitzt werden oder die Mikrowelle wird zurückgesetzt. ⇔ AG ((¬Close ∧ Start)→ A(G ¬Heat ∨ F Error)) 2.4 Verifikation In der Verifikationsphase wird ein Algorithmus angewendet, welches mit dem entworfenen Modell M und der erstellten Formel f die Menge der Zustände S berechnet, die die gegebene Formel erfüllen. Das heit, es muss {s ∈ S | M, s |= f } gelten. Ablauf des Algorithmus: Jeder Zustand s für die, die Unterformeln von f wahr sind, wird markiert. Die Menge der Unterformeln werden durch label(s) dargestellt. Das ist das gleiche wie L(s). Die kürzeste, am tiefsten verschachtelte Unterformel wird zuerst bearbeitet und nach und nach werden die äußeren Unterformeln schrittweise bearbeitet. Hat der Algorithmus terminiert, dann ist das Resultat die Menge 10 C: Modelchecking zur Qualitätssicherung von Komponentensystemen aller Zustände S die die gegebene Formel f erfüllen ( M, s |= f ) genau dann, wenn gilt: f ∈ label(s). Da alle CTL Formeln durch Terme mit ¬, ∨, EX, EU und EG ausgedrückt werden können, genügt es sechs Fälle zu behandeln: • Fall 1: g ist atomar Alle Zustände, in denen g gilt werden markiert. • Fall 2: g = ¬f1 Für Formeln der Form ¬f1 werden die Zustände markiert, in denen f1 nicht gilt. • Fall 3: g = f1 ∨f2 Mit f1 ∨f2 werden alle Zustände markiert, in denen entweder f1 oder f2 gilt. • Fall 4: g = EXf1 Für EXf1 werden alle Zustände markiert, die einen Nachfolger haben, der mit f1 markiert ist. • Fall 5: g = E[ f1 U f2 ] Hier werden alle Zustände entlang eines Pfades markiert von den aus ein mit f2 markierter Zustand erreicht werden kann. Der Pfad darf auch leer sein. Die Vorgehenweise ist wie folgt: Zuerst werden alle Zustände, in denen f2 gilt, markiert. Dann wird die Umkehrung der Übergangsrelation angewendet, indem der Pfad rückwärts entlang überprüft wird. Alle vorangegangenen Zustände, in dem f1 gilt werden markiert. Das wird solange gemacht bis alle Zustände gefunden wurden, die durch einen Pfad, auf dem jeder Zustand mit f1 markiert ist, (von f2 aus) erreicht werden können. • Fall 6: g = EGf1 In dem Fall wird der Graph in nichttriviale, stark zusammenhängende Komponenten zerlegt. Strongly Connected Components (SCC) sind maximale Teilgraphen, in dem jeder Knoten in Teilgraph C von jedem anderen Konten aus C durch einen gerichteten, vollständig in C enthaltenen Pfad erreichbar ist. C ist nichttrivial, wenn es mehr als einen Knoten hat oder mindestens einen Knoten mit einer Schleife enthält. Die eingeschränkte Kripke Struktur M’ = (S’, R’,L’) hat folgende Bestandteile: • S’ = { s ∈ S | M, s |= f1 } • R’ = R|S 0 ×S 0 • L’ = L|S 0 C: Modelchecking zur Qualitätssicherung von Komponentensystemen 11 Es gilt M, s |= EGf1 , genau dann wenn folgende Bedingungen erfüllt sind: • s ∈ S’ • Es existiert ein Pfad in M’, der von einem Knoten s zu einem Knoten t führt, wobei t in einem nichttrivialen SCC des Graphen (S’, R’) liegt. Der Algorithmus für den Fall g = EGf1 folgt aus den obigen Bedingungen: Zuerst wird die eingeschränkte Kripke Struktur M’ konstruiert und der Graph wird in SCC partitioniert. Nachdem alle Knoten der SCC mit EGf1 markiert sind, werden die Zustände gesucht, die zu nichttrivialen Komponenten gehören. Dabei wird wieder mit der Umkehrungrelation von R gearbeitet. Der Graph wird rückwärts abgearbeitet und alle Zustände, von denen aus ein SCC entlang eines Pfades erreicht werden kann, markiert. Die Verifikationsphase wird hier auch noch mal durch das Mikrowellenbeispiel besser verdeutlicht: In der Kripke-Struktur der Mikrowelle ist jeder Zustand mit den atomaren Aussagen, die wahr in einem Zustand sind, und mit der Negation der Aussagen, die falsch in einem Zustand sind, markiert. Überprüft wird die CTL-Spezifikation AG(Start → AF Heat). Das heit, wenn Start gedrückt wird, soll der Ofen beginnen zu heizen. Das ist zu der Formel ¬EF(Start ∧ EG¬Heat) quivalent. (Hierbei ist EFf die Abkürzung fr E[true U f]). Auch hier wird auf den Beweis der Umformung verzichtet. Es ist zu überprüfen, ob das System, gegeben durch die Kripke-Struktur, die durch die CTL-Formel gestellten Spezifikationen erfüllt. Im weiteren Verlauf bezeichne S(g) die Menge der Zustände, die mit der Teilformel g markiert sind. • 1. Schritt: S(Start) = {2, 5, 6, 7} • 2. Schritt: S(¬Heat) = {1, 2, 3, 5, 6} Um S(EG ¬Heat) berechnen zu können, muss die Menge der nichttrivialen, stark zusammenhängenden Komponenten in S’ = S(Heat) gefunden werden. Das ist die Menge {1, 2, 3, 5}. Danach werden die mit f1 markierten Zustände gesucht, von denen aus entlang eines komplett mit f1 markierten Pfades die stark zusammenhängende Komponente erreicht werden können. Es ist zu sehen, dass keine Zustände existieren, die diese Bedingung erfüllen. Also bleibt die Menge S(EG ¬Heat) = {1, 2, 3, 5} • 3. Schritt: S(Start ∧ EG ¬Heat) = {2, 5} 12 C: Modelchecking zur Qualitätssicherung von Komponentensystemen • 4. Schritt: S(EF(Start ∧ EG ¬Heat)) = {1, 2, 3, 4, 5, 6, 7} • 5. Schritt: S(¬EF(Start ∧ EG ¬Heat)) = ∅ Da der Anfangszustand l in dieser Menge nicht enthalten ist, folgt daraus, dass das durch die Kripke-Struktur beschriebene System die geforderte Spezifikation nicht erfüllt. 3 Ausblick Das Problem bei Modelchecking ist die Zustandsexplosion, denn mit Modellierung von komplexen Systemen kann die Anzahl der Zustände exponentiell wachsen. Um dieses Problem zu bekämpfen werden folgende Techniken wie Abstraktion, Komprimierung und Reduktion eingesetzt. In der Methode Abstraktion werden alle äquivalenten Zustände zusammengefasst (Schrittweise Verfeinerung). In der Methode Reduktion werden irrelevante Zustände nicht erforscht. Hier werden zum Beispiel Halbordnungstechniken angewandt. Die Methode Komprimierung ist die symbolische Dargestellund der Zustandsmengen. Das wird symbolisches Model Checking genannt, das meistens auf Ordered Binary Decision Diagrams (OBDD) basiert. Diese Methode verbraucht wenig Speicherplatz, da anstatt die Zustände und Übergänge zu speichern, die Struktur mittels BDD symbolisch dargestellt wird. Die Komplexität ist daher auch geringer. Der SMV Model Checker wendet diese Methode an und ist ein in der Praxis oft eingesetzter Model Checker. C: Modelchecking zur Qualitätssicherung von Komponentensystemen 13 References 1. Clark, Grumberg, Peled:Model Checking, MIT-Press (1999) 2. Lau,Hannes:CTL*,CTL,LTL,http://www.mtv.tu-berlin.de/fileadmin/a3435/Lehre/WiSe0607/MTV3/lauCTL Foliensatz.pdf (2007) 3. Schwoon,Stefan:Model-Checking,http://www.fmi.unistuttgart.de/szs/teaching/ss2004/modelchecking/modelchecking.pdf (2004)