Effizientes Model-Checking für CTL - Institut für Theoretische ...
Effizientes Model-Checking für CTL - Institut für Theoretische ...
Effizientes Model-Checking für CTL - Institut für Theoretische ...
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
<strong>Effizientes</strong> <strong>Model</strong>-<strong>Checking</strong> <strong>für</strong> <strong>CTL</strong><br />
Diplomarbeit<br />
im Studiengang Mathematik mit Studienrichtung Informatik<br />
Julia Gerock<br />
Mtr.-Nr. 2294990<br />
<strong>Institut</strong> <strong>für</strong> <strong>Theoretische</strong> Informatik<br />
Fakultät <strong>für</strong> Elektrotechnik und Informatik<br />
Leibniz Universität Hannover<br />
Prüfer: Prof. Dr. Heribert Vollmer<br />
Zweitprüfer: Prof. Dr. Rainer Parchmann<br />
Betreuer: M. Sc. Arne Meier<br />
26. Oktober 2009
Danksagung<br />
Ich bedanke mich ganz herzlich bei Herrn Arne Meier <strong>für</strong> die hervorragende Betreuung<br />
und Unterstützung meiner Diplomarbeit.
Inhaltsverzeichnis<br />
1 Einführung 1<br />
1.1 Motivation und Aufgabenstellung . . . . . . . . . . . . . . . . . . . . . . . . 1<br />
1.2 Gliederung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2<br />
2 <strong>Theoretische</strong> Grundlagen 3<br />
2.1 <strong>Model</strong>-<strong>Checking</strong>-Prozess . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3<br />
2.2 Kripke-Struktur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4<br />
2.3 <strong>CTL</strong> als eine von temporalen Logiken . . . . . . . . . . . . . . . . . . . . . . 5<br />
2.4 Beispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8<br />
2.5 Komplexitätstheorie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12<br />
3 <strong>Model</strong>-<strong>Checking</strong> <strong>für</strong> <strong>CTL</strong> 13<br />
3.1 Formulierung des Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13<br />
3.2 Komplexität des <strong>Model</strong>-<strong>Checking</strong>-Problems <strong>für</strong> <strong>CTL</strong> . . . . . . . . . . . . . 14<br />
3.3 <strong>Model</strong>-<strong>Checking</strong> <strong>für</strong> <strong>CTL</strong> und <strong>CTL</strong>pos . . . . . . . . . . . . . . . . . . . . . 15<br />
3.3.1 <strong>CTL</strong>-MC(ALL) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15<br />
3.3.2 <strong>CTL</strong>pos-MC(EX, EG, EU, ER) . . . . . . . . . . . . . . . . . . . . 17<br />
4 Design und Implementierung 21<br />
4.1 Basisprogramm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21<br />
4.2 Neue Klassenstruktur und die Implementierungsaspekte . . . . . . . . . . 22<br />
4.3 Bedienungsanleitung zum Programm . . . . . . . . . . . . . . . . . . . . . . 30<br />
5 Auswertung von Algorithmen 36<br />
5.1 Allgemeine Beschreibung der Experimente . . . . . . . . . . . . . . . . . . . 36<br />
5.1.1 Testsystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36<br />
5.1.2 Testdaten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37<br />
5.1.3 Ablauf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37<br />
5.2 Zwei Implementierungen des <strong>CTL</strong>pos-Algorithmus . . . . . . . . . . . . . . 38<br />
5.3 Auswertung von <strong>CTL</strong>pos- und <strong>CTL</strong>-Algorithmen . . . . . . . . . . . . . . . 40<br />
5.4 Laufzeit des <strong>CTL</strong>-Algorithmus <strong>für</strong> Kripke-Strukturen mit bis zu 300 Zuständen<br />
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43<br />
6 Zusammenfassung und Ausblick 48<br />
Literaturverzeichnis 54
1 Einführung<br />
1.1 Motivation und Aufgabenstellung<br />
Heutzutage werden Software- und Hardware-Systeme so gut wie in jedem Gebiet eingesetzt<br />
und haben sich in unserem Leben fest etabliert. Somit wird die Abhängigkeit<br />
von der Zuverlässigkeit dieser Systeme immer größer. Andererseits wird es schwieriger,<br />
die Funktionsweise fehlerfrei zu gewährleisten, da sich der Umfang und die Komplexität<br />
der Systeme auch ständig steigern. Mithilfe der Standardmittel wie Testen oder Simulation<br />
werden Fehlerfälle oft unvollständig abgedeckt. Und sogar bei einer vollständigen<br />
Abdeckung kann das System weitere Fehler enthalten, die nicht entdeckt wurden.<br />
Deswegen ist die Notwendigkeit entstanden, neue, möglichst effiziente Methoden zu<br />
entwickeln, um mit deren Hilfe die Korrektheit und somit die Qualität eines Systems<br />
zu sichern und beweisen zu können. Dies kann ermöglicht werden, indem ein zu entwickelndes<br />
System sowie dessen relevante Eigenschaften formalisiert werden, und es durch<br />
Verifikation überprüft wird, ob die gewünschten Eigenschaften im System erfüllt sind.<br />
<strong>Model</strong>-<strong>Checking</strong> als eine dieser Methoden basiert auf diesem Prinzip. Dabei werden<br />
ein <strong>Model</strong>l M, als eine Beschreibung des Systems, und eine logische Formel ϕ, als eine<br />
Spezifikation des Systems, verifiziert (M ⊧ ϕ).<br />
Je nach der Art der Formeln 1 werden diverse Klassen von <strong>Model</strong>-<strong>Checking</strong>-Problemen<br />
unterschieden. Diese Arbeit befasst sich mit dem <strong>Model</strong>-<strong>Checking</strong>-Problem <strong>für</strong> <strong>CTL</strong><br />
(Computation Tree Logic).<br />
Ziel der Arbeit besteht darin, dieses Problem in Bezug auf seine Effizienz auszuarbeiten.<br />
Als Basis werden die im <strong>Institut</strong> <strong>für</strong> <strong>Theoretische</strong> Informatik der Leibniz Universität<br />
Hannover entstandenen Ergebnisse der Forschung des <strong>Model</strong>-<strong>Checking</strong>-Problems verwendet,<br />
die weiter unten dargestellt sind. Das <strong>Model</strong>-<strong>Checking</strong>-Problem <strong>für</strong> <strong>CTL</strong> ist als<br />
P-vollständig bekannt. Zugehörigkeit eines Problems zu einer Komplexitätsklasse kann<br />
durch Angeben eines Algorithmus bewiesen werden, der dieses Problem entscheidet und<br />
selbst in dieser Komplexitätsklasse liegt. Ein weiteres Ziel der Arbeit ist es, diverse Algorithmen<br />
des <strong>Model</strong>-<strong>Checking</strong>-Problems <strong>für</strong> <strong>CTL</strong> vorzustellen, zu implementieren und<br />
ihre Effizienz zu vergleichen.<br />
1 In Abhängigkeit davon, welche Operatoren erlaubt bzw. welche Constraints festgelegt sind (z. B. <strong>CTL</strong>,<br />
<strong>CTL</strong>*, LTL).<br />
1
1.2 Gliederung<br />
1 Einführung<br />
In der vorliegenden Arbeit wird nach der Einleitung in Kapitel 2 auf theoretische<br />
Grundlagen eingegangen. Hier werden wichtige Grundbegriffe definiert, die <strong>für</strong> diese Arbeit<br />
benötigt werden. Danach wird ein Beispiel präsentiert, um ein intuitives Verständnis<br />
zu schaffen.<br />
Kapitel 3 bildet den Hauptteil dieser Arbeit. Hier wird das <strong>Model</strong>-<strong>Checking</strong>-Problem<br />
<strong>für</strong> <strong>CTL</strong> konkretisiert. Dabei wird untersucht, mit welcher Effizienz dieses Problem gelöst<br />
werden kann und welche Schwierigkeiten sich dabei ergeben. In Abschnitt 3.3.1 wird<br />
das <strong>Model</strong>-<strong>Checking</strong>-Problem auf die gesamte Klasse <strong>CTL</strong> verallgemeinert und ein Algorithmus<br />
aus [CGP99] präsentiert, der in Polynomialzeit arbeitet. In Abschnitt 3.3.2<br />
wird ein speziell definiertes Fragment <strong>CTL</strong>pos betrachtet. Für dieses wird hier ein weiterer<br />
Entscheidungsalgorithmus aus [BMT + ] vorgestellt.<br />
In Kapitel 4 wird behandelt, wie die in Kapitel 3 geschilderten Algorithmen implementiert<br />
werden können. Diese werden als eine Erweiterung eines existierenden Programms<br />
([Sol09]) realisiert. Das Programm wird hier auch kurz erläutert.<br />
In Kapitel 5 wird die Laufzeit der Algorithmen <strong>für</strong> <strong>CTL</strong> und <strong>CTL</strong>pos untersucht und<br />
verglichen. Experimente und deren Ergebnisse werden hier veranschaulicht.<br />
Kapitel 6 enthält eine Zusammenfassung und einen Ausblick der Diplomarbeit.<br />
2
2 <strong>Theoretische</strong> Grundlagen<br />
In diesem Kapitel werden die <strong>für</strong> diese Arbeit relevanten Begriffe wie <strong>Model</strong>-<strong>Checking</strong>,<br />
Kripke-Struktur, temporale Logik und insbesondere <strong>CTL</strong> eingeführt und in Anlehnung<br />
an [CGP99] definiert. Diese werden anschließend mittels eines Beispiels verdeutlicht.<br />
Um die Effizienz des <strong>Model</strong>-<strong>Checking</strong>-Problems untersuchen zu können, werden auch<br />
die <strong>für</strong> dieses Thema wichtigsten Resultate der Komplexitätstheorie in diesem Kapitel<br />
zusammengefasst.<br />
2.1 <strong>Model</strong>-<strong>Checking</strong>-Prozess<br />
<strong>Model</strong>-<strong>Checking</strong> ist als eine Verifikationsmethode von endlichen zustandsbasierten Systemen<br />
bekannt, die die Korrektheit eines Systems bezüglich seiner Spezifikation beweist<br />
oder widerlegt und dabei automatisch abläuft. Diese zwei vorteilhaften Aspekte unterscheiden<br />
<strong>Model</strong>-<strong>Checking</strong> von den anderen Verifikationsverfahren (z. B. deduktive Verifikation)<br />
sowie von dem Testen und der Simulation erheblich (vgl. [Sch]). Der Begriff wurde<br />
in den 80 Jahren geprägt. Diese Methode ist bereits <strong>für</strong> den Korrektheitsnachweis beim<br />
Entwurf von komplexen sequentiellen Schaltungen und von Kommunikationsprotokollen<br />
erfolgreich praktisch eingesetzt worden (vgl. [CGP99]). Mit Hilfe des <strong>Model</strong>-<strong>Checking</strong>s<br />
können zur Zeit sowohl Hardware- als auch Software-Systeme untersucht werden.<br />
Im Allgemeinen gliedert sich das <strong>Model</strong>-<strong>Checking</strong> in drei Schritte:<br />
1. <strong>Model</strong>lierung<br />
2. Spezifizierung<br />
3. Verifikation<br />
Im ersten Schritt muss ein zu analysierendes System S in eine vereinbarte Form gebracht<br />
werden. Somit wird ein <strong>Model</strong>l M des Systems S erzeugt. Hier ist es wichtig,<br />
relevante von nicht relevanten Eigenschaften des Systems zu trennen und nur die signifikanten,<br />
diese aber alle, abzubilden. Außerdem ist es zu entscheiden, ob das System zum<br />
Anwenden des <strong>Model</strong>-<strong>Checking</strong>s tauglich, d. h. zustandsbasiert und endlich (mit einem<br />
endlich repräsentierbaren Zustandsraum) ist. Dabei kann eine Zustandsexplosion entstehen.<br />
In den letzten zehn Jahren wurden aber erhebliche Fortschritte zur Behandlung<br />
dieses Problems erreicht (siehe [CGP99]).<br />
Es gibt mehrere Methoden, um ein System in ein <strong>Model</strong>l zu überführen. In dieser<br />
Arbeit erfolgt dies mittels Konstruierens einer Kripke-Struktur, die in Abschnitt 2.2<br />
erläutert wird.<br />
3
2 <strong>Theoretische</strong> Grundlagen<br />
In der Spezifikationsphase werden geforderte Eigenschaften des Systems S formal erfasst.<br />
Somit entsteht eine Spezifikation als eine Menge von Regeln, die das System erfüllen<br />
muss. Bei der Erstellung der Spezifikation spielt ihre Vollständigkeit eine zentrale Rolle,<br />
da nur diejenigen Eigenschaften mit dem <strong>Model</strong>l verifiziert werden, die in der Spezifikation<br />
vorkommen. Wenn nicht alle relevanten Systemanforderungen in der Spezifikation<br />
abgebildet sind, werden sie bei der Verifikation nicht beachtet. Dies kann allerdings zu<br />
einer falschen Entscheidung führen, dass das <strong>Model</strong>l die Systemanforderungen erfüllt,<br />
obwohl das nicht vollständig geprüft wurde.<br />
Meistens wird temporale Logik als Spezifikationssprache von den Software- und Hardware-Systemen<br />
benutzt. Temporale Logik ermöglicht es, zeitliche Abläufe des Systems zu<br />
beschreiben. In diesem Fall wird die Spezifikation als eine Menge von temporal-logischen<br />
Formeln ϕ formuliert. Jede Formel drückt das nachzuweisende Verhalten des Systems<br />
über die Zeit aus. In Abschnitt 2.3 wird auf die temporale Logik genauer eingegangen.<br />
Im letzten Schritt werden spezielle <strong>Model</strong>-<strong>Checking</strong>-Algorithmen angewendet, um<br />
nachzuweisen oder zu widerlegen, dass das <strong>Model</strong>l M die Spezifikation ϕ erfüllt. Dieser<br />
Schritt erfolgt größtenteils automatisch, menschliche Teilnahme wird in der Praxis nur<br />
bei der Analyse der Verifikationsergebnisse gefordert.<br />
Das <strong>Model</strong>-<strong>Checking</strong>-Problem kann folgendermaßen formuliert werden. Sei S ein zu<br />
analysierendes System.<br />
Eingabe: ein <strong>Model</strong>l M des Systems S<br />
Frage:<br />
eine nachzuweisende Eigenschaft ϕ, die das System S haben muss<br />
” Erfüllt das <strong>Model</strong>l M die Spezifikation ϕ?“<br />
(M ⊧ ϕ?)<br />
Eine genauere Definition <strong>für</strong> das <strong>für</strong> die vorliegende Arbeit auszuarbeitende <strong>Model</strong>-<br />
<strong>Checking</strong>-Problem <strong>für</strong> <strong>CTL</strong> wird in Abschnitt 3.1 gegeben, nachdem die Begriffe ” Kripke-<br />
Struktur“ und ” <strong>CTL</strong>“ in den nächsten Abschnitten eingeführt werden.<br />
2.2 Kripke-Struktur<br />
Zum <strong>Model</strong>lieren von endlichen zustandsbasierten Systemen werden beim <strong>Model</strong>-<strong>Checking</strong><br />
Kripke-Strukturen verwendet. Diese ermöglichen, Eigenschaften eines Systems in<br />
verschiedenen Zuständen zu beschreiben, indem bestimmte Aussagen über das System<br />
den Zuständen zugeordnet werden. Beispielsweise ist eine Ampel (ein System) in einem<br />
Zustand ” rot“, und dabei wird ein ” Tonsignal“ abgegeben. In diesem Fall wird dieser<br />
Zustand beim <strong>Model</strong>lieren der Ampel mit den beiden Aussagen ” rot“ und ” Tonsignal“<br />
markiert.<br />
Eine Kripke-Struktur ist wie folgt definiert (vgl. [CGP99], [BMT + ]).<br />
4
2 <strong>Theoretische</strong> Grundlagen<br />
Definition 2.2.1 (Kripke-Struktur) Sei AP eine Menge der atomaren Aussagen<br />
(atomic propositions). Eine Kripke-Struktur K über AP ist ein 4-Tupel K = (W, W0, R,<br />
η), wobei<br />
1. W eine endliche Menge der Zustände ist;<br />
2. W0 ⊆ W die Menge der Start-Zustände ist;<br />
3. R ⊆ W × W eine totale Transitionsrelation ist, d. h. <strong>für</strong> jeden Zustand w ∈ W gibt<br />
es einen Zustand w’ ∈ W mit (w, w’) ∈ R;<br />
4. η ∶ W → P(AP ) eine Beschriftungsfunktion (labelling function) ist, die jedem<br />
Zustand die Menge der atomaren Aussagen zuordnet, die in diesem Zustand erfüllt<br />
sind.<br />
Bemerkung:<br />
• Manchmal wird die Menge der Start-Zustände nicht explizit angegeben. In diesen<br />
Fällen wird W0 aus der Definition ausgelassen.<br />
• Üblicherweise wird die Menge der atomaren Aussagen AP im Hinblick auf die<br />
gewünschte Spezifikation konstruiert. (vgl. [Sch])<br />
In Abschnitt 2.4 ist ein Beispiel zu finden, wie sich ein System als eine Kripke-Struktur<br />
gestalten lässt.<br />
2.3 <strong>CTL</strong> als eine von temporalen Logiken<br />
Temporale Logik wurde als eine Erweiterung der Aussagenlogik mit dem Ziel definiert,<br />
zeitliche Änderungen beschreiben zu können. Die Zeit wird hier als Folge (oder später als<br />
Pfad) von Zuständen betrachtet. In diversen Zuständen können Aussagen verschiedene<br />
Wahrheitswerte annehmen. Temporale Logik ermöglicht es, <strong>für</strong> eine logische Aussage ϕ<br />
solche Beziehungen zu modellieren, wie z. B. ” ϕ gilt immer“, ” ϕ wird nie wahr“, ” ϕ wird<br />
zum nächsten Zeitpunkt gelten“ usw. Dies erfolgt mittels der sogenannten temporalen<br />
Operatoren. Um auszudrücken, dass eine Eigenschaft des Systems gelten muss bzw.<br />
kann, werden die Pfad-Quantoren A bzw. E verwendet. Temporale Operatoren und<br />
Pfad-Quantoren sind in den Tabellen 2.1 und 2.2 aufgelistet und erläutert.<br />
Temporale Logik wurde im Jahr 1977 in der Arbeit von A. Pnueli ” The Temporal Logic<br />
of Programs“ als eine Formalisierungssprache <strong>für</strong> Spezifikation und Verifikation von<br />
vergleichbaren Programmen zum ersten Mal vorgestellt und hat sich als eine Spezifikationsmethode<br />
zur Erfassung von Systemanforderungen beim <strong>Model</strong>-<strong>Checking</strong> etabliert.<br />
5
2 <strong>Theoretische</strong> Grundlagen<br />
Operator Syntax Bedeutung Semantik Beispielpfad<br />
F F ϕ<br />
” in the<br />
future“ oder<br />
” eventually“<br />
ϕ gilt irgendwann<br />
auf dem nachfolgenden<br />
Pfad<br />
G G ϕ<br />
X X ϕ<br />
U ϕ U ψ<br />
R ϕ R ψ<br />
” globally“<br />
oder<br />
” always“<br />
ϕ gilt in jedem Zustand<br />
auf dem Pfad<br />
” next time“ ϕ gilt im nächsten<br />
Zustand<br />
” until“ ϕ gilt in jedem Zustand,<br />
bis der Zustand<br />
erreicht wird,<br />
in dem ψ wahr ist<br />
” release“ ψ gilt bis zu einem<br />
Zustand, in dem ϕ<br />
gilt oder <strong>für</strong> immer,<br />
wenn ϕ immer<br />
falsch ist<br />
Tabelle 2.1: Temporale Operatoren. ϕ, ψ sind temporal-logische Formeln<br />
Quantor Syntax Name Semantik<br />
A A ϕ Allquantor Für alle Pfade gilt ϕ<br />
E E ϕ Existenzquantor Es existiert ein Pfad, <strong>für</strong> den ϕ gilt<br />
Tabelle 2.2: Pfad-Quantoren<br />
In Abhängigkeit von verwendeten Operatoren und von deren Semantik werden folgende<br />
Klassen von temporalen Logiken unterschieden:<br />
LTL: Linear Temporal Logic betrachtet die Zeit als eine lineare Abfolge von Zeitpunkten<br />
bzw. Zuständen<br />
<strong>CTL</strong>: Computational Tree Logic charakterisiert die Zeit als ein verzweigender Ablauf von<br />
Zuständen<br />
<strong>CTL</strong>*: Extended Computation Tree Logic. <strong>CTL</strong>* ⊃ LTL ∪ <strong>CTL</strong>. Ausdruckskraft von <strong>CTL</strong>*,<br />
<strong>CTL</strong> und LTL ist nicht vergleichbar, da sich nicht jede in einer Logik formulierte<br />
6
2 <strong>Theoretische</strong> Grundlagen<br />
Aussage in eine äquivalente Aussage in der anderen Logik transformieren lässt.<br />
Beispiele dazu sind in [CGP99], [Sol09] zu finden.<br />
Da das <strong>Model</strong>-<strong>Checking</strong>-Problem <strong>für</strong> diese Arbeit auf <strong>CTL</strong> eingeschränkt ist, wird diese<br />
Logik hier genauer betrachtet. <strong>CTL</strong> wurde von Emerson und Clarke eingeführt. Wie die<br />
anderen temporalen Logiken beinhaltet sie folgende Bausteine:<br />
• atomare Aussagen<br />
• boolesche Operatoren ¬(NOT), ∧(AND) und ∨(OR)<br />
• temporale Operatoren F, G, X, U, R<br />
• Pfad-Quantoren A, E<br />
Die Sprache, die aus diesen Operatoren und Quantoren besteht, heißt <strong>CTL</strong>*. Aus<br />
diesen Komponenten werden <strong>CTL</strong>*-Formeln gestaltet. <strong>CTL</strong>* ist in [CGP99] und [Sol09]<br />
ausführlich beschrieben.<br />
Eine <strong>CTL</strong>-Formel ist eine <strong>CTL</strong>*-Formel mit einer Einschränkung auf die Verwendung<br />
von temporalen Operatoren und Pfad-Quantoren. Jeder temporale Operator darf nur<br />
nach einem Pfad-Quantor auftreten, und jeder Pfad-Quantor darf nur gefolgt von einem<br />
temporalen Operator in den <strong>CTL</strong>-Formeln vorkommen. Die Operatoren AF, AG, AX,<br />
AU, AR werden universale Operatoren genannt, EF, EG, EX, EU, ER heißen existenzielle<br />
Operatoren. Universale und existenzielle Operatoren bilden die Menge ALL<br />
von allen <strong>CTL</strong>-Operatoren.<br />
Weiter wird eine <strong>CTL</strong>-Formel induktiv definiert.<br />
Definition 2.3.1 (<strong>CTL</strong>-Formel) Sei AP eine Menge von atomaren Aussagen, Q ∈<br />
{A, E}. Die Symbole ⊺ und repräsentieren die Wahrheitswerte ” wahr“ und ” falsch“.<br />
• ⊺, sind <strong>CTL</strong>-Formeln.<br />
• Ist p ∈ AP , so ist p eine <strong>CTL</strong>-Formel.<br />
• Sind ϕ, ψ <strong>CTL</strong>-Formeln, dann sind (ϕ), ¬ϕ, ϕ ∧ ψ, ϕ ∨ ψ, QF ϕ, QG ϕ, QX ϕ,<br />
Q(ϕ U ψ), Q(ϕ R ψ) auch <strong>CTL</strong>-Formeln.<br />
Man unterscheidet zwei Arten von Formeln: Zustand- und Pfad-Formeln. Zustand-<br />
Formeln beschreiben Eigenschaften, die in einem Zustand gelten, und Pfad-Formeln<br />
charakterisieren Eigenschaften entlang eines Pfades.<br />
Definition 2.3.2 (Zustand-Formel)<br />
• ⊺, sind Zustand-Formeln.<br />
• Ist p ∈ AP , so ist p eine Zustand-Formel.<br />
• Sind ϕ, ψ Zustand-Formeln, dann sind (ϕ), ¬ϕ, ϕ ∧ ψ, ϕ ∨ ψ Zustand-Formeln.<br />
• Ist χ eine Pfad-Formel, so ist Aχ eine Zustand-Formel.<br />
7
Definition 2.3.3 (Pfad-Formel)<br />
• Ist ϕ eine Zustand-Formel, so ist ϕ auch eine Pfad-Formel.<br />
2 <strong>Theoretische</strong> Grundlagen<br />
• Sind χ, π Pfad-Formeln, dann sind (χ), ¬χ, χ ∧ π, χ ∨ π, Xχ und χ U π Pfad-<br />
Formeln.<br />
Weiterhin ist {EX, EU, EG} eine minimale Menge der <strong>CTL</strong>-Operatoren, da jede<br />
<strong>CTL</strong>-Formel in eine äquivalente Formel konvertiert werden kann, in der nur die <strong>CTL</strong>-<br />
Operatoren EX, EU, EG sowie die booleschen Operatoren ¬ und ∨ verwendet werden.<br />
In der Tabelle 2.3 sind die entsprechenden Regeln aufgelistet.<br />
Regel № Allgemeine Form Konvertierte Form<br />
1 E ϕ ¬A¬ϕ<br />
2 ϕ ∧ ψ ¬(¬ϕ ∨ ¬ψ)<br />
3 EF ϕ E(⊺ U ϕ)<br />
4 E(ϕ R ψ) EG ψ∨ E (ψ U ¬(¬ϕ ∨ ¬ψ))<br />
5 AF ϕ ¬ EG(¬ϕ)<br />
6 AX ϕ ¬ EX(¬ϕ)<br />
7 AG ϕ ¬ EF(¬ϕ)<br />
8 A(ϕ U ψ) ¬ (EG (¬ψ)∨ E (¬ψ U ¬(ϕ ∨ ψ)))<br />
9 A(ϕ R ψ) ¬ E (¬ϕ U ¬ψ)<br />
Tabelle 2.3: Darstellung der <strong>CTL</strong>-Formeln durch die Operatoren EX, EU, EG, ¬, ∨<br />
<strong>CTL</strong>, als eine <strong>CTL</strong>*-Logik, basiert auf der Kripke-Struktur. Um Systemanforderungen<br />
mittels <strong>CTL</strong>-Formeln zu spezifizieren, müssen diverse Eigenschaften des Systems in verschiedenen<br />
Zeitpunkten beschrieben werden. Die Zeitskala wird als Pfad von Zuständen<br />
in der das System repräsentierenden Kripke-Struktur interpretiert. Weiter wird ein Pfad<br />
definiert.<br />
Definition 2.3.4 (Pfad) Sei K = (W, W0, R, η) eine Kripke-Struktur. Ein Pfad x in<br />
der Kripke-Struktur K ist eine unendliche Sequenz von Zuständen x = (x1, x2, ...) ∈ W ω ,<br />
so dass (xi, xi+1) ∈ R ∀i ≥ 1.<br />
In Abschnitt 2.4 wird mittels eines Beispiels gezeigt, wie Systemanforderungen als<br />
<strong>CTL</strong>-Formeln erfasst werden können.<br />
2.4 Beispiel<br />
Ein <strong>Model</strong>-<strong>Checking</strong>-Prozess kann in folgenden Schritten kurz gefasst werden. Sei S ein<br />
zu analysierendes System.<br />
1. <strong>Model</strong>lierung: im ersten Schritt wird ein <strong>Model</strong>l M vom System S erstellt. M ist<br />
eine formale Beschreibung des Systems und spiegelt relevante Eigenschaften von S<br />
wider. Als <strong>Model</strong>lierungsmechanismus wird hier Kripke-Struktur eingesetzt.<br />
8
2 <strong>Theoretische</strong> Grundlagen<br />
2. Spezifizierung: hier werden Systemanforderungen Φ = {φj ∣ j = 0, 1, ...} erfasst. Für<br />
diese Arbeit sind solche Eigenschaften von Systemen relevant, die über verzweigende<br />
Zeit festgelegt werden sollen. Diese werden mittels <strong>CTL</strong>-Formeln formalisiert.<br />
3. Verifikation: anschließend wird durch das Anwenden eines Algorithmus das <strong>Model</strong>-<br />
<strong>Checking</strong>-Problem entschieden, das folgendermaßen formuliert werden kann:<br />
” Erfüllt das <strong>Model</strong>l M die Spezifikation Φ?“<br />
An dieser Stelle wird ein Beispiel vorgestellt, mit dem gezeigt wird, wie <strong>Model</strong>-<strong>Checking</strong><br />
angewendet werden kann.<br />
Es handelt sich um das bekannte ” Speisende Philosophen“-Problem (siehe Abbildung<br />
2.1). 5 Philosophen A, B, C, D und E sitzen um einen Tisch. Es gibt fünf Teller mit<br />
dem Essen <strong>für</strong> jeden Philosophen, und zwischen je zwei Tellern liegt eine Gabel. Jeder<br />
denkt nach und isst abwechselnd. Zum Essen benötigen sie jeweils die beiden Gabeln<br />
neben sich. Es können somit maximal zwei Personen, die nicht nebeneinander sitzen,<br />
gleichzeitig speisen (vgl. [Har02]).<br />
Abbildung 2.1: Speisende Philosophen (vgl. [Sch])<br />
Dieses Problem kann als ein zu analysierendes System S betrachtet werden. S kann mit<br />
Hilfe eines Graphen G (Abbildung 2.2) oder als eine entsprechende Kripke-Struktur K<br />
(Abbildung 2.3) modelliert und durch bestimmte Regeln (Systemanforderungen) ρj,j=0,1,...,<br />
die mittels temporal-logischer Formeln (hier <strong>CTL</strong>-Formeln) ϕj beschrieben werden, spezifiziert<br />
werden.<br />
Die Bezeichnungen der Zustände sind so gewählt, dass man erkennen kann, welche<br />
Philosophen in diesem Moment essen (bis auf den Ausnahmezustand S). Das heißt, im<br />
Zustand A isst der Philosoph A, im Zustand AC speisen die Philosophen A und C, im Zustand<br />
S in der Mitte denken alle Philosophen nach. Die Übergänge zwischen den Zuständen<br />
stellen die Aktionen der Philosophen dar. Wenn ein Philosoph I ∈ {A, B, C, D, E}<br />
eine Gabel vom Tisch aufnimmt (pick up) bzw. zurückgibt (return), wird der entsprechende<br />
Übergang mit Ip bzw. Ir beschriftet.<br />
Wenn man das System S in eine Kripke-Struktur K über AP überführt, ist sie wie<br />
folgt definiert und in Abbildung 2.3 dargestellt.<br />
9
2 <strong>Theoretische</strong> Grundlagen<br />
Abbildung 2.2: Speisende Philosophen als ein <strong>Model</strong>l([Har02])<br />
K = (W, {S}, R, η), wobei<br />
• AP = {a, b, c, d, e} die Menge der atomaren Aussagen ist, die den Namen der<br />
speisenden Philosophen entsprechen;<br />
• W = {S, A, B, C, D, E, AC, DA, DB, EB, EC} die Menge der Zustände ist;<br />
• R = {(S, A), (S, B), (S, C), (S, D), (S, E), (A, S), (B, S), (C, S), (D, S),<br />
(E, S), (A, AC), (A, DA), (B, EB), (B, DB), (C, AC), (C, EC), (D, DB),<br />
(D, DA), (E, EC), (E, EB), (EB, B), (EB, E), (AC, A), (AC, C), (DB, B),<br />
(DB, D), (EC, C), (EC, E), (DA, A), (DA, D)} die Transitionsrelation ist;<br />
• η ∶ W → P(AP ), <strong>für</strong> p ∈ AP, w ∈ W gilt: p ∈ η(w), falls der Philosoph mit dem<br />
Namen P ( ” groß p“) in dem Zustand w isst. Z. B. wenn der Philosoph A in dem<br />
Zustand w speist, dann ist a ∈ η(w).<br />
Das System S muss unter anderen z. B. folgende Eigenschaften erfüllen:<br />
• ρ0 = ” Die Philosophen A und B dürfen nie gleichzeitig essen.“<br />
• ρ1 = ” Philosoph A isst als erster.“<br />
• ρ2 = ” Wenn Philosoph D nichts gegessen hat, kann er irgendwann zusammen mit<br />
B etwas essen.“<br />
10
2 <strong>Theoretische</strong> Grundlagen<br />
Abbildung 2.3: Speisende Philosophen als eine Kripke-Struktur<br />
• ρ3 = ” Immer, wenn Philosoph D fertig gegessen hat, muss er solange nachdenken<br />
oder warten, bis Philosoph E auch etwas gegessen hat.“<br />
Die entsprechenden <strong>CTL</strong>-Formeln sehen wie folgt aus:<br />
• ϕ0 = AG ¬(a ∧ b);<br />
• ϕ1 = A (¬(b ∨ c ∨ d ∨ e) U a);<br />
• ϕ2 = ¬d → EF(d ∧ b) = d ∨ EF(d ∧ b);<br />
• ϕ3 = AG(¬d → A(¬d U e)) = AG(d ∨ A(¬d U e));<br />
Somit ist K ein <strong>Model</strong>l des Systems S und Φ = {ϕi ∣ i = 0, ..., 3} ist eine Spezifikation.<br />
Die Frage, ob das <strong>Model</strong>l K die Spezifikation Φ erfüllt, kann beantwortet werden, indem<br />
K und jede φ ∈ Φ verifiziert werden. Dies erfolgt mittels spezieller <strong>Model</strong>-<strong>Checking</strong>-<br />
Algorithmen, die in Kapitel 3 vorgestellt und erläutert werden.<br />
11
2.5 Komplexitätstheorie<br />
2 <strong>Theoretische</strong> Grundlagen<br />
Da der Verifikationsschritt beim <strong>Model</strong>-<strong>Checking</strong> größtenteils automatisch verläuft, ist<br />
die Frage der Berechnungskomplexität dieses Entscheidungsproblems hoch interessant.<br />
Die Komplexität von <strong>Model</strong>-<strong>Checking</strong> <strong>für</strong> diverse temporale Logiken wurde in [CES86],<br />
[Sch02], [EL87] untersucht. Das <strong>Model</strong>-<strong>Checking</strong> ist <strong>für</strong> <strong>CTL</strong>* PSPACE-vollständig und<br />
<strong>für</strong> <strong>CTL</strong> P-vollständig. <strong>Theoretische</strong> Hintergründe da<strong>für</strong> werden in diesem Abschnitt<br />
einbezogen.<br />
Die Komplexitätsklasse P (PTIME), die Klasse der Probleme mit effizienten Algorithmen,<br />
wird oft als die Klasse der ” effizient lösbaren“ Probleme bezeichnet. Sie besteht<br />
aus allen Sprachen L, die einen Polynomialzeit-Entscheidungsalgorithmus haben. Ein<br />
Problem A heißt P-vollständig, falls A ∈ P und jedes andere Problem in P auf A reduzierbar<br />
ist. P-vollständige Probleme werden manchmal als inhärent sequentiell (inherently<br />
sequential) bezeichnet, da sie (wenn P ≠ NC) keine NC-Algorithmen haben.<br />
NC-Algorithmen laufen polylogarithmisch (in O(log c n), c konstant) an einem Parallelcomputer<br />
mit einer polynomiellen Anzahl von Prozessoren. Die Komplexitätsklasse<br />
NC beinhaltet die parallel effizient lösbaren Entscheidungsprobleme. Daher lassen sich<br />
P-vollständige Probleme nicht parallelisieren (wenn P ≠ NC).<br />
Es gibt einen NC-Algorithmus zum Parsen von kontextfreien Sprachen (CFL), d. h.<br />
CFL ⊆ NC. Deswegen ist die Klasse LOGCFL bei der Untersuchung der Komplexität des<br />
<strong>Model</strong>-<strong>Checking</strong>s <strong>für</strong> <strong>CTL</strong> von großem Interesse. Diese Klasse enthält alle mit logarithmischem<br />
Speicheraufwand auf CFL reduzierbaren Probleme. Daher gilt LOGCFL⊆NC.<br />
Andererseits können Sprachen in LOGCFL von nichtdeterministischen Turing Maschinen<br />
in Polynomialzeit entschieden werden, die ein Arbeitsband logarithmischer Größe<br />
und zusätzlich einen Stack unendlicher Größe haben (siehe [BMT + ]). Diese Eigenschaft<br />
von LOGCFL wird bei der Analyse der Komplexität vom <strong>Model</strong>-<strong>Checking</strong>-Problem <strong>für</strong><br />
<strong>CTL</strong> erzielt.<br />
Im Rahmen dieser Arbeit werden aber nur die Algorithmen aus P ausgearbeitet.<br />
12
3 <strong>Model</strong>-<strong>Checking</strong> <strong>für</strong> <strong>CTL</strong><br />
Im vorherigen Kapitel wurde der allgemeine <strong>Model</strong>-<strong>Checking</strong>-Prozess aufgeführt. Ziel<br />
dieses Kapitels ist es, diesen Prozess auf <strong>CTL</strong> zu präzisieren. Nachdem das <strong>Model</strong>-<br />
<strong>Checking</strong>-Problem <strong>für</strong> <strong>CTL</strong> definiert wird, wird seine Komplexität in Betracht gezogen.<br />
Dabei werden die in [BMT + ] (eine vorläufige, unveröffentlichte Version von [BMT + 09])<br />
präsentierten Hauptresultate sowie zwei <strong>Model</strong>-<strong>Checking</strong>-Algorithmen <strong>CTL</strong>pos-MC(EX,<br />
EG, EU, ER) und <strong>CTL</strong>-MC(ALL) vorgestellt, die in Polynomialzeit arbeiten. Die praktische<br />
Aufgabe der vorliegenden Arbeit besteht darin, diese Algorithmen zu implementieren<br />
und ihre Effizienz zu vergleichen.<br />
3.1 Formulierung des Problems<br />
In Abschnitt 2.3 wurde die Menge ALL von allen <strong>CTL</strong>-Operatoren erwähnt. Mit<br />
<strong>CTL</strong>(ALL) wird dann die Menge von <strong>CTL</strong>-Formeln bezeichnet. Bei Aufklärung der Komplexitätsfragen<br />
ist es hilfreich, nicht nur die gesamte Menge ALL, sondern auch kleinere<br />
Teilmengen davon zu betrachten.<br />
Definition 3.1.1 (<strong>CTL</strong>(T )) Sei T ⊆ ALL eine Menge von <strong>CTL</strong>-Operatoren. Mit<br />
<strong>CTL</strong>(T) wird die Menge von <strong>CTL</strong>-Formeln bezeichnet, in denen nur die booleschen Operatoren<br />
{¬, ∧, ∨} und die <strong>CTL</strong>-Operatoren aus T erlaubt sind.<br />
Ferner können beliebige eingeschränkte Fragmente von <strong>CTL</strong>(T ) definiert werden. Für<br />
die vorliegende Arbeit wird das Fragment <strong>CTL</strong>pos (T ) benötigt, in dem <strong>CTL</strong>-Operatoren<br />
im Bereich einer Negation nicht auftreten dürfen: <strong>für</strong> a, b ∈ AP gilt<br />
• ¬EX a ∉ <strong>CTL</strong>pos (T )<br />
• ¬(a ∧ ¬b) ∨ EX a ∈ <strong>CTL</strong>pos (T )<br />
In Abschnitt 2.1 wurde das <strong>Model</strong>-<strong>Checking</strong>-Problem in der Frage formuliert, ob ein<br />
<strong>Model</strong>l eine Spezifikation erfüllt. Weiterhin muss das auf eine Kripke-Struktur (<strong>Model</strong>l)<br />
und eine <strong>CTL</strong>-Formel (Spezifikation) übertragen werden. Anschließend wird die Erfüllbarkeit<br />
einer <strong>CTL</strong>-Formel in Bezug auf eine Kripke-Struktur definiert.<br />
13
3 <strong>Model</strong>-<strong>Checking</strong> <strong>für</strong> <strong>CTL</strong><br />
Definition 3.1.2 (<strong>Model</strong>-<strong>Checking</strong>-Problem) Sei L ∈ {<strong>CTL</strong>, <strong>CTL</strong>pos }.<br />
Problem: L-MC(T)<br />
Eingabe: ⟨K, w, ϕ⟩, wobei <strong>für</strong> die einzelnen Komponenten gilt:<br />
K = (W, R, η) ist eine Kripke-Struktur,<br />
w ∈ W ist ein Zustand,<br />
ϕ ist eine L(T)-Formel.<br />
Frage: Erfüllt K im Zustand w die Formel ϕ, also K, w ⊧ ϕ?<br />
Definition 3.1.3 (Semantik) Seien K, w wie in der Definition 3.1.2 und x = (x1,<br />
x2, ...) ∈ W ω ein Pfad. Ferner seien ϕ, ψ Zustand- und χ, π Pfad-Formeln. Die Evaluierung<br />
einer Formel zu wahr wird folgendermaßen induktiv definiert.<br />
K, w ⊧ ⊺ immer,<br />
K, w ⊧ nie,<br />
K, w ⊧ p falls p ∈ AP und p ∈ η(w),<br />
K, w ⊧ ¬ϕ falls K, w ⊧/ ϕ,<br />
K, w ⊧ (ϕ ∧ ψ) falls K, w ⊧ ϕ und K, w ⊧ ψ,<br />
K, w ⊧ (ϕ ∨ ψ) falls K, w ⊧ ϕ oder K, w ⊧ ψ,<br />
K, w ⊧ Aχ falls K, x ⊧ χ ∀x = (x1, x2, ...) mit x1 = w,<br />
K, w ⊧ χ falls K, x1 ⊧ χ,<br />
K, w ⊧ Xχ falls K, x2 ⊧ χ,<br />
K, w ⊧ [χUπ] falls ∃k ∈ IN, so dass K, xk ⊧ π und K, xi ⊧ χ∀1 ≤ i < k.<br />
Die Erfüllbarkeit der Formeln, in denen die übrigen <strong>CTL</strong>-Operatoren verwendet werden,<br />
kann mittels der in Tabelle 2.3 aufgelisteten Umwandlungsregeln überprüft werden.<br />
Außerdem sagt man, eine Zustand-Formel ϕ wird von einer Kripke-Struktur K erfüllt,<br />
wenn es einen Zustand w ∈ W gibt, so dass K, w ⊧ ϕ. Und analog, eine Pfad-Formel χ<br />
wird von einer Kripke-Struktur K erfüllt, wenn es einen Pfad x = (x1, x2, ...) gibt, so<br />
dass K, x ⊧ χ. Geschrieben:<br />
• K ⊧ ϕ ⇐⇒ ∃w ∈ W ∶ K, w ⊧ ϕ<br />
• K ⊧ χ ⇐⇒ ∃x = (x1, x2, ...) ∶ K, x ⊧ χ<br />
3.2 Komplexität des <strong>Model</strong>-<strong>Checking</strong>-Problems <strong>für</strong> <strong>CTL</strong><br />
Im Allgemeinen gilt <strong>Model</strong>-<strong>Checking</strong> <strong>für</strong> <strong>CTL</strong> als P-vollständig. Obwohl es in Polynomialzeit<br />
lösbar ist, lässt das Problem sich nicht parallelisieren (falls P ≠ NC). Daher werden<br />
Fragmente von <strong>CTL</strong> betrachtet, um leichtere Teilprobleme zu finden, die effizienter zu<br />
lösen sind.<br />
Die in [BMT + ], [BMT + 09] erhaltenen Resultate können folgendermaßen zusammengefasst<br />
werden.<br />
14
3 <strong>Model</strong>-<strong>Checking</strong> <strong>für</strong> <strong>CTL</strong><br />
1. Nicht-parallelisierbare Fälle: P-Vollständigkeit liegt <strong>für</strong> alle <strong>CTL</strong>-Fragmente vor, in<br />
denen mindestens ein <strong>CTL</strong>-Operator benutzt wird.<br />
2. Trivialfall: Für Fragmente ohne temporale Operatoren stimmt das <strong>Model</strong>-<strong>Checking</strong>-Problem<br />
mit der Auswertung einer aussagenlogischen Formel überein, und<br />
dieses Problem ist NC 1 -vollständig, d. h. parallelisierbar. NC 1 ist eine NC-Klasse<br />
der Sprachen, die in O(log 1 n)-arbeitende Entscheidungsalgorithmen haben (siehe<br />
[BMT + 09]).<br />
3. Parallelisierbare und nicht-triviale Fälle: <strong>Model</strong>-<strong>Checking</strong>-Problem <strong>CTL</strong>pos-MC(T )<br />
ist LOGCFL-vollständig, falls ∅ ⊊ T ⊆ {EX, EF} oder ∅ ⊊ T ⊆ {AX, AG} (vgl.<br />
[BMT + 09]).<br />
Für diese Arbeit ist der erste Fall relevant. Auf diesen wird in Abschnitt 3.3 genauer<br />
eingegangen.<br />
3.3 <strong>Model</strong>-<strong>Checking</strong> <strong>für</strong> <strong>CTL</strong> und <strong>CTL</strong>pos<br />
Dieser Abschnitt enthält wichtigste Ergebnisse zur Komplexität von <strong>Model</strong>-<strong>Checking</strong> <strong>für</strong><br />
<strong>CTL</strong> und <strong>für</strong> das in Abschnitt 3.1 definierte negationsbeschränkte Fragment <strong>CTL</strong>pos . Die<br />
entsprechenden Entscheidungsalgorithmen werden hier vorgestellt und erörtert.<br />
3.3.1 <strong>CTL</strong>-MC(ALL)<br />
Satz 3.3.1 <strong>CTL</strong>-MC(ALL) ∈ P<br />
In [CGP99] wurde ein Algorithmus vorgestellt, der das Problem <strong>CTL</strong>-MC(ALL) in<br />
Polynomialzeit entscheidet. Dieser wird im Weiteren beschrieben. Seien K = (W, R,<br />
η) eine Kripke-Struktur und ϕ eine <strong>CTL</strong>-Formel. Der Algorithmus bestimmt, in welchen<br />
Zuständen aus W die Formel ϕ erfüllt wird. Die Formel ϕ wird in die Teilformeln zerlegt.<br />
Unter einer Teilformel wird hier eine Formel verstanden, aus der mit Hilfe der Operatoren<br />
die betrachtete Formel konstruiert wird. Z. B. <strong>für</strong> ϕ = γ ∧ λ oder <strong>für</strong> ϕ = EXγ sind γ, λ<br />
die Teilformeln von ϕ. Jeder Zustand w wird mittels einer Menge label(w) markiert, zu<br />
der alle Teilformeln hinzugefügt werden, die in w erfüllt sind. Anfangs gilt: label(w) =<br />
η(w). Der Algorithmus läuft mehrere Stufen durch. Die Anzahl der Stufen entspricht dem<br />
Verschachtelungsgrad 1 (Anzahl der vorkommenden Operatoren) der Formel ϕ. In der i-en<br />
Stufe sind Teilformeln des Verschachtelungsgrades i-1 bereits abgearbeitet. Nachdem eine<br />
Teilformel γ behandelt wurde, wird sie zu der Menge label(w) von denjenigen Zuständen<br />
w hinzugefügt, in denen γ wahr ist. Sobald der Algorithmus terminiert, gilt K, w0 ⊧ ϕ,<br />
falls ϕ ∈ label(w0).<br />
In Abschnitt 2.3 wurde beschrieben, dass jede <strong>CTL</strong>-Formel durch atomare Aussagen<br />
und die Operatoren ¬, ∨, EX, EU und EG konstruiert werden kann. Deswegen müssen<br />
in jeder Stufe sechs Fälle behandelt werden. Seien φ eine <strong>CTL</strong>-Formel und w ein Zustand,<br />
die auf der i-en Stufe betrachtet werden.<br />
1 Verschachtelungsgrad ist 0, falls f ∈AP<br />
15
3 <strong>Model</strong>-<strong>Checking</strong> <strong>für</strong> <strong>CTL</strong><br />
1. φ ∈ AP: φ wird akzeptiert, falls φ ∈ label(w).<br />
In diesem Fall wird keine Markierung vorgenommen, da label(w) mit η(w) initialisiert<br />
wird;<br />
2. φ = ¬γ: markiert werden die Zustände, die mit γ nicht markiert sind.<br />
∀v ∈ W, γ ∉ label(v): label(v) = label(v) ∪ φ.<br />
3. φ = γ ∨ λ: betroffen sind diejenigen Zustände, die mit γ oder mit λ markiert sind.<br />
∀v, u ∈ W, γ ∈ label(v), λ ∈ label(u): label(v) = label(v)∪φ, label(u) = label(u)∪φ.<br />
4. φ = EXγ: markiert werden direkte Vorfahren der mit γ markierten Zustände.<br />
∀v, u ∈ W, γ ∈ label(v), (u, v) ∈ R: label(u) = label(u) ∪ φ<br />
5. φ = E(γUλ): markiert werden die Zustände, von denen aus ein Pfad existiert,<br />
der aus den mit γ markierten Zuständen besteht und mit dem mit λ markierten<br />
Zustand endet. Die Pfade werden rückwärts von den mit λ markierten Zuständen<br />
konstruiert. Dieser Fall wird in Algorithmus 1 behandelt.<br />
Algorithmus 1 Procedure CheckEU K, w0 ⊧ ϕ<br />
Eingabe: eine Kripke-Struktur K = (W, R, η), w0 ∈ W , ϕ = E(αUβ)<br />
1: T ← {s ∣ β ∈ label(s)}<br />
2: for all s ∈ T do<br />
3: label(s) ← label(s) ∪ {E(αUβ)}<br />
4: end for<br />
5: while T is not empty do<br />
6: choose s ∈ T<br />
7: T ← T /{s}<br />
8: for all t such that (t, s) ∈ R do<br />
9: if ϕ ∉ label(t) and α ∈ label(t) then<br />
10: label(t) ← label(t) ∪ {E(αUβ)}<br />
11: T ← T ∪ {t}<br />
12: end if<br />
13: end for<br />
14: end while<br />
6. φ = EGγ: hier werden diejenigen Zustände markiert, von denen aus ein Pfad<br />
existiert, entlang dessen nur die mit γ markierten Zustände vorkommen. Um solche<br />
Pfade zu finden, wird aus der Kripke-Struktur eine reduzierte Kripke-Struktur<br />
K ′ = (W ′ , R ′ , η ′ ) konstruiert, in die nur die mit γ markierten Zustände aus W und<br />
zugehörige Relationen aufgenommen werden. Formal: W ′ = {w ∈ W, γ ∈ label(w)},<br />
R ′ = R∣W ′ ×W ′ und η′ = η∣W ′. K′ wird mit Hilfe des Algorithmus von Tarjan<br />
[AHU74] in nicht triviale Zusammenhangskomponenten zerlegt. Eine Zusammenhangskomponente<br />
(strong connected component) C ist ein maximaler Teilgraph,<br />
in dem jeder Knoten in C von jedem anderen Knoten aus C über einen gerichteten<br />
16
3 <strong>Model</strong>-<strong>Checking</strong> <strong>für</strong> <strong>CTL</strong><br />
komplett in C verlaufenden Pfad erreichbar ist. C ist nicht trivial, falls sie entweder<br />
aus mehr als einem Knoten oder aus nur einem Knoten mit einer Selbstschleife<br />
besteht (C = {v ∈ W ′ }, (v, v) ∈ R ′ ). Nachdem K ′ partitioniert wurde, wird nach<br />
den Zuständen gesucht, die zu nicht trivialen Zusammenhangskomponenten gehören.<br />
Dabei wird rückwärts über R ′ abgearbeitet, und die erforderlichen Zustände<br />
werden markiert. Diesen Fall stellt Algorithmus 2 dar.<br />
Algorithmus 2 Procedure CheckEG K, w0 ⊧ ϕ<br />
Eingabe: eine Kripke-Struktur K = (W, R, η), w0 ∈ W , ϕ = EGα<br />
1: S ′ ← {s ∣ α ∈ label(s)}<br />
2: SCC ← {C ∣ C is a nontrivial SCC of S ′ }<br />
3: T ← ⋃C∈SCC{s ∣ s ∈ C}<br />
4: for all s ∈ T do<br />
5: label(s) ← label(s) ∪ {EGα}<br />
6: end for<br />
7: while T is not empty do<br />
8: choose s ∈ T<br />
9: T ← T /{s}<br />
10: for all t such that t ∈ S ′ and (t, s) ∈ R do<br />
11: if ϕ ∉ label(t) then<br />
12: label(t) ← label(t) ∪ {EGα}<br />
13: T ← T ∪ {t}<br />
14: end if<br />
15: end for<br />
16: end while<br />
Das Abarbeiten jeder der Teilformeln von ϕ benötigt O(∣W ∣ + ∣R∣)-Zeit 2 . Die Komplexität<br />
des gesamten Algorithmus beträgt somit O(∣ϕ∣ ⋅ (∣W ∣ + ∣R∣)) (Polynomialzeit),<br />
wobei ∣ϕ∣ die Anzahl der verschiedenen Teilformeln von ϕ ist.<br />
3.3.2 <strong>CTL</strong>pos -MC(EX, EG, EU, ER)<br />
Es ist bemerkenswert, dass sich jede obere Grenze <strong>für</strong> <strong>CTL</strong>-MC(T ) auch auf<br />
<strong>CTL</strong>pos -MC(T ) (<strong>für</strong> alle T ) übertragen lässt. Dennoch lässt sich die Komplexität von<br />
<strong>CTL</strong>pos-MC(T ) verbessern, wenn in T nur bestimmte Operatoren verwendet werden (vgl.<br />
[BMT + 09]). Dies ist eine zentrale Idee bei der Untersuchung des <strong>CTL</strong>pos-Fragmentes. Außerdem<br />
steht im Hintergrund die Eigenschaft von LOGCFL-Sprachen, dass sie sich mit<br />
einer nichtdeterministischen Turing Maschine in Polynomialzeit entscheiden lassen, die<br />
ein Arbeitsband logarithmischer Größe und einen unendlichen Stack besitzt. In diesem<br />
2 Im ersten Fall wird O(∣W ∣ + ∣AP ∣)-Zeit beansprucht, aber es wird angenommen, dass das zu analysierende<br />
System in Bezug auf das Zusammenspiel zwischen den Komponenten(|R|) im Vergleich zu der<br />
Anzahl der Eigenschaften des Systems (|AP |) genügend komplex ist. Deswegen wird die Komplexität<br />
auf O(∣W ∣ + ∣R∣) verallgemeinert.<br />
17
3 <strong>Model</strong>-<strong>Checking</strong> <strong>für</strong> <strong>CTL</strong><br />
Abschnitt wird aber ein in Exponentialzeit arbeitender Algorithmus <strong>CTL</strong>pos-MC(T ) vorgestellt,<br />
der dem in Abschnitt 3.3.1 aufgeführten Algorithmus <strong>CTL</strong>-MC(T ) in Bezug auf<br />
ihre Effizienz weiter unten gegenübergestellt wird.<br />
Satz 3.3.2 Sei T eine Menge von <strong>CTL</strong>-Operatoren, so dass alle Operatoren in T existenziell<br />
oder alle Operatoren in T universal sind. Dann ist <strong>CTL</strong>pos-MC(T) ∈ P.<br />
Als Erstes wird der Fall betrachtet, dass in T nur existenzielle Operatoren erhältlich<br />
sind. O. B. d. A. sei T ∈ {EX, EG, EU, ER}. Es wird behauptet, dass Algorithmus 3<br />
entscheidet, ob die Kripke-Struktur K = (W, R, η) die <strong>CTL</strong>pos(T )-Formel ϕ im Zustand<br />
w0 ∈ W erfüllt. S sei ein Stack zum Speichern von Paaren (ϕ, w) ∈ <strong>CTL</strong>pos(T ) × W .<br />
Jede Formel wird ähnlich wie im <strong>CTL</strong>-MC(ALL)-Algorithmus abgearbeitet. Sie wird<br />
je nach dem verwendeten Operator in die Teilformeln zerlegt und entsprechend behandelt.<br />
Ein deutlicher Unterschied liegt in dem Fall vor, wenn eine Pfad-Formel überprüft<br />
werden muss, z. B. ϕ = EGα oder ϕ = E(αUβ). Hier muss ein Pfad aus allen möglichen<br />
aus dem betrachteten Zustand ausgehenden Pfaden nichtdeterministisch gefunden werden.<br />
α wird dann in jedem Zustand entlang dieses Pfades geprüft. Im <strong>CTL</strong>-MC(ALL)-<br />
Algorithmus werden <strong>für</strong> solche Formeln erst die Zustände gefunden, in denen α erfüllt<br />
wird. Danach werden aus diesen Zuständen starke Zusammenhangskomponenten und<br />
aus diesen Ergebnispfade konstruiert.<br />
Die Konstruktion des Algorithmus macht die oben erwähnte Eigenschaft der LOGCFL-<br />
Sprachen erkennbar. Der Algorithmus lässt sich mit einer Turing Maschine mit einem<br />
Stack und einem Arbeitsband logarithmischer Größe entscheiden. Wenn der Algorithmus<br />
in Polynomialzeit arbeiten würde, dann könnte man das Problem<br />
<strong>CTL</strong>pos-MC(EX, EG, EU, ER) zu LOGCFL-Sprachen einordnen. Das ist aber <strong>für</strong> den<br />
Fall ϕ = EGα oder ϕ = E(αUβ) unmöglich. Das Problem liegt <strong>für</strong> die Formeln vor, die<br />
nach dem folgenden Schema geschachtelt sind. Sei ϕ = EGα0, wobei α0 eine Formel ist,<br />
die als Teilformel EGα1 enthält usw. Z. B. ϕ = EG(x0∨EG(x1∧EG(x2...))). Für jede<br />
Teilformel αi,i=0,... wird ein neuer Pfad geraten und jeweils |W|-mal auf den Stack gelegt.<br />
Analog gilt dies auch <strong>für</strong> die EU-Formeln. Dies führt zum exponentiellen Bedarf in der<br />
Stackgröße. Der Algorithmus benötigt exponentielle und nicht mehr polynomielle Zeit,<br />
wie es bei LOGCFL gefordert wird. ER-Formeln stellen eine Kombination von EG- und<br />
EU-Formeln dar. EX-Formeln können polynomiell mit der Turing Maschine abgearbeitet<br />
werden. Die übrigen Formeln repräsentieren Trivialfälle. Für die EG-, EU-Formeln<br />
besitzt der Algorithmus folgende Komplexität. Um alle Pfade abzuarbeiten, braucht<br />
man O(2 n ) Zeit. Bei geschickter Implementierung mit dem direkten Zugriff auf Teilformeln<br />
im Stack ergibt sich O(2 log(n) ) = O(n O(1) ) Bedarf. Folglich ist der Algorithmus <strong>für</strong><br />
<strong>CTL</strong>pos-MC(EX, EG, EU, ER) theoretisch polynomiell.<br />
Die Tatsache, dass der Algorithmus immer terminiert, folgt daraus, dass jede Teilformel<br />
von ϕ nicht mehr als |W |-mal im Stack S gespeichert wird. Außerdem zeigt die<br />
Induktivität der Struktur von Formeln, dass der Algorithmus genau dann false zurückgibt,<br />
wenn <strong>für</strong> alle aus dem Stack S geladenen Paare (φ, w) K, w ⊭ φ gilt. Folglich<br />
terminiert der Algorithmus mit true, genau dann wenn K, w ⊧ ϕ.<br />
18
Algorithmus 3 Entscheide, ob K, w ⊧ ϕ<br />
Eingabe: eine Kripke-Struktur K = (W, R, η), w0 ∈ W , ϕ ∈ <strong>CTL</strong>pos (T)<br />
Ausgabe: true (falls K, w ⊧ ϕ) oder false (sonst)<br />
1: push(S, (ϕ, w0))<br />
2: while S is not empty do<br />
3: (ϕ, w) ← pop(S)<br />
4: if ϕ is a propositional formula then<br />
5: if ϕ evaluates to false in w under η then<br />
6: return false<br />
7: end if<br />
8: else if ϕ = α ∧ β then<br />
9: push(S, (β, w))<br />
10: push(S, (α, w))<br />
11: else if ϕ = α ∨ β then<br />
12: nondet. push(S, (α, w)) or push(S, (β, w))<br />
13: else if ϕ = EXα then<br />
14: nondet. choose w ′ ∈ {w ′ ∣ (w, w ′ ) ∈ R}<br />
15: push(S, (α, w ′ ))<br />
16: else if ϕ = EGα then<br />
17: guess a path (wi)1≤i≤∣W ∣ such that w1 = w<br />
18: for all 1 ≤ i ≤ ∣W ∣ do<br />
19: push(S, (α, wi))<br />
20: end for<br />
21: else if ϕ = E(αUβ) then<br />
22: guess k ≤ ∣W ∣ and a path (wi)1≤i≤k such that w1 = w<br />
23: for all 1 ≤ i < k do<br />
24: push(S, (α, wi))<br />
25: end for<br />
26: push(S, (β, wk))<br />
27: else if ϕ = E (αRβ) then<br />
28: guess γ ∈ {EGβ, E(βU(α ∧ β))}<br />
29: push(S, (γ, w))<br />
30: end if<br />
31: end while<br />
32: return true<br />
19<br />
3 <strong>Model</strong>-<strong>Checking</strong> <strong>für</strong> <strong>CTL</strong>
3 <strong>Model</strong>-<strong>Checking</strong> <strong>für</strong> <strong>CTL</strong><br />
Bei der Implementierung dieses Algorithmus kollidiert man mit den Problemen, die<br />
sich durch den in den Zeilen 12, 14, 17, 22, 28 vorkommenden Nichtdeterminismus bekunden.<br />
Außerdem, um bessere Effizienz zu erreichen, müssen die Pfade in den Zeilen<br />
15, 19, 24 auf dem Stack knotenweise und nicht als Ganzes gespeichert und bearbeitet<br />
werden. Diese sowie weitere Besonderheiten bezüglich der Implementierung werden in<br />
Kapitel 4 besprochen.<br />
Der Fall, wenn alle Operatoren in T universal sind, folgt aus Abgeschlossenheit von P<br />
unter dem Komplement und kann analog gelöst werden (Eϕ ≡ ¬A¬ϕ).<br />
20
4 Design und Implementierung<br />
Im vorigen Kapitel wurden die <strong>Model</strong>-<strong>Checking</strong>-Algorithmen <strong>für</strong> <strong>CTL</strong>-MC(ALL) und<br />
<strong>CTL</strong>pos-MC(EX, EG, EU, ER) präsentiert. Diese werden im Rahmen dieser Diplomarbeit<br />
in Java implementiert. In diesem Kapitel werden Implementierungsaspekte erläutert.<br />
Dabei wird ein existierendes Programm um weitere Funktionalitäten erweitert. Dieses<br />
Programm wird in Abschnitt 4.1 vorgestellt. Die ausführliche Beschreibung findet man<br />
in [Sol09]. Die geänderte Klassenstruktur und die neuen Möglichkeiten des Programms<br />
werden auch in diesem Kapitel veranschaulicht.<br />
4.1 Basisprogramm<br />
Als Basis wurde ein Programm verwendet, das im Rahmen einer anderen Diplomarbeit<br />
am <strong>Institut</strong> <strong>für</strong> theoretische Informatik der Leibniz Universität Hannover entstanden ist.<br />
Dieses Programm wurde mit dem Ziel entwickelt, einige <strong>Model</strong>-<strong>Checking</strong>-Algorithmen<br />
<strong>für</strong> LTL zu realisieren. Die Benutzeroberfläche des Hauptfensters ist in Abbildungen 4.1<br />
zu sehen.<br />
Das Hauptfenster besteht aus drei Bereichen, die sich auf Kripke-Struktur, Formel<br />
und Algorithmen beziehen. In jedem Bereich gibt es Buttons zum Aufrufen diverser<br />
Aufgaben und ein Textfeld, in dem eine Kripke-Struktur, eine Formel oder Ergebnisse der<br />
Algorithmen veranschaulicht werden. Folgende Funktionalitäten sind bereits vorhanden:<br />
• Erstellung einer neuen Kripke-Struktur bzw. einer neuen Formel;<br />
• Speicherung einer Kripke-Struktur bzw. einer Formel in einer Datei;<br />
• Laden einer Kripke-Struktur bzw. einer Formel aus einer Datei;<br />
• Zeichnen einer Kripke-Struktur;<br />
• Starten der <strong>Model</strong>-<strong>Checking</strong>-Algorithmen <strong>für</strong> LTL angewendet auf die erstellte/geladene<br />
Kripke-Struktur und die erstellte/geladene Formel.<br />
Die implementierte Datenstruktur, die eine Kripke-Struktur repräsentiert, und alle zugehörigen<br />
Funktionalitäten werden übernommen. Die Visualisierung der Kripke-Struktur<br />
wird überarbeitet und um einige Funktionen ergänzt. Da das Basisprogramm speziell<br />
<strong>für</strong> das <strong>Model</strong>-<strong>Checking</strong> <strong>für</strong> LTL entwickelt wurde, müssen die Operationen zur Bearbeitung<br />
der Formeln angepasst und erweitert werden, um <strong>CTL</strong>-Formeln zu erfassen, um die<br />
in dieser Arbeit auszuarbeitenden <strong>Model</strong>-<strong>Checking</strong>-Algorithmen verwenden zu können.<br />
Weiter unten werden diese und andere Erweiterungen des Basisprogramms erörtert.<br />
21
4 Design und Implementierung<br />
Abbildung 4.1: Das Hauptfenster des Basisprogramms (Bild aus [Sol09])<br />
4.2 Neue Klassenstruktur und die<br />
Implementierungsaspekte<br />
In diesem Abschnitt wird die erweiterte Klassenstruktur des Programms erläutert. Abbildung<br />
4.2 stellt die Programmlogik dar, und Abbildung 4.3 zeigt die Klassenstruktur der<br />
Benutzerschnittstelle. Die <strong>für</strong> diese Arbeit relevanten Klassen des Basisprogramms werden<br />
ohne Attribute bzw. Operationen abgebildet. Die komplett übernommenen Klassen<br />
sind in schwarz und die erweiterten Klassen sind in grün dargestellt. Die neuen Klassen<br />
sind in blau hervorgehoben. Die get- und set-Methoden werden übersichtshalber nicht<br />
dargestellt.<br />
22
#not: boolean<br />
#and: boolean<br />
#or: boolean<br />
#EX: boolean<br />
#EG: boolean<br />
#EU: boolean<br />
#ER: boolean<br />
Formula<strong>CTL</strong>pos<br />
+isProposition(): boolean<br />
+stringToFormula(String): Formula<strong>CTL</strong>pos<br />
+stringInPrefixToFormula(String): Formula<strong>CTL</strong>pos<br />
+formulaToString(): String<br />
+formulaToStringInPrefix(): String<br />
#getIndexOfMainOperator(String): int<br />
-modifyAccordingDeMorgan()<br />
-getToken(String): String<br />
<strong>Model</strong><strong>Checking</strong><strong>CTL</strong>pos<br />
-formula<strong>CTL</strong>pos: Formula<strong>CTL</strong>pos<br />
-kripke: Kripke<br />
-state: State<br />
-paths: ArrayList<br />
-result: boolean<br />
+model<strong>Checking</strong><strong>CTL</strong>posArrayList(Kripke,Formula<strong>CTL</strong>pos,<br />
State): boolean<br />
+model<strong>Checking</strong><strong>CTL</strong>posTree(Kripke,Formula<strong>CTL</strong>pos,<br />
State): boolean<br />
State<br />
-key: int<br />
-name: String<br />
-initial: boolean<br />
-propositions: String[]<br />
-transitions: ArrayList<br />
-computaionTree : TreeNode<br />
-paths: ArrayList<br />
-index: int<br />
-lowLink: int<br />
...()<br />
+evaluatePropositionalFormula(Formula<strong>CTL</strong>Pos): booelan<br />
+getPredecessorStates(Kripke): HashMap<br />
+getSuccStates(Kripke): int[]<br />
+formPaths(int,Kripke)<br />
+createComputationTree(Kripke): TreeNode<br />
0..1<br />
TreeNode<br />
-value: T<br />
-parent: TreeNode<br />
-leftChild: TreeNode<br />
-rightSibling: TreeNode<br />
-depth: int<br />
0..2<br />
+addChild(T): TreeNode<br />
+addRightSibling(T): TreeNode<br />
+getChildren(): ArrayList<br />
Proposition<br />
1..*<br />
2<br />
0..1<br />
1..*<br />
1<br />
-EF: boolean<br />
-AF: boolean<br />
-AX: boolean<br />
-AG: boolean<br />
-AU: boolean<br />
-AR: boolean<br />
4 Design und Implementierung<br />
0..2<br />
Formula<strong>CTL</strong><br />
+isProposition(): boolean<br />
+stringToFormula(String): Formula<strong>CTL</strong><br />
+stringInPrefixToFormula(String): Formula<strong>CTL</strong><br />
+formulaToString(): String<br />
+formulaToStringInPrefix(): String<br />
+convert()<br />
-getToken(String)<br />
<strong>Model</strong><strong>Checking</strong><strong>CTL</strong><br />
-formula<strong>CTL</strong>: Formula<strong>CTL</strong><br />
-kripke: Kripke<br />
-labeledStates: HashMap<br />
+model<strong>Checking</strong><strong>CTL</strong>(Formula<strong>CTL</strong>): HashMap<br />
-checkPropositions(Proposition): HashMap<br />
-checkNot(HashMap): HashMap<br />
-checkOr(HashMap,HashMap): HashMap<br />
-checkEX(HashMap): HashMap<br />
-checkEU(HashMap,HashMap): HashMap<br />
-checkEG(HashMap): HashMap<br />
-getSCC(HashMap): ArrayList<br />
Kripke<br />
-...<br />
-allTransVector: ArrayList<br />
...()<br />
+edit()<br />
+createRandomKripke(int,int,int)<br />
-getRandomPropositions(int): String[]<br />
1<br />
Transition<br />
Abbildung 4.2: Klassendiagramm <strong>für</strong> Programmlogik<br />
23
State<br />
Formula<strong>CTL</strong>pos<br />
<strong>Model</strong><strong>Checking</strong><strong>CTL</strong>pos<br />
SettingsFrame<br />
-formulaFile: File<br />
-kripkeFile: File<br />
+loadProperties()<br />
+saveProperties()<br />
Kripke-Struktur<br />
Formula<strong>CTL</strong><br />
<strong>Model</strong>Checker<strong>CTL</strong><br />
-formula<strong>CTL</strong>: Formula<strong>CTL</strong><br />
-formula<strong>CTL</strong>pos: Formula<strong>CTL</strong>pos<br />
-kripke: Kripke<br />
-result: boolean<br />
-selectedStates: ArrayList<br />
+labelTrueStatesInGraph()<br />
-getStatesList(): ArrayList<br />
-setClickedStatesInGraph(ArrayList)<br />
Kripke<br />
Formula<br />
<strong>Model</strong>Checker<br />
<strong>Model</strong>Check<br />
4 Design und Implementierung<br />
<strong>Model</strong><strong>Checking</strong><strong>CTL</strong><br />
Abbildung 4.3: Klassendiagramm der Benutzerschnittstelle<br />
GraphVisualization<br />
+draw(Kripke)<br />
+saveImage(Kripke)<br />
Die Klasse Kripke stellt eine Kripke-Struktur als eine Liste von Zuständen dar, die<br />
mittels der Klasse State realisiert werden. Jeder Zustand hat eine eindeutige Identifikationsnummer,<br />
einen Namen und eine Liste der atomaren Aussagen, die in diesem<br />
Zustand gelten. Das Attribut initial gibt an, ob ein Zustand der Startzustand in der<br />
Kripke-Struktur ist. Übergänge zwischen den Zuständen in der Kripke-Struktur werden<br />
mittels der Klasse Transition gespeichert. Neben den übernommenen Funktionalitäten,<br />
die Kripke-Struktur zu erstellen/speichern/laden, kann sie jetzt auch geändert werden<br />
(edit()). Außerdem wird ermöglicht, eine zufällige Kripke-Struktur generieren zu lassen<br />
(createRandomKripke(int, int, int)). Als Argumente werden die Anzahl von Zuständen<br />
S, die Anzahl von Übergängen T , die aus jedem Zustand ausgehen, sowie die maximale<br />
Anzahl von atomaren Aussagen P , die jedem Zustand zugeordnet werden. Die Generierung<br />
geschieht folgendermaßen.<br />
1. Es wird eine Menge der Größe S von Zuständen erzeugt. Als Namen werden die<br />
natürliche Zahlen vergeben.<br />
2. Jedem Zustand werden Übergänge hinzugefügt. Die Anzahl der Übergänge T ist<br />
<strong>für</strong> jeden Zustand fest. Die Endzustände von Übergängen werden mittels einer<br />
Zufallsfunktion ermittelt.<br />
24
4 Design und Implementierung<br />
3. Jeder Zustand wird mit einer Menge von atomaren Aussagen beschriftet. Diese<br />
werden auch zufällig mittels getRandomPropositions(int) generiert. Als atomare<br />
Aussagen werden hier die Buchstaben des lateinischen Alphabets verwendet. Das<br />
heißt, dass jeder Zustand maximal 26 atomare Aussagen haben kann. Für jeden<br />
Buchstaben wird eine Zufallszahl generiert. Wenn diese Zahl größer als 0,5 ist,<br />
wird dieser Buchstabe dem aktuellen Zustand zugeordnet. Der letzte mögliche<br />
Buchstabe entspricht dem übergebenen Parameter P . Mit anderen Worten: jeder<br />
Zustand wird mit keinen oder mit maximal S ersten Buchstaben des lateinischen<br />
Alphabets beschriftet.<br />
Die Klasse State wurde um die Attribute index und lowLink erweitert, die den Aufbau<br />
von den <strong>für</strong> Algorithmus 2 notwendigen Zusammenhangskomponenten ermöglichen. Eine<br />
weitere relevante Methode getPredecessorStates(Kripke), die zu einem Zustand sämtliche<br />
direkten Vorfahren findet, wird auch in dieser Klasse implementiert. Mittels der Methode<br />
evaluatePropositionalFormula(Formula<strong>CTL</strong>pos) wird überprüft, ob eine <strong>CTL</strong>pos-Formel,<br />
in der keine <strong>CTL</strong>-Operatoren, sondern nur die booleschen Operatoren {¬, ∧, ∨} vorhanden<br />
sind, in dem aktuellen Zustand erfüllt wird.<br />
Algorithmus 3 benötigt bei der Analyse von EG-, EU-Formeln aus einem Zustand<br />
ausgehende Pfade. Diese können mittels der vom Basisprogramm übernommenen Methoden<br />
getSuccStates(Kripke) und formPaths(int, Kripke) ermittelt werden. formPaths(...)<br />
konstruiert solche Pfade. Jeder Pfad ist eine Liste von Zuständen. Alle aus einem Zustand<br />
ausgehenden Pfade werden als eine Liste von solchen Listen gespeichert. In Abschnitt<br />
3.3.2 wurde erwähnt, dass man eine bessere Effizienz erreichen kann, wenn Zustände auf<br />
den Pfaden knotenweise gespeichert werden. Um dies zu ermöglichen, wurde die Klasse<br />
TreeNode entwickelt, die einen Baum als Datenstruktur realisiert und alle nötigen<br />
Methoden bereitstellt. Jeder Zustand ist ein Knoten im Baum. Die von ihm erreichbaren<br />
Zustände sind seine Kinderknoten usw. Die Methode createComputationTree(Kripke)<br />
erzeugt einen Berechnungsbaum, in dem alle ausgehenden Pfade durch Tiefendurchlauf<br />
rekonstruiert werden können. In der Instanzvariable computaionTree wird der Wurzelknoten<br />
des Berechnungsbaumes gepeichert. Algorithmus 3 wird zweimal implementiert,<br />
um die beiden Möglichkeiten zu vergleichen, Pfade als Liste von Listen und als einen<br />
Baum abzuarbeiten.<br />
<strong>CTL</strong>-Formel<br />
<strong>CTL</strong>-Formeln werden im Hinblick auf Definition 2.3.1 mit Hilfe der Klassen Proposition,<br />
Formula<strong>CTL</strong>pos und Formula<strong>CTL</strong> implementiert. Jede <strong>CTL</strong>-Formel ist eine Instanz<br />
der Klasse Formula<strong>CTL</strong>pos bzw. Formula<strong>CTL</strong> und besteht aus <strong>CTL</strong>-Teilformeln, die<br />
in einer Liste gespeichert werden. Der verwendete Operator wird registriert, indem das<br />
entsprechende Attribut der Klasse Formula<strong>CTL</strong>pos bzw. Formula<strong>CTL</strong> auf ” wahr“<br />
gesetzt wird. Dabei gelten die üblichen Prioritätsregeln, und alle binären Operatoren<br />
sind linksassoziativ. Jede Formel mit einem binären Operator (z. B. OR, AND, EU,<br />
AR) wird somit als eine Liste mit zwei Elementen und jede Formel mit einem unären<br />
Operator (z. B. NOT, EX, AG) mit einem Element dargestellt.<br />
25
4 Design und Implementierung<br />
Die einfachste Form einer <strong>CTL</strong>-Formel ist eine atomare Aussage. Solche Formel wird<br />
als eine Liste mit einem Element, einer Instanz der Klasse Proposition, erzeugt. Alle<br />
Attribute werden in diesem Fall mit ” falsch“ initialisiert. Formeln dieser Art können mit<br />
Hilfe der Methode isProposition() identifiziert werden.<br />
Jede Formula<strong>CTL</strong>pos- oder Formula<strong>CTL</strong>-Formel besteht folglich entweder aus<br />
einem Objekt der Klasse Proposition oder aus einer Liste mit einem oder zwei Objekten<br />
der Klasse Formula<strong>CTL</strong>pos bzw. Formula<strong>CTL</strong>.<br />
Durch die Klasse Formula<strong>CTL</strong>pos können <strong>CTL</strong>pos-Formeln erzeugt werden, in denen<br />
<strong>CTL</strong>-Operatoren nicht negiert werden dürfen. Außerdem ist die Menge der <strong>CTL</strong>-<br />
Operatoren auf die Menge {EX, EG, EU, ER} eingeschränkt, da nur diese <strong>für</strong> den Algorithmus<br />
3 benötigt werden. Die Klasse Formula<strong>CTL</strong> enthält sowohl die von<br />
Formula<strong>CTL</strong>pos geerbten Attribute als auch weitere Attribute, die es zusammen<br />
ermöglichen, beliebige <strong>CTL</strong>-Formeln zu bilden. Die Formeln können über eine Benutzerschnittstelle<br />
in textueller Form in der Infix- oder Präfix-Notation eingegeben werden.<br />
Das Erstellen der Formeln aus dem Eingabetext geschieht mittels der Methoden<br />
StringToFormula(String) und StringInPrefixToFormula(String). Dies erfolgt, indem die<br />
Eingabe analysiert wird und ein Operator der Formel mittels der<br />
getIndexOfMainOperator(String) und getToken(String) gefunden wird. Folglich werden<br />
die Teilformeln der Formel ermittelt, die weiterhin analog in ” die Tiefe“ geparst werden.<br />
Die Konvertierung in die andere Richtung passiert mittels FormulaToString() bzw.<br />
FormulaToStringInPrefix().<br />
Die Methode modifyAccordingDeMorgan() bringt eine <strong>CTL</strong>pos -Formel nach den De<br />
Morganschen Gesetzen in so eine Form, dass die Negationen nur direkt von den atomaren<br />
Aussagen stehen. Diese Umwandlung vereinfacht die Auswertung der Formel in<br />
Algorithmus 3: K, w0 ⊧ ¬p, wenn p ∈ AP und p ∉ η(w0). Dies ermöglicht die Methode<br />
evaluatePropositionalFormula(Formula<strong>CTL</strong>pos) in der Klasse State.<br />
Die Methode convert() in der Klasse Formula<strong>CTL</strong> wandelt eine <strong>CTL</strong>-Formel in eine<br />
äquivalente um, die aus atomaren Aussagen und den Operatoren ¬, ∨, EX, EU und<br />
EG besteht. Diese Methode ist <strong>für</strong> <strong>CTL</strong>-MC(ALL) von großer Bedeutung, da diese Operatoren<br />
eine minimale Menge der Operatoren bilden, um alle möglichen <strong>CTL</strong>-Formeln<br />
konstruieren zu können. Die Konvertierung erfolgt mittels der in der Tabelle 2.3 aufgeführten<br />
Regeln.<br />
Algorithmen<br />
Die Klassen <strong>Model</strong><strong>Checking</strong><strong>CTL</strong>pos und <strong>Model</strong><strong>Checking</strong><strong>CTL</strong> bilden den Kern des<br />
Programms. Sie enthalten nämlich die <strong>Model</strong>-<strong>Checking</strong>-Algorithmen <strong>CTL</strong>pos -MC(EX,<br />
EG, EU, ER) bzw. <strong>CTL</strong>-MC(ALL).<br />
Um den <strong>CTL</strong>pos-Algorithmus ausführen zu können, müssen eine Kripke-Struktur, ein<br />
Zustand in der Kripke-Struktur und eine zu prüfende <strong>CTL</strong>pos-Formel bekannt sein. Diese<br />
Argumente werden in den entsprechenden Instanzvariablen gespeichert. Die Methoden<br />
model<strong>Checking</strong><strong>CTL</strong>posArrayList(Kripke, Formula<strong>CTL</strong>pos, State) und model<strong>Checking</strong>-<br />
<strong>CTL</strong>posTree(Kripke, Formula<strong>CTL</strong>pos, State) stellen die zwei oben vorgestellten Implementierungsmöglichkeiten<br />
des Algorithmus 3 dar. Die Ergebnisse des <strong>Model</strong>-<strong>Checking</strong>s<br />
26
4 Design und Implementierung<br />
werden in den Variablen result und paths gespeichert. result wird auf ” wahr“ gesetzt,<br />
falls die Kripke-Struktur kripke die Formel formula<strong>CTL</strong>pos im Zustand state erfüllt. In<br />
Abhängigkeit davon, ob es um eine Zustands- oder Pfad-Formel handelt, werden in paths<br />
Zustände bzw. Pfade verfasst, in denen die Erfüllbarkeit vorliegt.<br />
In Abschnitt 3.3.2 wurden die Implementierungsschwierigkeiten des Algorithmus 3<br />
erwähnt. Hier liegt das Problem vor, dass man nichtdeterministisch mehrere Teilformeln<br />
oder Zustände abarbeiten ( ” nondet. choose“) oder aus mehreren einen Pfad oder<br />
einen Zustand aussuchen ( ” guess“) muss, in denen eine bestimmte Eigenschaft – d. h.<br />
eine Formel – erfüllt wird. Dieser Nichtdeterminismus wird durch die Überprüfung jeder<br />
Teilformel, jedes Zustandes und jedes Pfades der Reihe nach ersetzt, die in Frage<br />
kommen. Da es sich um die existentiellen Formeln handelt, kann man die Abarbeitung<br />
abbrechen, sobald eine Forderung (ein Zustand <strong>für</strong> die EX- oder ein Pfad <strong>für</strong> die EGbzw.<br />
EU-Formeln) erfüllt wurde. Im schlimmsten Fall müssen aber alle Kandidaten<br />
überprüft werden.<br />
Betrachten wir den Fall ϕ = EGα. Wenn man alle aus einem Zustand w0 ausgehenden<br />
Pfade betrachtet, hat man die exponentielle Anzahl von Möglichkeiten: ∣T ∣ ∣T ∣ , wobei<br />
∣T ∣ die Anzahl aus einem Zustand ausgehender Übergänge ist. Die Laufzeit der Abarbeitung<br />
der Pfade ist entsprechend groß. Wenn die Pfade als ArrayList<br />
gespeichert sind, wird jeder Pfad vom ersten bis zum letzten Zustand auf die Erfüllbarkeit<br />
der Formel α geprüft. Die Situation ändert sich, wenn die Pfade in einem Baum<br />
gefasst sind. Abbildung 4.4 zeigt diese zwei Abarbeitunsmöglichkeiten. Oben ist eine<br />
Kripke-Struktur dargestellt. Die Zustände sind mit den atomaren Aussagen versehen.<br />
Sei ϕ = EGa. Unten links ist die Liste mit den Pfaden, rechts davon ist der entsprechende<br />
Berechnungsbaum. Die Pfade sowie der Berechnugsbaum sind unendlich, werden<br />
aber auf die Anzahl von Zuständen in der Kripke beschränkt, da die Pfade sonst einen<br />
Zyklus enthalten. Der gestrichelte Pfeil zeigt die Reihenfolge, in der die Zustände überprüft<br />
werden, ob die Formel α = a in diesen gilt. Bei der zweiten Implementierung wird<br />
nach einem ” falschen“ Zustand, in dem die Teilformel α nicht gilt, zu seinem rechten<br />
Geschwister übergegangen. Das wird solange durchgeführt, bis es noch solche vorhanden<br />
sind und noch kein Pfad gefunden wurde. Dies wird mittels des iterativen Tiefendurchlaufs<br />
(siehe [AUH82]) realisiert, bei dem zu jedem Knoten seine rechten Geschwister in<br />
einem Stack gespeichert werden. Im Gegensatz zu der ersten Implementierung wird somit<br />
die Überprüfung in allen vorherigen Zuständen gespart. Eine weitere Möglichkeit an<br />
der Laufzeit zu gewinnen, ist die Speicherung von Ergebnissen des <strong>Model</strong>-<strong>Checking</strong>s in<br />
den geprüften Zuständen. Das bedeutet, dass nachdem die Zustände ” a“, ” a,b“ und ” b“<br />
geprüft wurden, wird <strong>für</strong> die Formel α = a gespeichert, dass sie in den Zuständen ” a“<br />
und ” a,b“ erfüllt wird. Wenn der zweite Pfad im Baum analysiert wird, muss der <strong>Model</strong>-<br />
<strong>Checking</strong>-Algorithmus im nächsten potenziellen Zustand nicht mehr ausgeführt werden.<br />
Die schon ermittelten Ergebnisse müssen nur gelesen werden. Dieser Ansatz beansprucht<br />
einen zusätzlichen Speicher, vermindert aber die Laufzeit.<br />
Weiterhin setzt der Algorithmus einen Stack ein. Um den Nichtdeterminismus zu lösen,<br />
müssen alle möglichen Zustände bzw. Pfade sowie entsprechende Formeln im Stack<br />
gespeichert werden. Zusätzlich muss der Typ der Formeln bei der Speicherung ihrer Teilformeln<br />
mit angegeben werden, was jedoch <strong>für</strong> die Formeln ohne temporale Operatoren<br />
27
a<br />
a<br />
a,b a,b<br />
a<br />
a<br />
b a,b<br />
Kripke-Struktur<br />
a<br />
b a<br />
a,b a<br />
b<br />
a a,b<br />
ArrayList) hat als Argument eine Menge von Zuständen,<br />
die mit der Teilformel markiert wurden und selektiert diejenigen Zustände<br />
der Kripke-Struktur, die nicht in der Menge sind.<br />
28<br />
a<br />
a
4 Design und Implementierung<br />
• checkOr(HashMap < Number, State >, HashMap < Number, State >) gibt eine Vereinigung<br />
der beiden Argumente zurück.<br />
• checkEX (HashMap < Number, State >) markiert alle direkten Vorfahren von den in<br />
der Argument-Menge enthaltenen Zuständen. Diese werden mit Hilfe der Methode<br />
getPredecessorStates(Kripke) der Klasse State gefunden.<br />
• checkEU (HashMap < Number, State >, HashMap < Number, State >) hat als Argumente<br />
zwei Mengen der Zustände, in denen die erste bzw. die zweite Teilformel<br />
gilt und implementiert den Algorithmus 1.<br />
• checkEG(HashMap < Number, State >) realisiert den Algorithmus 2. Als Erstes<br />
müssen hier alle nicht trivialen Zusammenhangskomponenten von den Zuständen<br />
aus der Argument-Menge gefunden werden. Dies erfolgt mittels der Methode<br />
getSCC (HashMap < Number, State >).<br />
Parallel zur Implementierung werden die entwickelten Datenstrukturen und Algorithmen<br />
mit Hilfe von JUnit ständig getestet.<br />
Benutzerschnittstelle<br />
Im Basisprogramm wird eine Benutzerschnittstelle über die Klasse <strong>Model</strong>Checker realisiert,<br />
die das Hauptfenster des Programms darstellt. Auf dieses werden neue Bedien-<br />
Elemente hinzugefügt, um die neuen Funktionalitäten ansprechen zu können. Außerdem<br />
wird das Fenster benutzerfreundlicher gestaltet, indem ein anderes Swing-Layout, nämlich<br />
das GridBag-Layout, verwendet wird. Alle geänderten bzw. neuen Benutzeroberflächen<br />
werden in Abschnitt 4.3 veranschaulicht.<br />
Die neue Klasse SettingsFrame verwaltet die Benutzereinstellungen. Hierbei kann<br />
man jeweils eine Datei mit einer Kripke-Struktur und einer Formel angeben, die bei<br />
jedem Start des Programms geladen werden.<br />
Im Basisprogramm gab es die Möglichkeit, die Kripke-Struktur mit Hilfe des Frameworks<br />
JUNG 1 in Form eines Graphen zeichnen zu lassen. Die Möglichkeit wird beibehalten,<br />
wird aber mit einer neueren Version (2.0) des Frameworks umgesetzt und um<br />
die neuen Funktionalitäten wie die Skalierung des Graphen und die Verschiebung der<br />
Knoten erweitert. Für diese Funktionalität ist die Methode draw(Kripke) in der Klasse<br />
GraphVisualization verantwortlich. Außerdem werden zu den Knoten entsprechende<br />
atomare Aussagen angezeigt. Die Speicherung des Graphen (saveImage(Kripke)) wird<br />
beibehalten, als Format wird aber PNG statt JPEG benutzt, um die JPEG-Artifakte zu<br />
vermeiden.<br />
Die Klasse <strong>Model</strong>Checker<strong>CTL</strong> stellt die notwendigen Bedienelemente zum Vorbereiten<br />
der zu analysierenden Daten und zum Ausführen der beiden <strong>Model</strong>-<strong>Checking</strong>-<br />
Algorithmen <strong>CTL</strong>-MC(ALL) und <strong>CTL</strong>pos-MC(EX, EG, EU, ER) bereit. Die eingegebene<br />
Formel wird in den Instanzvariablen formula<strong>CTL</strong> und formula<strong>CTL</strong>pos gespeichert, falls<br />
sie den Einschränkungen von <strong>CTL</strong>pos genügt. Die Kripke-Struktur kripke wird hier auch<br />
1 http://jung.sourceforge.net/<br />
29
4 Design und Implementierung<br />
visualisiert, und es besteht die Möglichkeit, die Zustände im Graphen oder in einer Liste<br />
auszuwählen. Diese werden in selectedStates gespeichert. In diesen Zuständen wird die<br />
Formel mittels der Algorithmen überprüft. Nach dem Ablauf der Algorithmen wird das<br />
Ergebnis result ” wahr“, falls die überprüfte Formel in mindestens einem Zustand erfüllt<br />
wird. Die Zustände werden im Graphen mit Hilfe von labelTrueStatesInGraph() farblich<br />
hervorgehoben.<br />
4.3 Bedienungsanleitung zum Programm<br />
In diesem Abschnitt wird eine kurze Anleitung zur Verfügung gestellt, wie das neue<br />
Programm bedient werden kann. Anhand eines Beispiels wird die graphische Benutzeroberfläche<br />
des Programms veranschaulicht. Dabei werden die geänderten und die<br />
neuen Bestandteile akzentuiert. Die vom Basisprogramm übernommenen Komponenten<br />
wurden in Abschnitt 4.1 vorgestellt.<br />
Das geänderte Hauptfenster wird in Abbildung 4.5 dargestellt.<br />
Abbildung 4.5: Das geänderte Hauptfenster des Programms<br />
Die Grundstruktur des Programms wurde in Abschnitt 4.1 beschrieben. Es hat sich<br />
das Layout geändert. Die drei Bereiche <strong>für</strong> Kripke-Struktur, Formel und Algorithmen<br />
wurden durch die Rahmen hervorgehoben. Der Einheitlichkeit halber haben alle Buttons<br />
die gleiche Größe und einen gleichmäßigen Abstand zueinander erhalten.<br />
30
4 Design und Implementierung<br />
Die Einstellungen des Programms sind über das Menü Datei→Einstellungen abrufbar.<br />
In Abbildung 4.6 ist veranschaulicht, dass man die Kripke-Struktur- und Formelenthaltenen<br />
Dateien auswählen kann, die beim Starten des Programms automatisch geladen<br />
werden. Diese Funktionalität kann nützlich sein, wenn man z. B. diverse Formeln<br />
auf einer bestimmten Kripke-Struktur öfters prüfen will oder umgekehrt. Nach dem Betätigen<br />
des OK-Buttons werden die Datei-Namen, falls sie selektiert wurden, in einer<br />
INI-Datei gespeichert und beim nächsten Start des Programms geladen. Die INI-Datei<br />
befindet sich im selben Verzeichnis wie das Programm oder wird erzeugt.<br />
Mittels des Buttons Kripke-Struktur generieren wird ein neuer Dialog geöffnet, in<br />
dem die Anzahl von Zuständen, Übergängen und atomaren Aussagen eingegeben werden<br />
kann. Mit diesen Parametern wird eine zufällige Kripke-Struktur erzeugt.<br />
Abbildung 4.7 zeigt die neue Graph-Visualisierung einer Kripke-Struktur, die sich<br />
über den Button Kripke-Struktur zeichnen im Hauptfenster erscheinen lässt. Jeder<br />
Zustand wird mit seinem Namen sowie mit den atomaren Aussagen beschriftet, die in<br />
diesem Zustand gelten. Es besteht die Möglichkeit, den Kripke-Graphen zu manipulieren.<br />
Durch ” Drag and Drop“ können einzelne sowie mehrere ausgewählte Knoten verschoben<br />
werden. Selektion der Knoten erfolgt durch das An- bzw. Abwählen der Knoten mit dem<br />
linken Mausklick oder durch das Ziehen eines Rechtecks über die interessierenden Zustände.<br />
Mehrfachauswahl geschieht, wenn dazu gleichzeitig eine SHIFT-Taste gedrückt<br />
wird. Skalierung erfolgt mit Hilfe vom Scrollrad. Diese Funktionalitäten sind behilflich,<br />
wenn man mit einer komplexen Kripke-Struktur arbeitet, deren automatische Visualisierung<br />
unübersichtlich vorkommen kann. Die Speicherung des Bildes erfolgt wie im<br />
Basisprogramm über das Menü Datei→Bild speichern.<br />
Abbildung 4.6: Das Fenster mit den Einstellungen des Programms<br />
31
4 Design und Implementierung<br />
Abbildung 4.7: Graphische Darstellung einer Kripke-Struktur<br />
Bei der Erstellung einer neuen <strong>CTL</strong>-Formel ist Folgendes zu beachten. Die temporalen<br />
Operatoren müssen groß und ohne Leerzeichen geschrieben werden (z. B. EX <strong>für</strong> EX<br />
usw.). Eine AU-Formel muss in der Form A(α U β) eingegeben werden. Die gleiche Regel<br />
gilt auch <strong>für</strong> die AR-, EU- und ER-Formeln. Die booleschen Operatoren ¬, ∧ und ∨<br />
sind als ” ∼“, ” AND“ bzw. ” OR“ einzugeben. Alle übrigen Zeichenketten werden als atomare<br />
Aussagen interpretiert. Wenn man mit LTL-Formeln arbeitet, sind die dazu spezifischen<br />
Eingaberegeln zu berücksichtigen, die in [Sol09] aufgeführt sind. Allerdings findet<br />
die Eingabe sämtlicher Formeln im selben Fenster statt, das durch das Betätigen des<br />
Buttons neue Formel erstellen abrufbar ist. Danach wird intern entschieden, ob die<br />
eingegebene Formel die <strong>CTL</strong>-, insbesondere <strong>CTL</strong>pos- und/oder LTL-Kriterien erfüllt. Auf<br />
LTL-Formeln sind die Algorithmen anwendbar, die durch die Buttons <strong>Model</strong>CheckV<br />
und <strong>Model</strong>CheckL aus dem Basisprogramm ausgelöst werden können. Für <strong>CTL</strong>- und<br />
<strong>CTL</strong>pos-Formeln ist ein neu hinzugekommener Button <strong>Model</strong>Check<strong>CTL</strong> vorgesehen.<br />
Folglich wird Benutzer beim Versuch, einen unzulässigen Algorithmus auszuführen, entsprechend<br />
benachrichtigt.<br />
Im Formel-Bereich sind zwei Textfelder zu sehen. Im ersten wird die eingegebene bzw.<br />
geladene Formel angezeigt. Wenn eine <strong>CTL</strong>-Formel vorliegt, wird sie im zweiten Textfeld<br />
in der konvertierten Form dargestellt, in der nur die Operatoren aus der minimalen<br />
Menge {¬, ∨, EX, EU, EG} vorkommen.<br />
32
4 Design und Implementierung<br />
Das Anklicken des <strong>Model</strong>Check<strong>CTL</strong>-Buttons löst das Öffnen eines neuen Fensters<br />
aus, in dem das <strong>Model</strong>-<strong>Checking</strong> <strong>für</strong> <strong>CTL</strong> und insbesondere <strong>für</strong> <strong>CTL</strong>pos gesteuert werden<br />
kann. Abbildung 4.8 repräsentiert dieses Fenster.<br />
Abbildung 4.8: <strong>Model</strong>-<strong>Checking</strong>-Fenster <strong>für</strong> <strong>CTL</strong> vor dem Ausführen des <strong>CTL</strong>-<br />
MC(ALL)-Algorithmus<br />
Hier wird die Kripke-Struktur graphisch dargestellt und kann wie im oben erläuterten<br />
Visualisierungsfenster manipuliert werden. Außerdem werden alle ihre Zustände in einer<br />
Liste aufgezählt. Dies dient dazu, die zu prüfenden Zustände bequem auszuwählen. In<br />
der Liste werden sie mit dem linken Mausklick selektiert und mit einem wiederholten<br />
deselektiert. Wenn die Liste den Fokus besitzt, können alle Zustände durch die Tastenkombination<br />
STRG+A hervorgehoben werden. In Graph-Darstellung werden Zustände<br />
mit einem Doppelklick und bei Mehrfachauswahl mit gedrückter SHIFT-Taste selektiert.<br />
Beim (De-)Selektieren der Zustände in der Liste werden diese auch im Graphen farblich<br />
hervorgehoben und umgekehrt.<br />
Unter der Liste sind zwei Buttons <strong>für</strong> die <strong>CTL</strong>pos-MC(EX, EG, EU, ER)- und <strong>CTL</strong>-<br />
MC(ALL)-Algorithmen zu sehen. Wenn im Hauptfenster eine <strong>CTL</strong>-Formel erstellt/geladen<br />
wurde, die den <strong>CTL</strong>pos -Einschränkungen nicht genügt, wird der Button <strong>Model</strong>-<br />
<strong>Checking</strong><strong>CTL</strong>pos nicht aktiv sein.<br />
33
4 Design und Implementierung<br />
Um den <strong>CTL</strong>pos-Algorithmus starten zu können, muss man mindestens einen zu prüfenden<br />
Zustand auswählen. Für <strong>CTL</strong>-MC(ALL)-Algorithmus wird das nicht verlangt.<br />
Wenn kein Zustand ausgewählt und der Button <strong>Model</strong><strong>Checking</strong><strong>CTL</strong>all betätigt wurden,<br />
wird das Programm es so interpretieren, dass der Algorithmus die Formel überprüft<br />
und als Ergebnis alle Zustände aufzählt, in denen die Formel zu ” wahr“ evaluiert. Dieses<br />
unterschiedliche Verhalten liegt an der Besonderheiten der Funktionsweise von Algorithmen.<br />
Wenn die Algorithmen ausgeführt sind, werden Ergebnisse im Ergebnisfeld ausgegeben.<br />
Außerdem werden die untersuchten Zustände im Graphen grün oder rot markiert,<br />
um die Zustände zu betonen, in denen die Formel erfüllt bzw. nicht erfüllt wird. Das<br />
wird in Abbildung 4.9 veranschaulicht.<br />
Abbildung 4.9: <strong>Model</strong>-<strong>Checking</strong>-Fenster <strong>für</strong> <strong>CTL</strong> nach dem Ausführen des <strong>CTL</strong>-<br />
MC(ALL)-Algorithmus<br />
Der <strong>CTL</strong>pos -Algorithmus liefert nicht nur eine positive und/oder negative Antwort<br />
zu jedem Zustand, sondern auch Zustände <strong>für</strong> Zustand-Formeln oder Pfade <strong>für</strong> Pfad-<br />
Formeln, in denen sie erfüllt werden. Die Abbildungen 4.10 und 4.11 repräsentieren diese<br />
zwei Fälle. In der ersten Zeile in Abbildung 4.11 ist das Ergebnis des <strong>CTL</strong>-MC(ALL)-<br />
Algorithmus zu sehen, der vor dem <strong>CTL</strong>pos-Algorithmus ausgeführt wurde.<br />
34
4 Design und Implementierung<br />
Das Ändern der zu analysierenden Daten findet im Hauptfenster des Programms statt,<br />
in das man durch Schließen des <strong>CTL</strong>-<strong>Model</strong>-<strong>Checking</strong>-Fensters zurückkehrt.<br />
Abbildung 4.10: <strong>Model</strong>-<strong>Checking</strong>-Fenster <strong>für</strong> <strong>CTL</strong> nach dem Ausführen des <strong>CTL</strong>pos -<br />
MC(EX, EG, EU, ER)-Algorithmus <strong>für</strong> eine EX-Formel<br />
Abbildung 4.11: <strong>Model</strong>-<strong>Checking</strong>-Fenster <strong>für</strong> <strong>CTL</strong> nach dem Ausführen des <strong>CTL</strong>pos -<br />
MC(EX, EG, EU, ER)-Algorithmus <strong>für</strong> eine EG-Formel<br />
35
5 Auswertung von Algorithmen<br />
Ziel dieses Kapitels ist es, Laufzeit der vorgestellten Algorithmen anhand der Experimente<br />
zu analysieren und zu vergleichen. Nachdem das Testsystem, Ablauf der Experimente<br />
sowie verwendete Testdaten beschrieben werden, werden die Ergebnisse der Experimente<br />
mit bestimmten Laufzeiten vorgestellt. Die Experimente werden in drei Gruppen eingeteilt,<br />
die den folgenden Zielsetzungen entsprechen:<br />
• Auswertung der Laufzeiten von zwei Implementierungsarten des <strong>CTL</strong>pos-MC(EX,<br />
EG, EU, ER)-Algorithmus 1 : model<strong>Checking</strong><strong>CTL</strong>posArrayList(...) und model-<br />
<strong>Checking</strong><strong>CTL</strong>posTree(...).<br />
• Vergleich der Laufzeiten von <strong>CTL</strong>-MC(ALL)-Algorithmus 2 und von der effizienteren<br />
Implementierung des <strong>CTL</strong>pos-Algorithmus angewendet auf die Formeln des<br />
Fragmentes <strong>CTL</strong>pos(EX, EG, EU, ER) und ” kleine“ Kripke-Strukturen.<br />
• Auswertung des <strong>CTL</strong>-Algorithmus <strong>für</strong> diverse Formeln und ” größere“ Kripke-Strukturen.<br />
5.1 Allgemeine Beschreibung der Experimente<br />
5.1.1 Testsystem<br />
Algorithmen werden auf dem folgenden System getestet:<br />
• CPU: Intel Core Duo T5500 1,66 GHz<br />
• RAM: 1 GB (DDR2 SDRAM)<br />
• Mainboard: ASUSTek Computer Inc. F3JC<br />
• OS: Microsoft Windows XP<br />
• Java: J2SE Version 1.6<br />
1 weiter als ” <strong>CTL</strong>pos-Algorithmus“ genannt<br />
2 weiter als ” <strong>CTL</strong>-Algorithmus“ genannt<br />
36
5.1.2 Testdaten<br />
5 Auswertung von Algorithmen<br />
Zum Testen der Algorithmen werden verschiedene Kripke-Strukturen und Formeln benötigt.<br />
Um allgemeine Auswertung zu ermöglichen, werden zufällig erzeugte Kripke-<br />
Strukturen verwendet. Das Prinzip der Generierung wurde in Abschnitt 4.2 erläutert,<br />
da diese Funktion (createRandomKripke(int, int, int)) zu den Funktionalitäten des Programms<br />
gehört. Für die Experimente werden die Kripke-Strukturen mit unterschiedlicher<br />
Anzahl von Zuständen, Übergängen aus jedem Zustand und atomaren Aussagen<br />
automatisch erzeugt. Alle diese Kennzahlen werden <strong>für</strong> jedes Experiment aufgezeichnet<br />
und mit den Ergebnissen aufgelistet. In den Experimenten, in denen der <strong>CTL</strong>pos<br />
-Algorithmus analysiert wird, werden ” kleine“ Kripke-Strukturen generiert, die aus bis zu<br />
9 Zuständen bestehen. Diese Grenze wurde experimentell herausgefunden und ist genügend,<br />
um festzustellen, ob sich die Vermutung bestätigen lässt, dass die Laufzeit des<br />
<strong>CTL</strong>pos-Algorithmus mit der Anzahl von Zuständen und Übergängen beim Untersuchen<br />
der Pfad-Formeln exponentiell wächst. Bei der Analyse des <strong>CTL</strong>-Algorithmus werden<br />
auch ” größere“ Kripke-Strukturen mit bis zu 300 Zuständen untersucht, da dieser Algorithmus<br />
in Polynomialzeit arbeitet.<br />
Die zu testenden Formeln werden nicht zufällig erzeugt, sondern explizit definiert. Das<br />
ist wichtig, um die Algorithmen in Abhängigkeit von der Art der Formel (Pfad- oder<br />
Zustand-Formel), vom verwendeten Operator und vom Verschachtelungsgrad der Formel<br />
beurteilen zu können.<br />
5.1.3 Ablauf<br />
Jedes Experiment basiert auf folgenden Schritten.<br />
1. Erzeuge eine Kripke-Struktur mit W Zuständen, T Übergängen und maximal P<br />
atomaren Aussagen in jedem Zustand. Je nach Experiment werden verschiedene<br />
Werte <strong>für</strong> W und T eingesetzt. Für alle Experimente wird P = 5 verwendet, da die<br />
Evaluierung einer aussagenlogischen Formel NC 1 -vollständig ist. Deswegen kann die<br />
Laufzeit der Algorithmen durch einen größeren Wert von P nicht beeinträchtigt<br />
werden.<br />
2. Wähle eine Formel ϕ aus den Testformeln (siehe Tabelle 5.1).<br />
3. Für jede Kripke-Struktur und jede Formel ϕ rufe <strong>CTL</strong>pos- und/oder <strong>CTL</strong>-Algorithmus<br />
in jedem Zustand auf.<br />
4. Messe die Laufzeit der Algorithmen. Dabei wird die Methode currentTimeMillis()<br />
aus der Standardklasse java.lang.System benutzt, die die Laufzeit in Millisekunden<br />
misst.<br />
5. Speichere Ergebnisse: charakteristische Kennzahlen der Testdaten W , T , P , die<br />
analysierte Formel ϕ sowie die Laufzeiten von Algorithmen und die Anzahl der zu<br />
” wahr“ evaluierten Zustände. Diese werden in einer .csv-Datei gespeichert, um die<br />
Auswertung zu erleichtern.<br />
37
5 Auswertung von Algorithmen<br />
In manchen Experimenten werden Kripke-Strukturen mit bestimmten Vorgaben (W , T )<br />
mehrmals erzeugt und auf dieselbe Formel angewendet. Das ermöglicht, Ergebnisse mit<br />
verschiedener Anzahl von ” wahr“-Zuständen und mit unterschiedlichen Laufzeiten <strong>für</strong><br />
gleich-große Kripke-Strukturen zu beobachten. Die Kennzahlen von Testdaten sowie die<br />
Anzahl der Durchläufe, in denen solche Kripke-Strukturen erzeugt werden, werden <strong>für</strong><br />
jedes Experiment tabellarisch aufgeführt. Die getesteten Formeln, die Anzahl der ” wahr“-<br />
Zustände sowie die Laufzeiten werden graphisch veranschaulicht. In allen folgenden Abbildungen<br />
stehen auf der Y-Achse Laufzeiten in Millisekunden. In den Abbildungen, in<br />
denen jeweils nur eine Formel dargestellt ist, sind auf der X-Achse drei Reihen von Werten<br />
zu sehen. Die untere bzw. die mittlere Reihe repräsentiert die Anzahl von Zuständen<br />
bzw. Übergängen von generierten Kripke-Strukturen. Die obere Reihe gibt die Anzahl<br />
von ” wahr“-Zuständen an. Diese entfällt <strong>für</strong> die Abbildungen, in denen mehrere Formeln<br />
erfasst sind.<br />
a AND b (EX a) OR (a AND b)<br />
EX a AX a<br />
EG b AG b<br />
E(c U d) A(c U d)<br />
E(c R d) A(c R d)<br />
EF c AF c<br />
EG(e AND EX a) AG(e AND AX a)<br />
EG(EG b) AG(AG b)<br />
∼AG(∼e AND AX a) EG (b OR ∼b)<br />
EX ∼a EX(a AND ∼a)<br />
Tabelle 5.1: Test-Formeln<br />
5.2 Zwei Implementierungen des <strong>CTL</strong>pos -Algorithmus<br />
In diesem Abschnitt werden zwei Implementierungen (ArrayList<br />
und TreeNode) des <strong>CTL</strong>pos-Algorithmus unter der Anwendung der Pfad-Formeln<br />
gegenübergestellt. Hier werden zwei Experimente durchgeführt. In Tabelle 5.2 sind die<br />
Testsparameter sowie die überprüften Formeln aufgelistet. Die Ergebnisse sind in Abbildungen<br />
5.1, 5.2, 5.3 und 5.4 zu sehen.<br />
Im ersten Experiment wird die Laufzeit in Abhängigkeit von der Anzahl der Zustände<br />
gemessen. Im zweiten werden Kripke-Strukturen mit jeweils 9 Zuständen erzeugt. Die<br />
Anzahl der Übergänge wird variiert. Abbildung 5.1 ist ein Ausschnitt aus Abbildung 5.2.<br />
Das Verhalten von beiden Implementierungen ist <strong>für</strong> die Kripke-Strukturen mit bis zu<br />
7 Zuständen ähnlich. Danach wächst die Laufzeit der ” List“-Implementierung exponentiell.<br />
Für größere Kripke-Strukturen steigt die ” Tree“-Implementierung langsamer, aber<br />
auch exponentiell an. Dies ist in den Abbildungen 5.3 und 5.4 ersichtlich, in denen die<br />
Laufzeiten in Abhängigkeit von der Anzahl der Übergänge dargestellt sind. In diesen<br />
38
5 Auswertung von Algorithmen<br />
Abbildungen besteht die Möglichkeit, das Verhalten des Algorithmus in Bezug auf die<br />
Anzahl der zu ” wahr“ evaluierten Zustände zu analysieren, die in der obersten Zeile auf<br />
der X-Achse dargestellt sind.<br />
Wegen der exponentiellen Laufzeit und des Mangels an Ressourcen können ” größere“<br />
Kripke-Strukturen nicht getestet werden. Wenn eine Pfad-Formel auf einer Kripke-<br />
Struktur mit 9 Zuständen und 9 Übergängen mittels der model<strong>Checking</strong><strong>CTL</strong>pos-<br />
ArrayList(...) geprüft wird, tritt ein ” java.lang.OutOfMemoryError“ Fehler auf. Beim Verwenden<br />
der Methode model<strong>Checking</strong><strong>CTL</strong>posTree(...) tritt dieses Problem <strong>für</strong> Kripke-<br />
Strukturen mit 15 Zuständen und 6 Übergängen aus jedem Zustand auf. In Abbildung<br />
5.3 ist zu sehen, dass die Laufzeit von der Tree-Implementierung langsamer, aber auch<br />
exponentiell wächst.<br />
Experiment I Experiment II<br />
Anzahl der Zustände W 2..8 9<br />
Anzahl der Übergänge ⌊ W ⌋ 2 2..4<br />
Anzahl der Durchläufe 5 3<br />
Getestete Formeln EG b, E(c U d) EG b<br />
Abbildungen 5.1, 5.2 5.3, 5.4<br />
Tabelle 5.2: Experimentendaten <strong>für</strong> zwei Implementierungen des <strong>CTL</strong>pos-Algorithmus<br />
Abbildung 5.1: Zwei Implementierungen des <strong>CTL</strong>pos -Algorithmus: EG- und EU-<br />
Formeln, Zustände 2..7<br />
39
5 Auswertung von Algorithmen<br />
Abbildung 5.2: Zwei Implementierungen des <strong>CTL</strong>pos -Algorithmus: EG- und EU-<br />
Formeln, Zustände 2..8<br />
Abbildung 5.3: Zwei Implementierungen des <strong>CTL</strong>pos -Algorithmus: EG-Formel, 9<br />
Zustände<br />
5.3 Auswertung von <strong>CTL</strong>pos - und <strong>CTL</strong>-Algorithmen<br />
Hier werden die <strong>CTL</strong>pos- und <strong>CTL</strong>-Algorithmen verglichen. Wir führen zwei Experimente<br />
durch, in denen, wie im vorigen Abschnitt, die Abhängigkeit von der Anzahl der Zustände<br />
und der Übergänge anhand den Abbildungen herausgestellt wird. Um Algorithmen<br />
vergleichen zu können, werden Formeln betrachtet, die die <strong>CTL</strong>pos-Bedingungen erfüllen.<br />
40
5 Auswertung von Algorithmen<br />
Abbildung 5.4: Tree-Implementierung des <strong>CTL</strong>pos-Algorithmus: EG-Formel, 9 Zustände<br />
Die Tabelle 5.3 enthält die Testsdaten von diesen Experimenten.<br />
Anzahl der Zustände<br />
W<br />
Experiment I Experiment II<br />
2..8 5<br />
Anzahl<br />
Übergänge<br />
der ⌊ W ⌋ 2 2..5<br />
Anzahl<br />
Durchläufe<br />
der 5 5<br />
Getestete For- a AND b, EG b, (EX a) OR (a AND b), EX a, EG b<br />
meln<br />
EG(e AND EX a), EG(EG b)<br />
Abbildungen 5.5, 5.6, 5.7 5.9, 5.8<br />
Tabelle 5.3: Experimentendaten <strong>für</strong> <strong>CTL</strong>pos- und <strong>CTL</strong>-Algorithmen<br />
In Abbildung 5.5 werden die Laufzeiten von Zustand-Formeln präsentiert. Die Laufzeit-<br />
Kurven der beiden Algorithmen verlaufen ähnlich. Die herausragenden spitzigen Buckel<br />
stellen die Laufzeiten <strong>für</strong> diejenigen Kripke-Strukturen und Formeln dar, die in jedem<br />
Zustand erfüllt werden. Die Laufzeiten der beiden Algorithmen nehmen <strong>für</strong> diese Formeln<br />
auf diesem Intervall zu und tendieren zur linearen Laufzeit. Eine andere Situation<br />
ist in Abbildung 5.6 zu beobachten. Die Laufzeit des <strong>CTL</strong>pos-Algorithmus ist nicht mehr<br />
” linear“. Der <strong>CTL</strong>-Algorithmus ist <strong>für</strong> die EG-, EU-Formeln deutlich schneller als der<br />
<strong>CTL</strong>pos-Algorithmus. Die Kurven des <strong>CTL</strong>-Algorithmus sind kaum zu erkennen, da seine<br />
Laufzeit <strong>für</strong> diese Formeln zwischen 0 und 0,8 Millisekunden schwankt (siehe Abbildung<br />
5.7).<br />
41
5 Auswertung von Algorithmen<br />
Die Abbildungen 5.9, 5.8 zeigen das Verhalten der Algorithmen <strong>für</strong> Kripke-Strukturen<br />
mit jeweils 5 Zuständen und mit variierter Anzahl von Übergängen. Das exponentielle<br />
Wachstum des <strong>CTL</strong>pos-Algorithmus lässt sich noch nicht erkennen.<br />
Abbildung 5.5: Vergleich der <strong>CTL</strong>pos - und <strong>CTL</strong>-Algorithmen: Zustand-Formeln, 2..8<br />
Zustände<br />
Abbildung 5.6: Vergleich der <strong>CTL</strong>pos- und <strong>CTL</strong>-Algorithmen: EG- und EU-Formeln, 2..8<br />
Zustände<br />
42
5 Auswertung von Algorithmen<br />
Abbildung 5.7: Vergleich der <strong>CTL</strong>pos- und <strong>CTL</strong>-Algorithmen: Ausschnitt aus 5.6 mit den<br />
Laufzeiten des <strong>CTL</strong>-Algorithmus, 2..8 Zustände<br />
Abbildung 5.8: Vergleich der <strong>CTL</strong>pos - und <strong>CTL</strong>-Algorithmen: EG-Formel, 5 Zustände,<br />
2..5 Übergänge<br />
5.4 Laufzeit des <strong>CTL</strong>-Algorithmus <strong>für</strong> Kripke-Strukturen<br />
mit bis zu 300 Zuständen<br />
Ziel dieses Abschnitts ist die Analyse des <strong>CTL</strong>-Algorithmus <strong>für</strong> ” große“ Kripke-Strukturen.<br />
Im ersten Experiment beschränken wir uns auf die Kripke-Strukturen mit bis zu<br />
100 Zuständen. Abbildungen 5.10, 5.11, 5.12 zeigen die Laufzeiten je nach der Art der<br />
43
5 Auswertung von Algorithmen<br />
Abbildung 5.9: Vergleich der <strong>CTL</strong>pos - und <strong>CTL</strong>-Algorithmen: EX-Formel, 5 Zustände,<br />
2..5 Übergänge<br />
Operatoren (existenzielle oder universelle) bzw. in Abhängigkeit vom Verschachtellungsgrad<br />
der Formeln. Da jede Formel immer mittels der Operatoren der minimalen Menge<br />
{¬, ∨, EX, EU, EG} umgewandelt wird, bevor der <strong>CTL</strong>-Algorithmus gestartet wird,<br />
dienen die Abbildungen 5.11 und 5.12 nur zum Überblick und stellen die Laufzeiten <strong>für</strong><br />
die Formeln größeres Verschachtellungsgrades im Vergleich zu den Formeln aus Abbildung<br />
5.10 dar. Das zweite Experiment (Abbildung 5.13) visualisiert das polynomielle<br />
Verhalten des <strong>CTL</strong>-Algorithmus abhängig von der Anzahl der Zustände. Hier werden<br />
die Formeln betrachtet, die erzwingen, dass die entweder in keinem oder in allen Zuständen<br />
erfüllt werden. Die Laufzeit <strong>für</strong> die Formel EX ∼ a ist kleiner als <strong>für</strong> die Formel<br />
EG(b OR ∼ b), da die letzte mehr Zeit <strong>für</strong> den Aufbau der Zusammenhangkomponenten<br />
beansprucht. Die Laufzeiten <strong>für</strong> die Formeln, die nie erfüllt werden, betragen maximal<br />
fünf Millisekunden. Allerdings demonstrieren alle Abbildungen polynomielle Laufzeit des<br />
<strong>CTL</strong>-Algorithmus.<br />
44
Anzahl der<br />
Zustände<br />
W (Schritt)<br />
Anzahl der<br />
Übergänge<br />
Anzahl der<br />
Durchläufe<br />
Getestete Formeln<br />
5 Auswertung von Algorithmen<br />
Experiment I Experiment II<br />
10..100(10) 50..300(25)<br />
⌊ W<br />
W<br />
⌋ ⌊ 2 2 ⌋<br />
5 1<br />
EG b, (EX a), E(c U d), E(c R d), EF c,<br />
AG b, (AX a), A(c U d), A(c R d), AF c,<br />
EG(EG b), AG(AG b), AG(e AND AX<br />
a), AG( e AND AX a)<br />
Abbildungen 5.10, 5.11, 5.12 5.13<br />
EX a, EX ( a<br />
AND a), EG (b<br />
OR b), EG (a<br />
AND a)<br />
Tabelle 5.4: Experimentendaten <strong>für</strong> den <strong>CTL</strong>-Algorithmus mit ” großen“ Kripke-Strukturen<br />
Abbildung 5.10: Vergleich der Laufzeiten des <strong>CTL</strong>-Algorithmus: Formeln mit existentiellen<br />
Operatoren, 10..100 Zustände<br />
45
5 Auswertung von Algorithmen<br />
Abbildung 5.11: Vergleich der Laufzeiten des <strong>CTL</strong>-Algorithmus: Formeln mit universalen<br />
Operatoren, 10..100 Zustände<br />
Abbildung 5.12: Vergleich der Laufzeiten des <strong>CTL</strong>-Algorithmus: Formeln verschiedenes<br />
Verschachtellungsgrades, 10..100 Zustände<br />
46
5 Auswertung von Algorithmen<br />
Abbildung 5.13: Vergleich der Laufzeiten des <strong>CTL</strong>-Algorithmus: EX- und EG-Formeln,<br />
50..300 Zustände<br />
47
6 Zusammenfassung und Ausblick<br />
Die Aufgabe dieser Diplomarbeit ist es, das <strong>Model</strong>-<strong>Checking</strong>-Problem <strong>für</strong> <strong>CTL</strong> auszuarbeiten.<br />
Als Erstes wurde der allgemeine <strong>Model</strong>-<strong>Checking</strong>-Prozess betrachtet, und dessen<br />
grundlegende Begriffe wurden eingeführt. Insbesondere wurde die Kripke-Struktur definiert,<br />
mit deren Hilfe endliche zustandsbasierte Systeme modelliert werden können.<br />
Anforderungen an die Systeme werden mittels einer Spezifikationssprache formalisiert.<br />
Im Rahmen dieser Arbeit wurde auf die temporale Logik <strong>CTL</strong> (Computation Tree Logic)<br />
näher eingegangen, die <strong>für</strong> die Spezifikation verwendet wird. Die theoretischen Grundlagen<br />
wurden anhand von Beispielen veranschaulicht.<br />
Ein weiteres Ziel besteht darin, die Komplexität des <strong>Model</strong>-<strong>Checking</strong>-Problems <strong>für</strong><br />
<strong>CTL</strong> zu untersuchen. Dieses Problem ist als P-vollständig bekannt ([CES86], [Sch02]).<br />
Es wird versucht, leichtere Teilprobleme zu finden, die effizienter zu lösen sind. Da<strong>für</strong><br />
wurde <strong>CTL</strong>pos , ein Fragment von <strong>CTL</strong>, betrachtet, in dem die Negation nicht auf die<br />
temporalen Operatoren angewendet werden darf. Außerdem werden nur bestimmte temporale<br />
Operatoren erlaubt.<br />
Weiterhin wurden zwei <strong>Model</strong>-<strong>Checking</strong>-Algorithmen vorgestellt, und zwar <strong>für</strong> <strong>CTL</strong><br />
allgemein und <strong>für</strong> <strong>CTL</strong>pos. Als praktischer Teil dieser Arbeit wurden sie in Java implementiert.<br />
Dabei wurde ein schon existierendes Programm erweitert, in dem die Datenstruktur<br />
<strong>für</strong> die Kripke-Struktur vorhanden war. Dieses Programm wurde <strong>für</strong> <strong>Model</strong>-<strong>Checking</strong> <strong>für</strong><br />
eine andere temporale Logik entwickelt. Deswegen wurden die Datenstrukturen <strong>für</strong> <strong>CTL</strong>und<br />
<strong>CTL</strong>pos-Formeln geschaffen. Die beiden Algorithmen haben polynomielle Laufzeit.<br />
Im Algorithmus <strong>für</strong> <strong>CTL</strong>pos musste man nichtdeterministisch eine Entscheidung treffen.<br />
Dies wurde dadurch ersetzt, dass alle in Frage kommenden Möglichkeiten der Reihe<br />
nach untersucht wurden, bis eine Lösung gefunden wurde. Im schlimmsten Fall müssen<br />
aber alle Möglichkeiten überprüft werden. Dies führt zu der exponentiellen Laufzeit des<br />
implementierten Algorithmus. Als Verbesserung der exponentiellen Laufzeit wurde eine<br />
weitere Implementierung vorgenommen, in der Berechnungspfade in einer baumartigen<br />
Struktur gespeichert und entsprechend traversiert werden.<br />
Außerdem wurde ein großer Wert auf die Benutzerschnittstelle des Programms gelegt.<br />
Insbesondere wurde die graphische Benutzeroberfläche überarbeitet. Es wurden neue<br />
Funktionalitäten eingeführt, die unter anderem dem Benutzer ermöglichen, Zustände in<br />
der Kripke-Struktur per Mausklick zu (de-)selektieren und die Algorithmen <strong>für</strong> diverse<br />
Zustände auszuführen. Die Ergebnisse der Algorithmen werden nicht nur im Text,<br />
sondern auch graphisch angezeigt. Weiterhin kann der Benutzer das Programm so einzustellen,<br />
dass bestimmte Kripke-Struktur und Formel beim Öffnen des Programms automatisch<br />
geladen werden. Es besteht jetzt auch die Möglichkeit, Kripke-Strukturen mit<br />
bestimmter Anzahl der Zustände, der Übergänge und der atomaren Aussagen zufällig<br />
zu generieren.<br />
48
6 Zusammenfassung und Ausblick<br />
Anschließend wurden die betrachteten Algorithmen anhand der zufälligen Testdaten<br />
untersucht und ausgewertet. Die Laufzeiten wurden graphisch veranschaulicht.<br />
Die Auswertung der Algorithmen hat das polynomielle Verhalten des <strong>CTL</strong>- und das<br />
exponentielle Verhalten des implementierten <strong>CTL</strong>pos -Algorithmus <strong>für</strong> das betrachtete<br />
Fragment der temporalen Operatoren {EX, EG, EU, ER} anhand der Visualisierungen<br />
der Laufzeiten bestätigt.<br />
Um eine bessere Komplexität des <strong>Model</strong>-<strong>Checking</strong>-Problems <strong>für</strong> <strong>CTL</strong> zu erreichen,<br />
könnte man weitere Fragmente von <strong>CTL</strong> untersuchen. Da sich der <strong>CTL</strong>-Algorithmus als<br />
effizient erwiesen hat, kann er <strong>für</strong> das <strong>Model</strong>-<strong>Checking</strong> <strong>für</strong> <strong>CTL</strong> eingesetzt werden.<br />
Das Programm kann weiterentwickelt werden. Dabei können die bestehenden Datenstrukturen<br />
einerseits <strong>für</strong> weitere <strong>Model</strong>-<strong>Checking</strong>-Algorithmen verwendet, andererseits<br />
<strong>für</strong> andere temporale Logiken modifiziert werden.<br />
Weiterhin könnte man das Erstellen und das Ändern der Kripke-Struktur direkt in<br />
ihrer Visualisierung als Graphen ermöglichen, damit der Benutzer Zustände und Übergänge<br />
per Mausklick hinzufügen und löschen könnte.<br />
49
Abbildungsverzeichnis<br />
2.1 Speisende Philosophen (vgl. [Sch]) . . . . . . . . . . . . . . . . . . . . . . . 9<br />
2.2 Speisende Philosophen als ein <strong>Model</strong>l([Har02]) . . . . . . . . . . . . . . . . 10<br />
2.3 Speisende Philosophen als eine Kripke-Struktur . . . . . . . . . . . . . . . 11<br />
4.1 Das Hauptfenster des Basisprogramms (Bild aus [Sol09]) . . . . . . . . . . 22<br />
4.2 Klassendiagramm <strong>für</strong> Programmlogik . . . . . . . . . . . . . . . . . . . . . . 23<br />
4.3 Klassendiagramm der Benutzerschnittstelle . . . . . . . . . . . . . . . . . . 24<br />
4.4 Zwei Abarbeitungsmöglichkeiten bei der Untersuchung von Pfad-Formeln 28<br />
4.5 Das geänderte Hauptfenster des Programms . . . . . . . . . . . . . . . . . 30<br />
4.6 Das Fenster mit den Einstellungen des Programms . . . . . . . . . . . . . 31<br />
4.7 Graphische Darstellung einer Kripke-Struktur . . . . . . . . . . . . . . . . 32<br />
4.8 <strong>Model</strong>-<strong>Checking</strong>-Fenster <strong>für</strong> <strong>CTL</strong> vor dem Ausführen des <strong>CTL</strong>-MC(ALL)-<br />
Algorithmus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33<br />
4.9 <strong>Model</strong>-<strong>Checking</strong>-Fenster <strong>für</strong> <strong>CTL</strong> nach dem Ausführen des <strong>CTL</strong>-MC(ALL)-<br />
Algorithmus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34<br />
4.10 <strong>Model</strong>-<strong>Checking</strong>-Fenster <strong>für</strong> <strong>CTL</strong> nach dem Ausführen des <strong>CTL</strong>pos-MC(EX,<br />
EG, EU, ER)-Algorithmus <strong>für</strong> eine EX-Formel . . . . . . . . . . . . . . . 35<br />
4.11 <strong>Model</strong>-<strong>Checking</strong>-Fenster <strong>für</strong> <strong>CTL</strong> nach dem Ausführen des <strong>CTL</strong>pos-MC(EX,<br />
EG, EU, ER)-Algorithmus <strong>für</strong> eine EG-Formel . . . . . . . . . . . . . . . 35<br />
5.1 Zwei Implementierungen des <strong>CTL</strong>pos-Algorithmus: EG- und EU-Formeln,<br />
Zustände 2..7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39<br />
5.2 Zwei Implementierungen des <strong>CTL</strong>pos-Algorithmus: EG- und EU-Formeln,<br />
Zustände 2..8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40<br />
5.3 Zwei Implementierungen des <strong>CTL</strong>pos-Algorithmus: EG-Formel, 9 Zustände 40<br />
5.4 Tree-Implementierung des <strong>CTL</strong>pos-Algorithmus: EG-Formel, 9 Zustände . 41<br />
5.5 Vergleich der <strong>CTL</strong>pos- und <strong>CTL</strong>-Algorithmen: Zustand-Formeln, 2..8 Zustände<br />
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42<br />
5.6 Vergleich der <strong>CTL</strong>pos- und <strong>CTL</strong>-Algorithmen: EG- und EU-Formeln, 2..8<br />
Zustände . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42<br />
5.7 Vergleich der <strong>CTL</strong>pos- und <strong>CTL</strong>-Algorithmen: Ausschnitt aus 5.6 mit den<br />
Laufzeiten des <strong>CTL</strong>-Algorithmus, 2..8 Zustände . . . . . . . . . . . . . . . . 43<br />
5.8 Vergleich der <strong>CTL</strong>pos- und <strong>CTL</strong>-Algorithmen: EG-Formel, 5 Zustände, 2..5<br />
Übergänge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43<br />
5.9 Vergleich der <strong>CTL</strong>pos- und <strong>CTL</strong>-Algorithmen: EX-Formel, 5 Zustände, 2..5<br />
Übergänge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44<br />
50
Abbildungsverzeichnis<br />
5.10 Vergleich der Laufzeiten des <strong>CTL</strong>-Algorithmus: Formeln mit existentiellen<br />
Operatoren, 10..100 Zustände . . . . . . . . . . . . . . . . . . . . . . . . . . 45<br />
5.11 Vergleich der Laufzeiten des <strong>CTL</strong>-Algorithmus: Formeln mit universalen<br />
Operatoren, 10..100 Zustände . . . . . . . . . . . . . . . . . . . . . . . . . . 46<br />
5.12 Vergleich der Laufzeiten des <strong>CTL</strong>-Algorithmus: Formeln verschiedenes Verschachtellungsgrades,<br />
10..100 Zustände . . . . . . . . . . . . . . . . . . . . . 46<br />
5.13 Vergleich der Laufzeiten des <strong>CTL</strong>-Algorithmus: EX- und EG-Formeln,<br />
50..300 Zustände . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47<br />
51
Tabellenverzeichnis<br />
2.1 Temporale Operatoren. ϕ, ψ sind temporal-logische Formeln . . . . . . . . 6<br />
2.2 Pfad-Quantoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6<br />
2.3 Darstellung der <strong>CTL</strong>-Formeln durch die Operatoren EX, EU, EG, ¬, ∨ . 8<br />
5.1 Test-Formeln . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38<br />
5.2 Experimentendaten <strong>für</strong> zwei Implementierungen des <strong>CTL</strong>pos-Algorithmus 39<br />
5.3 Experimentendaten <strong>für</strong> <strong>CTL</strong>pos- und <strong>CTL</strong>-Algorithmen . . . . . . . . . . . 41<br />
5.4 Experimentendaten <strong>für</strong> den <strong>CTL</strong>-Algorithmus mit ” großen“ Kripke-Strukturen<br />
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45<br />
52
Literaturverzeichnis<br />
[AHU74] Aho, A. V., J. E. Hopcroft und J. D. Ullmann: The Design and Analysis<br />
of Computer Algorithms. Addison-Wesley Publishing Company, London,<br />
England, 1974.<br />
[AUH82] Aho, A. V., J. D. Ullman und J. E. Hopcroft: Data Structures and<br />
Algorithms. Addison Wesley Pub Co Inc, 1982.<br />
[BMT + ] Beyersdorff, O., A. Meier, M. Thomas, H. Vollmer, M. Mundhenk<br />
und T. Schneider: <strong>Model</strong> <strong>Checking</strong> for <strong>CTL</strong> Fragments Made Efficiently<br />
Parallel. Unveröffentlichte, vorläufige Version von [BMT + 09].<br />
[BMT + 09] Beyersdorff, O., A. Meier, M. Thomas, H. Vollmer, M. Mundhenk<br />
und T. Schneider: <strong>Model</strong> <strong>Checking</strong> <strong>CTL</strong> is Almost Always<br />
Inherently Sequential. Proc. of the 16th International Symposium<br />
on Temporal Representation and Reasoning, IEEE Computer Society<br />
Press, 2009. http://www.thi.uni-hannover.de/fileadmin/forschung/<br />
publikationen/daten/be-me-mu-sc-th-vo-09.pdf.<br />
[CES86] Clarke, E., A. E. Emerson und A. Systla: Automatic verification of<br />
finite-state concurrent systems using temporal logic specifications. ACM Transactions<br />
on Programming Languages and Systems, 1986.<br />
[CGP99] Clarke, E. M., O. Grumberg und D. A. Peled: <strong>Model</strong> <strong>Checking</strong>. The<br />
MIT Press, Cambridge, Massachusetts, London, England, 1999.<br />
[EL87] Emerson, A. E. und C.-L. Lei: Modalities for model checking: Branching<br />
time logic strikes back. Science of Computer Programming, 1987.<br />
[Har02] Hartmann, A.: Ein grafisches Werkzeug zur Unterstützung von <strong>Model</strong>-<br />
<strong>Checking</strong>-Prozessen. Diplomarbeit, Universität Rostock, Fachbereich Informatik,<br />
2002. http://www.cocooncenter.org/index/thesis_hartmann.<br />
pdf.<br />
[Sch] Schwoon, S.: <strong>Model</strong>-<strong>Checking</strong>. http://www.fmi.uni-stuttgart.de/szs/<br />
teaching/ss2004/modelchecking/modelchecking.pdf.<br />
[Sch02] Schnoebelen, P.: The complexity of temporal logic model <strong>Checking</strong>. Advances<br />
in Modal Logic, 2002.<br />
53
Literaturverzeichnis<br />
[Sol09] Soldatova, M.: <strong>Effizientes</strong> <strong>Model</strong>-<strong>Checking</strong> <strong>für</strong> <strong>CTL</strong>*. Diplomarbeit, Universität<br />
Hannover, 2009. http://www.thi.uni-hannover.de/fileadmin/<br />
forschung/arbeiten/soldatova-da.pdf.<br />
54
Erklärung<br />
Hiermit versichere ich, dass ich die vorliegende Arbeit und die zugehörige Implementierung<br />
selbständig verfasst und dabei nur die angegebenen Quellen und Hilfsmittel verwendet<br />
habe.<br />
Hannover, 26. Oktober 2009<br />
Julia Gerock