Effizientes Model-Checking f ur CTL

Die Seite wird erstellt Manuel Neubert
 
WEITER LESEN
Effizientes Model-Checking für CTL
                       Diplomarbeit
   im Studiengang Mathematik mit Studienrichtung Informatik

                         Julia Gerock
                       Mtr.-Nr. 2294990

              Institut für Theoretische Informatik
           Fakultät für Elektrotechnik und Informatik
                  Leibniz Universität Hannover

             Prüfer: Prof. Dr. Heribert Vollmer
           Zweitprüfer: Prof. Dr. Rainer Parchmann
                Betreuer: M. Sc. Arne Meier

                     26. Oktober 2009
Danksagung
Ich bedanke mich ganz herzlich bei Herrn Arne Meier für die hervorragende Betreuung
und Unterstützung meiner Diplomarbeit.
Inhaltsverzeichnis

1 Einführung                                                                                                                                   1
  1.1 Motivation und Aufgabenstellung . . . . . . . . . . . . . . . . . . . . . . . .                                                           1
  1.2 Gliederung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                                                    2

2 Theoretische Grundlagen                                                                                                                       3
  2.1 Model-Checking-Prozess . .           . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    3
  2.2 Kripke-Struktur . . . . . . . .      . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    4
  2.3 CTL als eine von temporalen          Logiken     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    5
  2.4 Beispiel . . . . . . . . . . . . .   . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    8
  2.5 Komplexitätstheorie . . . . .       . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   12

3 Model-Checking für CTL                                                                                                                      13
  3.1 Formulierung des Problems . . . . . . . . . . . .                        . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   13
  3.2 Komplexität des Model-Checking-Problems für                            CTL         .   .   .   .   .   .   .   .   .   .   .   .   .   14
  3.3 Model-Checking für CTL und CTLpos . . . . .                             . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   15
      3.3.1 CTL-MC(ALL) . . . . . . . . . . . . . .                            . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   15
      3.3.2 CTLpos -MC(EX, EG, EU, ER) . . . .                                 . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   17

4 Design und Implementierung                                                                                                                   21
  4.1 Basisprogramm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                                                      21
  4.2 Neue Klassenstruktur und die Implementierungsaspekte . . . . . . . . . .                                                                 22
  4.3 Bedienungsanleitung zum Programm . . . . . . . . . . . . . . . . . . . . . .                                                             30

5 Auswertung von Algorithmen                                                                                                                   36
  5.1 Allgemeine Beschreibung der Experimente . . . . . . . . . . . . . . . .                                                      . . .       36
      5.1.1 Testsystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                                                 . . .       36
      5.1.2 Testdaten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                                                . . .       37
      5.1.3 Ablauf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                                               . . .       37
  5.2 Zwei Implementierungen des CTLpos -Algorithmus . . . . . . . . . . .                                                         . . .       38
  5.3 Auswertung von CTLpos - und CTL-Algorithmen . . . . . . . . . . . .                                                          . . .       40
  5.4 Laufzeit des CTL-Algorithmus für Kripke-Strukturen mit bis zu 300                                                           Zu-
      ständen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                                           . . .       43

6 Zusammenfassung und Ausblick                                                                                                                 48

Literaturverzeichnis                                                                                                                           54
1 Einführung
1.1 Motivation und Aufgabenstellung
Heutzutage werden Software- und Hardware-Systeme so gut wie in jedem Gebiet ein-
gesetzt und haben sich in unserem Leben fest etabliert. Somit wird die Abhängigkeit
von der Zuverlässigkeit dieser Systeme immer größer. Andererseits wird es schwieriger,
die Funktionsweise fehlerfrei zu gewährleisten, da sich der Umfang und die Komplexität
der Systeme auch ständig steigern. Mithilfe der Standardmittel wie Testen oder Simu-
lation werden Fehlerfälle oft unvollständig abgedeckt. Und sogar bei einer vollständigen
Abdeckung kann das System weitere Fehler enthalten, die nicht entdeckt wurden.
   Deswegen ist die Notwendigkeit entstanden, neue, möglichst effiziente Methoden zu
entwickeln, um mit deren Hilfe die Korrektheit und somit die Qualität eines Systems
zu sichern und beweisen zu können. Dies kann ermöglicht werden, indem ein zu entwi-
ckelndes System sowie dessen relevante Eigenschaften formalisiert werden, und es durch
Verifikation überprüft wird, ob die gewünschten Eigenschaften im System erfüllt sind.
   Model-Checking als eine dieser Methoden basiert auf diesem Prinzip. Dabei werden
ein Modell M , als eine Beschreibung des Systems, und eine logische Formel ϕ, als eine
Spezifikation des Systems, verifiziert (M ⊧ ϕ).
   Je nach der Art der Formeln1 werden diverse Klassen von Model-Checking-Problemen
unterschieden. Diese Arbeit befasst sich mit dem Model-Checking-Problem für CTL
(Computation Tree Logic).
   Ziel der Arbeit besteht darin, dieses Problem in Bezug auf seine Effizienz auszuarbei-
ten. Als Basis werden die im Institut für Theoretische Informatik der Leibniz Universität
Hannover entstandenen Ergebnisse der Forschung des Model-Checking-Problems ver-
wendet, die weiter unten dargestellt sind. Das Model-Checking-Problem für CTL ist als
P-vollständig bekannt. Zugehörigkeit eines Problems zu einer Komplexitätsklasse kann
durch Angeben eines Algorithmus bewiesen werden, der dieses Problem entscheidet und
selbst in dieser Komplexitätsklasse liegt. Ein weiteres Ziel der Arbeit ist es, diverse Al-
gorithmen des Model-Checking-Problems für CTL vorzustellen, zu implementieren und
ihre Effizienz zu vergleichen.

 1
     In Abhängigkeit davon, welche Operatoren erlaubt bzw. welche Constraints festgelegt sind (z. B. CTL,
      CTL*, LTL).

                                                     1
1 Einführung

1.2 Gliederung
In der vorliegenden Arbeit wird nach der Einleitung in Kapitel 2 auf theoretische
Grundlagen eingegangen. Hier werden wichtige Grundbegriffe definiert, die für diese Ar-
beit benötigt werden. Danach wird ein Beispiel präsentiert, um ein intuitives Verständnis
zu schaffen.
   Kapitel 3 bildet den Hauptteil dieser Arbeit. Hier wird das Model-Checking-Problem
für CTL konkretisiert. Dabei wird untersucht, mit welcher Effizienz dieses Problem gelöst
werden kann und welche Schwierigkeiten sich dabei ergeben. In Abschnitt 3.3.1 wird
das Model-Checking-Problem auf die gesamte Klasse CTL verallgemeinert und ein Al-
gorithmus aus [CGP99] präsentiert, der in Polynomialzeit arbeitet. In Abschnitt 3.3.2
wird ein speziell definiertes Fragment CTLpos betrachtet. Für dieses wird hier ein weiterer
Entscheidungsalgorithmus aus [BMT+ ] vorgestellt.
   In Kapitel 4 wird behandelt, wie die in Kapitel 3 geschilderten Algorithmen im-
plementiert werden können. Diese werden als eine Erweiterung eines existierenden Pro-
gramms ([Sol09]) realisiert. Das Programm wird hier auch kurz erläutert.
   In Kapitel 5 wird die Laufzeit der Algorithmen für CTL und CTLpos untersucht und
verglichen. Experimente und deren Ergebnisse werden hier veranschaulicht.
   Kapitel 6 enthält eine Zusammenfassung und einen Ausblick der Diplomarbeit.

                                             2
2 Theoretische Grundlagen
In diesem Kapitel werden die für diese Arbeit relevanten Begriffe wie Model-Checking,
Kripke-Struktur, temporale Logik und insbesondere CTL eingeführt und in Anlehnung
an [CGP99] definiert. Diese werden anschließend mittels eines Beispiels verdeutlicht.
Um die Effizienz des Model-Checking-Problems untersuchen zu können, werden auch
die für dieses Thema wichtigsten Resultate der Komplexitätstheorie in diesem Kapitel
zusammengefasst.

2.1 Model-Checking-Prozess
Model-Checking ist als eine Verifikationsmethode von endlichen zustandsbasierten Sys-
temen bekannt, die die Korrektheit eines Systems bezüglich seiner Spezifikation beweist
oder widerlegt und dabei automatisch abläuft. Diese zwei vorteilhaften Aspekte unter-
scheiden Model-Checking von den anderen Verifikationsverfahren (z. B. deduktive Verifi-
kation) sowie von dem Testen und der Simulation erheblich (vgl. [Sch]). Der Begriff wurde
in den 80 Jahren geprägt. Diese Methode ist bereits für den Korrektheitsnachweis beim
Entwurf von komplexen sequentiellen Schaltungen und von Kommunikationsprotokollen
erfolgreich praktisch eingesetzt worden (vgl. [CGP99]). Mit Hilfe des Model-Checkings
können zur Zeit sowohl Hardware- als auch Software-Systeme untersucht werden.
   Im Allgemeinen gliedert sich das Model-Checking in drei Schritte:

  1. Modellierung

  2. Spezifizierung

  3. Verifikation

   Im ersten Schritt muss ein zu analysierendes System S in eine vereinbarte Form ge-
bracht werden. Somit wird ein Modell M des Systems S erzeugt. Hier ist es wichtig,
relevante von nicht relevanten Eigenschaften des Systems zu trennen und nur die signifi-
kanten, diese aber alle, abzubilden. Außerdem ist es zu entscheiden, ob das System zum
Anwenden des Model-Checkings tauglich, d. h. zustandsbasiert und endlich (mit einem
endlich repräsentierbaren Zustandsraum) ist. Dabei kann eine Zustandsexplosion ent-
stehen. In den letzten zehn Jahren wurden aber erhebliche Fortschritte zur Behandlung
dieses Problems erreicht (siehe [CGP99]).
   Es gibt mehrere Methoden, um ein System in ein Modell zu überführen. In dieser
Arbeit erfolgt dies mittels Konstruierens einer Kripke-Struktur, die in Abschnitt 2.2
erläutert wird.

                                           3
2 Theoretische Grundlagen

   In der Spezifikationsphase werden geforderte Eigenschaften des Systems S formal er-
fasst. Somit entsteht eine Spezifikation als eine Menge von Regeln, die das System erfüllen
muss. Bei der Erstellung der Spezifikation spielt ihre Vollständigkeit eine zentrale Rolle,
da nur diejenigen Eigenschaften mit dem Modell verifiziert werden, die in der Spezifika-
tion vorkommen. Wenn nicht alle relevanten Systemanforderungen in der Spezifikation
abgebildet sind, werden sie bei der Verifikation nicht beachtet. Dies kann allerdings zu
einer falschen Entscheidung führen, dass das Modell die Systemanforderungen erfüllt,
obwohl das nicht vollständig geprüft wurde.
   Meistens wird temporale Logik als Spezifikationssprache von den Software- und Hard-
ware-Systemen benutzt. Temporale Logik ermöglicht es, zeitliche Abläufe des Systems zu
beschreiben. In diesem Fall wird die Spezifikation als eine Menge von temporal-logischen
Formeln ϕ formuliert. Jede Formel drückt das nachzuweisende Verhalten des Systems
über die Zeit aus. In Abschnitt 2.3 wird auf die temporale Logik genauer eingegangen.
   Im letzten Schritt werden spezielle Model-Checking-Algorithmen angewendet, um
nachzuweisen oder zu widerlegen, dass das Modell M die Spezifikation ϕ erfüllt. Dieser
Schritt erfolgt größtenteils automatisch, menschliche Teilnahme wird in der Praxis nur
bei der Analyse der Verifikationsergebnisse gefordert.
   Das Model-Checking-Problem kann folgendermaßen formuliert werden. Sei S ein zu
analysierendes System.

Eingabe:       ein Modell M des Systems S
               eine nachzuweisende Eigenschaft ϕ, die das System S haben muss
  Frage:        Erfüllt das Modell M die Spezifikation ϕ?“
               ”
               (M ⊧ ϕ?)

Eine genauere Definition für das für die vorliegende Arbeit auszuarbeitende Model-
Checking-Problem für CTL wird in Abschnitt 3.1 gegeben, nachdem die Begriffe Kripke-
                                                                             ”
Struktur“ und CTL“ in den nächsten Abschnitten eingeführt werden.
             ”

2.2 Kripke-Struktur
Zum Modellieren von endlichen zustandsbasierten Systemen werden beim Model-Che-
cking Kripke-Strukturen verwendet. Diese ermöglichen, Eigenschaften eines Systems in
verschiedenen Zuständen zu beschreiben, indem bestimmte Aussagen über das System
den Zuständen zugeordnet werden. Beispielsweise ist eine Ampel (ein System) in einem
Zustand rot“, und dabei wird ein Tonsignal“ abgegeben. In diesem Fall wird dieser
         ”                          ”
Zustand beim Modellieren der Ampel mit den beiden Aussagen rot“ und Tonsignal“
                                                                 ”        ”
markiert.
  Eine Kripke-Struktur ist wie folgt definiert (vgl. [CGP99], [BMT+ ]).

                                             4
2 Theoretische Grundlagen

Definition 2.2.1 (Kripke-Struktur) Sei AP eine Menge der atomaren Aussagen
(atomic propositions). Eine Kripke-Struktur K über AP ist ein 4-Tupel K = (W, W0 , R,
η), wobei

  1. W eine endliche Menge der Zustände ist;

  2. W0 ⊆ W die Menge der Start-Zustände ist;

  3. R ⊆ W × W eine totale Transitionsrelation ist, d. h. für jeden Zustand w ∈ W gibt
     es einen Zustand w’ ∈ W mit (w, w’) ∈ R;

  4. η ∶ W → P(AP ) eine Beschriftungsfunktion (labelling function) ist, die jedem
     Zustand die Menge der atomaren Aussagen zuordnet, die in diesem Zustand erfüllt
     sind.

Bemerkung:

   • Manchmal wird die Menge der Start-Zustände nicht explizit angegeben. In diesen
     Fällen wird W0 aus der Definition ausgelassen.

   • Üblicherweise wird die Menge der atomaren Aussagen AP im Hinblick auf die
     gewünschte Spezifikation konstruiert. (vgl. [Sch])

  In Abschnitt 2.4 ist ein Beispiel zu finden, wie sich ein System als eine Kripke-Struktur
gestalten lässt.

2.3 CTL als eine von temporalen Logiken
Temporale Logik wurde als eine Erweiterung der Aussagenlogik mit dem Ziel definiert,
zeitliche Änderungen beschreiben zu können. Die Zeit wird hier als Folge (oder später als
Pfad) von Zuständen betrachtet. In diversen Zuständen können Aussagen verschiedene
Wahrheitswerte annehmen. Temporale Logik ermöglicht es, für eine logische Aussage ϕ
solche Beziehungen zu modellieren, wie z. B. ϕ gilt immer“, ϕ wird nie wahr“, ϕ wird
                                             ”                ”                    ”
zum nächsten Zeitpunkt gelten“ usw. Dies erfolgt mittels der sogenannten temporalen
Operatoren. Um auszudrücken, dass eine Eigenschaft des Systems gelten muss bzw.
kann, werden die Pfad-Quantoren A bzw. E verwendet. Temporale Operatoren und
Pfad-Quantoren sind in den Tabellen 2.1 und 2.2 aufgelistet und erläutert.
   Temporale Logik wurde im Jahr 1977 in der Arbeit von A. Pnueli The Temporal Lo-
                                                                       ”
gic of Programs“ als eine Formalisierungssprache für Spezifikation und Verifikation von
vergleichbaren Programmen zum ersten Mal vorgestellt und hat sich als eine Spezifika-
tionsmethode zur Erfassung von Systemanforderungen beim Model-Checking etabliert.

                                             5
2 Theoretische Grundlagen

    Operator     Syntax      Bedeutung        Semantik                Beispielpfad
    F            Fϕ            in       the   ϕ gilt irgendwann
                             ”
                             f uture“ oder    auf dem nachfol-
                               eventually“    genden Pfad
                             ”
    G            Gϕ           globally“       ϕ gilt in jedem Zu-
                             ”
                             oder       al-   stand auf dem Pfad
                                       ”
                             ways“

    X            Xϕ           next time“      ϕ gilt im nächsten
                             ”
                                              Zustand

    U            ϕUψ          until“          ϕ gilt in jedem Zu-
                             ”
                                              stand, bis der Zu-
                                              stand erreicht wird,
                                              in dem ψ wahr ist

    R            ϕRψ          release“        ψ gilt bis zu einem
                             ”
                                              Zustand, in dem ϕ
                                              gilt oder für im-
                                              mer, wenn ϕ immer
                                              falsch ist

        Tabelle 2.1: Temporale Operatoren. ϕ, ψ sind temporal-logische Formeln

      Quantor     Syntax    Name                  Semantik
      A           Aϕ        Allquantor            Für alle Pfade gilt ϕ
      E           Eϕ        Existenzquantor       Es existiert ein Pfad, für den ϕ gilt

                              Tabelle 2.2: Pfad-Quantoren

   In Abhängigkeit von verwendeten Operatoren und von deren Semantik werden folgen-
 de Klassen von temporalen Logiken unterschieden:
 LTL: Linear Temporal Logic betrachtet die Zeit als eine lineare Abfolge von Zeitpunkten
      bzw. Zuständen

 CTL: Computational Tree Logic charakterisiert die Zeit als ein verzweigender Ablauf von
      Zuständen

CTL*: Extended Computation Tree Logic. CTL* ⊃ LTL ∪ CTL. Ausdruckskraft von CTL*,
      CTL und LTL ist nicht vergleichbar, da sich nicht jede in einer Logik formulierte

                                              6
2 Theoretische Grundlagen

     Aussage in eine äquivalente Aussage in der anderen Logik transformieren lässt.
     Beispiele dazu sind in [CGP99], [Sol09] zu finden.
  Da das Model-Checking-Problem für diese Arbeit auf CTL eingeschränkt ist, wird diese
Logik hier genauer betrachtet. CTL wurde von Emerson und Clarke eingeführt. Wie die
anderen temporalen Logiken beinhaltet sie folgende Bausteine:
   • atomare Aussagen

   • boolesche Operatoren ¬(NOT), ∧(AND) und ∨(OR)

   • temporale Operatoren F, G, X, U, R

   • Pfad-Quantoren A, E
  Die Sprache, die aus diesen Operatoren und Quantoren besteht, heißt CTL*. Aus
diesen Komponenten werden CTL*-Formeln gestaltet. CTL* ist in [CGP99] und [Sol09]
ausführlich beschrieben.
  Eine CTL-Formel ist eine CTL*-Formel mit einer Einschränkung auf die Verwendung
von temporalen Operatoren und Pfad-Quantoren. Jeder temporale Operator darf nur
nach einem Pfad-Quantor auftreten, und jeder Pfad-Quantor darf nur gefolgt von einem
temporalen Operator in den CTL-Formeln vorkommen. Die Operatoren AF, AG, AX,
AU, AR werden universale Operatoren genannt, EF, EG, EX, EU, ER heißen exis-
tenzielle Operatoren. Universale und existenzielle Operatoren bilden die Menge ALL
von allen CTL-Operatoren.
  Weiter wird eine CTL-Formel induktiv definiert.

Definition 2.3.1 (CTL-Formel) Sei AP eine Menge von atomaren Aussagen, Q ∈
{A, E}. Die Symbole ⊺ und – repräsentieren die Wahrheitswerte wahr“ und falsch“.
                                                              ”         ”
  • ⊺, – sind CTL-Formeln.

   • Ist p ∈ AP , so ist p eine CTL-Formel.

   • Sind ϕ, ψ CTL-Formeln, dann sind (ϕ), ¬ϕ, ϕ ∧ ψ, ϕ ∨ ψ, QF ϕ, QG ϕ, QX ϕ,
     Q(ϕ U ψ), Q(ϕ R ψ) auch CTL-Formeln.

  Man unterscheidet zwei Arten von Formeln: Zustand- und Pfad-Formeln. Zustand-
Formeln beschreiben Eigenschaften, die in einem Zustand gelten, und Pfad-Formeln
charakterisieren Eigenschaften entlang eines Pfades.
Definition 2.3.2 (Zustand-Formel)
   • ⊺, – sind Zustand-Formeln.

   • Ist p ∈ AP , so ist p eine Zustand-Formel.

   • Sind ϕ, ψ Zustand-Formeln, dann sind (ϕ), ¬ϕ, ϕ ∧ ψ, ϕ ∨ ψ Zustand-Formeln.

   • Ist χ eine Pfad-Formel, so ist Aχ eine Zustand-Formel.

                                           7
2 Theoretische Grundlagen

Definition 2.3.3 (Pfad-Formel)
   • Ist ϕ eine Zustand-Formel, so ist ϕ auch eine Pfad-Formel.
   • Sind χ, π Pfad-Formeln, dann sind (χ), ¬χ, χ ∧ π, χ ∨ π, Xχ und χ U π Pfad-
     Formeln.
  Weiterhin ist {EX, EU, EG} eine minimale Menge der CTL-Operatoren, da jede
CTL-Formel in eine äquivalente Formel konvertiert werden kann, in der nur die CTL-
Operatoren EX, EU, EG sowie die booleschen Operatoren ¬ und ∨ verwendet werden.
In der Tabelle 2.3 sind die entsprechenden Regeln aufgelistet.

 Regel №     Allgemeine Form               Konvertierte Form
 1           Eϕ                            ¬A¬ϕ
 2           ϕ∧ψ                           ¬(¬ϕ ∨ ¬ψ)
 3           EF ϕ                          E(⊺ U ϕ)
 4           E(ϕ R ψ)                      EG ψ∨ E (ψ U ¬(¬ϕ ∨ ¬ψ))
 5           AF ϕ                          ¬ EG(¬ϕ)
 6           AX ϕ                          ¬ EX(¬ϕ)
 7           AG ϕ                          ¬ EF(¬ϕ)
 8           A(ϕ U ψ)                      ¬ (EG (¬ψ)∨ E (¬ψ U ¬(ϕ ∨ ψ)))
 9           A(ϕ R ψ)                      ¬ E (¬ϕ U ¬ψ)

 Tabelle 2.3: Darstellung der CTL-Formeln durch die Operatoren EX, EU, EG, ¬, ∨

   CTL, als eine CTL*-Logik, basiert auf der Kripke-Struktur. Um Systemanforderungen
mittels CTL-Formeln zu spezifizieren, müssen diverse Eigenschaften des Systems in ver-
schiedenen Zeitpunkten beschrieben werden. Die Zeitskala wird als Pfad von Zuständen
in der das System repräsentierenden Kripke-Struktur interpretiert. Weiter wird ein Pfad
definiert.
Definition 2.3.4 (Pfad) Sei K = (W, W0 , R, η) eine Kripke-Struktur. Ein Pfad x in
der Kripke-Struktur K ist eine unendliche Sequenz von Zuständen x = (x1 , x2 , ...) ∈ W ω ,
so dass (xi , xi+1 ) ∈ R ∀i ≥ 1.
  In Abschnitt 2.4 wird mittels eines Beispiels gezeigt, wie Systemanforderungen als
CTL-Formeln erfasst werden können.

2.4 Beispiel
Ein Model-Checking-Prozess kann in folgenden Schritten kurz gefasst werden. Sei S ein
zu analysierendes System.
  1. Modellierung: im ersten Schritt wird ein Modell M vom System S erstellt. M ist
     eine formale Beschreibung des Systems und spiegelt relevante Eigenschaften von S
     wider. Als Modellierungsmechanismus wird hier Kripke-Struktur eingesetzt.

                                             8
2 Theoretische Grundlagen

  2. Spezifizierung: hier werden Systemanforderungen Φ = {φj ∣ j = 0, 1, ...} erfasst. Für
     diese Arbeit sind solche Eigenschaften von Systemen relevant, die über verzweigen-
     de Zeit festgelegt werden sollen. Diese werden mittels CTL-Formeln formalisiert.

  3. Verifikation: anschließend wird durch das Anwenden eines Algorithmus das Model-
     Checking-Problem entschieden, das folgendermaßen formuliert werden kann:

                          Erfüllt das Modell M die Spezifikation Φ?“
                         ”
   An dieser Stelle wird ein Beispiel vorgestellt, mit dem gezeigt wird, wie Model-Checking
angewendet werden kann.
   Es handelt sich um das bekannte Speisende Philosophen“-Problem (siehe Abbildung
                                       ”
2.1). 5 Philosophen A, B, C, D und E sitzen um einen Tisch. Es gibt fünf Teller mit
dem Essen für jeden Philosophen, und zwischen je zwei Tellern liegt eine Gabel. Jeder
denkt nach und isst abwechselnd. Zum Essen benötigen sie jeweils die beiden Gabeln
neben sich. Es können somit maximal zwei Personen, die nicht nebeneinander sitzen,
gleichzeitig speisen (vgl. [Har02]).

                   Abbildung 2.1: Speisende Philosophen (vgl. [Sch])

   Dieses Problem kann als ein zu analysierendes System S betrachtet werden. S kann mit
Hilfe eines Graphen G (Abbildung 2.2) oder als eine entsprechende Kripke-Struktur K
(Abbildung 2.3) modelliert und durch bestimmte Regeln (Systemanforderungen) ρj,j=0,1,... ,
die mittels temporal-logischer Formeln (hier CTL-Formeln) ϕj beschrieben werden, spe-
zifiziert werden.
   Die Bezeichnungen der Zustände sind so gewählt, dass man erkennen kann, welche
Philosophen in diesem Moment essen (bis auf den Ausnahmezustand S). Das heißt, im
Zustand A isst der Philosoph A, im Zustand AC speisen die Philosophen A und C, im Zu-
stand S in der Mitte denken alle Philosophen nach. Die Übergänge zwischen den Zustän-
den stellen die Aktionen der Philosophen dar. Wenn ein Philosoph I ∈ {A, B, C, D, E}
eine Gabel vom Tisch aufnimmt (pick up) bzw. zurückgibt (return), wird der entspre-
chende Übergang mit Ip bzw. Ir beschriftet.
   Wenn man das System S in eine Kripke-Struktur K über AP überführt, ist sie wie
folgt definiert und in Abbildung 2.3 dargestellt.

                                            9
2 Theoretische Grundlagen

          Abbildung 2.2: Speisende Philosophen als ein Modell([Har02])

K = (W, {S}, R, η), wobei

 • AP = {a, b, c, d, e} die Menge der atomaren Aussagen ist, die den Namen der
   speisenden Philosophen entsprechen;

 • W = {S, A, B, C, D, E, AC, DA, DB, EB, EC} die Menge der Zustände ist;

 • R = {(S, A), (S, B), (S, C), (S, D), (S, E), (A, S), (B, S), (C, S), (D, S),
   (E, S), (A, AC), (A, DA), (B, EB), (B, DB), (C, AC), (C, EC), (D, DB),
   (D, DA), (E, EC), (E, EB), (EB, B), (EB, E), (AC, A), (AC, C), (DB, B),
   (DB, D), (EC, C), (EC, E), (DA, A), (DA, D)} die Transitionsrelation ist;

 • η ∶ W → P(AP ), für p ∈ AP, w ∈ W gilt: p ∈ η(w), falls der Philosoph mit dem
   Namen P ( groß p“) in dem Zustand w isst. Z. B. wenn der Philosoph A in dem
             ”
   Zustand w speist, dann ist a ∈ η(w).

Das System S muss unter anderen z. B. folgende Eigenschaften erfüllen:

 • ρ0 = Die Philosophen A und B dürfen nie gleichzeitig essen.“
        ”
 • ρ1 = Philosoph A isst als erster.“
        ”
 • ρ2 = Wenn Philosoph D nichts gegessen hat, kann er irgendwann zusammen mit
        ”
   B etwas essen.“

                                       10
2 Theoretische Grundlagen

            Abbildung 2.3: Speisende Philosophen als eine Kripke-Struktur

   • ρ3 = Immer, wenn Philosoph D fertig gegessen hat, muss er solange nachdenken
          ”
     oder warten, bis Philosoph E auch etwas gegessen hat.“

  Die entsprechenden CTL-Formeln sehen wie folgt aus:

   • ϕ0 = AG ¬(a ∧ b);

   • ϕ1 = A (¬(b ∨ c ∨ d ∨ e) U a);

   • ϕ2 = ¬d → EF(d ∧ b) = d ∨ EF(d ∧ b);

   • ϕ3 = AG(¬d → A(¬d U e)) = AG(d ∨ A(¬d U e));

  Somit ist K ein Modell des Systems S und Φ = {ϕi ∣ i = 0, ..., 3} ist eine Spezifikation.
  Die Frage, ob das Modell K die Spezifikation Φ erfüllt, kann beantwortet werden, in-
dem K und jede φ ∈ Φ verifiziert werden. Dies erfolgt mittels spezieller Model-Checking-
Algorithmen, die in Kapitel 3 vorgestellt und erläutert werden.

                                            11
2 Theoretische Grundlagen

2.5 Komplexitätstheorie
Da der Verifikationsschritt beim Model-Checking größtenteils automatisch verläuft, ist
die Frage der Berechnungskomplexität dieses Entscheidungsproblems hoch interessant.
Die Komplexität von Model-Checking für diverse temporale Logiken wurde in [CES86],
[Sch02], [EL87] untersucht. Das Model-Checking ist für CTL* PSPACE-vollständig und
für CTL P-vollständig. Theoretische Hintergründe dafür werden in diesem Abschnitt
einbezogen.
   Die Komplexitätsklasse P (PTIME), die Klasse der Probleme mit effizienten Algorith-
men, wird oft als die Klasse der effizient lösbaren“ Probleme bezeichnet. Sie besteht
                                   ”
aus allen Sprachen L, die einen Polynomialzeit-Entscheidungsalgorithmus haben. Ein
Problem A heißt P-vollständig, falls A ∈ P und jedes andere Problem in P auf A re-
duzierbar ist. P-vollständige Probleme werden manchmal als inhärent sequentiell (in-
herently sequential) bezeichnet, da sie (wenn P ≠ NC) keine NC-Algorithmen haben.
NC-Algorithmen laufen polylogarithmisch (in O(logc n), c konstant) an einem Paral-
lelcomputer mit einer polynomiellen Anzahl von Prozessoren. Die Komplexitätsklasse
NC beinhaltet die parallel effizient lösbaren Entscheidungsprobleme. Daher lassen sich
P-vollständige Probleme nicht parallelisieren (wenn P ≠ NC).
   Es gibt einen NC-Algorithmus zum Parsen von kontextfreien Sprachen (CFL), d. h.
CFL ⊆ NC. Deswegen ist die Klasse LOGCFL bei der Untersuchung der Komplexität des
Model-Checkings für CTL von großem Interesse. Diese Klasse enthält alle mit logarith-
mischem Speicheraufwand auf CFL reduzierbaren Probleme. Daher gilt LOGCFL⊆NC.
Andererseits können Sprachen in LOGCFL von nichtdeterministischen Turing Maschi-
nen in Polynomialzeit entschieden werden, die ein Arbeitsband logarithmischer Größe
und zusätzlich einen Stack unendlicher Größe haben (siehe [BMT+ ]). Diese Eigenschaft
von LOGCFL wird bei der Analyse der Komplexität vom Model-Checking-Problem für
CTL erzielt.
   Im Rahmen dieser Arbeit werden aber nur die Algorithmen aus P ausgearbeitet.

                                          12
3 Model-Checking für CTL
Im vorherigen Kapitel wurde der allgemeine Model-Checking-Prozess aufgeführt. Ziel
dieses Kapitels ist es, diesen Prozess auf CTL zu präzisieren. Nachdem das Model-
Checking-Problem für CTL definiert wird, wird seine Komplexität in Betracht gezogen.
Dabei werden die in [BMT+ ] (eine vorläufige, unveröffentlichte Version von [BMT+ 09])
präsentierten Hauptresultate sowie zwei Model-Checking-Algorithmen CTLpos -MC(EX,
EG, EU, ER) und CTL-MC(ALL) vorgestellt, die in Polynomialzeit arbeiten. Die prak-
tische Aufgabe der vorliegenden Arbeit besteht darin, diese Algorithmen zu implemen-
tieren und ihre Effizienz zu vergleichen.

3.1 Formulierung des Problems
In Abschnitt 2.3 wurde die Menge ALL von allen CTL-Operatoren erwähnt. Mit
CTL(ALL) wird dann die Menge von CTL-Formeln bezeichnet. Bei Aufklärung der Kom-
plexitätsfragen ist es hilfreich, nicht nur die gesamte Menge ALL, sondern auch kleinere
Teilmengen davon zu betrachten.

Definition 3.1.1 (CTL(T )) Sei T ⊆ ALL eine Menge von CTL-Operatoren. Mit
CTL(T) wird die Menge von CTL-Formeln bezeichnet, in denen nur die booleschen Ope-
ratoren {¬, ∧, ∨} und die CTL-Operatoren aus T erlaubt sind.

  Ferner können beliebige eingeschränkte Fragmente von CTL(T ) definiert werden. Für
die vorliegende Arbeit wird das Fragment CTLpos (T ) benötigt, in dem CTL-Operatoren
im Bereich einer Negation nicht auftreten dürfen: für a, b ∈ AP gilt

   • ¬EX a ∉ CTLpos (T )

   • ¬(a ∧ ¬b) ∨ EX a ∈ CTLpos (T )

  In Abschnitt 2.1 wurde das Model-Checking-Problem in der Frage formuliert, ob ein
Modell eine Spezifikation erfüllt. Weiterhin muss das auf eine Kripke-Struktur (Modell)
und eine CTL-Formel (Spezifikation) übertragen werden. Anschließend wird die Erfüll-
barkeit einer CTL-Formel in Bezug auf eine Kripke-Struktur definiert.

                                           13
3 Model-Checking für CTL

Definition 3.1.2 (Model-Checking-Problem) Sei L ∈ {CTL, CTLpos }.
Problem: L-MC(T)
 Eingabe: ⟨K, w, ϕ⟩, wobei für die einzelnen Komponenten gilt:
                K = (W, R, η) ist eine Kripke-Struktur,
                w ∈ W ist ein Zustand,
                ϕ ist eine L(T)-Formel.
   Frage: Erfüllt K im Zustand w die Formel ϕ, also K, w ⊧ ϕ?

Definition 3.1.3 (Semantik) Seien K, w wie in der Definition 3.1.2 und x = (x1 ,
x2 , ...) ∈ W ω ein Pfad. Ferner seien ϕ, ψ Zustand- und χ, π Pfad-Formeln. Die Evaluie-
rung einer Formel zu wahr wird folgendermaßen induktiv definiert.

 K, w ⊧ ⊺       immer,
 K, w ⊧ –       nie,
 K, w ⊧ p       falls p ∈ AP und p ∈ η(w),
 K, w ⊧ ¬ϕ      falls K, w /⊧ ϕ,
 K, w ⊧ (ϕ ∧ ψ) falls K, w ⊧ ϕ und K, w ⊧ ψ,
 K, w ⊧ (ϕ ∨ ψ) falls K, w ⊧ ϕ oder K, w ⊧ ψ,
 K, w ⊧ Aχ      falls K, x ⊧ χ ∀x = (x1 , x2 , ...) mit x1 = w,
 K, w ⊧ χ       falls K, x1 ⊧ χ,
 K, w ⊧ Xχ      falls K, x2 ⊧ χ,
 K, w ⊧ [χUπ] falls ∃k ∈ IN, so dass K, xk ⊧ π und K, xi ⊧ χ∀1 ≤ i < k.

  Die Erfüllbarkeit der Formeln, in denen die übrigen CTL-Operatoren verwendet wer-
den, kann mittels der in Tabelle 2.3 aufgelisteten Umwandlungsregeln überprüft werden.
  Außerdem sagt man, eine Zustand-Formel ϕ wird von einer Kripke-Struktur K erfüllt,
wenn es einen Zustand w ∈ W gibt, so dass K, w ⊧ ϕ. Und analog, eine Pfad-Formel χ
wird von einer Kripke-Struktur K erfüllt, wenn es einen Pfad x = (x1 , x2 , ...) gibt, so
dass K, x ⊧ χ. Geschrieben:
   • K ⊧ ϕ ⇐⇒ ∃w ∈ W ∶ K, w ⊧ ϕ
   • K ⊧ χ ⇐⇒ ∃x = (x1 , x2 , ...) ∶ K, x ⊧ χ

3.2 Komplexität des Model-Checking-Problems für CTL
Im Allgemeinen gilt Model-Checking für CTL als P-vollständig. Obwohl es in Polynomi-
alzeit lösbar ist, lässt das Problem sich nicht parallelisieren (falls P ≠ NC). Daher werden
Fragmente von CTL betrachtet, um leichtere Teilprobleme zu finden, die effizienter zu
lösen sind.
    Die in [BMT+ ], [BMT+ 09] erhaltenen Resultate können folgendermaßen zusammenge-
fasst werden.

                                             14
3 Model-Checking für CTL

      1. Nicht-parallelisierbare Fälle: P-Vollständigkeit liegt für alle CTL-Fragmente vor, in
         denen mindestens ein CTL-Operator benutzt wird.
      2. Trivialfall: Für Fragmente ohne temporale Operatoren stimmt das Model-Che-
         cking-Problem mit der Auswertung einer aussagenlogischen Formel überein, und
         dieses Problem ist NC1 -vollständig, d. h. parallelisierbar. NC1 ist eine NC-Klasse
         der Sprachen, die in O(log1 n)-arbeitende Entscheidungsalgorithmen haben (siehe
         [BMT+ 09]).
      3. Parallelisierbare und nicht-triviale Fälle: Model-Checking-Problem CTLpos -MC(T )
         ist LOGCFL-vollständig, falls ∅ ⊊ T ⊆ {EX, EF} oder ∅ ⊊ T ⊆ {AX, AG} (vgl.
         [BMT+ 09]).
   Für diese Arbeit ist der erste Fall relevant. Auf diesen wird in Abschnitt 3.3 genauer
eingegangen.

3.3 Model-Checking für CTL und CTLpos
Dieser Abschnitt enthält wichtigste Ergebnisse zur Komplexität von Model-Checking für
CTL und für das in Abschnitt 3.1 definierte negationsbeschränkte Fragment CTLpos . Die
entsprechenden Entscheidungsalgorithmen werden hier vorgestellt und erörtert.

3.3.1 CTL-MC(ALL)
Satz 3.3.1 CTL-MC(ALL) ∈ P
   In [CGP99] wurde ein Algorithmus vorgestellt, der das Problem CTL-MC(ALL) in
Polynomialzeit entscheidet. Dieser wird im Weiteren beschrieben. Seien K = (W, R,
η) eine Kripke-Struktur und ϕ eine CTL-Formel. Der Algorithmus bestimmt, in welchen
Zuständen aus W die Formel ϕ erfüllt wird. Die Formel ϕ wird in die Teilformeln zerlegt.
Unter einer Teilformel wird hier eine Formel verstanden, aus der mit Hilfe der Operatoren
die betrachtete Formel konstruiert wird. Z. B. für ϕ = γ ∧ λ oder für ϕ = EXγ sind γ, λ
die Teilformeln von ϕ. Jeder Zustand w wird mittels einer Menge label(w) markiert, zu
der alle Teilformeln hinzugefügt werden, die in w erfüllt sind. Anfangs gilt: label(w) =
η(w). Der Algorithmus läuft mehrere Stufen durch. Die Anzahl der Stufen entspricht dem
Verschachtelungsgrad1 (Anzahl der vorkommenden Operatoren) der Formel ϕ. In der i-en
Stufe sind Teilformeln des Verschachtelungsgrades i-1 bereits abgearbeitet. Nachdem eine
Teilformel γ behandelt wurde, wird sie zu der Menge label(w) von denjenigen Zuständen
w hinzugefügt, in denen γ wahr ist. Sobald der Algorithmus terminiert, gilt K, w0 ⊧ ϕ,
falls ϕ ∈ label(w0 ).
   In Abschnitt 2.3 wurde beschrieben, dass jede CTL-Formel durch atomare Aussagen
und die Operatoren ¬, ∨, EX, EU und EG konstruiert werden kann. Deswegen müssen
in jeder Stufe sechs Fälle behandelt werden. Seien φ eine CTL-Formel und w ein Zustand,
die auf der i-en Stufe betrachtet werden.
 1
     Verschachtelungsgrad ist 0, falls f ∈AP

                                                15
3 Model-Checking für CTL

  1. φ ∈ AP: φ wird akzeptiert, falls φ ∈ label(w).
     In diesem Fall wird keine Markierung vorgenommen, da label(w) mit η(w) initia-
     lisiert wird;

  2. φ = ¬γ: markiert werden die Zustände, die mit γ nicht markiert sind.
     ∀v ∈ W, γ ∉ label(v): label(v) = label(v) ∪ φ.

  3. φ = γ ∨ λ: betroffen sind diejenigen Zustände, die mit γ oder mit λ markiert sind.
     ∀v, u ∈ W, γ ∈ label(v), λ ∈ label(u): label(v) = label(v)∪φ, label(u) = label(u)∪φ.

  4. φ = EXγ: markiert werden direkte Vorfahren der mit γ markierten Zustände.
     ∀v, u ∈ W, γ ∈ label(v), (u, v) ∈ R: label(u) = label(u) ∪ φ

  5. φ = E(γUλ): markiert werden die Zustände, von denen aus ein Pfad existiert,
     der aus den mit γ markierten Zuständen besteht und mit dem mit λ markierten
     Zustand endet. Die Pfade werden rückwärts von den mit λ markierten Zuständen
     konstruiert. Dieser Fall wird in Algorithmus 1 behandelt.

Algorithmus 1 Procedure CheckEU K, w0 ⊧ ϕ
Eingabe: eine Kripke-Struktur K = (W, R, η), w0 ∈ W , ϕ = E(αUβ)
 1: T ← {s ∣ β ∈ label(s)}
 2: for all s ∈ T do
 3:   label(s) ← label(s) ∪ {E(αUβ)}
 4: end for
 5: while T is not empty do
 6:   choose s ∈ T
 7:   T ← T /{s}
 8:   for all t such that (t, s) ∈ R do
 9:     if ϕ ∉ label(t) and α ∈ label(t) then
10:        label(t) ← label(t) ∪ {E(αUβ)}
11:        T ← T ∪ {t}
12:     end if
13:   end for
14: end while

  6. φ = EGγ: hier werden diejenigen Zustände markiert, von denen aus ein Pfad
     existiert, entlang dessen nur die mit γ markierten Zustände vorkommen. Um sol-
     che Pfade zu finden, wird aus der Kripke-Struktur eine reduzierte Kripke-Struktur
     K ′ = (W ′ , R′ , η ′ ) konstruiert, in die nur die mit γ markierten Zustände aus W und
     zugehörige Relationen aufgenommen werden. Formal: W ′ = {w ∈ W, γ ∈ label(w)},
     R′ = R∣W ′ ×W ′ und η ′ = η∣W ′ . K ′ wird mit Hilfe des Algorithmus von Tarjan
     [AHU74] in nicht triviale Zusammenhangskomponenten zerlegt. Eine Zusammen-
     hangskomponente (strong connected component) C ist ein maximaler Teilgraph,
     in dem jeder Knoten in C von jedem anderen Knoten aus C über einen gerichteten

                                            16
3 Model-Checking für CTL

         komplett in C verlaufenden Pfad erreichbar ist. C ist nicht trivial, falls sie entwe-
         der aus mehr als einem Knoten oder aus nur einem Knoten mit einer Selbstschleife
         besteht (C = {v ∈ W ′ }, (v, v) ∈ R′ ). Nachdem K ′ partitioniert wurde, wird nach
         den Zuständen gesucht, die zu nicht trivialen Zusammenhangskomponenten gehö-
         ren. Dabei wird rückwärts über R′ abgearbeitet, und die erforderlichen Zustände
         werden markiert. Diesen Fall stellt Algorithmus 2 dar.

Algorithmus 2 Procedure CheckEG K, w0 ⊧ ϕ
Eingabe: eine Kripke-Struktur K = (W, R, η), w0 ∈ W , ϕ = EGα
 1: S ′ ← {s ∣ α ∈ label(s)}
 2: SCC ← {C ∣ C is a nontrivial SCC of S ′ }
 3: T ← ⋃C∈SCC {s ∣ s ∈ C}
 4: for all s ∈ T do
 5:    label(s) ← label(s) ∪ {EGα}
 6: end for
 7: while T is not empty do
 8:    choose s ∈ T
 9:    T ← T /{s}
10:    for all t such that t ∈ S ′ and (t, s) ∈ R do
11:      if ϕ ∉ label(t) then
12:         label(t) ← label(t) ∪ {EGα}
13:         T ← T ∪ {t}
14:      end if
15:    end for
16: end while

  Das Abarbeiten jeder der Teilformeln von ϕ benötigt O(∣W ∣ + ∣R∣)-Zeit2 . Die Kom-
plexität des gesamten Algorithmus beträgt somit O(∣ϕ∣ ⋅ (∣W ∣ + ∣R∣)) (Polynomialzeit),
wobei ∣ϕ∣ die Anzahl der verschiedenen Teilformeln von ϕ ist.

3.3.2 CTLpos -MC(EX, EG, EU, ER)
Es ist bemerkenswert, dass sich jede obere Grenze für CTL-MC(T ) auch auf
CTLpos -MC(T ) (für alle T ) übertragen lässt. Dennoch lässt sich die Komplexität von
CTLpos-MC(T ) verbessern, wenn in T nur bestimmte Operatoren verwendet werden (vgl.
[BMT+ 09]). Dies ist eine zentrale Idee bei der Untersuchung des CTLpos-Fragmentes. Au-
ßerdem steht im Hintergrund die Eigenschaft von LOGCFL-Sprachen, dass sie sich mit
einer nichtdeterministischen Turing Maschine in Polynomialzeit entscheiden lassen, die
ein Arbeitsband logarithmischer Größe und einen unendlichen Stack besitzt. In diesem
 2
     Im ersten Fall wird O(∣W ∣ + ∣AP ∣)-Zeit beansprucht, aber es wird angenommen, dass das zu analysie-
      rende System in Bezug auf das Zusammenspiel zwischen den Komponenten(|R|) im Vergleich zu der
      Anzahl der Eigenschaften des Systems (|AP |) genügend komplex ist. Deswegen wird die Komplexität
      auf O(∣W ∣ + ∣R∣) verallgemeinert.

                                                    17
3 Model-Checking für CTL

Abschnitt wird aber ein in Exponentialzeit arbeitender Algorithmus CTLpos-MC(T ) vor-
gestellt, der dem in Abschnitt 3.3.1 aufgeführten Algorithmus CTL-MC(T ) in Bezug auf
ihre Effizienz weiter unten gegenübergestellt wird.

Satz 3.3.2 Sei T eine Menge von CTL-Operatoren, so dass alle Operatoren in T exis-
tenziell oder alle Operatoren in T universal sind. Dann ist CTLpos -MC(T) ∈ P.

   Als Erstes wird der Fall betrachtet, dass in T nur existenzielle Operatoren erhältlich
sind. O. B. d. A. sei T ∈ {EX, EG, EU, ER}. Es wird behauptet, dass Algorithmus 3
entscheidet, ob die Kripke-Struktur K = (W, R, η) die CTLpos (T )-Formel ϕ im Zustand
w0 ∈ W erfüllt. S sei ein Stack zum Speichern von Paaren (ϕ, w) ∈ CTLpos (T ) × W .
   Jede Formel wird ähnlich wie im CTL-MC(ALL)-Algorithmus abgearbeitet. Sie wird
je nach dem verwendeten Operator in die Teilformeln zerlegt und entsprechend behan-
delt. Ein deutlicher Unterschied liegt in dem Fall vor, wenn eine Pfad-Formel überprüft
werden muss, z. B. ϕ = EGα oder ϕ = E(αUβ). Hier muss ein Pfad aus allen möglichen
aus dem betrachteten Zustand ausgehenden Pfaden nichtdeterministisch gefunden wer-
den. α wird dann in jedem Zustand entlang dieses Pfades geprüft. Im CTL-MC(ALL)-
Algorithmus werden für solche Formeln erst die Zustände gefunden, in denen α erfüllt
wird. Danach werden aus diesen Zuständen starke Zusammenhangskomponenten und
aus diesen Ergebnispfade konstruiert.
   Die Konstruktion des Algorithmus macht die oben erwähnte Eigenschaft der LOGCFL-
Sprachen erkennbar. Der Algorithmus lässt sich mit einer Turing Maschine mit einem
Stack und einem Arbeitsband logarithmischer Größe entscheiden. Wenn der Algorithmus
in Polynomialzeit arbeiten würde, dann könnte man das Problem
CTLpos -MC(EX, EG, EU, ER) zu LOGCFL-Sprachen einordnen. Das ist aber für den
Fall ϕ = EGα oder ϕ = E(αUβ) unmöglich. Das Problem liegt für die Formeln vor, die
nach dem folgenden Schema geschachtelt sind. Sei ϕ = EGα0 , wobei α0 eine Formel ist,
die als Teilformel EGα1 enthält usw. Z. B. ϕ = EG(x0 ∨EG(x1 ∧EG(x2 ...))). Für jede
Teilformel αi,i=0,... wird ein neuer Pfad geraten und jeweils |W|-mal auf den Stack gelegt.
Analog gilt dies auch für die EU-Formeln. Dies führt zum exponentiellen Bedarf in der
Stackgröße. Der Algorithmus benötigt exponentielle und nicht mehr polynomielle Zeit,
wie es bei LOGCFL gefordert wird. ER-Formeln stellen eine Kombination von EG- und
EU-Formeln dar. EX-Formeln können polynomiell mit der Turing Maschine abgearbei-
tet werden. Die übrigen Formeln repräsentieren Trivialfälle. Für die EG-, EU-Formeln
besitzt der Algorithmus folgende Komplexität. Um alle Pfade abzuarbeiten, braucht
man O(2n ) Zeit. Bei geschickter Implementierung mit dem direkten Zugriff auf Teilfor-
meln im Stack ergibt sich O(2log(n) ) = O(nO(1) ) Bedarf. Folglich ist der Algorithmus für
CTLpos -MC(EX, EG, EU, ER) theoretisch polynomiell.
   Die Tatsache, dass der Algorithmus immer terminiert, folgt daraus, dass jede Teil-
formel von ϕ nicht mehr als |W |-mal im Stack S gespeichert wird. Außerdem zeigt die
Induktivität der Struktur von Formeln, dass der Algorithmus genau dann false zurück-
gibt, wenn für alle aus dem Stack S geladenen Paare (φ, w) K, w ⊭ φ gilt. Folglich
terminiert der Algorithmus mit true, genau dann wenn K, w ⊧ ϕ.

                                            18
3 Model-Checking für CTL

Algorithmus 3 Entscheide, ob K, w ⊧ ϕ
Eingabe: eine Kripke-Struktur K = (W, R, η), w0 ∈ W , ϕ ∈ CTLpos (T)
Ausgabe: true (falls K, w ⊧ ϕ) oder false (sonst)
 1: push(S, (ϕ, w0 ))
 2: while S is not empty do
 3:   (ϕ, w) ← pop(S)
 4:   if ϕ is a propositional formula then
 5:      if ϕ evaluates to false in w under η then
 6:         return false
 7:      end if
 8:   else if ϕ = α ∧ β then
 9:      push(S, (β, w))
10:      push(S, (α, w))
11:   else if ϕ = α ∨ β then
12:      nondet. push(S, (α, w)) or push(S, (β, w))
13:   else if ϕ = EXα then
14:      nondet. choose w′ ∈ {w′ ∣ (w, w′ ) ∈ R}
15:      push(S, (α, w′ ))
16:   else if ϕ = EGα then
17:      guess a path (wi )1≤i≤∣W ∣ such that w1 = w
18:      for all 1 ≤ i ≤ ∣W ∣ do
19:         push(S, (α, wi ))
20:      end for
21:   else if ϕ = E(αUβ) then
22:      guess k ≤ ∣W ∣ and a path (wi )1≤i≤k such that w1 = w
23:      for all 1 ≤ i < k do
24:         push(S, (α, wi ))
25:      end for
26:      push(S, (β, wk ))
27:   else if ϕ = E (αRβ) then
28:      guess γ ∈ {EGβ, E(βU(α ∧ β))}
29:      push(S, (γ, w))
30:   end if
31: end while
32: return true

                                        19
3 Model-Checking für CTL

   Bei der Implementierung dieses Algorithmus kollidiert man mit den Problemen, die
sich durch den in den Zeilen 12, 14, 17, 22, 28 vorkommenden Nichtdeterminismus be-
kunden. Außerdem, um bessere Effizienz zu erreichen, müssen die Pfade in den Zeilen
15, 19, 24 auf dem Stack knotenweise und nicht als Ganzes gespeichert und bearbeitet
werden. Diese sowie weitere Besonderheiten bezüglich der Implementierung werden in
Kapitel 4 besprochen.
   Der Fall, wenn alle Operatoren in T universal sind, folgt aus Abgeschlossenheit von P
unter dem Komplement und kann analog gelöst werden (Eϕ ≡ ¬A¬ϕ).

                                          20
4 Design und Implementierung
Im vorigen Kapitel wurden die Model-Checking-Algorithmen für CTL-MC(ALL) und
CTLpos -MC(EX, EG, EU, ER) präsentiert. Diese werden im Rahmen dieser Diplomar-
beit in Java implementiert. In diesem Kapitel werden Implementierungsaspekte erläutert.
Dabei wird ein existierendes Programm um weitere Funktionalitäten erweitert. Dieses
Programm wird in Abschnitt 4.1 vorgestellt. Die ausführliche Beschreibung findet man
in [Sol09]. Die geänderte Klassenstruktur und die neuen Möglichkeiten des Programms
werden auch in diesem Kapitel veranschaulicht.

4.1 Basisprogramm
Als Basis wurde ein Programm verwendet, das im Rahmen einer anderen Diplomarbeit
am Institut für theoretische Informatik der Leibniz Universität Hannover entstanden ist.
Dieses Programm wurde mit dem Ziel entwickelt, einige Model-Checking-Algorithmen
für LTL zu realisieren. Die Benutzeroberfläche des Hauptfensters ist in Abbildungen 4.1
zu sehen.
   Das Hauptfenster besteht aus drei Bereichen, die sich auf Kripke-Struktur, Formel
und Algorithmen beziehen. In jedem Bereich gibt es Buttons zum Aufrufen diverser
Aufgaben und ein Textfeld, in dem eine Kripke-Struktur, eine Formel oder Ergebnisse der
Algorithmen veranschaulicht werden. Folgende Funktionalitäten sind bereits vorhanden:

   • Erstellung einer neuen Kripke-Struktur bzw. einer neuen Formel;

   • Speicherung einer Kripke-Struktur bzw. einer Formel in einer Datei;

   • Laden einer Kripke-Struktur bzw. einer Formel aus einer Datei;

   • Zeichnen einer Kripke-Struktur;

   • Starten der Model-Checking-Algorithmen für LTL angewendet auf die erstellte/ge-
     ladene Kripke-Struktur und die erstellte/geladene Formel.

Die implementierte Datenstruktur, die eine Kripke-Struktur repräsentiert, und alle zuge-
hörigen Funktionalitäten werden übernommen. Die Visualisierung der Kripke-Struktur
wird überarbeitet und um einige Funktionen ergänzt. Da das Basisprogramm speziell
für das Model-Checking für LTL entwickelt wurde, müssen die Operationen zur Bearbei-
tung der Formeln angepasst und erweitert werden, um CTL-Formeln zu erfassen, um die
in dieser Arbeit auszuarbeitenden Model-Checking-Algorithmen verwenden zu können.
Weiter unten werden diese und andere Erweiterungen des Basisprogramms erörtert.

                                           21
4 Design und Implementierung

       Abbildung 4.1: Das Hauptfenster des Basisprogramms (Bild aus [Sol09])

4.2 Neue Klassenstruktur und die
    Implementierungsaspekte
In diesem Abschnitt wird die erweiterte Klassenstruktur des Programms erläutert. Abbil-
dung 4.2 stellt die Programmlogik dar, und Abbildung 4.3 zeigt die Klassenstruktur der
Benutzerschnittstelle. Die für diese Arbeit relevanten Klassen des Basisprogramms wer-
den ohne Attribute bzw. Operationen abgebildet. Die komplett übernommenen Klassen
sind in schwarz und die erweiterten Klassen sind in grün dargestellt. Die neuen Klassen
sind in blau hervorgehoben. Die get- und set-Methoden werden übersichtshalber nicht
dargestellt.

                                          22
4 Design und Implementierung

                                                               Proposition
                                                                     0..1

                                       0..2                             1..*

                              FormulaCTLpos                                                                          0..2
           #not: boolean
           #and: boolean                                                                                       FormulaCTL
           #or: boolean                                                                    -EF:   boolean
           #EX: boolean                                                                    -AF:   boolean
           #EG: boolean                                                                    -AX:   boolean
           #EU: boolean                                                                    -AG:   boolean
           #ER: boolean                                                                    -AU:   boolean
           +isProposition(): boolean                                                       -AR:   boolean
           +stringToFormula(String): FormulaCTLpos                                         +isProposition(): boolean
           +stringInPrefixToFormula(String): FormulaCTLpos                                 +stringToFormula(String): FormulaCTL
           +formulaToString(): String                                                      +stringInPrefixToFormula(String): FormulaCTL
           +formulaToStringInPrefix(): String                                              +formulaToString(): String
           #getIndexOfMainOperator(String): int                                            +formulaToStringInPrefix(): String
           -modifyAccordingDeMorgan()                                                      +convert()
           -getToken(String): String                                                       -getToken(String)

                           ModelCheckingCTLpos                                                               ModelCheckingCTL
         -formulaCTLpos: FormulaCTLpos                                          -formulaCTL: FormulaCTL
         -kripke: Kripke                                                        -kripke: Kripke
         -state: State                                                          -labeledStates: HashMap
         -paths: ArrayList                                    +modelCheckingCTL(FormulaCTL): HashMap
         +modelCheckingCTLposArrayList(Kripke,FormulaCTLpos,                    -checkPropositions(Proposition): HashMap
         +modelCheckingCTLposTree(Kripke,FormulaCTLpos,                         -checkNot(HashMap): HashMap
                                                                                -checkOr(HashMap,HashMap): HashMap
                                                                                -checkEX(HashMap): HashMap
                                                                                -checkEU(HashMap,HashMap): HashMap
                                                                                -checkEG(HashMap): HashMap
                                                                                -getSCC(HashMap): ArrayList

                            State                                                                                 Kripke
-key: int                                                                            -...
-name: String                                                                        -allTransVector: ArrayList
                                                                 1..*       1
-initial: boolean                                                                     ...()
-propositions: String[]                                                              +edit()
-transitions: ArrayList                                                  +createRandomKripke(int,int,int)
-computaionTree : TreeNode                                                    -getRandomPropositions(int): String[]
-paths: ArrayList                                                                                   1
-index: int
-lowLink: int
 ...()
+evaluatePropositionalFormula(FormulaCTLPos): booelan
                                                                 2
+getPredecessorStates(Kripke): HashMap                                                           Transition
+getSuccStates(Kripke): int[]
+formPaths(int,Kripke)
+createComputationTree(Kripke): TreeNode

                               0..1

                        TreeNode
         -value: T
         -parent: TreeNode
         -leftChild: TreeNode
         -rightSibling: TreeNode
         -depth: int
         +addChild(T): TreeNode
         +addRightSibling(T): TreeNode
         +getChildren(): ArrayList

                             Abbildung 4.2: Klassendiagramm für Programmlogik

                                                                                23
4 Design und Implementierung

                          FormulaCTL                            ModelCheckingCTL

         State                             ModelCheckerCTL
                            -formulaCTL: FormulaCTL
                            -formulaCTLpos: FormulaCTLpos
                            -kripke: Kripke
     FormulaCTLpos          -result: boolean
                            -selectedStates: ArrayList
                            +labelTrueStatesInGraph()
  ModelCheckingCTLpos       -getStatesList(): ArrayList
                            -setClickedStatesInGraph(ArrayList)

                                                                                     GraphVisualization
                                 Kripke
                                                                                   +draw(Kripke)
                                                                                   +saveImage(Kripke)

       SettingsFrame                         ModelChecker
    -formulaFile: File
    -kripkeFile: File
    +loadProperties()
    +saveProperties()
                                Formula           ModelCheck

                 Abbildung 4.3: Klassendiagramm der Benutzerschnittstelle

Kripke-Struktur
Die Klasse Kripke stellt eine Kripke-Struktur als eine Liste von Zuständen dar, die
mittels der Klasse State realisiert werden. Jeder Zustand hat eine eindeutige Identi-
fikationsnummer, einen Namen und eine Liste der atomaren Aussagen, die in diesem
Zustand gelten. Das Attribut initial gibt an, ob ein Zustand der Startzustand in der
Kripke-Struktur ist. Übergänge zwischen den Zuständen in der Kripke-Struktur werden
mittels der Klasse Transition gespeichert. Neben den übernommenen Funktionalitäten,
die Kripke-Struktur zu erstellen/speichern/laden, kann sie jetzt auch geändert werden
(edit()). Außerdem wird ermöglicht, eine zufällige Kripke-Struktur generieren zu lassen
(createRandomKripke(int, int, int)). Als Argumente werden die Anzahl von Zuständen
S, die Anzahl von Übergängen T , die aus jedem Zustand ausgehen, sowie die maximale
Anzahl von atomaren Aussagen P , die jedem Zustand zugeordnet werden. Die Generie-
rung geschieht folgendermaßen.
  1. Es wird eine Menge der Größe S von Zuständen erzeugt. Als Namen werden die
     natürliche Zahlen vergeben.
  2. Jedem Zustand werden Übergänge hinzugefügt. Die Anzahl der Übergänge T ist
     für jeden Zustand fest. Die Endzustände von Übergängen werden mittels einer
     Zufallsfunktion ermittelt.

                                                  24
4 Design und Implementierung

  3. Jeder Zustand wird mit einer Menge von atomaren Aussagen beschriftet. Diese
     werden auch zufällig mittels getRandomPropositions(int) generiert. Als atomare
     Aussagen werden hier die Buchstaben des lateinischen Alphabets verwendet. Das
     heißt, dass jeder Zustand maximal 26 atomare Aussagen haben kann. Für jeden
     Buchstaben wird eine Zufallszahl generiert. Wenn diese Zahl größer als 0,5 ist,
     wird dieser Buchstabe dem aktuellen Zustand zugeordnet. Der letzte mögliche
     Buchstabe entspricht dem übergebenen Parameter P . Mit anderen Worten: jeder
     Zustand wird mit keinen oder mit maximal S ersten Buchstaben des lateinischen
     Alphabets beschriftet.

   Die Klasse State wurde um die Attribute index und lowLink erweitert, die den Aufbau
von den für Algorithmus 2 notwendigen Zusammenhangskomponenten ermöglichen. Eine
weitere relevante Methode getPredecessorStates(Kripke), die zu einem Zustand sämtliche
direkten Vorfahren findet, wird auch in dieser Klasse implementiert. Mittels der Methode
evaluatePropositionalFormula(FormulaCTLpos) wird überprüft, ob eine CTLpos-Formel,
in der keine CTL-Operatoren, sondern nur die booleschen Operatoren {¬, ∧, ∨} vorhanden
sind, in dem aktuellen Zustand erfüllt wird.
   Algorithmus 3 benötigt bei der Analyse von EG-, EU-Formeln aus einem Zustand
ausgehende Pfade. Diese können mittels der vom Basisprogramm übernommenen Metho-
den getSuccStates(Kripke) und formPaths(int, Kripke) ermittelt werden. formPaths(...)
konstruiert solche Pfade. Jeder Pfad ist eine Liste von Zuständen. Alle aus einem Zustand
ausgehenden Pfade werden als eine Liste von solchen Listen gespeichert. In Abschnitt
3.3.2 wurde erwähnt, dass man eine bessere Effizienz erreichen kann, wenn Zustände auf
den Pfaden knotenweise gespeichert werden. Um dies zu ermöglichen, wurde die Klasse
TreeNode entwickelt, die einen Baum als Datenstruktur realisiert und alle nötigen
Methoden bereitstellt. Jeder Zustand ist ein Knoten im Baum. Die von ihm erreichbaren
Zustände sind seine Kinderknoten usw. Die Methode createComputationTree(Kripke)
erzeugt einen Berechnungsbaum, in dem alle ausgehenden Pfade durch Tiefendurchlauf
rekonstruiert werden können. In der Instanzvariable computaionTree wird der Wurzel-
knoten des Berechnungsbaumes gepeichert. Algorithmus 3 wird zweimal implementiert,
um die beiden Möglichkeiten zu vergleichen, Pfade als Liste von Listen und als einen
Baum abzuarbeiten.

CTL-Formel
CTL-Formeln werden im Hinblick auf Definition 2.3.1 mit Hilfe der Klassen Proposition,
FormulaCTLpos und FormulaCTL implementiert. Jede CTL-Formel ist eine Instanz
der Klasse FormulaCTLpos bzw. FormulaCTL und besteht aus CTL-Teilformeln, die
in einer Liste gespeichert werden. Der verwendete Operator wird registriert, indem das
entsprechende Attribut der Klasse FormulaCTLpos bzw. FormulaCTL auf wahr“
                                                                                  ”
gesetzt wird. Dabei gelten die üblichen Prioritätsregeln, und alle binären Operatoren
sind linksassoziativ. Jede Formel mit einem binären Operator (z. B. OR, AND, EU,
AR) wird somit als eine Liste mit zwei Elementen und jede Formel mit einem unären
Operator (z. B. NOT, EX, AG) mit einem Element dargestellt.

                                           25
4 Design und Implementierung

   Die einfachste Form einer CTL-Formel ist eine atomare Aussage. Solche Formel wird
als eine Liste mit einem Element, einer Instanz der Klasse Proposition, erzeugt. Alle
Attribute werden in diesem Fall mit falsch“ initialisiert. Formeln dieser Art können mit
                                     ”
Hilfe der Methode isProposition() identifiziert werden.
   Jede FormulaCTLpos- oder FormulaCTL-Formel besteht folglich entweder aus
einem Objekt der Klasse Proposition oder aus einer Liste mit einem oder zwei Objekten
der Klasse FormulaCTLpos bzw. FormulaCTL.
   Durch die Klasse FormulaCTLpos können CTLpos -Formeln erzeugt werden, in de-
nen CTL-Operatoren nicht negiert werden dürfen. Außerdem ist die Menge der CTL-
Operatoren auf die Menge {EX, EG, EU, ER} eingeschränkt, da nur diese für den Algo-
rithmus 3 benötigt werden. Die Klasse FormulaCTL enthält sowohl die von
FormulaCTLpos geerbten Attribute als auch weitere Attribute, die es zusammen
ermöglichen, beliebige CTL-Formeln zu bilden. Die Formeln können über eine Benut-
zerschnittstelle in textueller Form in der Infix- oder Präfix-Notation eingegeben wer-
den. Das Erstellen der Formeln aus dem Eingabetext geschieht mittels der Methoden
StringToFormula(String) und StringInPrefixToFormula(String). Dies erfolgt, indem die
Eingabe analysiert wird und ein Operator der Formel mittels der
getIndexOfMainOperator (String) und getToken(String) gefunden wird. Folglich werden
die Teilformeln der Formel ermittelt, die weiterhin analog in die Tiefe“ geparst wer-
                                                                ”
den. Die Konvertierung in die andere Richtung passiert mittels FormulaToString() bzw.
FormulaToStringInPrefix ().
   Die Methode modifyAccordingDeMorgan() bringt eine CTLpos -Formel nach den De
Morganschen Gesetzen in so eine Form, dass die Negationen nur direkt von den ato-
maren Aussagen stehen. Diese Umwandlung vereinfacht die Auswertung der Formel in
Algorithmus 3: K, w0 ⊧ ¬p, wenn p ∈ AP und p ∉ η(w0 ). Dies ermöglicht die Methode
evaluatePropositionalFormula(FormulaCTLpos) in der Klasse State.
   Die Methode convert() in der Klasse FormulaCTL wandelt eine CTL-Formel in ei-
ne äquivalente um, die aus atomaren Aussagen und den Operatoren ¬, ∨, EX, EU und
EG besteht. Diese Methode ist für CTL-MC(ALL) von großer Bedeutung, da diese Ope-
ratoren eine minimale Menge der Operatoren bilden, um alle möglichen CTL-Formeln
konstruieren zu können. Die Konvertierung erfolgt mittels der in der Tabelle 2.3 aufge-
führten Regeln.

Algorithmen
Die Klassen ModelCheckingCTLpos und ModelCheckingCTL bilden den Kern des
Programms. Sie enthalten nämlich die Model-Checking-Algorithmen CTLpos -MC(EX,
EG, EU, ER) bzw. CTL-MC(ALL).
   Um den CTLpos -Algorithmus ausführen zu können, müssen eine Kripke-Struktur, ein
Zustand in der Kripke-Struktur und eine zu prüfende CTLpos -Formel bekannt sein. Die-
se Argumente werden in den entsprechenden Instanzvariablen gespeichert. Die Methoden
modelCheckingCTLposArrayList(Kripke, FormulaCTLpos, State) und modelChecking-
CTLposTree(Kripke, FormulaCTLpos, State) stellen die zwei oben vorgestellten Imple-
mentierungsmöglichkeiten des Algorithmus 3 dar. Die Ergebnisse des Model-Checkings

                                           26
4 Design und Implementierung

werden in den Variablen result und paths gespeichert. result wird auf wahr“ gesetzt,
                                                                           ”
falls die Kripke-Struktur kripke die Formel formulaCTLpos im Zustand state erfüllt. In
Abhängigkeit davon, ob es um eine Zustands- oder Pfad-Formel handelt, werden in paths
Zustände bzw. Pfade verfasst, in denen die Erfüllbarkeit vorliegt.
   In Abschnitt 3.3.2 wurden die Implementierungsschwierigkeiten des Algorithmus 3
erwähnt. Hier liegt das Problem vor, dass man nichtdeterministisch mehrere Teilfor-
meln oder Zustände abarbeiten ( nondet. choose“) oder aus mehreren einen Pfad oder
                                   ”
einen Zustand aussuchen ( guess“) muss, in denen eine bestimmte Eigenschaft – d. h.
                             ”
eine Formel – erfüllt wird. Dieser Nichtdeterminismus wird durch die Überprüfung je-
der Teilformel, jedes Zustandes und jedes Pfades der Reihe nach ersetzt, die in Frage
kommen. Da es sich um die existentiellen Formeln handelt, kann man die Abarbeitung
abbrechen, sobald eine Forderung (ein Zustand für die EX- oder ein Pfad für die EG-
bzw. EU-Formeln) erfüllt wurde. Im schlimmsten Fall müssen aber alle Kandidaten
überprüft werden.
   Betrachten wir den Fall ϕ = EGα. Wenn man alle aus einem Zustand w0 ausgehen-
den Pfade betrachtet, hat man die exponentielle Anzahl von Möglichkeiten: ∣T ∣∣T ∣ , wobei
∣T ∣ die Anzahl aus einem Zustand ausgehender Übergänge ist. Die Laufzeit der Abarbei-
tung der Pfade ist entsprechend groß. Wenn die Pfade als ArrayList
gespeichert sind, wird jeder Pfad vom ersten bis zum letzten Zustand auf die Erfüllbar-
keit der Formel α geprüft. Die Situation ändert sich, wenn die Pfade in einem Baum
gefasst sind. Abbildung 4.4 zeigt diese zwei Abarbeitunsmöglichkeiten. Oben ist eine
Kripke-Struktur dargestellt. Die Zustände sind mit den atomaren Aussagen versehen.
Sei ϕ = EGa. Unten links ist die Liste mit den Pfaden, rechts davon ist der entspre-
chende Berechnungsbaum. Die Pfade sowie der Berechnugsbaum sind unendlich, werden
aber auf die Anzahl von Zuständen in der Kripke beschränkt, da die Pfade sonst einen
Zyklus enthalten. Der gestrichelte Pfeil zeigt die Reihenfolge, in der die Zustände über-
prüft werden, ob die Formel α = a in diesen gilt. Bei der zweiten Implementierung wird
nach einem falschen“ Zustand, in dem die Teilformel α nicht gilt, zu seinem rechten
              ”
Geschwister übergegangen. Das wird solange durchgeführt, bis es noch solche vorhanden
sind und noch kein Pfad gefunden wurde. Dies wird mittels des iterativen Tiefendurch-
laufs (siehe [AUH82]) realisiert, bei dem zu jedem Knoten seine rechten Geschwister in
einem Stack gespeichert werden. Im Gegensatz zu der ersten Implementierung wird so-
mit die Überprüfung in allen vorherigen Zuständen gespart. Eine weitere Möglichkeit an
der Laufzeit zu gewinnen, ist die Speicherung von Ergebnissen des Model-Checkings in
den geprüften Zuständen. Das bedeutet, dass nachdem die Zustände a“, a,b“ und b“
                                                                        ” ”             ”
geprüft wurden, wird für die Formel α = a gespeichert, dass sie in den Zuständen a“
                                                                                        ”
und a,b“ erfüllt wird. Wenn der zweite Pfad im Baum analysiert wird, muss der Model-
      ”
Checking-Algorithmus im nächsten potenziellen Zustand nicht mehr ausgeführt werden.
Die schon ermittelten Ergebnisse müssen nur gelesen werden. Dieser Ansatz beansprucht
einen zusätzlichen Speicher, vermindert aber die Laufzeit.
   Weiterhin setzt der Algorithmus einen Stack ein. Um den Nichtdeterminismus zu lö-
sen, müssen alle möglichen Zustände bzw. Pfade sowie entsprechende Formeln im Stack
gespeichert werden. Zusätzlich muss der Typ der Formeln bei der Speicherung ihrer Teil-
formeln mit angegeben werden, was jedoch für die Formeln ohne temporale Operatoren

                                            27
Sie können auch lesen