Lässt es sich mit cremefarbenem Papier, einer Tönung, mehr Kontrast oder größerer Schrift besser lesen? Wählen Sie Ihre Farben und Ihre Schrift, einmalig für alle Seiten.

Kostenlose Lektion

Invarianten in TLA+ schreiben und prüfen

Nach dieser Lektion: Ich kann eine Invariante schreiben und das Gegenbeispiel von TLC lesen.

Lektion, 55 Min.8 BefehleLab für formale Methoden: Z3, SPIN, TLA+ und Alloy in einer VM

Beide Tore der Schleuse offen

Eine Invariante ist eine Aussage, die in jedem Zustand eines Systems wahr sein muss. TLA+ ist eine Sprache, in der man ein System aus Zuständen und Schritten beschreibt, und TLC ist das Programm, das alle Zustände durchprobiert.

Eine Schiffsschleuse hat ein Außentor und ein Innentor. Beide zugleich zu öffnen, lässt das Wasser durchlaufen. TLC findet den kürzesten Weg dorthin.

Am Ende dieser Lektion

Notiz

Ich kann eine Invariante schreiben und das Gegenbeispiel von TLC lesen.

Schlüsselwörter

BegriffWas er bedeutetBeispiel
Zustanddie Werte aller Variablen zu einem Zeitpunkt
Schrittein Übergang von einem Zustand zum nächsten
Invarianteeine Aussage, die in jedem Zustand wahr ist~(aussen /\ innen)
TLA+eine Sprache, um Systeme aus Zuständen und Schritten zu beschreiben
TLCdas Programm, das alle Zustände eines TLA+-Modells prüft
Gegenbeispielder Weg von Zustand zu Zustand bis zur verletzten Invariante

Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.

Ein System ist eine Folge von Zuständen

Die Schleuse hat zwei Variablen: aussen und innen, jede wahr, wenn das Tor offen ist. Ein Zustand gibt beiden einen Wert. Am Anfang sind beide Tore zu.

Ein Schritt ändert den Zustand: ein Tor öffnen oder beide schließen. Eine Invariante verbietet Zustände. Hier lautet sie: nie beide Tore offen.

Das Modell der Schleuse in TLA+

Code: bash
---- MODULE Schleuse ----
VARIABLES aussen, innen
vars == <<aussen, innen>>
Init == aussen = FALSE /\ innen = FALSE
OeffneAussen == aussen = FALSE /\ aussen' = TRUE /\ UNCHANGED innen
OeffneInnen == innen = FALSE /\ innen' = TRUE /\ UNCHANGED aussen
Schliesse == (aussen \/ innen) /\ aussen' = FALSE /\ innen' = FALSE
Next == OeffneAussen \/ OeffneInnen \/ Schliesse
Spec == Init /\ [][Next]_vars
NieBeide == ~(aussen /\ innen)
AussenImmerZu == ~aussen
====

So ändert sich der Zustand bei jedem Schritt

SchrittWirkungaussen danachinnen danach
Startbeide Tore zuFALSEFALSE
OeffneAussenAußentor aufTRUEunverändert
OeffneInnenInnentor aufunverändertTRUE
Schliessebeide Tore zuFALSEFALSE

Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.

Das Modell schreiben und von TLC prüfen lassen

Die Datei braucht zwei Teile: das Modell Schleuse.tla und die Einstellungen Schleuse.cfg. Darin steht, welche Aussage TLC prüfen soll.

Die zwei ersten Befehle schreiben das Modell, der dritte die Einstellungen. Der vierte lässt TLC alle Zustände prüfen und zeigt nur die Zeilen mit dem Ergebnis und den Zuständen.

Einen Ordner anlegen

Befehl
mkdir -p ~/schleuse

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Den Anfang des Modells schreiben

Befehl
printf '%s\n' "---- MODULE Schleuse ----" "VARIABLES aussen, innen" "vars == <<aussen, innen>>" "Init == aussen = FALSE /\ innen = FALSE" > ~/schleuse/Schleuse.tla

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Die Schritte und Invarianten anhängen

Befehl
printf '%s\n' "OeffneAussen == aussen = FALSE /\ aussen' = TRUE /\ UNCHANGED innen" "OeffneInnen == innen = FALSE /\ innen' = TRUE /\ UNCHANGED aussen" "Schliesse == (aussen \/ innen) /\ aussen' = FALSE /\ innen' = FALSE" "Next == OeffneAussen \/ OeffneInnen \/ Schliesse" "Spec == Init /\ [][Next]_vars" "NieBeide == ~(aussen /\ innen)" "AussenImmerZu == ~aussen" "====" >> ~/schleuse/Schleuse.tla

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Die Einstellungen für zwei Modelle schreiben

Befehl
printf '%s\n' "SPECIFICATION Spec" "INVARIANT NieBeide" | tee ~/schleuse/Schleuse.cfg > ~/schleuse/Schleuse2.cfg

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Hält die Invariante NieBeide?

Befehl
tlc ~/schleuse/Schleuse | grep -E "violated|^State"

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Das Gegenbeispiel ist der kürzeste Weg zum Fehler

TLC meldet, dass NieBeide verletzt ist, und nennt drei Zustände: den Start, das Öffnen des Außentors und das Öffnen des Innentors. Dahinter stehen Zeile und Spalte des Schritts in Ihrer Datei.

TLC sucht Zustand für Zustand, erst alle mit einem Schritt, dann mit zwei. Das erste Gegenbeispiel ist darum das kürzeste.

Ein häufiger Fehler

Warnung

Viele denken: Eine Invariante, die TLC nicht verletzt findet, beweist, dass das System sicher ist. Das stimmt nur für die Aussage, die dasteht. Die Invariante TRUE ist immer wahr und sagt nichts. Schreiben Sie die Aussage, die wirklich gelten soll.

Eine Reparatur ist eine zusätzliche Bedingung

Die Tore dürfen sich nur öffnen, wenn das andere Tor zu ist. Dafür bekommt jeder Öffnungsschritt eine Bedingung dazu. Der Befehl macht mit sed aus dem Modell ein zweites, Schleuse2, mit diesen beiden Bedingungen.

Danach prüft TLC dieselbe Invariante. Diesmal findet es keinen Fehler.

Das reparierte Modell schreiben

Befehl
sed -e 's/Schleuse ----/Schleuse2 ----/' -e 's/^OeffneAussen == aussen = FALSE/& \/\\ innen = FALSE/' -e 's/^OeffneInnen == innen = FALSE/& \/\\ aussen = FALSE/' ~/schleuse/Schleuse.tla > ~/schleuse/Schleuse2.tla

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Hält NieBeide im reparierten Modell?

Befehl
tlc ~/schleuse/Schleuse2 | grep -E "No error|violated|^State"

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Auch ein richtiges System verletzt manche Invariante

Die zweite Invariante, AussenImmerZu, behauptet, das Außentor sei nie offen. Das ist für eine Schleuse Unsinn, denn sie muss sich öffnen können.

TLC prüft sie trotzdem, wenn Sie ihren Namen hinter den Modellnamen schreiben. Das Gegenbeispiel zeigt dann: Das Tor lässt sich öffnen. Das beweist, dass die Schleuse nicht erstarrt ist.

Prüfen, ob das Außentor nie offen ist

Befehl
tlc ~/schleuse/Schleuse2 AussenImmerZu | grep -E "No error|violated|^State"

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Über dieses Lab und seinen Quellcode: Lab für formale Methoden: Z3, SPIN, TLA+ und Alloy in einer VM

Sie unterrichten eine Gruppe? Weisen Sie dieses Modul Ihren Studierenden zu, mit Handbuch für Lehrende, automatisch geprüften Aufgaben und einem Lab für jede Person.