31.08.2013 Aufrufe

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 ...

MEHR ANZEIGEN
WENIGER ANZEIGEN

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

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!