Folien zum Buch in Powerpoint - home.edvsz.hs

Download Report

Transcript Folien zum Buch in Powerpoint - home.edvsz.hs

Formale Modelle der
Softwareentwicklung
Model-Checking, Verifikation, Analyse und
Simulation
Prof. Dr. Stephan Kleuker
• Bitte beachten Sie die Rechte des Verlages Vieweg+Teubner an
der Buchinhalten und Bildern
• Diese Folien sind als Begleitfolien für das Buch konzipiert
Formale Modelle der Softwareentwicklung
Stephan Kleuker
1
Überblick
1 Motivation von Formalen Modelle
2 Modelchecking mit PROMELA und SPIN
3 Modelchecking mit Timed Automata und Uppaal
4 Petrinetze
5 Programmverifikation
Formale Modelle der Softwareentwicklung
Stephan Kleuker
2
Ablauf
• 2h Vorlesung + 2h Übung
• 70 %
+
= 6 CP
30 %
• getrennt bewertet, müssen beide bestanden werden
• Übung:
– 75% Anwesenheit = (Übungsblatt vorliegen +
Lösungsversuche zum vorherigen Aufgabenblatt)
– nicht bewertete, 10 kleine bewertete (je 1 Punkt) und zwei
größere bewertete Übungsaufgaben (je 10 Punkte) (für
erstere: Abgabe im Folgepraktikum)
• Vorlesung: Klausur am Ende der Veranstaltung auf Papier,
Ähnlichkeit zu Übungsaufgaben wahrscheinlich,
Verständnisfragen
• Folienveranstaltungen sind schnell; von Master-Studierenden
wird hoher Anteil an Eigenarbeit erwartet
Formale Modelle der Softwareentwicklung
Stephan Kleuker
3
Spielregeln
• Rechner sind zu Beginn der Veranstaltung aus
• Handys sind aus
• Wir sind pünktlich
• Es redet nur eine Person zur Zeit
• Sie haben die Folien zur Kommentierung in der
Vorlesung vorliegen
• Probleme sofort melden, wer aussteigt meldet bitte
kurz, warum
Formale Modelle der Softwareentwicklung
Stephan Kleuker
4
1. Motivation von Formalen Modellen
1.1 Modellbegriff
1.2 Software-Fehler
1.3 Software-Engineering
Formale Modelle der Softwareentwicklung
Stephan Kleuker
5
Begriff: Formale Modelle
1.1
formal kann bedeuten
• entweder: Formalismus und Bürokratie
• oder: Präzision und Exaktheit
Modell:
• Abbild der Realität, mit dem Aussagen über die Realität
gewonnen werden können
passendes Modell:
• Modell, das zur Lösung einer Aufgabenstellung passt (Modell
aus dem korrekte Aussagen bzgl. der Aufgabenstellung
ableitbar sind)
• folgt: für verschiedene Aufgabenstellungen zur gleichen realen
Situation können verschiedene Modelle sinnvoll sein
Formale Modelle der Softwareentwicklung
Stephan Kleuker
6
Bekannte Modelle
• Welche Modelle kennen Sie in der Realität (nicht
Informatik), wozu werden sie eingesetzt?
• Welche Modelle kennen Sie in der Informatik, wozu
werden sie eingesetzt?
• Welche Erfahrungen haben Sie mit der Kombination
von Modellen gemacht, bzw. erwarten Sie?
Formale Modelle der Softwareentwicklung
Stephan Kleuker
7
Beispiele markanter Software-Fehler (1/2)
1.2
1962 Trägerrakete Mariner 1, Selbstzerstörung nach
Kursabweichung; in SW ein Komma statt eines Punktes
1971 Eole 1, Satellit zur Steuerung von Wetterballons, 71
Ballons bekommen irrtümlich Befehl zur Selbstzerstörung
1982 Größte nicht-nukleare Explosion durch Fehler in
Steuerungs-SW einer russischen Gap-Pipeline
1982 Flugabwehrsystem der Fregatte Sheffield versagt, da
anfliegender argentinischer Flugkörper als Freund erkannt
1991 Flugabwehrsystem Patriot verfehlt Scud-Rakete, da
notwendiger Systemneustart nach max. 100 h vergessen
1992 Londoner Ambulance Service, neue SW führt zu
Wartezeiten von bis zu drei Stunden
1994 Mondsonde Clementine, Sonde sollte einen Asteroiden
ansteuern, durch einen Software-Fehler wurden die
Triebwerke nach der Kurskorrektur nicht mehr abgestellt
1993 Pentium-Chip, fehlerhafte Divisionsberechnung
1995 Automatischer Gepäcktransport im Flughafen Denver
funktioniert nicht; zu viele Informationen im Netz
Formale Modelle der Softwareentwicklung
Stephan Kleuker
8
Beispiele markanter Software-Fehler (2/2)
1996 Notwendige Selbstzerstörung der Ariane 5; falsche
Steuersignale durch SW-Übernahme von Ariane 4
1999 Fehlende Sturmwarnung für Süddeutschland, da SW
starken Druckabfall als Messfehler interpretierte
2001 Fehlerhafte Bestrahlung von Krebspatienten durch nicht
bedachten Bedienfehler
2002 Amerikanische Bomben schlagen wg. SW-Fehler 15 bis 250
m zu weit links ein
2003 Patriot schießt befreundetes englisches Flugzeug ab
2003 Stromausfall USA, falsche Reaktion in SW auf starke
Lastschwankungen im Netz
2004 Rückruf Mercedes-Transporter, Fehler in Steuerungs-SW
schalten evtl. Motor ab (auch andere Fahrzeughersteller)
2005 Arbeitslosengeld (ALG 2): Berechnungsfehler führt zur
Nichtzahlung von Krankenkassenbeiträgen
2005 ALG 2: keine Auszahlung bei neun-stelliger Kontonummer
2005 T-Mobile: SMS für 80 statt 19 Cent abgerechnet
2005 Russische Trägerrakete Cryosat; Signal zum Abschalten
der Triebwerke der zweiten Stufe nicht weiter geleitet
Formale Modelle der Softwareentwicklung
Stephan Kleuker
9
Schleichende Software-Fehler
• kleines Unternehmen geht mit viel Know-how und
neuer Individual-SW auf den Markt
• SW wird bei Kunden direkt vor Ort angepasst
• mit Kundenzahl wächst Zahl der Anpassungen und
weiterer Kundenwünsche
• dadurch, dass zentrale Daten mehrfach in Modulen
gehalten werden, Datenabhängigkeiten schwer
analysierbar sind und Individual-SW nicht
dokumentiert ist, wird SW unwartbar
• typisches Problem vieler SW-Systeme: am Anfang
erfolgreich werden sie irgendwann nicht mehr
weiterentwickelbar
Formale Modelle der Softwareentwicklung
Stephan Kleuker
10
Ursachen für Software-Fehler
• mangelndes Verständnis von Anforderungen
• Übersehen von Ablaufmöglichkeiten
• Programmierfehler
• zu wenig Zeit für Tests
• mangelnde Qualifikation der Mitarbeiter
• unpassende SW-Werkzeuge
• mangelndes Managementverständnis für ITEntwicklung
• hoher Kostendruck, starker Preiskampf
Formale Modelle der Softwareentwicklung
Stephan Kleuker
11
Historie der Software-Entwicklung
1.3
• erste Computer von Spezialisten mit sehr hohem
Bildungsniveau entwickelt und programmiert
• Computer und Programme waren
Individualleistungen
• Mit steigender Verfügbarkeit von Computern stieg
auch die Anzahl der SW- und HW-Fehler
• Software-Entwicklung ist hoch kreativer
(künstlerischer) Prozess, der mit der Zeit in einen
ingenieur-wissenschaftlichen Rahmen (SoftwareEngineering) eingebettet wurde
• Zentrale Ergebnisse: Vorgehensmodelle mit
Prozessmodellen (wer macht wann, was, mit wem,
mit welchen Hilfsmitteln, warum)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
12
Skizze eines Vorgehensmodells
Anforderungsanalyse
Grobdesign
Feindesign
Implementierung
Test und Integration
Merkmal:
Projekt in kleine Teilschritte
zerlegt, n+1-ter Schritt kann
Probleme des n-ten Schritts lösen
Vorteile:
- dynamische Reaktion auf Risiken
- Teilergebnisse mit Kunden
diskutierbar
mögliche Nachteile:
- schwierige Projektplanung
- schwierige Vertragssituation
- Kunde erwartet zu schnell
Endergebnis
Bsp.: vier Inkremente
Formale Modelle der Softwareentwicklung
Stephan Kleuker
13
Qualitätssicherung (1/2)
Anforderungsanalyse
Feindesign
Implementierung
Test und Integration
Formale Modelle der Softwareentwicklung
Qualitätssicherung (QS)
Grobdesign
• QS ist eigenständiges
Teilprojekt
• zu jedem Projekt gehört
ein QS-Plan
• QS Plan: was wird wann
von wem wie überprüft
• QS sollte unabhängig
vom Projekt organisiert
sein
• Form der QS sehr stark
projektabhängig
• häufig Forderung nach
Normen (z.B. ISO 9000)
und QS-Standards (z.B
DO 178-B)
Stephan Kleuker
14
Qualitätssicherung (2/2)
konstruktive Qualitätssicherung:
• QS vor Projekt planen
• Auswahl von Methoden, Werkzeugen, Prozessen,
Schulungen
• Normen, Guidelines und Styleguides
analytische Qualitätssicherung:
• manuelle Verfahren (z.B: Inspektion und Audit) zur
Prüfung der Einhaltung konstruktiver Ansätze
• Reviews von Teilprodukten (z.B. Anforderungen,
Design)
• Einsatz von Testverfahren (Äquivalenzklassen,
Überdeckungen) in unterschiedlichen Testphasen
(Entwicklertests, Integrationstests, Systemtests,
Abnahmetests)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
15
Qualitätssicherung und Qualitätsmanagement
• IT-Projekte sind Teilprozesse eines Unternehmens
• Qualitätssicherung ist Teilprozess von IT-Projekten
• Prozess: wer macht wann was, unter welchen Voraussetzungen
soll was produziert werden, wer arbeitet mit, welche Hilfsmittel
gibt es
• Jedes Unternehmen kann mit seinen Prozessen, Kernprozesse
zur Wertschöpfung und Unterstützungsprozessen, dargestellt
werden
• Prozessmodellierung und Optimierung wichtiges Erfolgsthema
für Unternehmen
• verschiedene Richtlinien und Standards, z. B.:
– IT-Projekte: V-Modell, RUP, XP
– Prozessqualität: Capability Maturity Model Integrated (CMMI)
– Unternehmensprozesse: ISO 9000, TQM
Formale Modelle der Softwareentwicklung
Stephan Kleuker
16
Qualitätssicherung und formale Modelle
• Der Einsatz formaler Modelle ist eine
Qualitätssicherungsmaßnahme
• Es muss frühzeitig die Modellart gewählt werden, die
am passendsten für die zu betrachtenden Probleme
ist (Korrektheit, Speicherverbrauch,
Laufzeitverhalten)
• Auf der anderen Seite hilft das Verständnis formaler
Modelle bei der Auswahl anderer QS-Maßnahmen
• Welche Aussagen können warum aus welchem
Testverfahren gewonnen werden
Formale Modelle der Softwareentwicklung
Stephan Kleuker
17
Fazit
• Formale Modelle und formale Methoden sind das
Handwerkszeug des Informatik-Ingenieurs um
korrekte Systeme zu ermöglichen
• Verständnis formaler Modelle sind der Ansatz zum
Verständnis von Qualitätssicherungsmaßnahmen
und der Beurteilung ihrer Effizienz
• Man muss das passende Modell zur
Aufgabenstellung finden
• Ursachen für mangelhafte Software können in
verschiedenen betrieblichen Abläufen neben der
SW-Produktion liegen; diese Fehlerquellen sind zu
minimieren
Formale Modelle der Softwareentwicklung
Stephan Kleuker
18
2. Modelchecking mit PROMELA und SPIN
2.1
2.2
2.3
2.4
2.5
2.6
2.7
Modelchecking im Entwicklungskontext
Die Spezifikationssprache PROMELA
Simulation von PROMELA-Spezifikationen
Einfache Verifikationsmöglichkeiten
Verifikation von in LTL formulierten Anforderungen
Beispiele
PROMELA und SDL
auch:
G .J. Holzmann, The SPIN Model Checker, Addison Wesley,
2004
M. Ben-Ari, Principles of the Spin Model Checker, Springer,
2008
Formale Modelle der Softwareentwicklung
Stephan Kleuker
19
2.1 Modelchecking im Entwicklungskontext
• Grundidee des Modelcheckings
• Probleme der klassischen Software-Entwicklung
• Chancen und Probleme der Nutzung formaler
Methoden
Formale Modelle der Softwareentwicklung
Stephan Kleuker
20
Motivation von Modelchecking
• Ansatz: Gegeben ist ein Modell (oder Spezifikation)
und eine Anforderung, dann überprüft der ModelChecking-Algorithmus, ob das Modell die
Anforderung erfüllt oder nicht. Falls das Modell die
Anforderung nicht erfüllt, sollte der Algorithmus ein
Gegenbeispiel liefern.
• SPIN entwickelt von Gerard Holzmann, zunächst als
Simulator, dann Verifikationswerkzeug
• 2001 renommierten ACM Software System Award
(z. B.: 1983 UNIX, 1987 Smalltalk, 1991 TCP/IP, 1995
World-Wide Web, 2002 Java)
• www.spinroot.com (frei verfügbar, seit 1991)
• Ansatz: Berechne alle erreichbaren Zustände und
analysiere sie
Formale Modelle der Softwareentwicklung
Stephan Kleuker
21
Mögliche Korrektheitsprobleme
möglicher Arbeitsweg
potenzielle Fehlerquelle
abgesicherter Weg
Aufgabenstellung
unzulässige
Interpretation
unpräzise
Aufgabenstellung
Lösungsidee
fehlerhafte
Formalisierung
Anforderungen
Modelchecking
unpassendes
Modell
Programmierfehler
zu starke Vereinfachung
Modell
Programm
Transformation
Formale Modelle der Softwareentwicklung
Stephan Kleuker
22
2.2 Die Spezifikationssprache PROMELA
•
•
•
•
•
•
Nichtdeterministische Schleifen und Alternativen
Datentypen
nebenläufige Prozesse
atomare Bereiche
synchrone und asynchrone Kommunikation
Varianten der Nachrichtenabarbeitung
Formale Modelle der Softwareentwicklung
Stephan Kleuker
23
Ziele von Spezifikationssprachen
• Erstellung von Modellen
– möglichst einfach beschreibbar
– fachlich möglichst kompakt
• Spezifikationssprachen bieten vielfältige
Sprachkonstrukte an; generell nur die nutzen, die in
der Praxis vorhanden sind
Formale Modelle der Softwareentwicklung
Stephan Kleuker
24
Erste Sprachkonstrukte von PROMELA
#define N 20
int erg;
proctype Ungerade(){
int x=1;
do
:: x <= N ->
erg=erg+x;
x=x+2
:: x > N -> break
od
}
proctype Gerade(){
int x=0;
do
:: x<=N ->
erg=erg+x;
x=x+2
:: x>N -> break
od
}
Formale Modelle der Softwareentwicklung
init{
erg=0;
run Ungerade();
run Gerade()
}
PROcess MEta LAnguage
- Prozesse spezifizieren
- Spezifikationen können
Nichtdeterminismus
enthalten
- Syntax lehnt sich leicht an
C an
- globale und lokale
Variablen
Stephan Kleuker
25
Nichtdeterminismus
if
:: x<10 -> x=x+2
:: x<15 -> x=x+1
:: else -> skip
fi;
• Es werden alle ausführbaren Alternativen (stehen nach ::)
bestimmt, dann nicht-deterministisch eine ausgewählt
(Guarded-Command-Language; Dijkstra)
• Boolesche Bedingungen sind ausführbar, genau dann, wenn
sie wahr sind
• x>4; x<3; x==5; kann Spezifikationsteil sein
• else nur, wenn alle anderen Alternativen nicht möglich
• Statt -> könnte auch ; stehen
Formale Modelle der Softwareentwicklung
Stephan Kleuker
26
Elementare Datentypen in PROMELA
Datentyp
bit
Wertebereich Anmerkung
bool
0..1
byte
0..255
chan
1..255
Kommunikationskanäle (später)
mtype
1..255
Nachrichtenwerte (gleich)
pid
0...255
für Prozessidentifikatoren (später)
short
-215..215-1
int
-231..231-1
0..1
unsigned 0..2<Wert>-1
Formale Modelle der Softwareentwicklung
auch Werte true (==1) und false (==0)
möglich
Anzahl Bits <Wert> wird angegeben,
z.B. unsigned x:5; Maximalwert 31
Stephan Kleuker
27
Prioritäten in PROMELA
Priorität Operator
() [] .
1
2
3
4
5
6
! ~
* / %
+ << >>
< <= > >=
7
8
9
10
11
12
== !=
&
|
&&
||
=
Formale Modelle der Softwareentwicklung
Kommentar
Klammern, Feldklammern,
Teilkomponente
Negation, Bit-Komplement
Multiplikation, Division, Modulo
Addition, Subtraktion
bitweiser Links- und Recht-Shift
kleiner, kleiner-gleich, größer, größergleich
Gleichheit, Ungleichheit
bitweise Und
bitweise Oder
logisches Und
logisches Oder
Zuweisung
Stephan Kleuker
28
Optimierte Summenberechnung
#define N 20
int erg;
proctype Summiere(int start){
int x=start;
do
:: x<=N -> erg=erg+x;
x=x+2
:: x>N -> break
od
}
init{
erg=0;
run Summiere(1);
run Summiere(0)
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
29
do, if, active, goto
#define PROZESSE 2
byte x=0;
byte y;
active [PROZESSE] proctype ifdoSpiel(){
do
:: x<10 -> x=x+1
:: (x> 0 && x<10) -> x=x-1
goto sollte selten
:: x< 9 -> x=x+3
verwandt werden, häufiger
:: else -> x=x+4; break
od;
benutzt, wenn aus anderer
if
Sprache nach PROMELA
:: x<10 -> y=0
übersetzt wird
:: x>=10 && x<15 -> y=1
:: else -> y=2
active: Prozess startet
fi;
nochmal:
sofort
if
:: x<10 && y>0 -> goto nochmal
:: else -> skip
fi
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
30
Datentypen in PROMELA
#define ANZAHL 3
/* Ein Aufzählungstyp mtype, Werte von rechts nach
links ausgehend von 1 (wasser==5) nummeriert */
mtype = {sekt,wodka,osaft,bier};
mtype = {whisky,wasser};
/* Records, wie in C, aber keine Zeiger */
typedef Person{
short id;
mtype trinkt;
};
/* Felder (Arrays) */
Person nase[ANZAHL];
/* Felder auch in Records erlaubt
typedef Kommuniziert{
Person p[2];
};
Formale Modelle der Softwareentwicklung
Stephan Kleuker
31
Spezifikation verteilter Systeme
byte x=0;
active proctype P1(){
x=x+1;
x=x+1;
}
active proctype P2(){
x=2;
}
• SPIN nutzt so genannte Interleaving-Semantik, Prozesse
können abwechselnd voranschreiten
• Mögliche Endergebnisse x=2, x=3, x=4
Formale Modelle der Softwareentwicklung
Stephan Kleuker
32
Atomare Bereiche
byte x=0;
active proctype P1(){
atomic{
x=x+1;
x=x+1;
}
}
active proctype P2(){
x=2;
}
• atomare Bereiche werden wie ein Schritt angesehen, sie sind
nicht unterbrechbar
• mögliche Ergebnisse: x=2, x=4
Formale Modelle der Softwareentwicklung
Stephan Kleuker
33
Interleaving genauer
• Analysiert man aus Sicht des Compilers, was bei
x=x+1 passiert, so handelt es sich um mehrere
Schritte:
– Lade von der zu x gehörenden Speicheradresse
den Wert von x in einen Speicher der CPU
– Führe auf der CPU die Erhöhung um eins durch
– Schreibe das Ergebnis aus der CPU wieder in die
zu x gehörende Speicheradresse
• zwei parallele Teilprogramme, die mit x=1 starten
und x=x+1 durchführen, können zu x=2 oder x=3
kommen
• Wichtig ist, welche Aktionen ununterbrechbar sind
(in Semantik festgelegt), diese Aktionen heißen
atomar
Formale Modelle der Softwareentwicklung
Stephan Kleuker
34
Kommunizierende Prozesse
zuP2
P1
zuP1
P2
• Prozesse können über Kanäle kommunizieren (z. B.
physikalische Leitungen)
• anders als im Bild können in PROMELA mehrere
Prozesse einen Kanal nutzen
• anders als im Bild sind Kanäle nicht gerichtet, jeder
kann lesen und schreiben
• Kanäle können gepuffert sein
• gewähltes Modell sollte zur Realität passen (deshalb
Pfeile im Bild)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
35
Beispiel: Kommunikationsprotokoll (1/3)
informelle Spezifikation:
• Der Prozess P1 versucht, über zuP2 die Werte von 1 bis 10 an
P2 zu senden. Eine Nachricht besteht dabei aus den
Teilinformationen Nachrichtenname (hier send) und dem
übermittelten Wert. P2 empfängt den Wert und schickt zur
Bestätigung den gleichen Wert mit dem Nachrichtennamen ack
für Acknowledge, also Bestätigung, an P1 über zuP1 zurück.
Nachdem P1 den bestätigten Wert erhalten hat, wird der
nächste Wert an P2 übermittelt.
• Weiterhin soll modelliert werden, dass die Verbindung von P1
nach P2 nicht fehlerfrei funktioniert. Wenn P2 einen Wert
empfängt und P2 an der Qualität zweifelt, wird der vorher
gesandte Wert an P1 gesendet. P1 wiederholt daraufhin den
zuletzt übertragenen Wert.
Formale Modelle der Softwareentwicklung
Stephan Kleuker
36
Beispiel: Kommunikationsprotokoll (2/3)
mtype = {send,ack};
byte N=10;
chan zuP2 = [0] of {mtype,byte}; /*Rendez-vous oder*/
chan zuP1 = [0] of {mtype,byte}; /*synchrone Komm.
*/
active proctype P1(){
byte wert=1;
byte antwort;
do
:: wert<=N ->
zuP2!send,wert; /* zuP2!send(wert); */
zuP1?ack,antwort
if
:: antwort==wert -> wert=wert+1
:: else ->skip
fi
:: else -> break
od
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
37
Beispiel: Kommunikationsprotokoll (3/3)
active proctype P2(){
byte neu=0;
byte ein=0;
do
:: zuP2?send,ein ->
if
:: true ->
neu=ein;
if
:: neu==N -> break
:: else -> skip
fi
:: true ->skip
fi;
zuP1!ack,neu;
od;
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
38
Synchrone Kommunikation
chan <Kanalname> = [<Puffergröße>] of {
<Nachrichtenteiltyp1>, ...
<NachrichtenteiltypN> };
• Puffergröße=0: Rendez-Vous oder synchrone
Kommunikation
• Sender muss warten, wenn Empfänger nicht bereit
• Empfänger muss warten, wenn Sender nicht bereit
• Sender und Empfänger „wissen“, dass
Kommunikation stattgefunden hat
• Sender und Empfänger kennen Reihenfolge der
Nachrichten
Formale Modelle der Softwareentwicklung
Stephan Kleuker
39
Asynchrone Kommunikation
zuP2
P1
zuP1
P2
chan <Kanalname> = [<Puffergröße>] of
{ <Nachrichtenteiltyp1>, ... , <NachrichtenteiltypN> };
•
•
•
•
•
Puffergröße>0: gepufferte oder asynchrone Kommunikation
Sender sendet unabhängig vom Empfänger in dessen Puffer
Empfänger entnimmt älteste Nachricht aus dem Puffer
Falls keine Nachricht im Puffer, muss Empfänger warten
Falls Puffer voll, können für SPIN zwei Varianten eingestellt
werden:
– Sender muss warten, bis Platz frei
– Nachricht geht verloren
Formale Modelle der Softwareentwicklung
Stephan Kleuker
40
Typische Kommunikationsprobleme
zuP2
P1
synchron: Deadlock
P1
P2
zuP1
asynchron: Race
P2
P1
P2
zuP2!a
zuP1!b
zuP2!a
zuP1!b
zuP1?b
zuP2?a
zuP1?b
zuP2?a
P1 meint erst a dann b
P2 meint erst b dann a
Formale Modelle der Softwareentwicklung
Stephan Kleuker
41
Message Sequence Charts (MSC)
• dienen zur Visualisierung der
P1
P2
Prozesskommunikationen
zuP2!a
zuP1!b
• Jeder Prozess als
senkrechter Balken
• Zeit verläuft von oben
nach unten
zuP1?b
zuP2?a
• Auf Lebenslinie des Prozesses sieht man, wann
Prozess Kommunikation begonnen hat (senden) und
wann sie empfangen wurde
• hilfreich:
– um typische Abläufe zu visualisieren
– um Testfälle zu definieren
• MSC in UML als Sequenzdiagramme mit erweiterten
Möglichkeiten in UML 2.0
Formale Modelle der Softwareentwicklung
Stephan Kleuker
42
MSC in XSPIN (synchrones Beispiel)
Nachrichtenaustausch
zwischen P1
und P2 aus
Beispiel
Formale Modelle der Softwareentwicklung
Stephan Kleuker
43
Kanalverhalten
• für die Simulation (später auch Verifikation) wird für
alle Kanäle festgelegt, wie sie sich bei vollen Puffern
verhalten
– blockierend: Sender muss warten, bis ein
Pufferplatz frei ist
– verlierend: Sender kann immer senden, Nachricht
geht eventuell verloren
Formale Modelle der Softwareentwicklung
Stephan Kleuker
44
Kanalanalysemöglichkeiten
Funktion
len(k)
empty(k)
nempty(k)
full(k)
nfull(k)
Bedeutung / Rückgabewert
Nachrichtenanzahl im Kanal k
ist Nachrichtenkanal k leer?
ist Nachrichtenkanal k nicht leer?
ist Nachrichtenkanal k voll?
ist Nachrichtenkanal k nicht voll?
• zur Nutzung muss der Prozess den Kanal kennen (er
muss sichtbar sein)
• hier: nur globale Kanäle (sonst auch als Variablen
nutzbar)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
45
Analyse der Kanäle in PROMELA
Spezifikation: chan k = [2] of {mtype,byte}
mögliche Visualisierungen
• gerichteter Kanal,
k
S
E
nur ein Sender,
nur ein Empfänger
• Kanal als EmpfangsS1
adresse, mehrere Sender,
k
E
nur ein Empfänger
S2
• Kanal als allgemeines
Austauschmedium,
S1
E1
k
mehrere Sender,
S2
E2
mehrere Empfänger
• PROMELA erlaubt alle Interpretationen; es ist die jeweils zum
Modell passende zu wählen
Formale Modelle der Softwareentwicklung
Stephan Kleuker
46
Beispiel: asynchrone Kommunikation (1/4)
Teilnehmer 1
toV
Teilnehmer 2
...
toV
toP[1]
Teilnehmer n
toV
toV
toP[2]
toP[n]
Verteiler
informelle Spezifikation:
Die Idee ist, dass beliebig viele Teilnehmer an einem Verteiler
angeschlossen sind, dabei nutzen alle Teilnehmer den gleichen
Kanal, um Informationen an den Verteiler zu senden. Jede
Information, die die Teilnehmer dem Verteiler schicken, wird an
alle anderen angeschlossenen Teilnehmer verteilt.
Im Beispiel schicken alle Teilnehmer die Zahlen 1 bis 10, jeder
Teilnehmer summiert alle empfangenen Zahlen auf. Durch
diese Festlegung ist es recht einfach, eine
Terminierungsbedingung anzugeben; bei n Prozessen erhält
man (n-1)-mal die Summe der Werte von 1 bis 10.
Formale Modelle der Softwareentwicklung
Stephan Kleuker
47
Beispiel: asynchrone Kommunikation (2/4)
#define PROZESSE 3
#define MAX 10
#define GESAMT ((MAX*(MAX+1))/2)
#define PUFFER 2
mtype={send,rec}
chan toV = [PUFFER] of {mtype,byte,byte};
chan toP[PROZESSE]= [PUFFER] of {mtype,byte,byte};
init{
/* für Erklärung vorgezogen, geht so nicht
*/
atomic{
byte i=0;
do
:: i<PROZESSE ->
run Teilnehmer(i);
i=i+1
:: else -> break
od;
run Verteiler()
};
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
48
Beispiel: asynchrone Kommunikation (3/4)
proctype Teilnehmer(byte id){
byte i=1;
int summe=0;
byte wert;
do
:: atomic{
i<=MAX && nfull(toV) ; /* 1 */
toV!send,id,i;
i=i+1
}
:: summe<GESAMT*(PROZESSE-1)
&& toP[id]?[rec,_,_] ->
toP[id]?rec,_,wert;
summe=summe+wert
:: i==MAX+1 && summe==GESAMT *(PROZESSE-1) ->
break
od;
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
49
Beispiel: asynchrone Kommunikation (4/4)
proctype Verteiler(){
byte name;
byte wert;
byte emp;
do
:: toV?send,name,wert ->
emp=0;
do
:: emp<PROZESSE && emp!=name ->
toP[emp]!rec, name, wert;
emp=emp+1
:: emp==name -> emp=emp+1
:: emp==PROZESSE -> break
od;
od;
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
50
Simulation: MSC asynchron
Formale Modelle der Softwareentwicklung
Stephan Kleuker
51
Empfangsarten
Befehl
c?x,y
c?42,y
Semantik
empfangene Werte werden in x und y gespeichert +
Empfang nur möglich, wenn erste Nachricht den +
Wert 42 hat
c?eval(x),y Empfang nur möglich, wenn erster Wert dem +
Wert von x entspricht
c?<x,y>
Empfang in x und y, Nachricht wird nicht aus dem
Puffer gelöscht
c??42,y
es wird die älteste Nachricht aus dem Puffer
empfangen, deren erster Wert 42 ist (wenn nicht
vorhanden, dann warten)
c??<42,y>
älteste passende Nachricht wird gelesen, bleibt
aber im Puffer
+ für erlaubt bei synchroner Kommunikation
Formale Modelle der Softwareentwicklung
Stephan Kleuker
52
Prüfungen der Kommunikationsbereitschaft
Befehl
Semantik
c?[x,y]
Prüfung, ob der Empfang möglich ist
c?[42,y]
ist c?42,y als nächstes möglich?
c??[42,y]
ist c??42,y möglich
erlaubt nur bei asynchroner Kommunikation
Formale Modelle der Softwareentwicklung
Stephan Kleuker
53
Asynchron: Bewachte Kommunikation
• folgende Spezifikation funktioniert nur asynchron (leider
synchron kein Syntaxproblem)
• _ für beliebiger Wert (wird weggeworfen)
chan a =[1] of {bit};
chan b =[1] of {bit};
active proctype Sender(){
do
:: a!1;
:: b!0;
od;
}
active proctype Empfaenger(){
byte count=0;
do /* synchron syntaktisch ok, semantisch nicht */
:: count%2==0 && a?[_] -> a?_; count=count+1;
:: count%2==1 && b?[_] -> b?_; count=count+1;
od;
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
54
Nie Kommunikation mit Bedingung verbinden
• letzte Folie: Verknüpfung von Boolescher Bedingung und
Kommunikationsbereitschaft ist ok
• Prüfung der Kommunikationsbereitschaft nur bei asynchron
sinnvoll
• Verknüpfung von Boolescher Bedingung und Kommunikation
nicht erlaubt [wäre semantisch Ausführbarkeit testen und
gleichzeitig ausführen]
:: count%2==0 && a?_ -> count=count+1;
spin: line 18 "pan_in", Error: syntax error saw 'an identifier'
• Man beachte, folgendes hat andere Bedeutung
:: count%2==0 ->
a?_;
count=count+1;
Formale Modelle der Softwareentwicklung
Stephan Kleuker
55
Spezifikation eines Kommunikationskanals (1/3)
• Man kann Kommunikationskanäle auch „von Hand“
spezifizieren, dazu muss eine Queue als globale Variable
spezifiziert werden
• Interleaving-Probleme sind zu beachten,
Kommunikationsschritte sollten atomar sein
#define PUFFER 3
byte pos=0; /* Realisierung einer Queue */
#define ISTVOLL (pos>=PUFFER)
mtype={send};
typedef Nachricht{
mtype typ;
byte inhalt;
};
Nachricht kanal[PUFFER];
Formale Modelle der Softwareentwicklung
Stephan Kleuker
56
Spezifikation eines Kommunikationskanals (2/3)
active proctype Sender(){
byte wert=1;
Nachricht nach;
do
:: wert>=10 -> break;
:: atomic{
wert<=10 && !ISTVOLL;
nach.typ=send; /* geht einfacher, zeigt
Prinzip */
nach.inhalt=wert;
kanal[pos].typ=nach.typ;
kanal[pos].inhalt=nach.inhalt;
pos=pos+1;
}
wert=wert+1;
od;
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
57
Spezifikation eines Kommunikationskanals (3/3)
active proctype Empfaenger(){
byte summe=0;
byte tmp;
do
:: atomic{
pos>0;
summe=summe+kanal[0].inhalt;
tmp=0;
do
:: tmp<pos-1 ->
kanal[tmp].typ=kanal[tmp+1].typ;
kanal[tmp].inhalt=kanal[tmp+1].inhalt;
tmp=tmp+1;
:: else -> break;
od;
pos=pos-1;
}
od;
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
58
_pid
#define N 5
chan c[N]=[0] of {byte};
byte erg=0;
active [N] proctype P(){
c[_pid]!_pid;
}
active proctype Emp(){
byte tmp=0;
byte wert;
do
:: tmp<N ->
c[tmp]?wert;
erg=erg+wert;
tmp++;
:: else -> break;
od;
}
Formale Modelle der Softwareentwicklung
• Jeder Prozess erhält bei
seiner Erzeugung eine
lokale Variable _pid
• Die Erzeugung erfolgt in
der Reihenfolge, in der die
Spezifikationen in
PROMELA stehen
• Typischer Einsatz:
Erzeugung gleichartiger
Prozesse mit _pid zur
Unterscheidung
• Ergebnis: In erg steht die
Summe von 1 bis N-1
Stephan Kleuker
59
2.3 Simulation von PROMELA-Spezifikationen
• Einführung in XSPIN
• Syntaxprüfung
• Simulationseinstellung
Formale Modelle der Softwareentwicklung
Stephan Kleuker
60
Spezifikationsentwicklung mit PROMELA und XSPIN
• vorher auf Papier planen
• Iterativ im Großen entwickeln
– erst typischen Ablauf zum Laufen bringen
– dann weitere Fälle ergänzen
• Iterativ im Kleinen entwickeln
– wenige syntaktisch korrekte (?) Zeilen eingeben und Syntax
prüfen (Fehlermeldungen helfen nicht immer)
– immer zu do ein od und zu if ein fi eingeben
• auf Sprachelemente der Vorlesung konzentrieren (Experimente
getrennt durchführen)
• Simulieren; interaktiv und zufällig gemischt
• später: dann Verifikationsmöglichkeiten vorbereiten und
verifizieren
Formale Modelle der Softwareentwicklung
Stephan Kleuker
61
Simulation mit XSPIN
XSPIN ist etwas „verstaubte“
Oberfläche zur Steuerung von
SPIN (JSpin nicht besser).
Alternativ kann SPIN als
Kommandozeilen-Werkzeug
genutzt werden!
Fenster zur Bearbeitung von
Spezifikationen
Aktionen, die mit SPIN zuletzt
ausgeführt wurden
Formale Modelle der Softwareentwicklung
Stephan Kleuker
62
XSPIN-Menüs
• „Clear Selections“, Markierungen löschen, wenn z.B.
bei Syntaxprüfung Fehler markiert wurden
Formale Modelle der Softwareentwicklung
Stephan Kleuker
63
Syntax-Prüfung in XSPIN
Formale Modelle der Softwareentwicklung
Stephan Kleuker
64
Simulationseinstellungen
Welche
Ausgabefenster
sollen
neben
Standardausgabe
sichtbar
sein?
Formale Modelle der Softwareentwicklung
Stephan Kleuker
65
Simulationsarten
• Random: Wenn
ausgewählt werden kann,
welcher Schritt als
nächstes möglich ist,
wird diese Auswahl vom
Simulator getroffen (seed
steuert
Zufallszahlengenerator)
• Guided: nur sinnvoll, wenn in einer Datei abgespeichert ist,
welche Schritte ausgeführt werden sollen, beim gescheiterten
Modelchecking gibt es für den Fehlerfall eine
Ausführungssequenz
• Interactive: Bei jeder Auswahlmöglichkeit, welcher Schritt als
nächstes durchgeführt werden soll, wird der Nutzer befragt
Formale Modelle der Softwareentwicklung
Stephan Kleuker
66
Start einer Simulation
Schrittnummer
welcher Prozess
welche Zeile
was ausgeführt
Beispielfenster mit
Werten aktueller
Variablen
Formale Modelle der Softwareentwicklung
Stephan Kleuker
67
Simulationsergebnis
• Simulation der ersten Spezifikation zur Summenbildung
• Im Hauptfenster immer: Schrittnummer, welcher Prozess,
welche Zeile, was ausgeführt
• do-Schleifen werden intern zu if mit goto (siehe Schritt 92)
• man erkennt ob Prozesse terminiert sind
Formale Modelle der Softwareentwicklung
Stephan Kleuker
68
Interaktive Simulation
oben: man sieht welche
Möglichkeiten analysiert wurden
ausführbare Möglichkeiten
werden dem Nutzer angeboten
(nicht ausführbar teilweise trotzdem
wählbar, dann nicht ausgeführt)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
69
Zusatzinformation: Time Sequence
Visualisierung
welcher Prozess
wann tätig war
Markierung:
Schrittnummer,
Prozess-ID
Formale Modelle der Softwareentwicklung
Stephan Kleuker
70
printf
• Spezifikationen können printf-Befehl aus C enthalten
• printf("Text mit Platzhaltern", Var1, … VarN);
#define PROZESSE 4
byte x=0;
active[PROZESSE] proctype P(){
do
:: x<8 -> atomic{x=x+1;
printf("Prozess %d: x=%d\n",_pid,x)
}
:: else -> break
od
}
in Simulationsausgabe:
24: proc 1 (P) line 5 "pan_in" (state 4)
[x = (x+1)]
Prozess 1: x=6
25:
proc 1 (P) line 7 "pan_in" (state 3) [printf('Prozess %d: x=%d\\n',_pid,x)]
Formale Modelle der Softwareentwicklung
Stephan Kleuker
71
printf in MSC
•
printf("MSC: Prozess %d: x=%d\n",_pid,x)
• Anfang: MSC+Leerzeichen
Formale Modelle der Softwareentwicklung
Ende: \n
Stephan Kleuker
72
Zusatzinformation: etwas Performanceanalyse
Ausgabe, welcher Prozess
wie häufig tätig
kann auch während
laufender Simulation
mitlaufen (wie andere
Fenster auch)
evtl. hilfreich bei BottleneckAnalyse
Formale Modelle der Softwareentwicklung
Stephan Kleuker
73
Analyse von atomic (1/2)
int x=0;
int y=0;
active proctype P(){
atomic{
x==1;
printf("MSC: Prozess
y=1;
printf("MSC: Prozess
y=y+1;
printf("MSC: Prozess
}
}
active proctype Q(){
atomic{
x=1;
printf("MSC: Prozess
y==1;
printf("MSC: Prozess
x=x+1;
printf("MSC: Prozess
}
}
Formale Modelle der Softwareentwicklung
P: x==1\n");
P: y=1\n");
P: y=y+1\n")
Q: x=1\n");
Q: y==1\n");
Q: x=x+1\n")
Stephan Kleuker
74
Analyse von atomic (2/2)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
75
2.4 Einfache Verifikationsmöglichkeiten
2.4.1
2.4.2
2.4.3
2.4.4
2.4.5
2.4.6
2.4.7
2.4.8
2.4.9
Grundideen des Modelcheckings
Modelchecking sehr großer Systeme
Lebendigkeit und Sicherheit
Zusicherungen
Prozessterminierung
Ausführung einfacher Verifikationen
Nachweis von Lebendigkeitseigenschaften
Trace-Zusicherungen
Never-Claims
Formale Modelle der Softwareentwicklung
Stephan Kleuker
76
Verifikationsansatz
2.4.1
• SPIN berechnet alle möglichen Zustände, dabei werden
Zustandseigenschaften bei Erstellung geprüft
• SPIN muss Zustandswiederholungen erkennen
• Beispielspezifikation:
byte x=0;
/* 1 */
byte y=0;
/* 2 */
active proctype Mini(){
do
/* 3 */
:: x<2 ->
/* 4 */
x=x+1;
/* 5 */
:: y<2 ->
/* 6 */
y=y+1;
/* 7 */
:: else ->
/* 8 */
break;
/* 9 */
od;
}
/* 10 */
Formale Modelle der Softwareentwicklung
Stephan Kleuker
77
Zustandsraum
(_,3,0,0)
x<2
y<2
(0,5,0,0)
(0,7,0,0)
x=x+1
y=y+1
(0,3,1,0)
x<2
y<2
(0,5,1,0)
x<2
(0,7,1,0)
x=x+1
(0,7,2,0)
(0,3,1,1)
(0,5,1,1)
y=y+1
(0,7,0,1)
y=y+1
x=x+1
x<2
y<2
(0,3,0,2)
y<2
x<2
(0,7,1,1)
x=x+1
(0,5,0,2)
y=y+1
(0,3,2,1)
x=x+1
(0,3,1,2)
y<2
(0,7,2,1)
x<2
y=y+1
( ProzessID,
Folgezeile,
x-Wert,
y-Wert) = Zustandsvektor
Formale Modelle der Softwareentwicklung
y<2
(0,5,0,1)
y=y+1
(0,3,2,0)
(0,3,0,1)
x=x+1
(0,5,1,2)
(0,3,2,2)
else
(0,9,2,2)
break
(0,10,2,2)
Stephan Kleuker
78
Verwaltung der Zustände mit Hash-Tabellen
Wert
0
1
(0,3,2,2)
(0,7,1,0)
(0,10,2,2)
(0,5,1,2)
2
(0,7,2,0)
(0,7,1,1)
3
(_,3,0,0)
(0,7,2,1)
4
(0,3,1,0)
(0,3,0,1)
5
(0,5,0,0)
(0,5,1,0)
(0,3,2,0)
(0,3,2,1)
6
(0,5,1,1)
(0,7,0,1)
(0,7,0,0)
(0,5,0,2)
(0,3,1,1)
(0,9,2,2)
(0,3,0,2)
(0,3,1,2)
(0,5,0,1)
• schnelle Hashfunktion zur Berechnung der Position in HashTabelle, Hashfunktion: (Folgezeile+x+y) % 7
• wenn Tabelleneintrag belegt, prüfen ob gleich
• wenn nicht, gleich einfügen (anhängen), sonst gleicher Zustand
gefunden
Formale Modelle der Softwareentwicklung
Stephan Kleuker
79
Zentrale Aufgabe: kleines Modell (1/2)
• es ist Aufgabe des Spezifizierers, das Modell
möglichst klein und trotzdem realistisch zu halten
• möglichst klein:
– wenig Prozesse
– kleinst-mögliche Datentypen
– keine überflüssigen Informationen in
Kommunikationsprotokollen
– möglichst kleine Puffer
– wenig Nichtdeterminismus: atomic, d_step
realistisch:
• Antworten des Modells auf Fragen müssen sich auf
Realität übertragen lassen
• z. B. kann man Puffer nicht einfach vergrößern oder
verkleinern
Formale Modelle der Softwareentwicklung
Stephan Kleuker
80
Zentrale Aufgabe: kleines Modell (2/2)
In Spezifikation:
• chan c1 =[2] of {byte,short};
chan c2 =[2] of {short,bool};
active proctype P(){
xr c1;
// nur P liest aus c1
xs c2; ... // nur P schreibt auf c2
•
•
•
•
geht nur, wenn c1 und c2 keine Arrays sind
atomic{}: Bei Blockade kann Kontrolle an anderen Prozess
übergehen, wenn Kontrolle zurück, dann auch Rest atomar
d_step{}: Spezifizierer garantiert, dass innerer Ablauf
deterministisch
alles deterministisch machen, was für Analyse unwichtig
evtl. pro Aufgabenstellung neues Modell
Formale Modelle der Softwareentwicklung
Stephan Kleuker
81
Optimierungen und Kompromisse
2.4.2
• Die Verifikation großer Modelle kann sehr lange dauern und mit
unbefriedigenden Ergebnissen enden:
– Speicherüberlauf
– maximale Suchtiefe überschritten
• Lösungsansätze
– weitere Modelloptimierungen, wenn möglich
– Reduktion der Zustände mit bestimmten Regeln (partial
order reduction)
– Reduktion auf den Wunsch, möglichst viele Zustände zu
untersuchen (gefundene Fehler sind echte Fehler, keine
gefundenen Fehler keine Garantie)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
82
Partial Order Reduction
proctype P1(){
...
a;
...
}
proctype P2(){
...
b;
...
}
a
z1
b
z11
z12
b
z2
a
• Häufig führen unabhängige Teilspezifikationen zu Rauten im
Zustandsraum
• links und rechts zusammen nur interessant, wenn von ihnen
weitere Zustände abgehen oder nach Detailinformationen
gesucht wird
• Ansatz: wenn uninteressant, lasse einen Zustand weg
• geht immer, wenn nur Endzustände interessant
• kritisch, wenn z. B. niemals x>3  y<4 gefordert
Formale Modelle der Softwareentwicklung
Stephan Kleuker
83
Beispiel: Partial Order Reduction
#define PROZESSE 2
#define GRENZE 10
byte x[PROZESSE];
active [PROZESSE] proctype P(){
x[_pid]=0;
do
:: x[_pid]<GRENZE -> x[_pid]=x[_pid]+1;
:: else -> break;
od;
}
• _pid steht für Systemvariable mit eindeutigem
Prozessidentifikator
• ohne Partial Order Reduction: 553 stored + 506 matched
• mit Partial Order Reduction: 553 stored + 484 matched
Formale Modelle der Softwareentwicklung
Stephan Kleuker
84
Bitstate-Hashing
• Standard-Hashfunktion speichert für jeden Zustand den
Zustandsvektor (einige Bytes)
• Alternativ: Hashfunktion speichert nur ein Bit
• Annahme: Ist Bit gesetzt, wurde Zustand vorher besucht
• Annahme stimmt nicht immer, da Hash-Funktion
unterschiedliche Zustände auf gleichen Wert abbilden kann
• da Raum für Hashwerte sehr sehr groß gewählt werden kann,
kann man so die Gefahr reduzieren (mit
Wahrscheinlichkeitsrechnung analysierbar))
• SPIN-Ansatz: Nutzung mehrerer unterschiedlicher
Hashfunktionen (Standard:2) und mehrerer Bits (= Anzahl
Hashfunktionen)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
85
Variante
• Kleines Beispiel hat bereits Zustandsvektorgröße 12
Byte ( typisch > 100 Byte)
• Hash-Variante nach Wolper: Nimm Hashfunktion, die
sehr großen Zahlenbereich abdeckt, z.B. 0 – 264-1,
Ergebnis benötigt 8 Byte
• Diese Zahl wird in echter Hashtabelle gespeichert
• Durch sehr großen Zahlenraum der ersten HashFunktion ist Wahrscheinlichkeit der unerwünschten
Kollisionen sehr gering
Formale Modelle der Softwareentwicklung
Stephan Kleuker
86
Speicheroptimierung dann Näherung (1/2)
• Die fortgeschrittenen Parameter sind bei Problemen mit dem
Speicher schrittweise zu optimieren (kann zeitaufwändig sein)
• zuerst: Speicheroptimierung durch Komprimierung (viel
langsamer, aber vollständige Prüfung)
• wenn das nicht geht: eine der vorgestellten Annäherungen an
die vollständige Durchsuchung nutzen
pan: out of memory
3.73208e+08 bytes used
102400 bytes more needed
3.73293e+08 bytes limit
hint: to reduce memory, recompile with
-DCOLLAPSE # good, fast compression, or
-DMA=72
# better/slower compression, or
-DHC # hash-compaction, approximation
-DBITSTATE # supertrace, approximation
Formale Modelle der Softwareentwicklung
Stephan Kleuker
87
Speicheroptimierung dann Näherung (2/2)
hier einfache
Optimierung
(Kompression), ergibt
-DCOLLAPSE
Formale Modelle der Softwareentwicklung
Stephan Kleuker
88
Überblick: Zustandsraumannäherung
Obermenge
der erreichbaren Zustände
(in SPIN keine
Betrachtung der
Obermenge)
I1
erreichbare Zustände
Teilmenge
der erreichbaren Zustände
x
I2
Formale Modelle der Softwareentwicklung
x
F1
x
F2
x
x
Stephan Kleuker
89
Arten von funktionalen Anforderungen
2.4.3
• Sicherheitseigenschaften (Safety): Dies sind
Eigenschaften, die das System in bestimmten
Zuständen erfüllen muss. Anschaulich wird so
zugesichert, dass „nichts Schlechtes“ passiert. Zur
Überprüfung muss für jeden relevanten Zustand
überprüft werden, dass er die gewünschte
Eigenschaft hat.
• Lebendigkeitseigenschaften (Liveness): Dies sind
Forderungen an das System, dass unter bestimmten
Bedingungen diese Eigenschaft erreicht werden
muss. Anschaulich wird so zugesichert, dass „etwas
Gutes“ passieren wird. Zur Überprüfung müssen für
jeden relevanten Zustand alle möglichen
Folgeabläufe analysiert werden.
Formale Modelle der Softwareentwicklung
Stephan Kleuker
90
Visualisierung von Sicherheit
Zustandsraum
erlaubt
verboten
Start
erlaubte Abläufe
Formale Modelle der Softwareentwicklung
verbotener Ablauf
Stephan Kleuker
91
Visualisierung von Lebendigkeit
Zustandsraum
Zustandsmenge mit
gewünschtem Verhalten
Start
erlaubte Abläufe
Formale Modelle der Softwareentwicklung
verbotener Ablauf
Stephan Kleuker
92
Zusicherungen
2.4.4
• Als Sicherheitseigenschaften können, wie aus Java und C
bekannt, mit assert Zusicherungen eingebaut werden
• assert(<Boolescher Ausdruck>) ist immer ausführbar, meldet
Fehler bei Auswertung nach false
• Möglichkeit, assert zur Prüfung von Invarianten zu nutzen:
byte y=0
bool b=false;
active proctype Invariante(){
assert( !b || y>42);
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
93
Ausnutzung von Markierungen
• Zugriff auf Markierungen Prozess@Marke
/* Verifikation scheitert */
byte x=0;
auch P@m3 möglich (wahr wenn
active[3] proctype P(){
ein P-Prozess an Markierung m3
m1: do
steht
:: x<10 ->
m2: x++
:: x>5 ->
m3: break
od
}
active proctype
P[0]@m3;
P[1]@m3;
P[2]@m3;
assert(x<=11)
}
Inv(){
Formale Modelle der Softwareentwicklung
steht vorher
active[4] proctype Q(){
dann muss in eckigen Klammern
Prozessnummer stehen: P[4]@m3
für ersten P-Prozess
Anmerkung: Inv muss nicht
termineren
Stephan Kleuker
94
Lesender Zugriff auf lokale Variablen
bool dran=false
active proctype P(){
byte x=0;
do
:: x<10 && dran ->
x=x+1;
dran=!dran
:: x>=10 -> break
od
}
active proctype Q(){
byte x=0;
do
:: x<10 && !dran ->
x=x+1;
dran=!dran
:: x>=10 -> break
od
}
active proctype Inv(){
assert (Q:x-P:x>=0 && Q:x-P:x<=1)
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
95
Erfolgreiche Terminierung
2.4.5
• SPIN geht davon aus, dass in einem Zustand, aus dem keine
weiteren Schritte mehr möglich sind, alle Prozesse nicht
terminiert sind
• so werden z.B. Deadlocks gefunden
• Idee klappt nicht bei Server-Prozessen, die haben StandardWartezustand, in dem sie auf Aufträge von Clienten warten
• In PROMELA können Zeilen, die sinnvolle Endzustände
darstellen, mit einer „end“-Markierung versehen werden
• Markierungen innerhalb eines Prozesses müssen
unterschiedlich heißen, „end“-Markierungen müssen nur mit ‚e‘
‚n‘ ‚d‘ beginnen
emp=0;
endOK: do
:: emp<prozesse && emp!=name ->
toP[emp]!rec, name, wert;
Formale Modelle der Softwareentwicklung
Stephan Kleuker
96
Beispiel: Kommunikationsprotokoll (1/2)
P1 schickt Informationen an P2, P2 kann diese bestätigen oder
(zur Prüfung) an P3 schicken, dann bestätigt P3 an P2 und P2
an P1
mtype={send1,send2,ack1,ack2};
chan c12 = [0] of {mtype,byte};
chan c21 = [0] of {mtype,byte};
chan c23= [0] of {mtype,byte};
chan c32= [0] of {mtype,byte};
active proctype P1(){
byte i=1;
do
:: i<=10 ->
c12!send1,i;
c21?ack1,_;
i=i+1
od;
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
97
Beispiel: Kommunikationsprotokoll (2/2)
active proctype P2(){
byte x;
end : do
:: c12?send1,x ->
if
:: x%2==1 -> c21!ack1,x
:: x%2==0 ->
c23!send2,x;
c32?ack2,x;
c21!ack1,x
fi;
od
}
active proctype P3(){
byte x;
end: do
:: c23?send2,x ->
c32!ack2,x
od;
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
98
Verifikationseinstellungen
2.4.6
Sicherheits- und
Lebendigkeitsanforderungen
müssen getrennt
geprüft werden
was bei Senden
in volle Puffer?
weitere
Einstellungen
(weitere Details
später)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
99
Detaileinstellungen der Verifikation
Freier HW-Speicher
Zustandsschätzung
(bei zweitem Lauf
anpassen)
Suchtiefe
(Tiefendurchlauf),
danach Abbruch
Ende bei erstem
Fehler
Formale Modelle der Softwareentwicklung
Stephan Kleuker
100
Einstellungen für Komplexitätsbetrachtung
für jede Zeile der
Spezifikation wird
gezählt, wie häufig sie
ausgeführt wurde
Options unter „Choose“
einstellen
Formale Modelle der Softwareentwicklung
Stephan Kleuker
101
Verifikationsablauf
PROMELA-Spezifikation
SPIN
C-Programm
kompilieren
und
ausführen
Verifikationseinstellung
Formale Modelle der Softwareentwicklung
Ausgabe
Pfad zum Fehler
Stephan Kleuker
102
Beispiel: Ausgabe bei gescheitertem Beweis
• Es wird die Art des Fehlers angegeben, hier Verletzung eines
assert
• Es besteht sofort die Möglichkeit, einen Pfad zum Fehler im
Simulator ablaufen zu lassen
Formale Modelle der Softwareentwicklung
Stephan Kleuker
103
Verifikationsergebnis (Standardeinstellungen) 1/2
für Spezifikation Mini
Formale Modelle der Softwareentwicklung
Stephan Kleuker
104
Verifikationsergebnis (Standardeinstellungen) 2/2
Formale Modelle der Softwareentwicklung
Stephan Kleuker
105
Längere Verifikationsläufe
Ausgabe jeden
millionsten Zustand
Ausgabe jede Minute
Formale Modelle der Softwareentwicklung
Stephan Kleuker
106
Prüfung von Wertebereichen
• Spin erlaubt eine recht genaue Prüfung, welche Werte eine
Variable annehmen kann.
• Folgende Verifikationseinstellungen werden benötigt [Set
Advanced Options]:
• Beispielausgabe:
Values assigned within interval [0..255]:
Emp:wert
: 0-4,
Emp:tmp: 0-5,
erg
: 0-1, 3, 6, 10,
Formale Modelle der Softwareentwicklung
Stephan Kleuker
107
Lebendigkeitsanforderungen
2.4.7
• „etwas Gutes soll passieren“
• Wunsch: Das System soll immer sinnvoll
voranschreiten
• genauer: Verhinderung von Livelocks, z. B. jeder
fragt zyklisch: kann ich nächsten Schritt machen?
Antwort: nein.
• Erfolgreicher Fortschritt wird in PROMELA mit
„progress“-Markierungen definiert
• Forderung: Jeder unendliche Ablaufpfad durchläuft
unendlich oft „progress“-Marken
Formale Modelle der Softwareentwicklung
Stephan Kleuker
108
Beispiel: Spezifikation mit „progress“-Marken
bool guard=true;
byte x=1;
active proctype P1(){
do
:: x<10 -> x=x+1; guard=!guard
:: x>1 -> x=x-1; guard=!guard
:: guard=!guard
od;
}
active proctype P2(){
progress: do
/* 1 */
:: x<10 -> x=x+1; guard=!guard
:: x>1 -> x=x-1; guard=!guard
:: guard=!guard
od;
}
active proctype P3(){
do
:: guard ->
progress: guard=!guard /* 2 */
od;
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
109
Verifikationsergebnis für Lebendigkeit
pan: non-progress cycle (at depth 50)
pan: wrote pan_in.trail
als Time Sequence Diagramm:
2:22
|
|
|>(guard)
2:23
|
|
|>guard
!(guard)
1:14
|
|>((x<10))
1:14
|
|>x = (x+1)
<<<<<START OF CYCLE>>>>>
0:8
|>guard = !(guard)
0:8
|>guard = !(guard)
2:21
|
|
|>1:14
|
|>0:5
|>-
=
Kein Fortschritt, da P1 immer durch dritte Alternative läuft
(realistisch?)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
110
Anmerkung zu progress
• nicht:
active proctype P(){
do
::a!send ->
if
::progress: b?ack,0;
::b?ack,1;
fi;
od;
}
• Die Syntax erlaubt es nicht, progress-Markierungen direkt mit
guards zu verbinden
Formale Modelle der Softwareentwicklung
Stephan Kleuker
111
Fairness
• Grundsätzlich sollen Entwickler von verteilten Systemen keine
Annahmen machen, welcher Prozess wie schnell ist (Annahme
muss sonst aufwändig nachgewiesen werden)
• Aber, dass ein Prozess immer und ein anderer bereiter Prozess
nie rankommt ist unwahrscheinlich, deshalb können folgende
Eigenschaften von Ausführungspfaden gefordert werden:
– schwache Fairness: ein Prozess, der immer fortschreiten
könnte, schreitet letztendlich auch fort
– starke Fairness: ein Prozess, der immer wieder fortschreiten
könnte, schreitet letztendlich auch fort
• in SPIN kann nur „schwache Fairness“ gefordert werden
• vorherige Verifikation klappt mit schwacher Fairness
• Die Implementierung von Fairness ist sehr aufwändig
Formale Modelle der Softwareentwicklung
Stephan Kleuker
112
Veranschaulichung von Fairness
ab hier: P3 immer wieder ausführbar
ab hier: P2 immer ausführbar
ausführbare
Prozesse:
P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1
P2 P3
P2 P2 P2 P2 P2 P2 P2 P2
P3
P3
...
P3
unfairer Pfad
P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1
...
schwach fairer,
nicht stark fairer Pfad
P1 P1 P1 P1 P1 P1 P2 P1 P1 P2 P1 P1
...
stark fairer Pfad
P1 P1 P1 P1 P1 P2 P1 P3 P1 P2 P1 P3
...
Formale Modelle der Softwareentwicklung
Stephan Kleuker
113
Acceptance
• „accept“-Markierungen“ sind praktisch das
Gegenteil von „progress“-Markierungen
• es wird gefordert, dass jeder unendliche Ablaufpfad
nur endlich oft durch eine „accept“-Markierung läuft
• wieder spielt Fairness eine Rolle
• in der Praxis werden Markierungen direkt selten
genutzt, sie treten in generierten Never-Claims
(später) auf
Formale Modelle der Softwareentwicklung
Stephan Kleuker
114
Trace-Zusicherungen
•
•
•
•
•
2.4.8
wenn man nur an den Reihenfolgen der Kommunikationen
interessiert ist, kann man Trace-Zusicherungen nutzen
Dazu wird in einer Zusicherung ein deterministischer Automat
mit den gewünschten Kommunikationen spezifiziert (es dürfen
nur Kommunikationen in der Trace genutzt werden)
trace{
do
c12?send1(_)
:: c12?send1(_);
z1
z2
c21?ack1(_);
c21?ack1(_)
od;
}
Trace-Zusicherung bezieht sich nur auf Kanäle, die in der
Zusicherung vorkommen (Projektion)
Trace-Zusicherung läuft parallel zur Spezifikation, wenn
Kommunikation auf relevantem Kanal stattfindet, muss auch
Trace-Zusicherung einen Schritt machen können
Variante: notrace
Formale Modelle der Softwareentwicklung
Stephan Kleuker
115
Zur Trace passende Spezifikation (Wdh.)
mtype={send1,send2,ack1,ac active proctype P2(){
byte x;
k2};
end : do
chan c12 = [0] of
:: c12?send1(x);
{mtype,byte};
if
chan c21 = [0] of
:: x%2==1 ->
{mtype,byte};
c21!ack1(x)
chan c23 = [0] of
:: x%2==0 ->
{mtype,byte};
c23!send2(x);
chan c32 = [0] of
c32?ack2(x);
{mtype,byte};
c21!ack1(x)
fi
od;
}
active proctype P1(){
active proctype P3(){
byte i=1;
byte x;
end: do
end: do
:: i<=10;
:: c23?send2(x);
c12!send1(i);
c32!ack2(x)
c21?ack1(_);
od;
i=i+1
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
od;
116
Never-Claim
2.4.9
• Never-Claim ist ein Prozess, der parallel zu den restlichen
Prozessen läuft, genauer macht der Never-Claim, dann die
Spezifikation, dann wieder der Never-Claim … einen Schritt
(Ping-Pong)
• Never-Claim kann auf globale Variablen zugreifen, sieht aber
anders als Trace-Zusicherung keine Kommunikationen
• Never-Claims dürfen anders als Trace-Zusicherungen nichtdeterministisch sein
• Für globale Kommunikationskanäle stehen Zugriffe mit z. B.
len(c), nempty(c) zur Verfügung
• Never-Claims spezifizieren unerwünschtes Verhalten, enthalten
typischerweise „accept“-Markierungen
• weiterhin scheitert Verifikation, wenn Never-Claim terminieren
kann
Formale Modelle der Softwareentwicklung
Stephan Kleuker
117
Schritte der Never-Claim-Nutzung
Formale Modelle der Softwareentwicklung
Stephan Kleuker
118
Ping-Pong-Analyse (1/2)
Never-Claim findet kein
Gegenbeispiel
Never-Claim findet
Gegenbeispiel
byte x=0;
active proctype P(){
x=1
}
byte x=3;
active proctype P(){
x=1
}
never{
x==1
}
never{
x==3;
x==1
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
119
Ping-Pong-Analyse (2/2)
Never-Claim findet
Gegenbeispiel (läuft nach
Prozessterminierung weiter)
byte x=3;
active proctype P(){
x=1
}
never{
x==3;
x==1;
x==1;
x==1
}
Formale Modelle der Softwareentwicklung
Never-Claim findet
Gegenbeispiel mit acceptMarkierung
byte x=3;
active proctype P(){
x=1;
}
never{
x==3;
do
:: x==1 ->
accept: skip
:: true -> skip
od
}
Stephan Kleuker
120
Erstellung eines Never-Claim
#define p (zustand==ok)
• Für die Spezifikation soll
#define q (alarm!=rot)
gelten, dass immer der Wert
mtype={ok,nok,gruen,rot};
mtype zustand=ok;
der Variablen zustand ok ist
mtype alarm=gruen;
oder wenn der zustand nicht
never{
mehr ok ist, ab da die Variable
do
alarm immer den Wert rot hat.
:: (!p && q) -> break
:: (!p) ->
• Never-Claim soll
do
allgemeinstes Gegenbeispiel
:: q -> break
sein
:: true
• Hier: wenn einmal zustand
od;
break;
nicht ok und dann der alarm
:: true
jetzt oder später nicht rot ist,
od
dann terminiert Never-Claim
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
121
Beispiel-Spezifikation mit Never-Claim
active proctype Rauchmelder(){
#define p (zustand==ok)
zustand=ok;
#define q (alarm!=rot)
start: if
mtype={ok,nok,gruen,rot};
:: stand>100 && zustand==okmtype zustand=ok;
>
mtype alarm=gruen;
atomic{
never{
zustand=nok;
do
alarm=rot
:: (!p && q) -> break
}
:: (!p) ->
:: else -> skip;
do
fi;
:: q -> break
if
:: true
:: stand >20 ->
od;
stand=stand-1
break;
:: stand <120 ->
:: true
stand=stand+1
od
fi;
}
goto start
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
122
2.5 Verifikation von in LTL formulierten Anforderungen
• Syntax der Linearen Temporalen Logik (LTL)
• Semantik von LTL
• typische LTL-Anforderungen
• LTL in SPIN
Formale Modelle der Softwareentwicklung
Stephan Kleuker
123
Bedeutung von Anforderungen
•
•
•
•
Die direkte Erstellung von Never-Claims erfordert
einiges Umdenken
Weiterhin muss man tief in der Spezifikation
stecken, um Never-Claims zu formulieren
eher typischer Entwicklungsansatz:
1. informelle Spezifikation
2. formale Anforderungen
3. PROMELA-Spezifikation
4. SPIN prüft Spezifikation gegen Anforderungen
Zur Formalisierung von Anforderungen werden
Logiken eingesetzt (Aussagenlogik und
Prädikatenlogik erster Stufe sollten bekannt sein)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
124
Syntax von LTL
Definition (Syntax der Linearen Temporalen Logik
(LTL)): Zunächst sind alle einfachen Prädikate LTLFormeln. Seien weiterhin p, q und r LTL-Formeln,
dann sind auch
1.  p , heißt „always p“, immer p
2.  p , heißt „eventually p”, irgendwann p
3. X p , heißt „next p”, danach p
4. p U q , heißt „p until q“, p solange bis q
syntaktisch korrekte LTL-Formeln. Neue LTLFormeln entstehen weiterhin durch die Verwendung
der bekannten logischen Operatoren , , ,  und
 auch für LTL-Formeln. Klammern können genutzt
werden, um die Auswertungsreihenfolge
vorzugeben. Es gelten sonst die bekannten
Ausführungsprioritäten.
Formale Modelle der Softwareentwicklung
Stephan Kleuker
125
Veranschaulichung von LTL-Formeln
Zeit
z0 z1 z2 z3 z4 z5 z6 z7 ... Pfad
LTL-Formel
p
p
.
p
p
p p p p p p p ...
p
.
.
.
.
.
p
.
. ...
Xp
.
p
.
.
.
.
.
. ...
pUq
p
p p p p
.
.
. ...
.
.
q
.
. ...
p
p p p p p p p ...
.
.
(stark, SPIN)
pUq
(schwach)
auch
Formale Modelle der Softwareentwicklung
.
.
.
.
.
.
.
.
.
.
.
.
.
. ...
. ...
Stephan Kleuker
126
Semantik von LTL (1/2)
Definition (Semantik von LTL-Formeln): Gegeben sei eine
PROMELA-Spezifikation P und ein unendlicher
Ausführungspfad z der Form z0 z1 ... zi ... von Zuständen einer
Ausführung von P. Die Funktion Sem zur Berechnung der
Semantik einfacher Prädikate ist aus der Programmverifikation
(siehe später) entnommen.
[ Sem(a < b, z)  z(a) < z(b)  3 < 42  true; z ordnet jeder
Variable einen Wert zu, hier z(a)=3; z(b)=42]
1. Sei p eine einfaches Prädikat, dann erfüllt z die LTL-Formel p,
wenn Sem(p,z0)=wahr gilt, also der erste Zustand p erfüllt.
2. Sei  p eine LTL-Formel, dann erfüllt z diese LTL-Formel, wenn
alle Zustände p erfüllen, also für alle i Sem(p,zi)=wahr gilt.
3. Sei  p eine LTL-Formel, dann erfüllt z diese LTL-Formel, wenn
ein Zustand p erfüllt, also es ein i mit Sem(p,zi)=wahr gibt.
Formale Modelle der Softwareentwicklung
Stephan Kleuker
127
Semantik von LTL (2/2)
4. Sei X p eine LTL-Formel, dann erfüllt z diese LTL-Formel, wenn
im folgenden Zustand p erfüllt ist, also Sem(p,z1)=wahr gilt.
5. Sei p U q eine LTL Formel, dann erfüllt z die starke Variante des
Until-Operators, wenn es einen Zustand zj gibt, so dass für alle
Zustände zi mit i<j Sem(p,zi)=wahr gilt und Sem(q,zj)=wahr gilt.
6. Sei p U q eine LTL Formel, dann erfüllt z die schwache Variante
des Until-Operators, wenn die starke Variante erfüllt ist oder
wenn alle Zustände p erfüllen, also für alle i Sem(p,zi)=wahr gilt.
• Anmerkung: SPIN unterstützt nur starke Variante des UntilOperators und keinen Next-Operator
• (Next-Operator nutzbar, mit speziellen Einstellungen, schwierig,
da Spezifikation dann „stotterfrei“ sein muss)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
128
Typische LTL-Formeln
• p
(Invariante)
• auf Versenden (Prädikat p) wird Antwort (q) erwartet
p  q
(Antwort)
• immer wieder eine Antwort, also Invariante,
 (p  q)
(Senden-Bestätigen)
sauberer:  (p  X(q))
• kontinuierlicher Fortschritt p als Invariante
 ( p)
(Fortschritt)
• ab einem bestimmten Zeitpunkt immer p
 ( p)
(Stabilität)
• solange eine Eigenschaft p gilt, soll q nicht gelten
 (p  q)
(Ausschluss)
• wechselseitiger Ausschluss von p und q
 (p  q)
(wechselseitiger Ausschluss)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
129
LTL-Rechenregeln
( p)

 (p)
( p)

 (p)
 (p  q)

( p)  ( q)
 (p  q)

( p)  ( q)
p

true U p
 (p  q)

( p)  ( q)
 (p  q)

( p)  ( q)
p U (q  r)

(p U q)  (p U r)
(p  q) U r

(p U r)  (q U r)
Formale Modelle der Softwareentwicklung
(nur stark)
Stephan Kleuker
130
LTL-Formeln in XSPIN
Formeleingabe
Anforderung
immer / nie
Info (informell)
#defineStatements
generierter
Never-Claim
Verifikationsergebnis
Speichern der
Formel
Formale Modelle der Softwareentwicklung
Stephan Kleuker
131
LTL in ASCII
LTL-Formel
ASCII-Darstellung
p
p
p
[] p
p
<> p
pUq
p U q
p
!p
pq
p -> q
pq
p <-> q
pq
p && q
pq
p || q
Formale Modelle der Softwareentwicklung
Stephan Kleuker
132
Beispiel-Übersetzungen von LTL-Formeln (1/2)
• [] p
never {
/* !([] p) */
T0_init:
if
:: (! ((p))) -> goto accept_all
:: (1) -> goto T0_init
fi;
accept_all: skip
}
• <> p
never {
/* !(<> p) */
accept_init: T0_init: if
:: (! ((p))) -> goto T0_init
fi;
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
133
Beispiel-Übersetzungen von LTL-Formeln (2/2)
• [] (<>
never {
T0_init:
p)
/* !([] (<> p)) */
if
:: (! ((p))) -> goto accept_S4
:: (1) -> goto T0_init
fi;
accept_S4: if
:: (! ((p))) -> goto accept_S4
fi;
}
• [] (p <-> !q)
never {
/* !([] (p <-> !q)) */
T0_init:
if
:: ((! (p) && ! (q)) || ((p) && (q))) ->
goto accept_all
:: (1) -> goto T0_init
fi;
accept_all: skip
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
134
Never-Claim aus LTL-Formel in XSPIN
Formale Modelle der Softwareentwicklung
Stephan Kleuker
135
2.6 Beispiele
• deterministische Programme (sortieren)
• Prioritätenregelung
• Ampelsteuerung
Formale Modelle der Softwareentwicklung
Stephan Kleuker
136
Verifikation deterministischer Programme
• Sortierverfahren, informelle Spezifikation:
Laufe mit dem Zähler i von 0 bis zur Arraygröße-1
Laufe mit dem Zähler j von i+1 bis zur Arraygröße
falls das j-te Element kleiner als das i-te Element ist,
vertausche diese
Formale Modelle der Softwareentwicklung
Stephan Kleuker
137
Sortierverfahren (1/5)
proctype Initialize(){
#define N 5
byte count=0;
#define MAX 3
byte rnd=0;
byte array[N];
do
byte save[N];
bool initialized = false; :: count<N ->
rnd=0;
bool sorted=false;
do
:: rnd<MAX -> rnd=rnd+1
:: true ->
/* muss später stehen */
array[count]=rnd;
init{
save[count]=
run Initialize();
array[count];
run Sort();
break
run Proof()
od;
}
count=count+1;
:: else -> break
od;
initialized=true
Formale Modelle der Softwareentwicklung
Stephan Kleuker
138
}
Sortierverfahren (2/5)
proctype Sort(){
byte i=0;
byte j;
byte tmp;
initialized;
do
:: i<N-1 ->
j=i+1;
do
:: j<N-1 -> /*< muss <=
sein */
if
:: array[i]>array[j] ->
tmp=array[i];
array[i]=array[j];
array[j]=tmp
:: else ->
skip
fi;
j=j+1
Formale Modelle der Softwareentwicklung
>
:: else break
od;
i=i+1;
:: else ->
break
od;
sorted=true
}
Stephan Kleuker
139
Sortierverfahren (3/5)
proctype Proof(){
byte count=0;
byte count2=0;
byte anzahl1=0;
byte anzahl2=0;
sorted;
/* pruefe ob array sortiert ist */
do
:: count<N-1 ->
assert(array[count]<=array[count+1]);
count=count+1
:: else ->
break
od;
Formale Modelle der Softwareentwicklung
Stephan Kleuker
140
Sortierverfahren (4/5)
count=0; /* pruefe auf gleiche Elemente */
do
:: count<=MAX ->
anzahl1=0;
anzahl2=0;
count2=0;
do
:: count2<N ->
if
:: save[count2] == count ->
anzahl1=anzahl1+1
:: else ->
skip
fi;
if
:: array[count2] == count ->
anzahl2=anzahl2+1
:: else -> skip
fi;
count2=count2+1
:: else -> break
od;
assert(anzahl1==anzahl2);
count=count+1
:: else -> break
Formale
Stephan Kleuker
odModelle der Softwareentwicklung
141
Sortierverfahren (5/5)
• Ausgabe der Simulation im Fehlerfall
array[0] = 3
array[1] = 3
array[2] = 3
array[3] = 3
array[4] = 2
initialized = 1
save[0] = 3
save[1] = 3
save[2] = 3
save[3] = 3
save[4] = 2
sorted = 1
Formale Modelle der Softwareentwicklung
Stephan Kleuker
142
Spezifikation
Schreiben Sie eine Spezifikation, bei der Prozesse P, Q, und R
jeweils über einen eigenen Kanal zu einem Prozess S Anfragen
schicken können. Diese Anfrage wird von S immer über einen
Rückkanal an den jeweiligen Prozess beantwortet. S nimmt dabei
Anfragen von Q nur an, wenn P keine Anfrage stellt, und von R
nur an, wenn P und Q keine Anfrage stellen. Nutzen Sie
asynchrone Kommunikation, das Senden entspricht einer
Anfragenstellung. Die Nutzung von atomic ist erlaubt. Überlegen
Sie sich einen Weg, die geforderten Eigenschaften zu verifizieren.
req
P
ack
req
Q
ack
req
ack
R
Formale Modelle der Softwareentwicklung
S
Stephan Kleuker
143
Anforderungen präzisiert
• Standardfunktionalität in Schleife : Prozess stellt Anfrage (req)
an S; Prozess wartet auf Antwort (ack)
Prioritäten genauer (Immer):
• Wenn P eine Anfrage stellt und sich S in der Auswahl des zu
beantwortenden Prozesses befindet, muss P die Antwort
erhalten
• Wenn Q eine Anfrage stellt und sich S in der Auswahl des zu
beantwortenden Prozesses befindet und P keine Anfrage
gestellt hat, muss Q die Antwort erhalten
• Wenn R eine Anfrage stellt und sich S in der Auswahl des zu
beantwortenden Prozesses befindet und P sowie Q keine
Anfrage gestellt haben, muss R eine Antwort erhalten
Formale Modelle der Softwareentwicklung
Stephan Kleuker
144
Basisspezifikation P, Q, R
mtype={req,ack};
chan pTos = [1] of
chan qTos = [1] of
chan rTos = [1] of
chan sTop = [1] of
chan sToq = [1] of
chan sTor = [1] of
{mtype};
{mtype};
{mtype};
{mtype};
{mtype};
{mtype};
active proctype P(){
do
:: pTos!req;
sTop?ack;
od;
}
Formale Modelle der Softwareentwicklung
active proctype Q(){
do
:: qTos!req;
sToq?ack;
od;
}
active proctype R(){
do
:: rTos!req;
sTor?ack;
od;
}
Stephan Kleuker
145
Spezifikation S
active proctype S(){
do
:: atomic{
pTos?[req] || qTos?[req] || rTos?[req];
if
:: pTos?[req] -> pTos?req;
sTop!ack;
:: else ->
if
:: qTos?[req] -> qTos?req;
sToq!ack;
:: else -> rTos?req;
sTor!ack;
fi;
fi;
}
od;
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
146
Erweiterung für die Verifikation (1/3)
• Wir müssen festhalten, dass Prozess Anfrage gestellt hat, z. B.:
bool pReq=false;
• Setzen unmittelbar nach Anfrage; Rücksetzen nach Antwort
bool pReq=false;
bool qReq=false;
bool rReq=false;
active proctype P(){
do
:: atomic {pTos!req; pReq=true}
atomic {sTop?ack; pReq=false}
od;
}
• (Q,R analog)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
147
Erweiterung für die Verifikation (2/3)
• Anfragen alleine analysieren reicht nicht; wir müssen auf den
Antwortzeitpunkt zugreifen können: bool pAck=false;
• Setzen beim Senden der Antwort; Rücksetzen bei Erhalt
bool pAck=false;
bool qAck=false;
bool rAck=false;
active proctype P(){
do
:: atomic {pTos!req; pReq=true}
atomic {sTop?ack; pReq=false; pAck=false}
od;
}
• (Q,R analog)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
148
Erweiterung für die Verifikation (3/3)
active proctype S(){
do
:: atomic{
pTos?[req] || qTos?[req] || rTos?[req];
if
:: pTos?[req] -> pTos?req;
sTop!ack; pAck=true;
:: else ->
if
:: qTos?[req] -> qTos?req;
sToq!ack; qAck=true;
:: else -> rTos?req;
sTor!ack; rAck=true;
fi;
fi;
}
od;
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
149
Umsetzung der Anforderungen (1/2)
(Immer):
Wenn P eine Anfrage stellt
und sich S in der Auswahl
des zu beantwortenden
Prozesses befindet,
muss P die Antwort
erhalten
Formale Modelle der Softwareentwicklung
[] (
(pReq==true
genauer: keine alten
Antworten noch
unterwegs sind
&& pAck==false
&& qAck==false
&& rAck==false)
->
genauer: nächste
Antwort an P
((qAck==false
&& rAck==false)
U pAck==true) )
Stephan Kleuker
150
Umsetzung der Anforderungen (2/2)
#define
#define
#define
#define
#define
#define
[]( (pr
pr
qr
rr
pa
qa
ra
&&
(pReq)
(qReq)
(rReq)
(pAck)
(qAck)
(rAck)
(!pa) && (!qa) && (!ra))
-> (((!qa) && (!ra)) U pa ))
zweite Anforderung:
[]( (qr && (!pa) && (!qa) && (!ra))
-> ((!ra) U (pa || qa) ) )
Anmerkung: Da Mächtigkeit von LTL eingeschränkt,
Anforderungen nur näherungsweise formulierbar
Formale Modelle der Softwareentwicklung
Stephan Kleuker
151
Beispiel: Ampelsystem (1/6)
optimiertes
Modell:
• nur Farben
grün und rot
• Ampeln in
einer Richtung
gleich
geschaltet
• nur eine
Richtung grün
Formale Modelle der Softwareentwicklung
Ampel 1
Ampel 0
Ampel 0
Ampel 1
Stephan Kleuker
152
Beispiel: Ampelsystem (2/6)
•
•
informelle Spezifikation:
1. Die Ampeln zeigen entweder rot oder grün an.
2. Die Ampeln schalten immer wieder zwischen rot
und grün hin und her.
3. Es ist immer maximal eine Ampel grün.
4. Die Ampeln werden abwechselnd grün.
typischer Entwicklungsweg:
– informell Prädikate festlegen, dann mit
Spezifikationsinformationen füllen
– häufig muss Spezifikation angepasst werden
(neue globale Hilfsvariablen)
– ab und zu müssen Prädikate angepasst werden
Formale Modelle der Softwareentwicklung
Stephan Kleuker
153
Beispiel: Ampelsystem (3/6)
informelle Prädikate:
• ampel0rot: gilt genau dann, wenn die Ampel 0 rot ist
• ampel0grün: gilt genau dann, wenn die Ampel 0 grün
ist
• ampel1rot: gilt genau dann, wenn die Ampel 1 rot ist
• ampel1grün: gilt genau dann, wenn die Ampel 1 grün
ist
• ampel0zuletzt: gilt genau dann, wenn Ampel 0 zuletzt
grün war
• ampel1zuletzt: gilt genau dann, wenn Ampel 1 zuletzt
grün war
Formale Modelle der Softwareentwicklung
Stephan Kleuker
154
Beispiel: Ampelsystem (4/6)
1.  (
((ampel0rot  ampel0grün)  (ampel0rot  ampel0grün))
 ((ampel1rot  ampel1grün)  (ampel1rot  ampel1grün))
2.  ( (ampel0rot  ( ampel0grün))
 (ampel0grün  ( ampel0rot))
 (ampel1rot  ( ampel1grün))
 (ampel1grün  ( ampel1rot)))
3.  ( (ampel0grün  ampel1grün)
 (ampel1grün  ampel0grün))
4.  (
( (ampel0zuletzt) U (ampel1zuletzt  ampel0zuletzt) )
 ( (ampel1zuletzt) U (ampel0zuletzt  ampel1zuletzt) )
 (ampel0zuletzt  ampel1zuletzt) )
Formale Modelle der Softwareentwicklung
Stephan Kleuker
155
Beispiel: Ampelsystem (5/6)
mtype={p,v, rot,gruen};
proctype Umschalter(){
mtype zustand[2];
do
bool gestartet=false;
::
zentrale?p,eval(dran
chan zentrale= [0] of {mtype,bit};
);
bit dran=0; /* wer als nächstes */
zentrale?v,_;
dran=1-dran;
proctype ampel(bit name){
od;
do
}
:: zustand[name]==rot ->
zentrale!p,name;
init{
zustand[name]=gruen;
atomic{
zustand[name]=rot;
zustand[0]=rot;
zentrale!v,name;
zustand[1]=rot;
od;
run ampel(0);
}
run ampel(1);
Formale Modelle der Softwareentwicklung
}
run Umschalter();
gestartet=true;
};
Stephan Kleuker
156
Beispiel: Ampelsystem (6/6)
#define
#define
#define
#define
#define
#define
ampel0rot (zustand[0]==rot)
ampel0gruen (zustand[0]==gruen)
ampel1rot (zustand[1]==rot)
ampel1gruen (zustand[1]==gruen)
ampel0zuletzt (dran==1)
ampel1zuletzt (dran==0)
• Verifikation der ersten Anforderung scheitert, da vor
Initialisierung alle Ampeln weder rot noch grün sind,
typische Lösung
– (initialisiert  Anforderung)
– #define initialisiert (gestartet==true)
– ==true kann natürlich weggelassen werden
Formale Modelle der Softwareentwicklung
Stephan Kleuker
157
2.7 PROMELA und SDL
• Bedeutung der Specification and Description
Language (SDL)
• Prozesse in SDL
• Kommunikation in SDL
• Transformation von SDL nach PROMELA
Formale Modelle der Softwareentwicklung
Stephan Kleuker
158
SDL (Specification and Description Language)
• Zur Spezifikation von verteilten Systemen wurden
unterschiedliche Spezifikationssprachen mit unterschiedlichen
Zielrichtungen entworfen
– algebraische Beschreibung durch Gleichungen „was
passieren soll“, z.B. CSP, LOTOS
– automatenbasierte Beschreibung, wie Abläufe aussehen
sollen
• SDL ist automatenbasierte, graphische Spezifikationssprache
für verteilte Systeme
• SDL ist in der Telekommunikation weit verbreitet
• SDL ist standardisiert (erst CCITT, dann ITU-T, Z.100)
• SDL wird in Standards genutzt
• SDL hat kommerzielle Werkzeuge (z. B. Telelogic), z. B. mit
Anbindung an Code-Generierung
• hier: keine detaillierte Einführung, nur Verwandtschaft zu
PROMELA aufzeigen (SDL ist sehr viel mächtiger)
• Literatur: H. König, Protocol Engineering, Teubner, 2003
Formale Modelle der Softwareentwicklung
Stephan Kleuker
159
Struktur von Spezifikationen
• Zentraler Begriff: Agent, kann einfacher Prozess sein oder zur
hierarchischen Struktur beitragen
– Blöcke: können weitere Blöcke und Prozesse enthalten
– Prozesse: können nur weitere Teilprozesse enthalten
• asynchrone Kommunikation über Kanäle
• Beschreibung offener Systeme mit Schnittstellen (Gates) zur
Umwelt möglich (PROMELA-Spezifikationen sind geschlossen)
System
Kanal
Block
Block
Block
Prozess
Kanal
Kanal
Prozess
Formale Modelle der Softwareentwicklung
Prozess
Kanal
Block
Stephan Kleuker
Prozess
160
Beispielhafter Aufbau eines Blockes
block B
[t]
signal t1,t2
signallist t: t1,t2
block B1
[t]
dcl i Integer;
signal a,b,c,d,e
signallist s1: a
signallist s2: b,c
Prozess1
[s1]
[s2]
Prozess2
• in Boxen mit Eselsohren stehen Variablendeklarationen
• für Kanäle können Signallisten definiert werden
Formale Modelle der Softwareentwicklung
Stephan Kleuker
161
Beispielhafte Prozessbeschreibung
verbunden
b
a
x:=x+1
c
Berechnung
-
• typisches
reaktives System,
das sich in einem
Zustand befindet,
auf Eingabe
wartet und dann
in Folgezustand
geht
Ausgabe
zum vorherigen Zustand
terminieren
Zustand
b
Eingabe
Terminierung
Formale Modelle der Softwareentwicklung
Stephan Kleuker
162
Abarbeitung von Nachrichten
Prozesseingabequeue
... b
x
... b
c
x
... b
w1
a
c
w2
x
b
... x
b
a
x
x wird verarbeitet
...
Formale Modelle der Softwareentwicklung
w3
x
Signal wird gerettet,
verbleibt in der
Eingabequeue
b
Stephan Kleuker
163
Weitere SDL-Prozesssprachkonstrukte
Prioritäten
Timer
set(now+3,t)
warten
timer t
b
a
normal
warten
x>0
hohe Priorität
gefeuerter Timer
Nichtdeterminismus
Alternativen
Frage
Antwort
else
t
a
Bedingung
(intern,
niedrigste
Priorität)
w1
Frage
Antwort1 Antwort2 else
Formale Modelle der Softwareentwicklung
none
Stephan Kleuker
b
164
Beispiel in SDL und PROMELA (1/4)
• Spezifikation: Ein Sender sendet Signale i1 und i2 an einen
Empfänger, wenn der Empfänger mindestens 10 Signale jeweils
von i1 und i2 erhalten hat, sendet er dem Sender eine
Terminierungsnachricht, die bestätigt wird
• hier Skizze für eine Übersetzung von SDL nach PROMELA ohne
SDL-Besonderheiten
block Bsp
signal i1,i2,term,ack
signallist toE: i1,i2,ack
signallist toS: term
Sender
Formale Modelle der Softwareentwicklung
SundE
[toS]
[toE]
Empfaenger
Stephan Kleuker
165
Beispiel in SDL und PROMELA (2/4)
process Sender
senden
none
none
term
i1
i2
ack
-
-
Formale Modelle der Softwareentwicklung
Stephan Kleuker
166
Beispiel in SDL und PROMELA (3/4)
process Empfaenger
dcl
x1 Natural =0,
x2 Natural =0;
empfangen
i1
i2
x1:=x1+1
x2:=x2+1
x1>10 und
x2>10?
beenden
i1
i2
-
-
ack
else
-
term
beenden
Formale Modelle der Softwareentwicklung
Stephan Kleuker
167
Beispiel in SDL und PROMELA (4/4)
active proctype empfaenger(){
empfangen:
if
:: SundEE?i1-> x1=x1+1
:: SundEE?i2-> x2=x2+1
fi;
if
:: x1>10 && x2>10 ->
SundES!term;
goto beenden
active proctype sender(){
:: else ->
do
goto empfangen
:: SundEE!i1
fi;
:: SundEE!i2
beenden:
:: SundES?term->
do
SundEE!ack;
:: SundEE?i1
break
:: SundEE?i2
:: SundEE?ack -> break
od;
od;
}
}
mtype={i1,i2,term,ack};
byte x1=0;
byte x2=0;
chan SundES=[5]
of {mtype};
chan SundEE=[5]
of {mtype};
Formale Modelle der Softwareentwicklung
Stephan Kleuker
168
3. Modelchecking mit Timed Automata und Uppaal
3.1 Synchron kommunizierende Automaten
3.2 Spezifikationen mit Zeit
3.3 Nutzung von Uppaal
3.4 Timed Computation Tree Logic und
Verifikation
3.5 Beispiele
Formale Modelle der Softwareentwicklung
Stephan Kleuker
169
3.1 Synchron kommunizierende Automaten
•
•
•
•
•
Automaten mit Kommunikationen
bedingte Transitionen
parametrisierte Transitionen
parametrisierte Automaten
Zustandsinvarianten
Formale Modelle der Softwareentwicklung
Stephan Kleuker
170
Graphische Spezifikation
//global
chan a;
chan b;
chan c;
c?
a!
Template A
a?
b!
Template B
c!
b?
Template C
system A,B,C;
Formale Modelle der Softwareentwicklung
Stephan Kleuker
171
Automaten mit lokalen Variablen
• Jeder Automat kann zusätzlich lokale Variablen haben, die auf
Transitionen geändert werden können
• weiterhin können Funktionen zur Änderung spezifiziert werden
• Parameter: int x (Call by Value)
int& x (Call by Reference)
Template A
// lokale Variablen
int x:=0;
void sub (int& v){
v:=v-1;
}
Formale Modelle der Softwareentwicklung
c?
sub(x)
Stephan Kleuker
a!
x:=x+1
172
eA
Transitionen mit Bedingungen
Template A
//global
chan c,d,e,q;
v%2==1
//system
system A,B;
q?
// A local
int[0,255] v:=0;
v%2==0
d!
v%4==0
c!
v:=(v+1)%256
e!
v:=v+1
v:=v+1
Template B
Template B
v%2==1
d!
=(v+1)%256
v%2==0
c!
v:=v+1
v%4==0
q!
e!
c?
v:=v+1
d?
Formale Modelle der Softwareentwicklung
e?
Stephan Kleuker
q!
173
Parametrisierte Transition und Automaten
//global
const int N=4;
chan c[N];
chan d[N];
bool gesendet[N];
Template V
i:int[0,N-1]
i: int[0,N-1]
!gesendet[i]
c[i]!
sum:=sum+i,
gesendet[i]:=true
// template instantiations
d[i]?
E0 = Emp(0);
check()
E1 = Emp(1);
E2 = Emp(2);
E3 = Emp(3);
// processes composed to system
system V,E0,E1,E2,E3;
Template Emp
// local V
Parameter: int name
int sum:=0;
void check(){
bool allegesendet:=true;
for(i: int[0,N-1])
c[name]?
allegesendet:=allegesendet && gesendet[i];
d[name]!
if(allegesendet)
for(i: int[0,N-1])
gesendet[i]:=false;
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
174
Variante: Visualisierter Ablauf
// local V
int sum:=0;
int[0,N] tmp;
bool allegesendet;
Statt C-artige Funktionen zu nutzen,
kann Ablauf visualisiert werden
Vorteil: bessere Debug-Möglichkeit
Nachteil: wesentlich mehr Zustände
auch in der Verifikation
tmp==N
tmp<N
tmp==N &&
!allegesendet
gesendet[tmp]:=false,
tmp:=tmp+1
tmp==N &&
allegesendet
tmp:=0
tmp<N
i: int[0,N-1]
d[i]?
tmp:=0,
allegesendet:=true
i: int[0,N-1]
!gesendet[i]
c[i]!
sum:=sum+i,
gesendet[i]:=true
allegesendet:=
allegesendet && gesendet[tmp],
tmp:=tmp+1
Formale Modelle der Softwareentwicklung
Stephan Kleuker
175
Kommunikation mit Werten
• Da Kanäle keine Parameterlisten haben, müssen diese mit
globalen Variablen simuliert werden
• Übertragen der Werte von 1 bis 10
// global
const int max:=10;
int[0,max] senden:=0;
chan c;
//Empfaenger
Template
Sender
int summe:=0;
senden<max
systemc!
Sender,
Empfaenger
senden:=senden+1
Formale Modelle der Softwareentwicklung
Template Sender
Template Em
senden<max
c!
senden:=senden+1
c?
sum
Template Empfaenger
c?
summe:=summe+senden
Stephan Kleuker
176
Berücksichtigung von Zustandsinvarianten
• Zustände können Namen haben
• Transitionen ausgehend von z1 nur abwechselnd nutzbar
• In Zuständen stehen Invarianten
int x:=0
z1
x:=x+1
z2
x:=x+1
z3
x%2==1
x%2==0
Formale Modelle der Softwareentwicklung
Stephan Kleuker
177
3.2 Spezifikationen mit Zeit
•
•
•
•
•
•
typische Anforderungen mit Zeitbezug
Einführung von Uhren
Semantik von Uhren
Datentypen
Deadlocks durch Zeitbedingungen
Urgent und Committed
Formale Modelle der Softwareentwicklung
Stephan Kleuker
178
Spezifikation mit Zeit
• Zeit spielt bei verteilten und eingebetteten Systemen
häufig eine wichtige Rolle für die Korrektheit, es
sollen Fragen beantwortet werden, wie
– läuft das Protokoll, wenn man Verzögerungen
durch Laufzeiten berücksichtigt?
– welche neuen Situationen entstehen, wenn man
die Dauer einer Aktion berücksichtigt?
– welche minimalen Reaktionszeiten kann man
erhoffen?
– welche maximalen Reaktionszeiten sind zu
befürchten?
– wann kann ein Zustand erreicht werden?
• Diese Fragen können neben den schon bekannten
Fragen eine wichtige Rolle spielen
Formale Modelle der Softwareentwicklung
Stephan Kleuker
179
Timed Automata (zeitbehaftete Automaten)
• Idee: Parallelkomposition von Automaten, die um spezielle
Variablen für Zeit (sogenannte Uhren) erweitert werden
• In den Zuständen kann Zeit vergehen, Zustände können
abhängig von Zeitbedingungen verlassen werden (Zustände
besser als Locations, Lokationen, Aufenthaltsbereiche
bezeichnen)
• Anforderungen können in einer temporalen Logik TCTL (Timed
Computation Tree Logic) formuliert werden; dazu existiert
Modelchecking-Ansatz
• Realisiert im Werkzeug Uppaal, entwickelt in Uppsala
(Schweden) und Aalborg (Dänemark)
z1 x<=5
clock x;
Invariante fordert, dass z1 nach
höchstens 5 Einheiten verlassen wird
x>=2
Bedingung der Transition fordert, dass
mindestens 2 Einheiten vergangen
sind
Formale Modelle der Softwareentwicklung
Stephan Kleuker
180
Invarianten in Zuständen
• Zustandsinvarianten geben Regeln für die Zustände an
• x<=2: Der Zustand muss spätestens dann verlassen werden,
wenn die Uhr x mehr als zwei Zeiteinheiten (2 E) hat
• Uhren laufen kontinuierlich weiter
• Invarianten haben die Form <clock> op <Ausdruck> mit op
{<,<=,=} , Ausdruck darf Uhren, Integer-Variablen und
Konstanten enthalten, keine oder-Verknüpfung von Uhren
• Auf den Transitionen wird keine Zeit verbraucht
• Automat verlässt nach maximal 2 E start, da Uhr
weiterläuft, und versucht nach maximal 3E wieder
nach start zurück zu kehren
• Theoretisch können Zustände beliebig oft
gewechselt werden
• Läuft die Uhr im Zustand weiter über 2 E hinaus, ist
Rückkehr nach start nicht mehr möglich, da
Invariante verletzt würde
Formale Modelle der Softwareentwicklung
Stephan Kleuker
181
Transitionswächter (Guard)
• Wächter ist Boolesche Bedingung, kann
Uhren, Integer-Variablen und Konstanten
enthalten
• Uhren und Differenzen zwischen Uhren
start
werden nur mit Integer-Ausdrücken
x<=2
verglichen
• Uhren-Bedingungen können nur mit
x>2
Konjunktionen verknüpft werden
x>1
• Ausgangstransition von start kann nach
einer Zeiteinheit verlassen werden, es
folgt: start wird im Intervall (1,2]
verlassen („(“ offen, „[“ geschlossen)
• weiter kann erst nach 2 E verlassen
weiter
x<=3
werden; dies verstößt gegen Invariante
von start, d. h. deadlock (bzw. nicht
wohldefinierter Zustand)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
182
Zuweisungen, Nichtdeterminismus, Variablen
start
clock x;
clock y;
int [0,5] zwei:=0;
int [0,5] drei:=0; x:=0
x<=4
x>3 && drei<5
x>2 && zwei<5
zwei:=zwei+1
drei:=drei+1
weiter
• nach 3 E kann nichtdeterministisch eine ausgehende Kante
gewählt werden
• Integer-Variablen erlaubt, können in Wächtern gelesen und bei
Transitionsnutzung verändert werden
• Uhren können zurückgesetzt werden
• System kann jede von start ausgehende Transition 5-mal nutzen
• Uhr y zur Beobachtung; Analysefrage: Welchen Wert nimmt y
minimal bis Deadlock (genauer: Inkonsistenz in start) an?
Formale Modelle der Softwareentwicklung
Stephan Kleuker
183
Visualisierung als Zeitdiagramm
start
x<=4
x>3 && drei<5
x>2 && zwei<5
zwei:=zwei+1
x:=0
drei:=drei+1
weiter
zwei 0
drei 0
1
2
1
start
weiter
Zeit
x 0
Gesamtzeit y 0
2.7
2.7
Formale Modelle der Softwareentwicklung
0
9
3.7
0
12.7 12.7
Stephan Kleuker
3.1
15.8
184
Variablenarten
• Definition von Konstanten: const <Typ> <name> = <wert>;
• Variable im Wertebereich min bis max
int[<min>,<max>] <Variablenname>;
ohne min max [-32768 bis 32767]
• Boolesche Variablen: bool <Variablenname>;
• Definition von Uhren: clock <Uhrenname>;
• Kanal, über den synchron (Paar Sender, Empfänger)
kommuniziert wird:
chan <Kanalname>;
• ein Sender kann mit beliebig vielen Empfängern synchronisiert
werden (auch null):
broadcast chan <Kanalname>;
• Kanal wird für unmittelbare Kommunikation ohne Zeitverbrauch
genutzt, Transition darf keinen Zeitwächter haben
urgent <Kanaldeklaration wie vorher>;
• Felddeklarationen für alle Typen, z.B. clock x[4];
• Initialisierungen sind bei Integer-Variablen möglich, z.B.
int i:=3;
int[2,5] j[3]:={2,3,4};
Formale Modelle der Softwareentwicklung
Stephan Kleuker
185
Doppelklick
clock x;
int[0,2] modus:=0;
chan klick;
start
x>=3
modus:=1
einfach
klick?
x:=0
x<=3
klick?
modus:=2
doppelt
• In modus wird Auswahlart codiert (=1 einfach, =2 doppelt)
• doppelt ist committed Zustand; d. h. in diesem Zustand darf
keine Zeit verbracht werden, er wird sofort verlassen (für einen
Automaten entspricht dies atomarem Schritt, Ausnahme wenn
mehrere Automaten interleavt committed Zustände durchlaufen)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
186
Zustand Committed
• Zustand mit C markiert ©
• „Committed“: Zustand muss so schnell wie möglich,
d. h. ohne Zeit zu verbrauchen, verlassen werden
• sinnvoll, wen man mehrere Zustände nutzt um
Berechnungen durchzuführen, damit diese ohne Zeit
ablaufen
• Alternativen mit Uhren, in denen man warten müsste,
werden nie ausgeführt
• Vorheriges Beispiel: modus-Variable soll sofort Wert
annehmen (Variante: modus auf vorheriger Kante
setzen)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
187
Deadlocks durch Zeit
clock x;
wegen Zeitbedingung nicht ausführbare Transition
wegen Zeitbedingung nicht betretbarer Zustand
Formale Modelle der Softwareentwicklung
Stephan Kleuker
188
Zustand Urgent
• Die Markierung mit U ist verwandt mit Committed
• wieder Ziel, Zustand schnellstmöglich zu verlassen
• etwas weicher als Committed
– Committed: Zustand muss im nächsten Schritt
verlassen werden (genauer: solange es bei
Ausführung mit committed markierte, erreichte
Zustände gibt, müssen diese verlassen werden)
– Urgent: es darf auch auf keinen Fall Zeit
verbraucht werden, aber andere, nicht Zeit
verbrauchende, Schritte sind erlaubt
Formale Modelle der Softwareentwicklung
Stephan Kleuker
189
Urgent- und Committed-Zustände
(a) Deadlock mit Committed (und Urgent)
x>=2
c?
c!
(b) Urgent: c und d ausführbar
c?
c!
d!
d?
(c) Committed: nur c ausführbar
c?
c!
d!
d?
Formale Modelle der Softwareentwicklung
Stephan Kleuker
190
Zusammenfassung typischer Zeitnutzungen
z
z
z
Formale Modelle der Softwareentwicklung
Der Zustand z wird nach
weniger als 3 E verlassen
Der Zustand z kann
zwischen 3 und 5 E
verlassen werden, Zustand
muss aber nicht verlassen
werden
Der Zustand z wird
garantiert zwischen 3 und
5 E verlassen
Stephan Kleuker
191
3.3 Nutzung von Uppaal
• Beispiel: Weiterleitungsmodul
• Eingabe von Timed Automata
• Nutzung des Simulators
Formale Modelle der Softwareentwicklung
Stephan Kleuker
192
Weiterleitung (1/7)
• Zu untersuchen ist die Verzögerung, die durch ein
Weiterleitungsmodul TM (transmission module) entstehen
kann. Das Modul übernimmt eine Nachricht, liefert diese weiter,
wartet auf eine Bestätigung und leitet dann diese weiter.
• Uppaal erlaubt die Erzeugung von Systemen durch so
genannte Templates (einzelne Prozesse als Timed Automata),
dabei können Parameter an eine Spezifikation übergeben
werden
• Dies wird im folgenden zusammen mit der Nutzung von Uppaal
erklärt
Sender
(Send)
Trans1
(TM)
Formale Modelle der Softwareentwicklung
Trans2
(TM)
Trans3
(TM)
Stephan Kleuker
Empfaenger
(Emp)
193
Weiterleitung (2/7)
Zustandseingabe
Transitionseingabe
Kanteneckpunkte
(Nails)
Prozessparameter
(Templateparameter)
Prozessname
Formale Modelle der Softwareentwicklung
Stephan Kleuker
194
Weiterleitung (3/7)
„System Editor“ zur Eingabe
„Declarations“: Eingabefenster
für lokale Variablen
Syntaxprüfung mit F7 (oder
File->Check Syntax), Ergebnis
wird unten angezeigt (von
Hand vergrößern)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
195
Weiterleitung (4/7)
Empfängerprozess Emp
Doppelklick auf Zustand ermöglicht
Eingabe von Invarianten und Zustandsart
Formale Modelle der Softwareentwicklung
Stephan Kleuker
196
Weiterleitung (5/7)
Spezifikation von TM
Durch Doppelklick auf eine Kante können
deren Eigenschaften
parametrisiert,
Wächter,
Kommunikation und
veränderte Variablen angegeben werden
Formale Modelle der Softwareentwicklung
Stephan Kleuker
197
Weiterleitung (6/7)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
198
Weiterleitung (7/7)
Hier müssen globale Variablen stehen, direkte Angaben wie 2 als
Parameter sind nicht möglich
Formale Modelle der Softwareentwicklung
Stephan Kleuker
199
Überblick Simulator (1/7)
Ausführbare Aktionen
bisher ausgeführte
Aktionen
aktuelle
Variabenwerte
(mit
Uhren)
Simulationssteuerung
Formale Modelle der Softwareentwicklung
Prozesse in ihren aktuellen
Zuständen
ausgeführte Aktionen als Message
Sequence Chart
Stephan Kleuker
200
Überblick Simulator (2/7)
mögliche Transition
anwählen (hier nur eine
möglich)
dann Next drücken
Neuanfang mit Reset
(gewählte Transition hat
Einfluss auf andere
Fenster)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
201
Überblick Simulator (3/7)
zuletzt ausgeführte
Aktionen (auswählbar)
in der Form
(Zustände)
(Transition)
(Auswahl hat Einfluss auf
andere Fenster)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
202
Überblick Simulator (4/7)
Simulationssteuerung:
Simulationen können
geladen,
gespeichert und
wiederholt werden
Bei Random läuft die Simulation automatisch ab,
dazu kann die Geschwindigkeit eingestellt
werden (Ist Togglebutton, bleibt also gedrückt)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
203
Überblick Simulator (5/7)
Anzeige der Werte aller
Variablen und Uhren,
für die Uhren und die
angewählte Aktion
werden die Intervalle
der Uhren angezeigt
Formale Modelle der Softwareentwicklung
Stephan Kleuker
204
Überblick Simulator (6/7)
Prozessnamen
aktuelle Zustände
Kommunikationen
(immer synchron)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
205
Überblick Simulator (7/7)
Prozesse
Formale Modelle der Softwareentwicklung
Stephan Kleuker
206
3.4 Timed Computation Tree Logic und Verifikation
• Syntax und Semantik von Timed Computation Tree
Logic (TCTL)
• typische Anforderungen in TCTL
• Fairnessuntersuchung in Timed Automata
• Nutzung der Verifikationskomponente in Uppaal
• Interpretation von Verifikationsergebnissen
Formale Modelle der Softwareentwicklung
Stephan Kleuker
207
Ansatz von CTL
• LTL betrachtet alle möglichen
Ausführungssequenzen
• CTL (Computation Tree Logic) betrachtet alle
möglichen Folgezustände und macht Aussagen, was
in diesen Folgezuständen gilt
Ausgangszustand
alle möglichen Folgezustände
wieder unendliche
Abläufe betrachtet
• Es gibt Anforderungen, die man in LTL und nicht in
CTL und Anforderungen, die man in CTL und nicht in
LTL ausdrücken kann
Formale Modelle der Softwareentwicklung
Stephan Kleuker
208
Syntax von TCTL in Uppaal
• Einfache Prädikate der Form
– <Integer-Ausdruck> <op> <Integer-Ausdruck>
– <Uhr-Variable> <op> <Integer-Ausdruck>
In <Integer-Ausdruck> können außer Uhren beliebige
Variablen vorkommen
• Sind p und q Prädikate, dann auch
– p and q, p or q, not p, p imply q, (p)
(Logik wird ausgeschrieben, oder &&, || sowie ! )
– A p (all pathes always, „immer“)
– A  p (all pathes sometimes, „immer irgendwann“)
– E p (exists a path always, „für einen Weg immer“)
– E  p (exists a path sometimes, „kann garantiert irgendwo“)
– p  q (p leads to q, „wenn p dann irgendwann q“)
• Spezielle Formel: deadlock; erfüllt, wenn kein Prozess weiter
kann
• man beachte: Keine Schachtelungen erlaubt E  A p (wäre in
CTL möglich, erhöht aber Modelcheck-Aufwand drastisch)
• A: für alle Pfade E: es gibt einen Pfad
Formale Modelle der Softwareentwicklung
Stephan Kleuker
209
Veranschaulichung der Formeln (1/3)
A p
A[] p
...
... ...
... ...
... ...
: genau hier
gilt p
...
E p
E[] p
...
... ...
... ...
... ...
...
• Anmerkung: Knoten müssen nicht immer zwei Blätter haben
Formale Modelle der Softwareentwicklung
Stephan Kleuker
210
Veranschaulichung der Formeln (2/3)
A p
A<> p
...
... ...
... ...
... ...
...
E p
E<> p
...
... ...
... ...
Formale Modelle der Softwareentwicklung
... ...
...
Stephan Kleuker
211
Veranschaulichung der Formeln (3/3)
p q
p leads to q
p
p
q
q
...
q
... ...
Rechenregeln:
A p 
A p 
q
... ...
q
... ...
...
p --> q
E   p
E   p
(nicht mit unserer eingeschränkten Version von CTL,
aber im normalen CTL formulierbar)
p  q  A  (p imply (A  q))
Formale Modelle der Softwareentwicklung
Stephan Kleuker
212
Typische Formeln
• Sicherheit: A[] p (Invariante)
• Sicherheit: E[] p (Es gibt einen sicheren Pfad)
• Lebendigkeit: A<> p (Zustand muss erreicht werden)
• Lebendigkeit: p --> q (p führt irgendwann zu q)
• Erreichbarkeit = Mix aus Sicherheit und
Lebendigkeit:
E<> p (p kann irgendwann eintreten)
• Anmerkung: In Uppaal nie Leerzeichen zwischen A
(E) und [] (<>)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
213
Analyse von Fairness in Uppaal
Automat Fairness
int i:=0;
Formale Modelle der Softwareentwicklung
Stephan Kleuker
214
Nutzung der Verifikationskomponente (1/2)
Ansicht der Formeln (keine
Änderung)
Formeln werden durch Anklicken
selektiert (mehrere mit gedrückter
Hochstelltaste)
Modelchecking starten,
unten wird Ergebnis angezeigt
Formelverwaltung
Eingabe von Formeln
informeller Kommentar
Formale Modelle der Softwareentwicklung
Stephan Kleuker
215
Nutzung der Verifikationskomponente (2/2)
Achtung! Formeln (Queries) können getrennt
gespeichert und geladen werden
Weitere Einstellungen werden
hier nicht im Detail betrachtet
Um Trace zum Fehler (A)
oder Erfolg (E) zu bekommen,
muss eine „Diagnostic Trace“
gewählt werden
Formale Modelle der Softwareentwicklung
Stephan Kleuker
216
Analyse des Verifikationsverhaltens (1/3)
Automat P
int i:=0;
clock x;
• Es wird immer s3
durchlaufen
A<> P.s3
• Es wird Gegenbeispiel
erzeugt, das schrittweise
mit „Next“ im Simulator
durchlaufen werden kann
Formale Modelle der Softwareentwicklung
Stephan Kleuker
217
Analyse des Verifikationsverhaltens (2/3)
Achtung, Ausgaben hängen von
Verifikationseinstellungen
(Options) ab, hier:
- Breadth First
- State Space Reduction: none
- State Diagnostic
Representation: DBM
- Diagnostic Trace: shortest
Formale Modelle der Softwareentwicklung
Stephan Kleuker
218
Analyse des Verifikationsverhaltens (3/3)
• i hat nie den Wert 42
A[] P.i!=42 (erzeugt Trace mit Gegenbeispiel)
• i hat irgendwann den Wert 5
E<> P.i==5 (Verifikation scheitert, kein Gegenbeispiel [!?])
• möglich, dass i nie einen Wert größer-gleich 7 annehmen wird
E[] P.i<7 (Verifikation scheitert, kein Gegenbeispiel)
Anmerkung: Ohne Uhren ist Beweis erfolgreich [!])
• Möglich, dass i nie einen Wert größer 8 annimmt
E[] P.i<8 (Verifikation erfolgreich, Trace wird konstruiert mit
Deadlock in s3)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
219
3.5 Beispiele
•
•
•
•
•
Timeout
Systemstart
Modellierung von Arbeitsabläufen
Verifikation deterministischer Programme (sortieren)
Telefonsystem
Formale Modelle der Softwareentwicklung
Stephan Kleuker
220
Timeout (1/2)
• Reaktive Systeme haben oft einen Timer, der Aktionen
abbrechen kann oder Alarm auslöst; dies kann auch in Uppaal
spezifiziert werden
chan reset;
chan abort;
Automat Timer
const int grenze:=10;
clock x;
clock timer;
reset!
start
timer<grenze
x:=0
reset?
timer:=0
timer==grenze
abort!
s1 x<5
s0
x<4
x:=0
abort?
x<6
x:=0
abort?
s2
abort?
abbruch
s3
Formale Modelle der Softwareentwicklung
Stephan Kleuker
221
Timeout (2/2)
const int grenze:=10;
chan reset;clock x;
clock timer;
chan abort;
reset!
start
timer<grenze
x:=0
reset?
timer:=0
timer==grenze
abort!
s1 x<5
s0
x<4
x:=0
abort?
x<6
x:=0
abort?
s2
abort?
abbruch
s3
• Ist es möglich, dass nie ein Abbruch passiert? (ja)
E[] !Timer.abbruch
• Ist es garantiert, dass kein Abbruch passiert? (nein)
A[] !Timer.abbruch
Formale Modelle der Softwareentwicklung
Stephan Kleuker
222
Systemstart und Invarianten
• Häufig sollen Invarianten erst gelten, wenn eine Initialisierung
durchlaufen wurde
• Ansatz: Definiere Boolesche Variable ok:=false, die nach der
Initialisierung auf true gesetzt wird und den Wert behält
• Beispiel: Nach Initialisierung liegt der Wert von i immer
zwischen 10 und 20
Automat P
int[0,30] i:=0;
bool ok:=false;
• Folgende Anforderung ist erfüllt:
A[] P.ok imply (P.i>10 && P.i<20)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
223
Modellierung von Arbeitsabläufen (1/2)
• Modelle werden nicht nur für HW- und SW-Systeme
zur Prüfung genutzt, sie können auch zur Analyse
von Geschäftsprozessen dienen; dazu bietet auch
Uppaal Möglichkeiten
• Anmerkung: Natürlich kann man solche
Modellierungsansätze auch mit SPIN verfolgen; es
gibt kommerzielle Ansätze, um hier mit (linearen)
Optimierungen zu arbeiten
• Spezifikation: Es gibt zwei Möglichkeiten, ein
Gesamtergebnis herzustellen, einmal in zwei
Teilschritten, die etwas zeitintensiver, aber
kostengünstiger sind, der andere Ansatz besteht aus
einem Schritt, der kostenintensiver, aber schneller ist
Formale Modelle der Softwareentwicklung
Stephan Kleuker
224
Modellierung von Arbeitsabläufen (2/2)
Automat P
clock x;
clock y;
int i:=0;
bool fertig:=false;
• x misst die Gesamtzeit
• fertig gesetzt, wenn Arbeit abgeschlossen (alternativ P.s3)
• i steht für Kosten
• Gibt es kostengünstigen (i<3) Weg in maximal 7 E (nein)
E<> P.fertig && P.i<3 && P.x<=7
• Gibt es Weg in maximal 7 E (ja)
E<> P.fertig && P.x<=7
• Gibt es kostengünstigen Weg in maximal 8 E (ja)
E<> P.fertig && P.i<3 && P.x<=8
Formale Modelle der Softwareentwicklung
Stephan Kleuker
225
Verifikation deterministischer Programme
• Sortierverfahren, informelle Spezifikation:
Laufe mit dem Zähler i von 0 bis zur Arraygröße-1
Laufe mit dem Zähler j von i+1 bis zur Arraygröße
falls das j-te Element kleiner als das i-te Element ist,
vertausche diese
Formale Modelle der Softwareentwicklung
Stephan Kleuker
226
Sortierer (1/4)
const int N:=5;
const int MAX:=3;
int[0,MAX] array[N];
int[0,MAX] save[N];
int count:=0;
int[0,N] count2:=0;
int[0,N] j:=0;
int[0,MAX] tmp;
int[0,N] anzahl1;
int[0,N] anzahl2;
Formale Modelle der Softwareentwicklung
Stephan Kleuker
227
Sortierer (2/4) mit kleinem Fehler
Formale Modelle der Softwareentwicklung
Stephan Kleuker
228
Sortierer (3/4)
Gleiche
Elemente
Formale Modelle der Softwareentwicklung
Stephan Kleuker
229
Sortierer (4/4)
A[] !deadlock || Process.ok
Process.ok)
Process.array[0] = 0
Process.array[1] = 0
Process.array[2] = 0
Process.array[3] = 1
Process.array[4] = 0
Process.save[0] = 0
Process.save[1] = 0
Process.save[2] = 0
Process.save[3] = 1
Process.save[4] = 0
Process.count = 3
Process.j = 4
Process.tmp = 0
Formale Modelle der Softwareentwicklung
(alternativ: A<>
Ergebnis nach Ausführung
fehlerhafter Trace
(Korrekt im Sortieren:
j>N-1
und jeweils j<=N-1 && …)
alternativ e Formel:
A<> Process.ok
Stephan Kleuker
230
Beispiel: Telefonsystem (1/8)
• Informelle Beschreibung: Zu entwickeln ist eine Timed
Automata-Spezifikation für ein Telefonsystem mit N
Teilnehmern. Dabei besteht das System aus den Teilnehmern
und dem Vermittlungssystem. Zur Kommunikation zwischen
den Teilnehmern und dem Vermittlungssystem werden
folgende Kommunikationen (Synchronisationen) genutzt.
Kommunikation
dial, x
Bedeutung
busy
Teilnehmer erhält die Information gewählte Nummer besetzt
connect
Teilnehmer erhält die Information gewählte Nummer erreicht
dialled
Teilnehmer erhält die Information, dass er von einem anderen
Teilnehmer angerufen wurde
disconnect
Teilnehmer beendet das Gespräch
Teilnehmer wählt Nummer x
disconnected verbundener Teilnehmer hat Gespräch beendet
• Vereinfachend wird angenommen, dass ein erfolgreich
angerufener Teilnehmer immer das Gespräch annimmt und
dass der Telefonhörer unmittelbar mit busy, disconnect und
disconnected aufgelegt wird.
Formale Modelle der Softwareentwicklung
Stephan Kleuker
231
Beispiel: Telefonsystem (2/8)
Teilnehmer 1
Vermittlungssystem
Teilnehmer 2
dial,2
dialled
alternativ kann
Teilnehmer 1
auflegen
connect
disconnect
disconnected
Teilnehmer 1
Vermittlungssystem
dial,2
busy
Formale Modelle der Softwareentwicklung
Stephan Kleuker
232
Beispiel: Telefonsystem (3/8)
Anforderungen:
Die zentrale funktionale Anforderung ist, dass jeder Teilnehmer
immer wieder die Möglichkeit hat, jeden anderen Teilnehmer zu
erreichen.
Weiterhin soll das System folgende Zeitrandbedingungen
berücksichtigen:
– Es werden minimal 3 und maximal 7 Zeiteinheiten benötigt,
um festzustellen, dass ein Teilnehmer nicht erreichbar ist
– Es werden minimal 4 und maximal 10 Zeiteinheiten benötigt,
um die Verbindung (dialled) zu einem erreichbaren
Teilnehmer aufzubauen
– Ein Telefonat (zwischen connect und disconnect, bzw.
dialled und disconnect) dauert minimal 20 und maximal 40
Zeiteinheiten (z. B. Werbung + echtes Gespräch)
Wie lange kann es maximal dauern, bis ein
Telefonat(sversuch) beendet wurde?
Formale Modelle der Softwareentwicklung
Stephan Kleuker
233
Beispiel: Telefonsystem (4/8)
Verwaltungsdaten:
const int N := 5;
mit
// für vier Teilnehmer,
// Nummern 1,2,3,4
// Teilnehmer 0, bzw. Wert 0 für keine
Verbindung
chan dial[N];
chan connect[N];
chan busy[N];
chan disconnect[N];
chan disconnected[N];
chan dialled[N];
int[0,N] anrufen[N]; // Nummer, die
Teilnehmer i
Formale Modelle der Softwareentwicklung
Stephan Kleuker
// anruft
234
Beispiel: Telefonsystem (5/8)
Teilnehmer
Parameter:
int[1,N] ich
Formale Modelle der Softwareentwicklung
clock y;
clock dauer;
Stephan Kleuker
235
Beispiel: Telefonsystem (6/8)
int[1,N]
caller;
int[1,N]
calling;
int[1,N] tmp;
clock x;
Formale Modelle der Softwareentwicklung
Telefonsystem
Stephan Kleuker
236
Beispiel: Telefonsystem (7/8)
// Komposition unter Nutzung eines
// Verbindungsknotens
Tel1 = Teilnehmer(1);
Tel2 = Teilnehmer(2);
Tel3 = Teilnehmer(3);
Tel4 = Teilnehmer(4);
Verbindung = Telefonsystem()
system Tel1, Tel2, Tel3, Tel4, Verbindung;
• System hat kein Deadlock
A[] !deadlock
Property is satisfied.
Formale Modelle der Softwareentwicklung
Stephan Kleuker
237
Beispiel: Telefonsystem (8/8)
• Analyse der maximalen Gesprächsdauer (Grenzen durch try
and error)
A[] ((!Tel2.start) imply Tel2.dauer<47)
Property is not satisfied.
A[] ((!Tel2.start) imply Tel2.dauer<48)
Property is satisfied.
• Annäherung an: Jeder kann jeden anrufen
E<> (aktiv[1]==2 && aktiv[2]==1)
Property is satisfied.
• Prüfung: alle gleichzeitig aktiv
E<> (Tel1.verbunden && Tel2.verbunden
&& Tel3.verbunden && Tel4.verbunden)
Property is not satisfied.
• Spezifikation zusätzlicher Leitungen (Verbindungsknoten)
Verbindung2 = Telefonsystem()
system Tel1, Tel2, Tel3, Tel4, Verbindung,
Verbindung2;
Formale Modelle der Softwareentwicklung
Stephan Kleuker
238
Grenzen von Timed Automata
• Alle Uhren laufen synchron, d.h. es ist keine ClockDrift einfach spezifizierbar (Uhren weichen mit der
Zeit leicht voneinander ab)
• Anforderungssprache TCTL nicht sehr mächtig,
weniger als CTL oder CTL* (hauptsächlich
Performancegründe)
• Umgang mit Uhren nur sehr eingeschränkt in
Bedingungen möglich; keine Zuweisungen an Uhren;
keine Nutzung im Zusammenhang mit Variablen
(Problem: Logik wird sonst schnell unentscheidbar)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
239
4. Spezifikation mit Petrinetzen
4.1 Funktionsweise von Petrinetzen
4.2 Erreichbarkeitsgraphen und
Überdeckungsgraphen
4.3 S- und T-Invarianten
4.4 Werkzeuggestützte Analyse von Petrinetzen
4.5 Fallstudien
4.6 Äquivalenzen von Petri-Netzen
Formale Modelle der Softwareentwicklung
Stephan Kleuker
240
4.1 Funktionsweise von Petrinetzen
• Motivation für Petrinetze
• Schaltverhalten
• typische Netzeigenschaften
• Fairness
Formale Modelle der Softwareentwicklung
Stephan Kleuker
241
Motivation für Petrinetze
• Modelle sollen zur Verifikation möglichst einfach
sein
• Generell gibt es zwei Arten von Informationen in
Modellen
• Daten, die bearbeitet werden
• Aktionen (Transitionen), die Daten verarbeiten; aus
Daten neue Daten berechnen
•
•
•
•
Petrinetz-Ansatz nach C. A. Petri (1962)
Stellen, die Daten aufnehmen können
Daten als Token, die auf Stellen liegen
Transitionen nehmen Token aus Stellen und legen
neue Token auf evtl. andere Stellen
Formale Modelle der Softwareentwicklung
Stephan Kleuker
242
Schaltregel von Petrinetzen
• Eine Transition (Kasten oder Strich) kann schalten, wenn auf
jeder eingehenden Kante einer Stelle (Kreis) mindestens ein
Token (gefüllter Punkt) liegt
• Beim Schalten wird ein Token von jeder Stelle einer
eingehenden Kante weggenommen und ein Token auf jede
Stelle einer ausgehenden Kante gelegt
Formale Modelle der Softwareentwicklung
Stephan Kleuker
243
Beispiel für Schaltmöglichkeiten
s1
t2
s3
t1
s2
s1
{t1}
t3
s4
t2
s3
t1
schaltet
s2
s1
{t2,t3}
t3
s4
t2
s3
t1
schaltet
s2
s1
{t1,t4}
t3
s4
t2
s3
t1
schaltet
s2
Formale Modelle der Softwareentwicklung
t3
t4
s5
t4
s5
t4
s5
t4
s5
s4
Stephan Kleuker
244
Definition S/T-Netz (1/2)
• Definition (Petri-Netz): Ein Petri-Netz P =(S,T,G)
besteht aus einer Menge von Stellen S, einer Menge
von Transitionen T und einem gerichteten
Verbindungsgraphen G, bei dem nur Stellen mit
Transitionen und Transitionen mit Stellen verbunden
sind, G  (S  T)  (T  S).
• Definition (Vorbereich, Nachbereich): Sei tT eine
Transition eines Petri-Netzes, dann heißt
pre(t) = {s  S | (s,t)  G} Vorbereich von t
post(t) = {s  S | (t,s)  G} Nachbereich von t
• Definition (Markierung): Eine Markierung M eines
Petrinetzes P=(S,T,G) ist eine Abbildung, die jeder
Stelle des Netzes eine Anzahl von Token zuordnet,
M: S  N0
Formale Modelle der Softwareentwicklung
Stephan Kleuker
245
Definition S/T-Netz (2/2)
• Definition (Schalten eines Netzes): Sei M eine Markierung eines
Petri-Netzes P=(S,T,G), dann heißt eine Transition t aktiviert unter
M, bzw. kann t schalten unter M, wenn auf allen Stellen des
Vorbereichs von t mindestens ein Token liegt, d.h.
für alle s  pre(t): M(s)1
• Eine Transitionsmenge T‘T ist zusammen aktiviert, bzw. kann
zusammen schalten, wenn genügend Marken auch in den
gemeinsamen Vorbereichen liegen. Für alle s sei spre(T‘) die
Häufigkeit, mit der s in den Vorbereichen von T‘ vorkommt,
spre(T‘)= |{t  T‘ | s  pre(t)}|, dann muss für alle s  S: M(s)  spre(T‘)
Weiterhin sei spost(T‘)= |{t  T‘ | s  post(t)}|.
• Sei M eine Markierung und T‘T aktiviert unter M, dann hat das
Netz nach dem Schalten die Folgemarkierung M‘ (geschrieben:
M[T‘>M‘), wobei für alle s S gilt: M‘(s) = M(s)-spre(T‘)+ spost(T‘). Für
eine Transition t  T‘ heißt das:
M(s), falls s pre(t) post(t) oder s  pre(t)  post(t)
M‘(s) =
M(s)-1 falls s  pre(t) und s  post(t)
M(s)+1 falls s  post(t) und s  pre(t)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
246
Analyse des Schaltverhaltens
t1
s1
s2
t2
t3
s4
s3
t4
Formale Modelle der Softwareentwicklung
t1 und t2 sind jeweils aktiviert,
{t1,t2} ist nicht aktiviert, da nur
ein Token auf s1
t3 immer aktiviert, kann beliebig
viele Token erzeugen
t4 aktiviert, kann beliebig viele
Token (wenn vorhanden) von s4
löschen
Stephan Kleuker
247
Petri-Netze als Prozesse
• Zu einem Petri-Netz wird immer eine Anfangsmarkierung M0
angegeben, dann können Fragen aus der Prozesswelt relevant
werden:
• kann das Netz terminieren: wird eine Markierung erreicht, unter
der keine Transition mehr aktiviert ist
• terminiert das Netz immer: da Netze nicht-deterministisch sind,
können in verschiedenen Abläufen verschiedene Markierungen
erreicht werden
• unerwünschte Terminierung = Deadlock
• wie bei Prozessen spielt bei Fragestellungen Fairness für einen
Ausführungspfad M0[t1>M1[t2>M2[ ... eine Rolle
– schwach fair: Transition, die unendlich oft aktiviert ist,
schaltet auch
– stark fair: Transition, die unendlich oft immer wieder
aktiviert ist, schaltet auch
Formale Modelle der Softwareentwicklung
Stephan Kleuker
248
Fairness bei Netzen
t3
t1
t2
t3
t1
unfair terminiert das Netz
nicht, schwach fair
terminiert es, da immer t1
aktiviert
unfair und schwach fair
terminiert das Netz nicht,
stark fair terminiert es, da
immer wieder t1 aktiviert
t2
Formale Modelle der Softwareentwicklung
Stephan Kleuker
249
Spezielle Netze
• In unserer Definition können beliebig viele Token auf einer
Stelle liegen, weiterhin bewegt jede Transition pro Stelle nur ein
Token
s1
s2
2
3
• Variante 1: Die Kanten des Netzes werden gewichtet, z,B. t1
zieht zwei Token von s1 ab (benötigt diese) und erzeugt drei
Token auf s2
2
1
• Variante 2: Die Tokenanzahl pro Stelle wird begrenzt, es dürfen
maximal max(s)-Token auf einer Stelle s liegen, d.h. zum
Schalten muss sichergestellt sein, dass auf post(s) genügend
Platz ist
• Variante 2.1: Es wird für alle Stellen s max(s)=1 gesetzt,
entweder ein Token vorhanden oder nicht
• Variante 1 ist ausdrucksmächtig wie S/T-Netze
• Varianten 2 und 2.1 ausdrucksmächtig wie endliche Automaten
Formale Modelle der Softwareentwicklung
Stephan Kleuker
250
4.2 Erreichbarkeits- und Überdeckungsgraphen
• Erreichbarkeit von Markierungen
• Erreichbarkeitsgraph
• Überdeckungsgraph
• Aus Graphen ableitbare Erkenntnisse
Formale Modelle der Softwareentwicklung
Stephan Kleuker
251
Erreichbare Markierungen
• Definition (Erreichbare Markierungen): Sei M eine
Markierung eines Petri-Netzes P=(S,T,G), dann
bezeichnet Erreichbar(P,M) die Menge aller von M
aus erreichbaren Markierungen. Formal:
Erreichbar(P,M)={ M’ | es gibt ein i mit 0in und
Transitionen tiT, sowie Markierungen Mi, so dass
es eine Transitionsfolge
M [t1> M1 [t2> M2 ... [tn> Mn=M’ gibt}
• Abhängig vom Petrinetz kann Erreichbar(P,M)
endlich oder unendlich sein.
Formale Modelle der Softwareentwicklung
Stephan Kleuker
252
Erreichbarkeitsgraph (auch: Fallgraph)
• Man kann alle erreichbaren Markierungen (Zustände) in einen
Graphen eintragen und Kanten mit gefeuerten Transitionen
beschriften:
s1
s2
(2,0,1,0)
t1
s3
t1
s4
t2
t3
t1,t2
t2
(1,1,1,0)
(2,0,0,1)
t2
t1
(0,2,1,0)
t3
t1,t2
t2
t1
(1,1,0,1)
t3
t1
(0,2,0,1)
• Problem: Erreichbarkeitsgraph nicht immer endlich (nur
garantiert bei Stellenkapazitätsbeschränkung)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
253
Formale Definition des Erreichbarkeitsgraphen
• Definition (Erreichbarkeitsgraph): Sei M eine
Markierung eines Petri-Netzes P=(S,T,G), dann heißt
ein Graph G=(Erreichbar(P,M), Tr), wobei
TrErreichbar(P,M)2TErreichbar(P,M) genau die
Kanten (M,T’,M’) enthält, für die es eine Menge von
Transtionen T’T mit M [T’> M’ gibt,
Erreichbarkeitsgraph (oder auch Fallgraph) von P
und M.
• 2T bezeichnet die Potenzmenge von T
• Ein Erreichbarkeitsgraph kann nur dann sinnvoll
dargestellt werden, wenn Erreichbar(P,M) endlich ist.
Formale Modelle der Softwareentwicklung
Stephan Kleuker
254
Ordnung auf Markierungen
• Möchte man einen endlichen Graphen zur
Darstellung der Zustandsfolgen, ist die Idee, wenn
die Werte einer erreichten Markierung M‘ echt größer
als die Werte einer vorher erreichten Markierung M
sind, dann kann die Tokenanzahl an den Stellen
beliebig steigen, an denen die Tokenanzahl
gestiegen ist.
• M‘ > M: für alle sS: M‘(s)M(s) und es gibt ein sS:
M‘(s)>M(s)
• gilt M‘>M und für eine Stelle s damit M‘(s)>M(s), dann
können auf s beliebig viele Token erzeugt werden.
• z. B. (0,4,1,1) > (0,3,0,1), d.h. (0,x,y,1) mit beliebig
großen x und y erreichbar
• nicht jede x,y-Kombination erreichbar
Formale Modelle der Softwareentwicklung
Stephan Kleuker
255
Überdeckungsgraph
• Überdeckungsgraph wird wie Erreichbarkeitsgraph konstruiert,
allerdings, wenn M‘ > M für vorher auf dem Pfad dahin
berechnete Markierungen wird für alle Stellen s mit M‘(s)>M(s),
wird statt M‘(s) der Wert  für unendlich eingetragen (es
werden alle bisher erreichten M betrachtet)
s1
s3
a
b
s2
(1,0,0)
a
(0,1,0)
b
(1,0, )
a
b
(0,1, )
• Aus dem Überdeckungsgraphen lässt sich ablesen, welche
Stellen beschränkt, bzw. unbeschränkt sind; bei
unbeschränkten Stellen kann die Tokenanzahl beliebig
wachsen
Formale Modelle der Softwareentwicklung
Stephan Kleuker
256
Überdeckungsgraph nicht eindeutig [Rei]
s2
(0,0,1)
1
a
s1
d
(1,0,0)
a
6
c
s3
b
b
(1,0,0)
1a
d 8
c
c 3
(0,1,0)
d 2
c
c
(0,1,0)
3
c
2
(0,1,)
d
4
5
(0,,)
6
4
(0,,)
1: gibt Arbeitsschrittnummer an
(0,0,1)
7
b
5
d
Anmerkung:
(0,,) muss nicht
bedeuten, dass
beliebige (0,x,y)
erreicht werden
können
d
Formale Modelle der Softwareentwicklung
Stephan Kleuker
257
Theoretische Aussagen zu Petri-Netzen
• Die Frage für ein gegebenes Petri-Netz, ob eine
Markierung erreichbar ist, ist unendscheidbar
• Die Frage für ein gegebenes Petri-Netz, ob eine
Markierung M überdeckt werden kann, ist
entscheidbar (konstruiere Überdeckungsgraph,
analysiere alle Markierungen M‘, falls M‘M, dann
überdeckbar)
• Sind alle Stellen beschränkt, sind die genannten
Probleme trivial entscheidbar
Formale Modelle der Softwareentwicklung
Stephan Kleuker
258
4.3 S- und T-Invarianten
• Typische zu prüfende Eigenschaften
• Netze als Matrizen
• T- Invarianten
• S-Invarianten
Formale Modelle der Softwareentwicklung
Stephan Kleuker
259
Typische Fragen an Netzmodelle
• Ist das Netz lebendig? (Kann immer eine neue
Transition schalten?)
• Ist die Tokenanzahl für alle (für bestimmte) Stellen
beschränkt?
• Bleibt die Tokenanzahl für bestimmte Stellen
konstant (z. B. für wechselseitigen Ausschluss?)
• Wird zyklisch durch schaltende Transitionen immer
wieder die gleiche Situation erzeugt?
Formale Modelle der Softwareentwicklung
Stephan Kleuker
260
Matrixdarstellung von Netzen
• Jedes Petrinetz P kann durch eine Matrix Matrix(P) dargestellt
werden, Transitionen geben an, von welchen Stellen Token
entfernt werden, an welche Stellen Token gelegt werden
• Anfangsmarkierung (generell Markierungen) als Vektor
darstellbar
s3
s1
s2
a
b
c
d
Anfang
s1
-1
0
1
0
1
s2
0
-1
0
1
1
s3
-1
-1
1
1
1
s4
1
0
-1
0
0
s5
0
1
0
-1
0
a
s4
s5
c
• Schalten entspricht dann
Summenbildung von Vektoren (z. B. Anfang +a)
Formale Modelle der Softwareentwicklung
b
Stephan Kleuker
d
261
Bedeutung der Matrixmultiplikation
a
b
c
d
i
e
s1
-1
0
1
0
1
0
s2
0
-1
0
1
1
-1
s3
-1
-1
1
1
s4
1
0
-1
0
s5
0
1
0
-1
*
1
=
0
-1
0
1
• i bedeutet, dass a, b ,c jeweils einmal, d null-mal ausgeführt
wurde
• e beschreibt die Veränderung der Ausgangsmarkierung, s1 und
s4 haben genauso viele Token wie vorher, s2 und s3 verlieren
ein Token, s5 gewinnt ein Token
• i beschreibt nicht, in welcher Reihenfolge die Transitionen
ausgeführt werden
• i garantiert nicht, dass Transitionen (in dieser Reihenfolge)
ausführbar, da Matrixmultiplikation auch mit negativen Werten
arbeitet, z. b. a.c.b ausführbar, a.b.c nicht
Formale Modelle der Softwareentwicklung
Stephan Kleuker
262
T-Invarianten informell
• Petri-Netze eignen sich gut, sich
wiederholende Prozesse, z. B.
Steuerungen zu modellieren
• Nach einem Durchlauf soll
möglichst die gleiche Situation
wieder hergestellt sein
• Frage: gibt es Schaltsequenzen,
die die gleiche Situation wieder
herstellen? Die Häufigkeit der
benutzten Transitionen wird TInvariante genannt
• Im Beispiel: Schaltsequenzen a.c
und b.d, formal
i(a)=1, i(b)=0, i(c)=1, i(d)=0;
i(a)=0, i(b)=1, i(c)=0, i(d)=1;
Formale Modelle der Softwareentwicklung
s3
s1
a
s2
b
s4
s5
c
Stephan Kleuker
d
263
T-Invarianten
• Eine Markierung M eines Netzes P heißt reproduzierbar, wenn
es eine nicht leere Folge von Transitionen mit
M[t1>M1[t2>...[tn>Mn=M gibt, dabei müssen die ti und
Markierungen Mi nicht unterschiedlich sein.
• Sei Matrix(P) die Matrix des Netzes P. Dann heißt eine Lösung i
der Gleichung Matrix(P)*i=0 T-Invariante von P.
Anschaulich gibt i(t) an, wie häufig eine Transition für eine
reproduzierbare Markierung schalten muss
• Satz: P besitzt genau dann eine positive T-Variante i (für alle t:
i(t)0, für mindestens ein t i(t)>0), wenn P eine reproduzierbare
Markierung hat
• Achtung: Nicht jede positive T-Invariante kann realisiert
werden, d.h. in eine mögliche Schaltfolge übersetzt werden
(abhängig von Anfangsmarkierung)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
264
Beispiel: Lösung des Gleichungssystems (1/2)
-1
0
1
0
i1
0
0
-1
0
1
i2
0
-1
-1
1
1
1
0
-1
0
0
1
0
-1
*
1. und 4. Zeile tauschen,
neue 1. Zeile zur 3. und 4. Zeile
addieren
i3
=
0
i4
0
0
3. Zeile = 3. Zeile – 2. Zeile
5. Zeile = 5. Zeile + 2. Zeile
1
0
-1
0
1
0
-1
0
0
-1
0
1
0
-1
0
1
0
-1
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
-1
0
0
0
0
Formale Modelle der Softwareentwicklung
Stephan Kleuker
265
Beispiel: Lösung des Gleichungssystems (2/2)
•
•
•
•
j*
1
0
-1
0
i1
0
0
-1
0
1
i2
0
0
0
0
0
0
0
0
0
0
0
0
0
*
i3
i4
=
0
0
0
man erhält, dass i4=1 und i3=2 frei wählbar sind
2. Zeile ergibt i2=i4=1
j=1, k=0: i(a)=0, i(b)=1, i(c)=0, i(d)=1,
1. Zeile ergibt i1=i3=2
b.d ausführbar, d.b nicht
Lösungsraum:
j=0, k=1: i(a)=1, i(b)=0, i(c)=1, i(d)=0
a.c ausführbar, c.a nicht
0
1
1
0
1
+k*
0
1
0
Formale Modelle der Softwareentwicklung
j=1, k=1: i(a)=1, i(b)=1, i(c)=1, i(d)=1
b.d.a.c, a.c.b.d ausführbar,
Rest z. B. a.b.c.d nicht
Stephan Kleuker
266
Beispiel: T-Invariante
s1
t1
t2
t3
1
-1
-1
0
1
-1
s2
i(t3) = 
i(t2) = 
i(t1)=i(t2)+i(t3)= 2 
z.B. i(t1)=2, i(t2)=1, i(t3)=1
Analysieren, ob eine der Schaltfolgen, die zweimal t1 und je
einmal t2 und t3 enthalten, realisierbar sind:
t1.t2.t1.t3, t1.t1.t2.t3 sind realisierbar, alle anderen nicht
Formale Modelle der Softwareentwicklung
Stephan Kleuker
267
T-Invarianten eventuell nicht nutzbar
s5
s1
t1
s2
t2
t3
s3
t4
t5
s4
t6
s6
• Netz mit T-Invariante i mit i(t1)=i(t2)=i(t5)=i(t6)=1 und
i(t3)=i(t4)=0
• Invariante ist nicht realisierbar [Rei]
• Nach Satz existiert aber Markierung, die T-Invariante nutzt:
M(s1)=1, M(s3)=1
Formale Modelle der Softwareentwicklung
Stephan Kleuker
268
S-Invariante informell
• Das Netz soll für den
s3
s1
s2
wechselseitigen Ausschluss stehen.
• Informell, immer nur maximal ein
Token auf s4 oder s5
a
b
• ein Ansatz: Berechne
Erreichbarkeitsgraph oder
s4
s5
Überdeckungsgraph
• Graph-Berechnung oft recht
aufwändig, folgender Ansatz zeigt,
c
d
dass man leicht Invarianten
berechnen kann
• S-Invariante: Gegeben eine Teilmenge von Stellen, dann bleibt
die Anzahl der Token auf diesen Stellen immer gleich
• im Beispiel: Wenn s3, s4, s5 eine S-Invariante wäre, dann wäre
auch wechselseitiger Ausschluss gezeigt
Formale Modelle der Softwareentwicklung
Stephan Kleuker
269
Berechnung von S-Invarianten
• Definition (S-Invariante): Sei Matrix(P) die Matrix zu
einem Petrinetz P und Matrix‘(P) deren transponierte
Matrix dann sind S-Invarianten durch Lösung des
linearen Gleichungssystem Matrix‘(P) * x =0
bestimmt.
• Transponieren: die i-te Zeile von Matrix(P) von links
nach rechts gelesen zur i-ten Spalte von Matrix‘(P)
von oben nach unten gelesen.
• Da die Lösung x dann genau |S| Zeilen hat, kann man
die einzelnen Werte direkt der Matrix zuordnen, also
für ein sS auch x(s) schreiben.
• S-Invarianten haben natürlich nur einen Sinn, wenn
alle Markierungswerte positiv und ganzzahlig sind.
Formale Modelle der Softwareentwicklung
Stephan Kleuker
270
Beispielberechnung S-Invariante
-1
0
-1
1
0
0
-1
-1
0
1
1
0
1
-1
0
0
1
1
0
-1
x1
0
x2
*
=
x3
x4
0
0
0
x5
1. und 3. Zeile tauschen
2. und 4. Zeile tauschen
3. Zeile= 3.Zeile +1. Zeile
4. Zeile= 4.Zeile +2- zeile
x3= 1, x4= 2, x5= 3
x2+x3-x5=0 d.h. x2= - 1 + 3
x1+x3-x4=0 d.h. x1=- 1+ 2
Lösungsraum
-1
1
0
-1
0
1
1
0
1
-1
0
0
1
1
0
-1
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
1
Formale Modelle der Softwareentwicklung
i*
1
+ j*
Stephan Kleuker
0
+ k*
0
271
Interpretation der Lösung
s3
s1
a
s2
b
s4
s5
c
i*
d
-1
1
0
-1
0
1
1
+ j*
0
+ k*
0
0
1
0
0
0
1
Formale Modelle der Softwareentwicklung
• i=0, j=1, k=0: (1,0,0,1,0), Summe
der Token auf s1 und s4 bleibt
konstant
• i=0, j=0, k=1: (0,1,0,0,1), Summe
der Token auf s2 und s5 bleibt
konstant
• i=1, j=1, k=1: (0,0,1,1,1), Summe
der Token auf s3, s4 und s5
bleibt konstant (da hier nur ein
Token, gilt wechselseitiger
Ausschluss)
• obige drei Invarianten: Netz mit
Invarianten überdeckt
• i=1, j=2, k=2: (1,1,1,2,2),
M(s1)+M(s2)+M(s3)+2*M(s4)
+2*M(s5) bleibt konstant
Stephan Kleuker
272
Aussagen über S-Invarianten
• Definition: Eine S-Invariante heißt positiv, wenn alle
Werte größer-gleich und mindestens ein Wert größer
als Null ist
• Definition: Ein Netz P heißt von S-Invarianten
überdeckt, wenn es für jede Stelle des Netzes eine
positive S-Invariante gibt, deren Wert für diese Stelle
größer Null ist
• Satz: Ist ein Netz mit S-Invarianten überdeckt, gibt es
eine S-Invariante, die für alle Stellen einen Wert
größer Null hat
• Satz: Ist ein Netz N von S-Invarianten überdeckt,
dann ist N beschränkt, d.h. für alle Stellen gibt es
eine maximale Anzahl von Token, die erreicht
werden kann (dann ist der Überdeckungsgraph
gleich dem Erreichbarkeitsgraphen)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
273
4.4 Werkzeuggestützte Analyse von Petrinetzen
•
•
•
•
•
Überblick Netlab
Spezifikation von Stellen
Spezifikation von Transitionen
Durchführung des Tokenspiels
Berechnung von Erreichbarkeits- und
Überdeckungsgraphen
• Berechnung und Visualisierung von S- und TInvarianten
Formale Modelle der Softwareentwicklung
Stephan Kleuker
274
Beispiel- Werkzeug: NetLab für Windows (Übersicht)
Institut für
Regelungstechnik,
RWTH Aachen,
Leitung Prof. Dr. D.
Abel
Bearbeiten
Stellen eingeben
Transitionen eingeben
Kanten eingeben
Name
Nummer (automatisch)
aktuelle Token/ max. Token
keine schaltenden
Transitionsmengen
(nur Interleaving)
Name
Nummer (automatisch)
Formale Modelle der Softwareentwicklung
Einfache S/T-Netze
mit Simulation und
Invariantenberechnung
Stephan Kleuker
275
Bearbeitung einer Stelle bzw. eines Knotens
Anzahl der Marken am Anfang
(soll Anzahl unendlich sein)
maximale Tokenanzahl
Stelle ist unbeschränkt
angezeigter Name
Formale Modelle der Softwareentwicklung
Stephan Kleuker
276
Bearbeitung einer Transition
angezeigter Name
Nummer (editierbar, bleibt
immer eindeutig)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
277
Tokenspiel in Netlab
Start/Beendigung des
Tokenspiels
ausführbare Transitionen mit
beteiligten Stellen sind
umrandet
Schalten durch Klick auf
Transition
Formale Modelle der Softwareentwicklung
Stephan Kleuker
278
Berechung der Graphen
Formale Modelle der Softwareentwicklung
Stephan Kleuker
279
Berechnung und Anzeige von S-Invarianten
T-Invarianten analog
als umrahmte
Transitionen
Formale Modelle der Softwareentwicklung
Stephan Kleuker
280
4.5 Fallstudien
• Geschäftsprozessmodellierung
• Dinierende Philosophen
• Deadlockvermeidung
Formale Modelle der Softwareentwicklung
Stephan Kleuker
281
Prozessmodellierung
• Damit verschiedene Menschen (genauer Rollen)
zusammenarbeiten können, muss geregelt sein, wann was
passiert; dies sind Prozessbeschreibungen
• „Wer (verantwortlich) macht mit wem (mitwirkend, beratend)
wann (welche Bedingungen müssen eingetreten sein, welche
Eingangsprodukte müssen vorliegen) was (welche
Detailschritte sind durchzuführen) mit welchen Hilfsmitteln
(z.B. welche SW, welche Standards und Guidelines) wo (an
welchen Orten) um welches Ergebnis (Ergebnisprodukt und
Zustand des Ergebnisses) zu erreichen.“
• Diese Prozesse sind zu dokumentieren und zu pflegen (z. B. an
neue Bedingungen anzupassen); eine zentrale Aufgabe des
Qualitätsmanagements
• Prozessabläufe durch Petrinetze beschreibbar, Token sind zu
bearbeitende Objekte, Transitionen sind Bearbeitungsschritte
• Semantik von UML-Aktivitätsdiagrammen formal mit
Petrinetzen definiert
Formale Modelle der Softwareentwicklung
Stephan Kleuker
282
Projektplanung
Formale Modelle der Softwareentwicklung
Stephan Kleuker
283
S-Invarianten der Projektplanung
• jede Stelle maximal ein Token
Formale Modelle der Softwareentwicklung
Stephan Kleuker
284
Verknüpfung von Prozessen
Projektplanung
Formale Modelle der Softwareentwicklung
Risikoverwaltung
Stephan Kleuker
285
Dinierende Philosophen (1/4)
Drei Philosophen haben
sich zum SpaghettiEssen getroffen. In
der Mitte steht ein
Topf mit Nudeln.
Zwischen zwei
Philsophen liegt
jeweils eine Gabel.
Wenn ein Philosoph
Hunger hat, nimmt er
die linke und die
rechte Gabel, isst
und legt die Gabeln
wieder weg.
Formale Modelle der Softwareentwicklung
Stephan Kleuker
286
Dinierende Philosophen (2/4)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
287
Dinierende Philosophen (3/4)
• Erreichbarkeitsgraph zeigt Deadlock
• Deadlock durch Regeln (z. B. wer nimmt in welcher
Reihenfolge) vermeidbar
Formale Modelle der Softwareentwicklung
Stephan Kleuker
288
Dinierende Philosophen (4/4)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
289
4.6 Äquivalenzen von Petri-Netzen
• Parallelkomposition von Netzen
• τ-Transitionen, markiertes Netz
• Sprache eines Netzes
• Trace-Readiness-Semantik
Formale Modelle der Softwareentwicklung
Stephan Kleuker
290
Parallelkomposition von Netzen
• Transitionsbeschriftungen können als
Kommunikationen angesehen werden, analog zu
Timed Automata: senden c!, empfangen c?
a
a!
c?
a?
b!
b?
c
c!
b
Kompositionsergebnis
Formale Modelle der Softwareentwicklung
Stephan Kleuker
291
τ-Transitionen
• τ -Transitionen, bezeichnen interne Schritte, die nach außen
nicht beobachtbar sind
• τ -Transitionen erlauben es, Nicht-Determinismus ohne
sichtbare Transition auszuführen
τ
τ
<- Interne Entscheidung über
mögliche
Folgekommunikation
-> Externe Entscheidung
über mögliche
Folgekommunikation
a!
b!
Formale Modelle der Softwareentwicklung
a!
Stephan Kleuker
b!
292
Markiertes Petrinetz
• Definition (markiertes Petrinetz): Sei P=(S,T,G) ein
Petrinetz, A eine endliche Menge von
Kommunikationen und L eine Funktion, die jeder
Transition eine Kommunikation oder  zuordnet, also
L: T  A{}. Dann heißt PM=(S,T,G,A,L) markiertes
Petrinetz.
Weiterhin können die Kommunikation mit den
Zeichen „!“ und „?“ ergänzt werden.
Formale Modelle der Softwareentwicklung
Stephan Kleuker
293
Sprache und Ready-Mengen
• Definition (Sprache eines markierten Petrinetzes): Sei
PM=(S,T,G,A,L) ein Petrinetz mit Markierung M. Dann
bezeichnet L(PM,M)  A* die von PM beschriebene formale
Sprache.
L(PM,M)= {t | t=c1. ... .cn, ci  A für alle 1 i  n, es gibt eine
ausführbare Transitionsfolge M[t1>M1[t2>M2[ ... >Mm, so dass
w(t1.t2. ... .tm) = t gilt}
Die Funktion w entfernt alle -Transitionen und ist wie folgt
definiert.
L(t1).w(t2. ... .tm), wenn L(t1)  
w(t1.t2. ... .tm) =
w(t2. ... .tm), wenn L(t1) = 
• Eine zur Trace t=c1. ... .cn gehörende Ready-Menge enthält
genau alle Kommunikationen ciA, für die es eine von der nach
t erreichten Markierung Mm ausführbare Transitionsfolge
Mm[u1>Mm+1[u2>...[uk> mit w(u1.u2. ... .uk)= ci gibt.
Formale Modelle der Softwareentwicklung
Stephan Kleuker
294
Beispiel: kontextsensitive Sprache
τ
s1
τ
s3
a
s2
s5
b
s4
c
s6
• Das Netz erzeugt pref({ap.bq.cr | pqr})
• pref(L) für Präfix-Abschluss (alle Anfangswörter),
z. B. pref({a.b.c})={ε, a, a.b, a.b.c}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
295
Motivation von Äquivalenz
• Um die Performance eines lauffähigen verteilten
Systems zu erhöhen, kann man entweder den
Algorithmus ändern (sehr aufwändig) oder wichtige
Komponente optimieren (weniger aufwändig)
• Optimiere Komponente K, welche Eigenschaften
muss K‘ als Ergebnis haben
• Allgemeine Forderung: K‘ muss sich wie K verhalten
(exakt? wo ist Optimierung?)
• meist reicht: K‘ muss K simulieren können oder
äquivalent zu K sein, aber was heißt äquivalent?
Formale Modelle der Softwareentwicklung
Stephan Kleuker
296
Sprachäquivalenz (1/2)
• Man kann Netzen N, wie Automaten, eine formale
Sprache L(N) zuordnen
• Äquivalenzforderung: L(K)=L(K‘)
• Erinnerung: Berechnung minimaler
deterministischer Automaten
a?
b!
b!
a?
• Beispiel: Sprache
pref({(ab)n| n>=0})
a?
Formale Modelle der Softwareentwicklung
b!
Stephan Kleuker
297
Sprachäquivalenz (2/2)
• für N1 und N2 keine Austauschmöglichkeit in
Parallelkomposition mit N3 garantiert
N1
N3
N2
a!
a!
b!
c!
Formale Modelle der Softwareentwicklung
a!
b!
c!
Stephan Kleuker
a?
a?
b?
c?
298
Trace-Readiness-Semantik
• Definition (Trace-Readiness-Semantik eines
markierten Petrinetzes): Sei PM=(S,T,G,A,L) ein
Petrinetz mit Markierung M. Dann bezeichnet
Sem(PM,M)={(t,R) | t=c1. ... .cn, ci  A für alle 1 i 
n, es gibt eine ausführbare Transitionsfolge
M[t1>M1[t2>M2[ ... >Mm, so dass w(t1.t2. ... .tm) = t
gilt,
weiterhin gehört cjA zu R (cjR) genau dann, wenn
es eine ausführbare Transitionsfolge
Mm[u1>Mm+1[u2>...[uk> mit w(u1.u2. ... .uk)= ci gibt}
die Trace-Readiness-Semantik.
Formale Modelle der Softwareentwicklung
Stephan Kleuker
299
Beispiele: Trace-Readiness-Semantik
a!
b!
Sem(PM,M)={ ((ε,{a,b}),
(a, ),
(b, )}
Sem(PM,M)={ ((ε,{a,b}),
(ε,{a}),
(ε,{b}),
(a, ),
(b, )}
Formale Modelle der Softwareentwicklung
τ
τ
a!
b!
Stephan Kleuker
300
Trace-Readiness-Äquivalenz
• Zwei Netze M und M‘ heißen Trace-Readiness-äquivalent, wenn
sie die gleiche Trace-Readiness-Semantik haben
• Äquivalenz erlaubt τ -Transitionen, die weiteres Verhalten nicht
ändern
τ
τ
a!
τ
b!
τ
τ
a!
τ
τ
b!
äquivalent
Formale Modelle der Softwareentwicklung
a!
τ
b!
nicht äquivalent
Stephan Kleuker
301
Abschlussbemerkungen
• Es gibt viele weitere Varianten Äquivalenzen auf Petri-Netzen
zu definieren (z. B. Bi-Simulation)
• Sinn der Äquivalenzbegriffe hängt von Art der Netze ab: Sind τ
–Transitionen erlaubt? Ist Nichtdeterminismus mit Transitionen
gleichen Namens erlaubt?
• Auch bei Trace-Readiness-Semantik sind Varianten möglich
• Generell ist der Austausch einzelner Komponenten eines
parallelen Systems sehr problematisch, da genau das
gewünschte Verhalten bekannt sein muss
• Betrachtungen können für viele Netz-Arten (Stellenbegrenzung,
stochastische Erweiterung, Zeiterweiterung) erweitert werden
Formale Modelle der Softwareentwicklung
Stephan Kleuker
302
5. Programmverifikation
5.1 Eine einfache Programmiersprache
5.2 Operationelle Semantik
5.3 Zusicherungen
5.4 Partielle und totale Korrektheit
5.5 Beweissysteme für partielle und totale
Korrektheit
5.6 Programmverifikation in der Praxis
5.7 Syntax und Semantik paralleler Programme
5.8 Beweissysteme für parallele Programme
auch: K. R. Apt, E.-R. Olderog, Programmverifikation.
Sequentielle, parallele und verteilte Programme,
Springer, 1994
Formale Modelle der Softwareentwicklung
Stephan Kleuker
303
5.1 Eine einfache Programmiersprache
• Zentrale Sprachkonstrukte
• Syntax
• Bedingungen
Formale Modelle der Softwareentwicklung
Stephan Kleuker
304
Syntax und Semantik
• Sprachen haben eine Syntax mit der man Worte der Sprache
bilden kann
• bekannt: Grammatiken zur Spracherzeugung, verschiedene
Automatentypen zur Sprachakzeptanz
• Zur konkreten Festlegung der Bedeutung (Semantik) eines
Wortes gibt es konkrete Regeln
• Viele Regeln sind intuitiv und müssen nicht formalisiert werden
(Gilt für große Teile von Programmiersprachen und
Spezifikationssprachen)
• Damit sichergestellt ist, dass zwei Personen/Compiler das
Gleiche unter einem Programm (Wort) verstehen, müssen die
Regeln mathematisch exakt festgelegt werden
• Für Randfälle ist eine eindeutige Semantik unerlässlich
if( x<4 || x/y>2) ...
• Semantik von Programmiersprachen in Standards oder von
Kommissionen festgelegt
• C-Standard auch : ... Verhalten des Compilers undefiniert
Formale Modelle der Softwareentwicklung
Stephan Kleuker
305
Kern imperativer Programmiersprachen
drei zentrale Sprachkonstrukte:
• Sequenz oder Hintereinanderausführung, nachdem ein Befehl
abgearbeitet wurde, folgt die Bearbeitung des nächsten Befehls
• Alternative, abhängig von einer auszuwertenden Bedingung
wird entweder der eine oder der andere Folgebefehl ausgeführt
• Schleife, ein Befehl wird solange wiederholt ausgeführt, bis
eine Abbruchbedingung erfüllt ist
• dazu kommen Variablen um Zwischenergebnisse zu speichern
(Zuweisung)
• damit können alle Arten von Algorithmen beschrieben werden;
ist turing-mächtig
• Anmerkung: Es gibt andere Programmiersprachentypen:
funktional (Lisp, Haskell, ML), logikorientiert (Prolog)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
306
Syntax der Beispielsprache
<Befehl> ::=
x = <Ausdruck>;
(Zuweisung)
<Befehlssequenz> ::= <Befehl> <Befehlssequenz>
| <Befehl>
(Sequenz)
<Befehl> ::= if ( <Bedingung> ) {
<Befehlssequenz>
}
else {
<Befehlssequenz>
}
(Alternative)
<Befehl> ::= while( <Bedingung>) {
<Befehlssequenz>
}
(Schleife)
<Programm> ::= <Befehlssequenz>
• Anmerkung: Leerzeichen und Einrückungen nur für Lesbarkeit,
kein Teil der Syntax
• Anmerkung: Variablentypen werden nicht im Detail betrachtet,
können aber wie andere Sprachkonstrukte ergänzt werden
Formale Modelle der Softwareentwicklung
Stephan Kleuker
307
Syntax von Bedingungen
<Bedingung> ::= <Ausdruck> <op> <Ausdruck>
<Bedingung> ::= <Bedingung> && <Bedingung>
<Bedingung> ::= <Bedingung> || <Bedingung>
<Bedingung> ::= ! <Bedingung>
<Bedingung> ::= (<Bedingung>)
op ::= == | < | <= | > | >= | !=
• Klammern werden genutzt, um
Auswertungsreihenfolgen zu steuern
• && und
|| oder
! nicht
• != ungleich
== gleich
• Anlehnung an C, C++, Java, C#
Formale Modelle der Softwareentwicklung
Stephan Kleuker
308
Beispielprogramm
erg=0;
add=1;
if(x>0){
while(x>0){
erg=erg+add;
add=add+2;
x=x-1;
}
}
else{
erg=erg;
}
Formale Modelle der Softwareentwicklung
• da x keinen Wert bekommt
kann man sich x als Eingabe
denken
• Auffällig ist der else-Zweig, da
es kein if ohne else-Zweig gibt
• weiterhin muss im else-Zweig
ein Befehl stehen
• Ansatz: Semantik für diese
Kernsprache definieren, dann
syntaktische Vereinfachungen
Stephan Kleuker
309
5.2 Operationelle Semantik
•
•
•
•
•
Variable
Wertebereich
Zustand
Semantik von Bedingungen
Semantik von Programmausführungen (SOS)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
310
Variablen und Wertebereiche
Definition (Variablen eines Programms): Sei Prog ein
Programm unserer Programmiersprache, dann
bezeichnet Var(Prog) die Menge aller Variablen, die
im Programm vorkommen. Für eine Variable
xєVar(Prog) (x Element aus Prog) sei Wert(x) der
Wertebereich (oder die Domäne) von Werten, die x
erg=0;
annehmen kann.
add=1;
• Var(Prog)={add, erg, x}
if(x>0){
while(x>0){
erg=erg+add;
add=add+2;
x=x-1;
}
}
else{
erg=erg;
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
311
Zustände
Definition (Zustände eines Programms): Sei Prog ein
Programm unserer Programmiersprache mit
Var(Prog)={x1,...,xn}, Sei Var={x1,...,xn,xn+1,...,xm} eine
Obermenge von Var(Prog), also Var(Prog)  Var,
dann ist eine Abbildung
z: Var  Wert(x1)...Wert(xm)
mit z(xi)Wert(xi) für i=1,..m, ein Zustand des
Programms Prog. Die Menge aller Zustände von
Prog wird mit Zust(Prog) bezeichnet.
• Ein Zustand des Programms auf der vorherigen Folie
ist z.B. z(x)=3, z(add)=1 und z(erg)=0.
Formale Modelle der Softwareentwicklung
Stephan Kleuker
312
Ansatz: Semantik von Ausdrücken
• Da die Syntax von Ausdrücken nicht detailliert
definiert wurde, erfolgt dies nur anschaulich (siehe
auch Übungsaufgabe)
• Zustand: z(x)=3 und z(y)=4
• Ausdruck: aus=(x+y)*6
• Sem(aus,z)= (z(x)+z(y))*6 = 7*6 = 42
• Generell gilt für Variablen x: Sem(x,z)=z(x).
• Semantik bildet Menge von Ausdrücken (AUS)
zusammen mit Menge von Zuständen (Zust) auf
Wertebereich des Ausdrucks ab
• ganzzahlige Ausdrücke:
Sem: AUS x Zust  Integer
Formale Modelle der Softwareentwicklung
Stephan Kleuker
313
Semantik von Bedingungen (1/3)
Definition (Semantik von Bedingungen): Sei bedBED eine
Bedingung aus einem Programm P, wobei BED für die Menge
aller Bedingungen steht. Sei zZust(P). Die Semantik von
Bedingungen ist generell eine Abbildung einer Bedingung und
eines Zustandes auf einen der Werte „wahr“ oder „falsch“, also
• Sem: BED  Zust(P)  {wahr,falsch}. Dabei ist die Semantik von
bed im Zustand z wie folgt definiert:
• falls bed die Form <Ausdruck1> <op> <Ausdruck2> hat, gilt
Sem(bed,z) = Sem(<Ausdruck1>,z) <op>Sem
Sem(<Ausdruck2>,z)
• falls bed die Form <Bedingung1> && <Bedingung2> hat, gilt
Sem(bed,z) = Sem(<Bedingung1>,z) und Sem(<Bedingung2>,z)
• falls bed die Form <Bedingung1> || <Bedingung2>hat, gilt
Sem(bed,z) = Sem(<Bedingung1>,z) oder Sem(<Bedingung2>,z)
• falls bed die Form ! <Bedingung> hat, gilt
Sem(bed,z) = nicht Sem(<Bedingung>,z)
• falls bed die Form (<Bedingung>) hat, gilt
Sem(bed,z)
= ( Sem(<Bedingung>,z) )Stephan Kleuker
Formale
Modelle der Softwareentwicklung
314
Semantik von Bedingungen (2/3)
• Die Semantik benutzt zunächst die anschauliche Interpretation
von „und“, „oder“ und „nicht“
• Diese Interpretation kann wie folgt formalisiert werden:
X
Y
nicht X
X und Y
X oder Y
wahr
wahr
falsch
wahr
wahr
wahr
falsch
falsch
falsch
wahr
falsch
wahr
wahr
falsch
wahr
falsch
falsch
wahr
falsch
falsch
• weiterhin (wahr) ist wahr und (falsch) ist falsch
• Generell bauen Semantiken meist auf den Semantiken der
darunter liegenden Konstrukte auf
• In Fällen wie ganzen Zahlen, wird meist die intuitive Semantik
genutzt, da sonst z. B. immer eine formale Rückführung auf die
Peano-Axiome notwendig ist
Formale Modelle der Softwareentwicklung
Stephan Kleuker
315
Semantik von Bedingungen (3/3)
bed = (y > x)||((x-5) < y) , Zustand z(x)=42 und z(y)=40
Sem(bed,z)= Sem( (y > x) ,z) oder Sem( ((x-5) < y) ,z)
= (Sem( y > x ,z)) oder (Sem( (x-5) < y ,z));
= (Sem(y,z) > Sem(x,z)) oder (Sem( (x-5) ,z) < Sem(y,z)) [*]
= (z(y) > z(x)) oder ((Sem( x-5 ,z)) < z(y))
= (40 > 42) oder ((Sem(x,z)-5) < 40)
= (falsch) oder ((z(x)-5) < 40)
[*] hier findet auch der
= falsch oder ((42-5) < 40)
Übergang vom Syntax= falsch oder ((37) < 40)
Zeichen > zum semantischen
= falsch oder (37 < 40)
Zeichen >, genauer >Sem statt,
= falsch oder (wahr)
wobei letztes Zeichen eine
= falsch oder wahr
Semantik für Zahlenpaare hat
= wahr
Formale Modelle der Softwareentwicklung
Stephan Kleuker
316
Semantik einer Zuweisung
Definition (Zustandsänderung): Gegeben sei ein Programm P, ein
Zustand zZust(P), eine Variable xVar(P) und ein Wert
wWert(x). Eine Zustandsänderung in der Variablen x auf den
Wert w, geschrieben z[x:=w], ist für yVar(P) definiert als:
z(y), falls yx
z[x:=w](y) =
w, falls y=x
• w kann auch ein Ausdruck sein, dann Sem(z,w) rechts
• Anschaulich wird durch eine Zuweisung der Wert der Variablen
auf der linken Seite verändert, so dass ein neuer Zustand
resultiert
• Gilt z(x)=3 und z(y)=5 dann ist
z[y:=x](x)=3 und z[y:=x](y)=3
Formale Modelle der Softwareentwicklung
Stephan Kleuker
317
Semantik von Programmausführungen (SOS)
• Anschaulich wird ein Programm schrittweise abgearbeitet
• jeder Befehl findet in einem bestimmten Zustand statt; der
Zustand wird zur Auswertung der Ausdrücke genutzt
• nach einer Befehlsausführung befindet sich das Programm in
einem evtl. neuen Zustand
• Idee der strukturierten operationellen Semantik (SOS) nach
Plotkin:
– Definiere Semantik für einen Schritt, mit dem ein Programm
in einem Zustand in ein neues Programm (das
Restprogramm) mit einem neuen Zustand überführt wird
– Dieser Übergang wird als Transition beschrieben:
<P1,z1>  <P2,z2>
• <P,z> wird auch Konfiguration genannt
Formale Modelle der Softwareentwicklung
Stephan Kleuker
318
Semantik: Abarbeitung unserer Programmiersprache
Definition (Semantik von Programmen): Bezeichne E ein
Programm ohne Anweisungen, wie es z. B. nach der
vollständigen Abarbeitung eines Programms erreicht wird.
Dabei soll E;P und P;E jeweils als P interpretiert werden. Ein
Programm P unserer Programmiersprache mit zZust(P) wird
durch folgende Transitionen der Übergangsrelation
schrittweise abgearbeitet:
(1) <x= <Ausdruck>; ,z> <E, z[x:=Sem(<Ausdruck>,z)]>
(2) Wenn <P1,z1>  <P2,z2>, dann <P1; P, z1> <P2; P, z2>
(3) Wenn Sem(<Bedingung>,z)=wahr, dann
<if(<Bedingung>){P1}else{P2}, z>  <P1,z>
(4) Wenn Sem(<Bedingung>,z)=falsch, dann
<if(<Bedingung>){P1}else{P2}, z>  <P2,z>
(5) Wenn Sem(<Bedingung>,z)=wahr, dann
<while(<Bedingung>){P}, z> 
<P; while(<Bedingung>){P}, z>
(6) Wenn Sem(<Bedingung>,z)=falsch, dann
<while(<Bedingung>){P}, z>  <E, z>
Formale Modelle der Softwareentwicklung
Stephan Kleuker
319
Möglichkeiten zur Syntax- und Semantikerweiterung
• Grundsätzlich kann man neue Sprachkonstrukte einführen und
ihnen weitere Transitionsregeln zuordnen
• <Befehl> ::= if ( <Bedingung> ) {<Befehlssequenz>}
(7) Wenn Sem(<Bedingung>,z)=wahr, dann
<if(<Bedingung>){P}, z>  <P,z>
(8) Wenn Sem(<Bedingung>,z)=falsch, dann
<if(<Bedingung>){P}, z>  <E,z>
• Alternativ kann man eine Abbildung der neuen
Sprachkonstrukte auf die alten Sprachkonstrukte definieren,
wodurch die Semantik sofort festgelegt ist
• Obige Bedingung ist eine Abkürzung für:
if(<Bedingung>){<Befehlssequenz>} else {x=x;}
Werden zwei Semantiken angegeben, muss wenn möglich
nachgewiesen werden, dass sie das gleiche Verhalten
beschreiben
Formale Modelle der Softwareentwicklung
Stephan Kleuker
320
Reflexive transitive Hülle
Definition (Erreichbare Konfigurationen): Zu einem
Programm P unserer Programmiersprache mit
zZust(P) wird folgende Transitionsrelation * als
erweiterte Übergangsrelation definiert:
(a) <P,z> * <P,z> (reflexiv)
(b) Wenn <P1,z1> * <P2,z2> und <P2,z2> 
<P3,z3> dann auch <P1,z1> * <P3,z3> (transitiv)
• Anmerkung: Die Relation kann auch zur Definition
von Semantik-Regeln in Form der SOS-Semantik
genutzt werden (wird teilweise sogar benötigt)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
321
Semantik der do-while-Schleife
• Die do-while Schleife sei wie folgt definiert:
<Befehl> ::= do {P} while ( <Bedingung>);
• eine mögliche Semantikdefinition durch Übersetzung:
P; while(<Bedingung>){P}
• alternativ: Angabe von Semantikregeln für die erweiterte
Übergangsrelation
Wenn <P,z1> * <E,z2> und
Sem(<Bedingung>,z2)=wahr, dann
<do {P} while(<Bedingung>); , z1>
* < do {P} while(<Bedingung>); , z2>
Wenn <P,z1> * <E,z2> und
Sem(<Bedingung>,z2)=falsch, dann
<do {P} while(<Bedingung>); ,z1> * <E,z2>
Formale Modelle der Softwareentwicklung
Stephan Kleuker
322
Beispiel: Programmabarbeitung (1/2)
<P,z>
mit (1),(2)  < while(x>0){
P≡
erg=erg*2;
erg=1;
x=x-1;
while(x>0){
} , z1> mit z1(x)=2 und z1(erg)=1
erg=erg*2;
mit (5)  < erg=erg*2;
x=x-1;
x=x-1;
}
while(x>0){
erg=erg*2;
z(x)=2
x=x-1;
z(erg)=0
} , z1>
mit (1),(2)  < x=x-1;
while(x>0){
erg=erg*2;
x=x-1;
} , z2> mit z2(x)=2 und z2(erg)=2
Formale Modelle der Softwareentwicklung
Stephan Kleuker
323
Beispiel: Programmabarbeitung (2/2)
mit (1),(2)  < while(x>0){
erg=erg*2;
x=x-1;
} , z3> mit z3(x)=1 und z3(erg)=2
mit (5)  < erg=erg*2;
x=x-1;
while(x>0){
erg=erg*2;
x=x-1;
} , z3>
mit (1),(2)  < x=x-1;
while(x>0){
erg=erg*2;
x=x-1;
} , z4> mit z4(x)=1 und z4(erg)=4
mit (1),(2)  < while(x>0){
erg=erg*2;
x=x-1;
} , z5> mit z5(x)=0 und z5(erg)=4
mit (6)  <E,z5>
Formale Modelle der Softwareentwicklung
Stephan Kleuker
324
5.3 Zusicherungen
• Syntax von Zusicherungen
• Spezifikation von Zustandsmengen
• Semantik von Zusicherungen
Formale Modelle der Softwareentwicklung
Stephan Kleuker
325
Zusicherung
• Bisher wurden einzelne Zustände durch ihre Paare Variable und
Wert einzeln angegeben
• Man kann Zustandmengen aber auch durch Formeln
(Zusicherungen) beschreiben, die verwandt mit Bedingungen
sind
Definition (Zusicherung): Jede <Bedingung> die aus
<Bedingung> ::= <Ausdruck> <op> <Ausdruck>
op::= == | < | <= | > | >= | !=
konstruiert wurde, ist eine einfache Zusicherung. Weiterhin
werden Zusicherungen induktiv definiert. Seien p und q
Zusicherungen, dann sind
(1) p (nicht p)
(2) p  q (p und q)
(3) p  q (p oder q)
(4) (p)
auch Zusicherungen.
Formale Modelle der Softwareentwicklung
Stephan Kleuker
326
Zusicherung und Zustandsmengen
informelle Definition (Semantik von Zusicherungen):
Jede Zusicherung p kann für einen gegebenen
Zustand z, der Werte für die vorkommenden
Variablen enthält, nach wahr oder falsch ausgewertet
werden.
Zur Berechnung wird eine Semantik-Funktion Sem
für Zusicherungen definiert. Es kann also für eine
Zusicherung p und einen von den Variablen
passenden Zustand z immer Sem(p,z) nach wahr
oder falsch ausgewertet werden.
Formale Modelle der Softwareentwicklung
Stephan Kleuker
327
Semantik von Zusicherungen (1/3)
Definition (Semantik von Zusicherungen): Sei zuZU eine Zusicherung
aus einem Programm Prog, wobei ZU für die Menge aller
Zusicherungen steht. Sei zZust(Prog). Die Semantik von
Zusicherungen ist generell eine Abbildung einer Zusicherung und
eines Zustandes auf einen der Werte „wahr“ oder „falsch“, also
• Sem: ZU  Zust(Prog)  {wahr,falsch}. Dabei ist die Semantik von zu
im Zustand z wie folgt definiert:
• falls zu die Form <Ausdruck1> <op> <Ausdruck2> hat, gilt
Sem(zu,z) = Sem(<Ausdruck1>,z) <op>Sem Sem(<Ausdruck2>,z)
• falls zu die Form <Zusicherung1>  <Zusicherung2> hat, gilt
Sem(zu,z) = Sem(<Zusicherung1>,z) und Sem(<Zusicherung2>,z)
• falls zu die Form <Zusicherung1>  <Zusicherung2>hat, gilt
Sem(zu,z) = Sem(<Zusicherung1>,z) oder Sem(<Zusicherung2>,z)
• falls zu die Form ! <Zusicherung> hat, gilt
Sem(zu,z) = nicht Sem(<Zusicherung>,z)
• falls zu die Form (<Zusicherung>) hat, gilt
Sem(zu,z) = ( Sem(<Zusicherung>,z) )
Formale Modelle der Softwareentwicklung
Stephan Kleuker
328
Semantik von Zusicherungen (2/3)
• Die Semantik benutzt zunächst die anschauliche Interpretation
von „und“, „oder“ und „nicht“
• Diese Interpretation kann wie folgt formalisiert werden:
X
Y
nicht X
X und Y
X oder Y
wahr
wahr
falsch
wahr
wahr
wahr
falsch
falsch
falsch
wahr
falsch
wahr
wahr
falsch
wahr
falsch
falsch
wahr
falsch
falsch
• weiterhin (wahr) ist wahr und (falsch) ist falsch
• Generell bauen Semantiken meist auf den Semantiken der
darunter liegenden Konstrukte auf
• In Fällen wie ganzen Zahlen, wird meist die intuitive Semantik
genutzt, da sonst z. B. immer eine formale Rückführung auf die
Peano-Axiome notwendig ist
Formale Modelle der Softwareentwicklung
Stephan Kleuker
329
Semantik von Zusicherungen (3/3)
zu = (y > x) ((x-5) < y) , Zustand z(x)=42 und z(y)=40
Sem(zu,z)= Sem( (y > x) ,z) oder Sem( ((x-5) < y) ,z)
= (Sem( y > x ,z)) oder (Sem( (x-5) < y ,z));
= (Sem(y,z) > Sem(x,z)) oder (Sem( (x-5) ,z) < Sem(y,z)) [*]
= (z(y) > z(x)) oder ((Sem( x-5 ,z)) < z(y))
= (40 > 42) oder ((Sem(x,z)-5) < 40)
= (falsch) oder ((z(x)-5) < 40)
[*] hier findet auch der
= falsch oder ((42-5) < 40)
Übergang vom Syntax= falsch oder ((37) < 40)
Zeichen > zum semantischen
= falsch oder (37 < 40)
Zeichen >, genauer >Sem statt,
= falsch oder (wahr)
wobei letztes Zeichen eine
= falsch oder wahr
Semantik für Zahlenpaare hat
= wahr
Formale Modelle der Softwareentwicklung
Stephan Kleuker
330
Beispiel: Zusicherung
• p  q ist durch p  q definiert (logische Folgerung)
• p  q ist durch (p  q)  (q  p) definiert (logische
Äquivalenz)
• p ≡ x>2  y>4
z(x)=3 und z(y)= 5, es gilt
Sem(p,z)= Sem(x>2  y>4,z)
= Sem(x2  y>4,z)
= Sem(x2,z)  Sem(y>4,z)
= z(x)2  z(y)>4
= 32  5>4
= falsch  wahr = wahr
Formale Modelle der Softwareentwicklung
Stephan Kleuker
331
Zusicherungen als Zustandsmengen
Definition (Zusicherungen als Zustandsmengen): Jede
Zusicherung p steht anschaulich für alle Zustände, die diese
Zusicherung erfüllen. Die Menge wird mit Sem(p) bezeichnet
und ist durch
Sem(p) = { z | Sem(p,z) ist wahr}
also die Menge aller Zustände z, mit denen p nach wahr
ausgewertet wird, definiert.
• Sem(x>2  y>4) = {z| z(x)  2}  {z | z(y)>4}
• Statt p wird im Zustand z nach wahr ausgewertet, schreiben wir
auch vereinfachend z erfüllt p.
• Um einige Klammern einzusparen, wird vereinbart, dass
folgende Prioritäten genutzt werden. Die Prioritäten sind von
hoch nach niedrig:





Dies bedeutet, dass ein Operator mit hoher Priorität vor einem
Operator mit niedriger Priorität ausgewertet wird.
Formale Modelle der Softwareentwicklung
Stephan Kleuker
332
Substitution
Definition (Substitution): Sei p eine Zusicherung, dann
ist eine Substitution p[x:=w] dadurch definiert, dass
alle Vorkommen von x in p durch w ersetzt werden.
Beispiel: Sei p die Zusicherung x>2  y<4. Dann kann
man folgende Berechnungen anstellen
p[x:=z+2] ergibt z+2>2  y<4, was äquivalent zu z>0 
y<4 ist
p[x:=y-3] ergibt y-3>2  y<4, was äquivalent zu y>5 
y<4, was äquivalent zu false ist
p[y:=3] ergibt x>2  3<4, was äquivalent zu x>2 ist.
Dabei bedeutet „äquivalent zu“, dass die
Zusicherungen p und q die gleiche Semantik haben.
Dies wird auch p  q geschrieben.
Formale Modelle der Softwareentwicklung
Stephan Kleuker
333
5.4 Partielle und totale Korrektheit
•
•
•
•
•
Divergenz
Partielle Semantik eines Programms
Definition von Korrektheit
Korrektheitsformel
Totale Semantik eines Programms
Formale Modelle der Softwareentwicklung
Stephan Kleuker
334
Informelle Semantik von Programmen
• Anschaulich startet ein Programm mit einem
Zustand z1 und endet (falls es terminiert) im Zustand
z2
• Genauer kann man für jeden Programmschritt
beschreiben, wie ein Eingangszustand in einen
Folgezustand transformiert wird, genauer:
Programm im Zustand z1 macht einen Schritt in
(Rest)-Programm im Zustand z2
• Idee auf Zusicherungen übertragbar: {p} Prog {q}:
Wenn ein Zustand die Zusicherung p erfüllt und Prog
ausgeführt wird, landet man in einem Zustand, der q
erfüllt
Formale Modelle der Softwareentwicklung
Stephan Kleuker
335
Divergenz
erg=1;
while(x>0){
erg=erg*2;
x=x+1;
}
• Programm terminiert nicht, z.B. für z(x)=1
• „nicht terminierend“ heißt divergierend (Nomen:
Divergenz)
• Divergenz kann Fehler bedeuten, muss es nicht, z. B.
Steuerungssystem
• Programmsemantiken können Divergenz
berücksichtigen
Formale Modelle der Softwareentwicklung
Stephan Kleuker
336
Partielle Semantik eines Programms
Definition (partielle Semantik): Gegeben sei ein
Programm Prog und ein Zustand zZust(Prog). Dann
ist die partielle Semantik definiert als
SemP(Prog,z)={ zz | zz wird erreicht, wenn Prog
terminiert}
Sei weiterhin eine Zusicherung p gegeben, dann
kann die partielle Semantik auch auf p erweitert
werden:
SemP(Prog,p)={ zz | Es gibt einen Zustand z1, mit
Sem(p,z1)=wahr und zz wird erreicht, wenn Prog
terminiert}
• Da Zustände maximal einen Nachfolger haben, ist
die resultierende Menge leer oder enthält ein
Element
Formale Modelle der Softwareentwicklung
Stephan Kleuker
337
Was heißt Korrektheit?
• Forderung „Programm soll korrekt sein“ macht
wenig Sinn, evtl.:
– Programm soll terminieren
– Programm soll Rechner nicht zerstören
– Programm soll private Daten schützen
• Für Korrektheit wird präzise Anforderung verlangt
• Anforderungen sollten die Form haben:
Unter der folgenden Bedingungen wird erwartet,
dass folgendes passiert und das Ergebnis die
folgende Form hat
Formale Modelle der Softwareentwicklung
Stephan Kleuker
338
Korrektheit genauer
• beschreibe Vorbedingung als Zusicherung p
• beschreibe Nachbedingung als Zusicherung q
• Programm Prog ist korrekt, wenn jeder Zustand, der p erfüllt,
durch Ausführung von Prog in einen Zustand am Ende
transformiert wird, der q erfüllt.
Beispiel:
• Zusicherung x ist positiv: p  x>0
• Nachbedingung erg enthält am Ende x2: q  erg=x2
• Ein Programm Prog, dass x nicht verändert (wieso, s. später!)
und am Ende in erg den quadrierten Wert enthält ist korrekt
bezüglich der Vorbedingung und Nachbedingung
• Beispiel: Wenn Prog startet mit z1(x)=2 und endet mit z2(x)=2
und z2(erg)=4, kann Prog korrekt sein
• späteres Ziel: Beweise, dass Prog korrekt bezüglich aller
Zustände ist, die die Vorbedingung erfüllen
Formale Modelle der Softwareentwicklung
Stephan Kleuker
339
Partielle Korrektheit
Definition (partielle Korrektheit): Ein Programm Prog
heißt partiell korrekt bezüglich einer als Zusicherung
p formulierten Vorbedingung und einem als
Zusicherung q formulierten gewünschten Ergebnis,
geschrieben als Korrektheitsformel {p} Prog {q} ,
wenn die Programmausführung jeden Zustand der p
erfüllt in einen Zustand transformiert, der q erfüllt.
 zzSemP(Prog,p): Sem(q,zz)=wahr
In {p} Prog {q} wird p Vorbedingung und q
Nachbedingung genannt. Man sagt auch, dass dann
die Korrektheitsformel {p} Prog {q} (für partielle
Korrektheit) gilt.
Formale Modelle der Softwareentwicklung
Stephan Kleuker
340
Anforderungen als Korrektheitsformeln
• Programm Prog soll x quadrieren
– {x>0} Prog {erg=x2}
– problematisch, wenn x in Prog verändert wird
– {x>0} x=0; erg=0; {erg=x2} ist Korrektheitsformel
– besser
{y=x  x>0} Prog {erg=y2} und yVar(Prog)
• Nachweis mit Semantik möglich, aber sehr
aufwändig
• Frage: Welche Korrektheitsformeln gelten, wenn
Prog nicht terminiert?
Formale Modelle der Softwareentwicklung
Stephan Kleuker
341
Totale Semantik eines Programms
Definition (totale Semantik): Gegeben sei ein Programm Prog und
ein Zustand zZust(Prog). Dann ist die totale Semantik definiert
als
Sem(Prog,z)= { zz | zz wird erreicht, wenn Prog terminiert>}
 {  | Prog divergiert von z aus}
Sei weiterhin eine Zusicherung p gegeben, dann kann die totale
Semantik auch auf p erweitert werden:
Sem(Prog,p)={ zz | Es gibt einen Zustand z1, mit
Sem(p,z1)=wahr und zz wird erreicht, wenn Prog
terminiert>}  {  | Es gibt einen Zustand z1, mit
Sem(p,z1)=wahr und Prog divergiert von z1 aus}
• spezielles Element , das so genannte Bottom-Symbol, falls
Prog divergieren kann.
Formale Modelle der Softwareentwicklung
Stephan Kleuker
342
Totale Korrektheit
Definition (totale Korrektheit): Ein Programm Prog heißt total
korrekt bezüglich einer als Zusicherung p formulierten
Vorbedingung und einem als Zusicherung q formulierten
gewünschten Ergebnis, geschrieben als Korrektheitsformel
{p} Prog {q}, wenn die Programmausführung jeden Zustand,
der p erfüllt, in einen Zustand transformiert, der q erfüllt.
Formal muss gelten:
 zzSem(Prog,p): Sem(q,zz)=wahr
In {p} Prog {q} wird p Vorbedingung und q Nachbedingung
genannt. Man sagt auch, dass dann die Korrektheitsformel
{p} Prog {q} (für totale Korrektheit) gilt.
• Totale Korrektheit: Prog terminiert garantiert
• Man beachte: zz kann  sein und Sem(q, ) ist undefiniert
(nicht wahr)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
343
Beispiel: Korrektheitsbetrachtung
erg=0; // Programm Prog
while(x!=0){
erg=erg+2;
x=x-2;
}
• totale Korrektheit:
– {x=2  x=4} Prog {erg=2  erg=4}
– {(x=2 x=4)  y=x}
Prog
{(y=2  erg=2)  (y=4  erg=4)}
• nur partielle Korrektheit
– {y=x} Prog {erg=y}
• Forderung nach Terminierung unter Vorbedingung p:
totale Korrektheit von {p} Prog {true}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
344
5.5 Beweissysteme für partielle und totale Korrektheit
•
•
•
•
•
•
Idee von Beweissystemen
Beweissystem für partielle Korrektheit
Konzept zur Beweisfindung
Beweissystem für totale Korrektheit
Terminierungsfunktion
Beweisskizze
Formale Modelle der Softwareentwicklung
Stephan Kleuker
345
Idee: Beweissysteme
• Beweise in der Semantik zu rechnen ist sehr aufwändig, viele
Schritte wiederholen sich
• Frage: Gibt es Beweisstrukturen, von denen man einmal zeigt,
dass sie korrekt sind, die man immer wieder anwenden kann
• Lösung: Beweissystem
• typische Form einer Beweisregel:
P
wenn P bewiesen, dann auch Q bewiesen
Q
• Beispiel: Logik (Aussagenlogik), Komma für und
A  B, B  C
A
A,B
AB
AB
AC
AB
AB
BA
BA
A  B, A
A  B, B
A  B, B
B
A
A
Formale Modelle der Softwareentwicklung
Stephan Kleuker
346
Beweissystem für partielle Korrektheit (1/2)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
347
Beweissystem für partielle Korrektheit (2/2)
{p} Prog {q}
Beweissystem ist korrekt und vollständig
Formale Modelle der Softwareentwicklung
Stephan Kleuker
348
Beispielhafte Analyse der Zuweisungsregel
• zu zeigen: { y=4 } x=3; {x=3  y=4}
– (x=3  y=4) [x:=3]  (3=3  y=4)  y=4
(Zuweisungsregel und logische Umformung)
– es gilt auch { x=3  y=4 } x=3; {x=3  y=4}, da
(x=3  y=4)  (y=4) folgt Aussage mit
Konsequenzregel („Verstärkung“ vorne)
• auch { (x=5  y=4) [x:=3] } x=3; {x=5  y=4},
umgeformt { false } x=3; {x=5  y=4}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
349
Beweis einer Zuweisungskette
• zu zeigen: {x=y} x= x*2; y= y/2; {x=4y}
• Aus (x=4y)[y:=y/2] wird x=4(y/2) und damit x=2y
• Es gilt: {x=2y} y=y/2; {x=4y}
• (x=2y)[x:=x*2] wird zu x*2=2y und damit x=y
• Es gilt: {x=y} x=x*2; {x=2y}
• Mit Kompositionsregel folgt Behauptung
Formale Modelle der Softwareentwicklung
Stephan Kleuker
350
Beweis für if
zeige:
{x>5  x<10}
if(x>8) {x=x-5;} else {x=x+3;}
{x>3  x11}
Ansatz mit Zuweisungsregel:
{x>3  x 11}[x:=x-5]  {x>8  x 16}
Verstärkung vorne: (x>5  x<10  x>8)  (x>8  x 16)
{x>3  x11}[x:=x+3]  {x>0  x8}
(x>5  x<10  x8)  (x>0  x8)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
351
Beweis einer Schleife (1/2)
erg=1; // Programm Prog
while(x!=0){
erg=erg*2;
x=x-1;
}
• zu zeigen: {y=x  x>0} Prog {erg=2y}
• generell schwierig: Finden einer Schleifeninvariante
{p} <Schleifenrumpf> {p}
(genauer gesucht: {p  B} <Schleifenrumpf> {p} )
• Hier weiß man was rauskommen soll, {erg=2y} nicht als
Invariante geeignet
• genereller Ansatz: Schleifen haben meist Schleifenzähler,
dieser muss in das gewünschte Ergebnis eingebaut werden
hier: {erg=2y-x}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
352
Beweis einer Schleife (2/2)
• erg=2y-x [x:=x-1]  erg=2y-(x-1)  erg=21+y-x
• erg=21+y-x [erg:= erg*2]  erg*2=21+y-x  erg=2y-x
• mit Kompositionsregel:
{erg=2y-x} erg=erg*2; x=x-1; {erg=2y-x}
• mit Verstärkung {erg=2y-x  x≠0} erg=erg*2; x=x-1; {erg=2y-x}
da : (erg=2y-x  x≠0)  erg=2y-x (benötigt für Schleifenregel)
• mit Schleifenregel:
{erg=2y-x}
while(x!=0){erg=erg*2; x=x-1;}
{erg=2y-x  (x!=0)}
• mit Konsequenzregel wird aus {erg=2y-x  (x!=0)} die
Zusicherung {erg=2y}
• vor der Schleife: Aus (erg=2y-x)[erg:=1] wird Zusicherung 1=2y-x
mit mathematischen Kenntnissen und Verstärkung folgt y=x 
x>0 , der Rest mit Kompositionsregel
Formale Modelle der Softwareentwicklung
Stephan Kleuker
353
Bessere Abbruchbedingung
• Coding-Guideline: Nicht auf Gleichheit bzw.
Ungleichheit bei Abbruch testen, hier besser:
while (x>0)
• Invariante reicht dann nicht aus, muss zu
erg=2y-x  x>-1 geändert werden, weiterhin muss x
als ganzzahlig bekannt sein
dann:
aus (x>0)  x>-1 folgt dann x0  x>-1 und da x
ganzzahlig ist x=0.
Formale Modelle der Softwareentwicklung
Stephan Kleuker
354
Konzept zur Beweisfindung
• Es gibt kein eindeutiges Kochrezept zur Beweiskonstruktion,
aber typisch
– bei Zuweisungsketten rückwärts rechnen
– von innen nach außen arbeiten
– Beweisfindung ist iterativer Prozess, mit Ansatz, Teilerfolg
nur für einen Schritt, notenwendiger Korrektur, Teilerfolg für
größeres Programmstück, notwendige Korrektur, ...
• Beispiel:
if (..){
if(..){Prog1} (1) Bew. für Prog1
(3) Beweis
(2) Bew. für Prog2
für inneres if
else{Prog2}
(7) Beweis
else{
für äußeres
if
if(..){Prog3} (4) Bew. für Prog3
(6) Beweis
für inneres if
else{Prog4} (5) Bew. für Prog4
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
355
Geschachtelte Alternative (Ansatz)
Zeige: {x>10  x<35} Prog {x>12  x<25}
if(x>18){
if(x<30){
x=x-5;
}
else{
x=x-10;
}
}
else{
x=x+4;
}
a1) {x>10  x<35  x>18  x<30 }
x=x-5;
{x>12  x<25}
b1) {x>10  x<35  x>18  (x<30)}
x=x-10;
{x>12  x<25}
a2) {x>10  x<35  x>18}
if(x<30){x=x-5;} else{x=x-10;}
{x>12  x<25}
b2) {x>10  x<35  (x>18)}
x=x+4;
{x>12  x<25}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
356
Rechentricks zur Alternative
zeigt man {p} Prog1 {q1} und {p} Prog2 {q2}
• weiß man, dass nachdem Prog1 oder Prog2 unter der
Vorbedingung p immer q1  q2 gilt,
da (p  B)  p und (p   B)  p sowie
q1  (q1  q2 ) und q2  (q1  q2 ) gilt
{p} if (B) {Prog1} else {Prog2} {q1  q2}
• wenn weiterhin in den Programmen Prog1 und Prog2 die zum
Booleschen Ausdruck B gehörenden Variablen nicht verändert
werden, gilt
{p} if (B) {Prog1} else {Prog2} {(Bq1)  (Bq2)}
statt (B  q1)  (B  q2) kann auch der logisch äquivalente
Ausdruck (B  q1)  (B  q2) stehen
Formale Modelle der Softwareentwicklung
Stephan Kleuker
357
Überlegungen zur Terminierung
• Betrachten wir folgendes Programm mit der Zusicherung {x>0}
(x ganzzahlig); warum terminiert es
while(x!=0){
erg=erg*2;
x=x-1;
}
• Anschaulich: x wird immer kleiner, so dass es irgendwann Null
werden muss
• Formaler Ansatz: Es gibt eine Funktion t,
– die einen ganzzahligen Wert liefert,
– die von den Programmvariablen abhängt (z. B. x),
– die bei jedem Schleifendurchlauf echt kleiner wird
– z. B. t=x
• Ganzzahlig, da x auch bei x=x/2 immer echt kleiner wird
• t muss vor der Schleifenausführung einen positiven Wert
haben und darf nie negativ werden
Formale Modelle der Softwareentwicklung
Stephan Kleuker
358
Beweissystem für totale Korrektheit (1/2)
{p} Prog {q}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
359
Beweissystem für totale Korrektheit (2/2)
• Regel ersetzt Regel (4) für partielle Korrektheit
• t heißt Terminierungsfunktion
• Beweissystem ist korrekt und vollständig
Formale Modelle der Softwareentwicklung
Stephan Kleuker
360
Anmerkungen zur Terminierungsfunktion
• Wichtig ist, dass sie immer runterzählt und dass sie größer 0
ist, dies muss auch Invariante garantieren
• Programm while(x>0){ ...; x=x-1;}
wenn am Anfang x>=0 dann t=x wählen
wenn x<0 am Anfang y=x (y kommt nicht vor und t= |y|+x
wählen ( | Betrag |)
• Es gibt kein automatisches Verfahren zur Bestimmung einer
sinnvollen Invarianten und Terminierungsfunktion (wg.
Unentscheidbarkeit)
• Man kann Heuristiken aufstellen, wie man anhand der
Schleifenstruktur Invarianten und Terminierungsfunktionen
finden kann
• Potenzrechenbeispiel: Invariante erweitern zu
{erg=2y-x  x0 } , dann t=x wählbar, wegen
{x=z} erg=erg*2; x=x-1; {x+1=z} und x+1=z  x<z
Formale Modelle der Softwareentwicklung
Stephan Kleuker
361
Detailliertes Beispiel (1/6)
• sei x ganzzahlig, zu Beweisen ist die totale Korrektheit von
{x>0  y=x}
erg=-6;
while(x!=-2){
x=x-1;
erg=erg+3;
}
{erg=3*y}
• Generell gilt, dass hier nur ein Weg detailliert beschrieben wird,
es aber Alternativen gibt
• Ansatz: Suche Invariante, versuche dann den Beweis zu
vervollständigen
• Schwierig wird es dadurch, dass es viele Zusicherungen geben
kann, die eine Korrektheitsformel erfüllen, aber nicht zum Rest
des Beweises passen
Formale Modelle der Softwareentwicklung
Stephan Kleuker
362
Detailliertes Beispiel (2/6)
• Zunächst wird eine Invariante für den Teil „ {p  B} Prog {p}“
für den Schleifenrumpf Prog  x=x-1; erg=erg+3; und die
Bedingung B  x!=-2 benötigt.
• Als Invariante wird: p  erg=(3*(y-x-2))  x-2 gewählt. Der
Nachweis erfolgt durch Rückwärtsrechnen mit der
Zuweisungsregel
1. Schritt: erg=(3*(y-x-2))  x-2 [erg:=erg+3]
 erg+3=(3*(y-x-2))  x-2
2. Schritt: erg+3=(3*(y-x-2))  x-2 [x:=x-1]
 erg+3=(3*(y-x+1-2))  x-1-2
 erg=(3*(y-x-2))  x-1
• Gezeigt ist damit mit der Kompositionsregel:
(1) { erg=(3*(y-x-2))  x-1} Prog { erg=(3*(y-x-2))  x-2}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
363
Detailliertes Beispiel (3/6)
• Betrachtet man die Zuweisung p  B, so gilt:
(2) (erg+3=(3*(y-x-2))  x-2  x≠-2)
 (erg=(3*(y-x-2))  x-1)
dies gilt nur, da x eine ganzzahlige Variable ist und
aus x-2  x≠-2 immer x-1 folgt
• Damit kann die Vorbedingung in (1) durch die linke
Seite von (2) verstärkt werden und man erhält mit
der Konsequenzregel {p  B} Prog {p}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
364
Detailliertes Beispiel (4/6)
• weiterhin wird für die Schleife eine Terminierungsfunktion
benötigt. Dies ist im Beispiel t=x+2. Nun muss der Teil „ {p  B
 t=z} Prog {t<z}“ gezeigt werden
• Anmerkung: Folgender Ansatz für t=z am Anfang und t<z am
Ende klappt nicht immer, aber sehr häufig
• statt die Nachbedingung x+2<z zu nutzen, wird x+2=z-1 und
später die Konsequenzregel mit (3) (x+2=z-1)  (x+2<z) zur
Abschwächung der Nachbedingung genutzt
• jetzt wird wieder mit der Zuweisungsregel rückwärts gerechnet
1. Schritt: x+2=z-1 [erg:=erg+3]  x+2=z-1
2. Schritt: x+2=z-1 [x:=x-1]  x-1+2=z-1  x+2=z
• Gezeigt ist damit mit der Kompositionsregel:
{x+2=z} Prog {x+2=z-1}
mit (3) folgt der zu beweisende Teil
Formale Modelle der Softwareentwicklung
Stephan Kleuker
365
Detailliertes Beispiel (5/6)
• Anmerkung: Der folgende Beweisteil kann einen Beweisansatz
auch noch zerstören, deshalb muss man alle drei Beweisteile
auf einem Schmierzettel „passend“ rechnen
• Für die totale Korrektheit muss abschließend noch „p  t>0“
gelten, dies folgt direkt aus
(erg=(3*(y-x-2))  x-2)  x-2  x+20
• Zusammengefasst kann dann die Schleifenregel für totale
Korrektheit angewandt werden, es gilt:
{erg=(3*(y-x-2))  x-2}
while(x!=-2){x=x-1; erg=erg+3;}
{ erg=(3*(y-x-2))  x-2  (x≠-2)}
• Die Nachbedingung ist äquivalent zu erg=(3*(y-x-2))  x=-2,
diese kann mit mathematischer Umformung wie folgt
abgeschwächt werden:
(erg=(3*(y-x-2))  x=-2)  erg=3*y
• damit folgt mit der Konsequenzregel das gewünschte
Beweisende
Formale Modelle der Softwareentwicklung
Stephan Kleuker
366
Detailliertes Beispiel (6/6)
• Gezeigt ist damit :
(4)
{erg=(3*(y-x-2))  x-2}
while(x!=-2){x=x-1; erg=erg+3;}
{ erg=3*y}
• Zu zeigen bleibt noch der Anfang des Beweises, Hierzu wird
wieder die Zuweisungsregel rückwärts gerechnet.
erg=(3*(y-x-2))  x-2[erg:=-6]  -6=(3*(y-x-2))  x-2
 -6= 3*y - 3*x -6  x-2  y=x  x-2
• Gezeigt ist damit:
(5) { y=x  x-2} erg=-6; {erg=(3*(y-x-2))  x-2}
• Die Vorbedingung von (5) kann mit (y=x  x0)  (y=x  x-2)
verstärkt werden. Es folgt mit der Konsequenzregel:
(6) { y=x  x0} erg=-6; {erg=(3*(y-x-2))  x-2}
• (4) und (6) können mit der Kompositionsregel zum
gewünschten Beweis kombiniert werden
Formale Modelle der Softwareentwicklung
Stephan Kleuker
367
Beweisskizze
{p0}
Prog1
{q1}
{p1}
Prog2
{q2}
..
.
{qn-1}
{pn-1}
Progn
{qn}
typisches Beweisergebnis für Programm
Prog1;Prog2;...;Progn auf rechter Seite,
es gilt
• {pi-1} Progi {qi} korrekte Beweisskizze
• qi  pi
• vereinfachte Darstellung links nennt sich
Beweisskizze
• für Schleifen werden
– {inv: <Zusicherung>} Invariante
– {bd : <Ausdruck>}
Terminierungsfunktion
angegeben
Formale Modelle der Softwareentwicklung
Stephan Kleuker
{p0}
Prog1
{p1}
Prog2
{p2}
..
.
{pn-1}
Progn
{pn}
(pn=qn)
368
5.6 Programmverifikation in der Praxis
• Umsetzung von Beweisskizzen in Programme
• Verknüpfung von Beweisskizzen und Testen
• Weitere praxisrelevante Fragestellungen
Formale Modelle der Softwareentwicklung
Stephan Kleuker
369
Beispiel: Beweisskizze (sequenzielles Programm)
{y=x  x>0}
erg=1;
{inv: x0  erg=2y-x} {bd:x}
while(x!=0){
{x0  x≠0  erg=2y-x}
erg=erg*2;
{x1  erg=21+y-x }
x=x-1;
{x0  erg=2y-x }
}
{erg=2y}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
370
Programm mit Beweisskizze verknüpft
public int zweierPotenz(int x){
int y=x; // neue Hilfsvariable
int z; // Hilfsvariable fuer Terminierungsfunktion
int erg;
assert(y==x && x>0);
erg=1;
assert(x>=0 && erg==(int)Math.pow(2,y-x));
while(x!=0){
z=x; // Terminierungsfunktion initialisieren
assert(x>=0 && x!=0 && erg==(int)Math.pow(2,y-x));
erg=erg*2;
assert(x>=1 && erg==(int)Math.pow(2,1+y-x));
x=x-1;
assert(x>=0 && erg==(int)Math.pow(2,y-x));
assert(x<z); // für Terminierungsfunktion
}
assert(erg==(int)Math.pow(2,y));
return erg;
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
371
Beweisskizzen und Testen
• Die Ergänzung von Zusicherungen ermöglicht es,
das laufende Programm zu testen
• Wichtig wäre, dass alle Zusicherungen in
unterschiedlichen Situationen durchlaufen werden;
dies ist mit zufälligen Tests kaum möglich
• Ansatz zur systematischen Nutzung von
Zusicherungen:
– Äquivalenzklassenansatz zur systematischen
Bestimmung sinnvoller Eingaben
– Überdeckungsmessung zur Feststellung, ob alle
Programmteile ausgeführt wurden
Formale Modelle der Softwareentwicklung
Stephan Kleuker
372
Gezielte Suche nach Fehlern
• Ziel des Testens ist das Finden von Fehlern und
nicht die Aussage, dass die Software keine Fehler
enthält
• Schlussrichtung: korrekt bewiesen => keine Fehler
• aber es gilt nicht der Umkehrschluss:
keine Fehler gefunden => korrekt
• Testen bedeutet die Suche nach Fehlern, ein Testfall
ist erfolgreich, wenn er einen Fehler gefunden hat
• Verifikation bedeut den Nachweis der Fehlerfreiheit
• Die Fragen: Wer testet den Tester, wer verifiziert den
Verifizierer bleiben im Raum
Formale Modelle der Softwareentwicklung
Stephan Kleuker
373
Äquivalenzklassenbildung
• Durch eine Äquivalenzklassenbildung wird eine
Menge in disjunkte Teilmengen zerlegt, wobei jeder
Repräsentant einer Teilmenge das gleiche Verhalten
bzgl. einer vorgegebenen Operation nach außen
zeigt
• Beispiel: Restklassen (modulo x), werden zwei
beliebige Repräsentanten aus Restklassen addiert,
liegt das Ergebnis immer in derselben Restklasse
• Übertragungsidee auf Tests: Eingaben werden in
Klassen unterteilt, die durch die Ausführung des zu
testenden Systems zu „gleichartigen“ Ergebnissen
führen
Formale Modelle der Softwareentwicklung
Stephan Kleuker
374
Beispiele für Äquivalenzklassen von Eingaben
• erlaubte Eingabe: 1 <= Wert <= 99 (Wert sei ganzzahlig)
– eine gültige Äquivalenzklasse: 1 <= Wert <= 99
– zwei ungültige Äquivalenzklassen: Wert < 1, Wert > 99
• erlaubte Eingabe in einer Textliste: für ein Auto können
zwischen einem und sechs Besitzer eingetragen werden
– eine gültige Äquivalenzklasse: ein bis sechs Besitzer
– zwei ungültige Äquivalenzklassen: kein Besitzer, mehr als
sechs Besitzer
• erlaubte Eingabe: Instrumente Klavier, Geige, Orgel, Pauke
– vier gültige Äquivalenzklassen: Klavier, Geige, Orgel, Pauke
– eine ungültige Äquivalenzklasse: alles andere, z.B. Zimbeln
Formale Modelle der Softwareentwicklung
Stephan Kleuker
375
Regeln zur Bildung von Äquivalenzklassen
• Wichtig ist, dass man mögliche Eingaben kennt, aus der
Spezifikation sollte der mögliche Eingabedatenbereich
hervorgehen
• für einfache Zahlenparameter meist einfach: ein Intervall mit
gültigen Werten, eventuell ein Intervall mit zu kleinen und ein
Intervall mit zu großen Werten (wenn z.B. alle int erlaubt, gibt
es nur eine Äquivalenzklasse, etwas schwieriger bei double))
• falls explizit eine Menge von Werten vorgegeben ist, stellt jeder
Wert eine Äquivalenzklasse dar, falls andere Eingaben möglich
sind, ist dies eine zusätzliche Äquivalenzklasse
• falls Werte miteinander verknüpft werden , muss diese
Verknüpfung berücksichtigt werden (z.B. betrachte x+y, dann
Integer.MIN_VALUE<=x+y<=Integer.MAX_VALUE eine
Äquivalenzklasse und zwei Äquivalenzklassen mit ungültigen
Ergebnissen)
• falls nach Analyse der Spezifikation Grund zur Annahme
besteht, dass Elemente einer Äquivalenzklasse unterschiedlich
behandelt werden, ist die Klasse aufzuspalten
Formale Modelle der Softwareentwicklung
Stephan Kleuker
376
Testfallerzeugung aus Äquivalenzklassen
• Die Äquivalenzklassen sind eindeutig zu
nummerieren. Für die Erzeugung von Testfällen aus
den Äquivalenzklassen sind zwei Regeln zu
beachten:
• gültige Äquivalenzklassen:
– möglichst viele Klassen in einem Test
kombinieren
• ungültige Äquivalenzklassen:
– Auswahl eines Testdatums aus einer ungültigen
Äquivalenzklasse
– Kombination mit Werten, die ausschließlich aus
gültigen Äquivalenzklassen entnommen sind.
– Grund: für alle ungültigen Eingabewerte muss
eine Fehlerbehandlung existieren
Formale Modelle der Softwareentwicklung
Stephan Kleuker
377
Grenzwertanalyse
• Viele Software-Fehler sind auf Schwierigkeiten in Grenzbereichen
der Äquivalenzklassen zurück zu führen (z.B. Extremwert nicht
berücksichtigt, Array um ein Feld zu klein)
• Aus diesem Grund wird die Untersuchung von
Äquivalenzklassen um die Untersuchung der Grenzen ergänzt
• Beispiel: 1<=Wert<=99 (wobei Wert ganzzahlig ist)
– Äquivalenzklasse Int-Wert<1: obere Grenze Wert=0 (untere
Grenze spielt hier keine Rolle)
– Äquivalenzklasse Int-Wert>99: untere Grenze Wert=100 (obere
Grenze spielt keine Rolle)
– Äquivalenzklasse 1<=Int-Wert<=99 : untere Grenze Wert=1
und obere Grenze Wert=99
• Diese Grenzfallbetrachtung kann direkt in die Testfallerzeugung
eingehen (es gibt Ansätze, bei denen zusätzlich ein Fall mit
einem Wert aus der „Mitte“ der Äquivalenzklasse genommen
wird)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
378
Beispielentwicklung (1/4)
• Spezifikation:
Das Medikament ist für Personen ab 6 Jahren geeignet. Für je
zehn Kilo Körpergewicht werden 5 Einheiten benötigt, für
Männer müssen 10% mehr Einheiten gerechnet werden. Falls
einer der Risikofaktoren A oder B auftritt, ist die Dosierung um
20 Einheiten zu senken, falls die Risikofaktoren zusammen
auftreten, ist das Medikament nicht anzuwenden.
• zunächst: Klärung der Vorbedingung, entweder Berechnung
nur für bestimmte Patientengruppe oder für alle Personen
für alle Personen: Vorbedingung {true}, ggfls. Ergebnis 0
• Frage: Wird die Erhöhung um 10% für den bis dahin
berechneten Wert durchgeführt oder soll zuerst der Abzug von
20 Einheiten stattfinden?
• genauer: Berechnungen für Personen mit minimal 10 kg, sonst
Dosis 0.
Formale Modelle der Softwareentwicklung
Stephan Kleuker
379
Beispielentwicklung (2/4)
• Spezifikation der Nachbedingung:
((alter<6  (risikoA  risikoB)  gewicht<10)  dosis=0)
 ((alter 6  risikoA   risikoB  geschlecht=’w’)
 dosis=5*gewicht/10))
 ((alter  6  risikoA   risikoB  geschlecht=’m’)
 dosis=1.1*5*gewicht/10))
 ((alter  6  (risikoA   risikoB)  geschlecht=’w’)
 dosis=5*gewicht/10-20))
 ((alter  6  (risikoA   risikoB)  geschlecht=’m’)
 dosis=1.1*5*gewicht/10-20))
• erster Implementierungsansatz: Arbeite spezifizierte
Alternativen Schritt für Schritt ab
• Problem: Denkfehler aus Erstellung der Nachbedingung wird in
Implementierung übertragen
• deshalb: alternativer Implementierungsweg
Formale Modelle der Softwareentwicklung
Stephan Kleuker
380
Beispielentwicklung (3/4)
public double dosis_berechnen(int alter, int gewicht,
boolean geschlecht, boolean risikoA, boolean risikoB){
double dosis;
if(alter<6)
dosis=0.;
else
Fehlt: Annotation mit
if(risikoA && risikoB)
dosis=0.;
Zusicherungen vor und
else
nach jeder Anweisung
if(gewicht<10)
Zusicherungen können
dosis=0.;
rückwärts aus
else{
Nachbedingung
dosis=5*gewicht/10.;
berechnet werden
if(!geschlecht)
(sehr länglich)
dosis=dosis*1.1;
if(risikoA || risikoB)
dosis=dosis-20.;
}
return dosis;
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
381
Beispielentwicklung (4/4)
• Testfallentwicklung mit Äquivalenzklassen,
Grenzwerten (und Überdeckung)
Testfall
1
2
3
4
5
Alter
6
6
6
5
6
Gewicht
10
10
10
10
9
Geschlecht
m
w
w
m
m
Risikoklasse A
n
n
j
j
n
Risikoklasse B
n
j
j
n
n
Erwartetes Ergebnis:
5.5
-15
0
0
0
Parameter
• Tests laufen, allerdings bereits bei systematischer
Testerstellung Problem mit negativen Ergebnissen
gefunden
Formale Modelle der Softwareentwicklung
Stephan Kleuker
382
Praxisthemen für Verifikation
• Einführung von Datentypen
• Einführung von Funktionen, Methoden,
Objektorientierung
• Einführung von Sichtbarkeiten, lokale und globale
Variablen
• Wertübergabe: Call by Value und Call by Reference
• Polymorphie bei Vererbung (Typbestimmung zur
Laufzeit)
• Kommunikation im System
kann alles in Semantik eingebaut werden, wobei
eventuell nicht mehr der operationelle Ansatz
gewählt wird
Formale Modelle der Softwareentwicklung
Stephan Kleuker
383
Programmiersprachbesonderheiten
public static void main(String[] args){
int imax=Integer.MAX_VALUE;
int imax1=imax+1;
double dmax=Double.MAX_VALUE;
double dmax1=dmax*100.;
double dmin1=-dmax1;
double aha1=dmax1/dmax1;
double aha2= 3./0.;
System.out.println("imax: "+imax);
System.out.println("imax1: "+imax1);
System.out.println("dmax: "+dmax);
System.out.println("dmax1: "+dmax1);
System.out.println("dmin1: "+dmin1);
System.out.println("aha1: "+aha1);
System.out.println("aha2: "+aha2);
}
imax: 2147483647
imax1: -2147483648
dmax: 1.7976931348623157E308
dmax1: Infinity
dmin1: -Infinity
aha1: NaN
aha2: Infinity
Formale Modelle der Softwareentwicklung
Stephan Kleuker
384
Programmverifikation in der Praxis
• Automatische Überprüfung, ob Zusicherungen korrekt gewählt
wurden, ist nicht möglich, da i.a. unentscheidbar
• Korrekte Regelanwendung kann durch Werkzeug
(Theorembeweiser) kontrolliert werden
falls nicht verifiziert wird:
• Vor- und Nachbedingungen sind für jede Methode/ jedes Modul
festzulegen und zu prüfen, C, C++, C# und Java haben dazu
Befehl assert
• assert(<Boolesche Bedingung>) bricht Programm ab, wenn
Bedingung nicht erfüllt ist
• sauberer Programmierstil: einfache kurze Methoden, z. B.
niedrige McCabe-Zahl
• komplexe Algorithmen sind zu dokumentieren, damit ein
Anderer sie verstehen (prüfen) kann
• jede Anweisung beim Testen mindestens einmal ausführen
• bei Testerstellung über Grenzfälle genau nachdenken
Formale Modelle der Softwareentwicklung
Stephan Kleuker
385
5.7 Syntax und Semantik paralleler Programme
• Syntax paralleler Programme
• Interleaving-Semantik
• Divergenz durch Parallelität
• Atomare Bereiche
Formale Modelle der Softwareentwicklung
Stephan Kleuker
386
Parallele Programme
• Das Leben ist ein verteiltes System mit vielen parallelen
Abläufen
• häufig: verteilte Systeme, jedes System mit eigenem Programm
• fast immer: ein Rechner, ein Betriebssystem und viele pseudoparallel laufende Prozesse
• Parallelelität in unserer Programmiersprache:
<Programmname>::= <Variablenname> is {Befehlssequenz}
<Parallelprogramm> ::= <Variablenname> is
{start( <Programmname> );
…
start( <Programmname> );}
• hier nur ein Start für parallele Prozesse, keine dynamische
Erzeugung
Formale Modelle der Softwareentwicklung
Stephan Kleuker
387
Beispielprogramm mit Parallelität
P1 is {
i=1;
while(i<4){
i=i+1;
}
}
P2 is {
j=1;
while(j<4){
j=j+1;
}
}
P is{
start(P1);
start(P2);
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
388
Semantik der Parallelität
Definition (Semantik der parallelen Programmausführung): Die
bisherige Semantik der Programmausführung wird um folgende
Regeln ergänzt:
(7) < start(P);Q, z>  <Par(Q,P), z>
(8) Wenn <Pi , z1>  <Qi , z2> dann
<Par(P1,...,Pi-1,Pi,Pi+1,..., Pn), z1> 
<Par(P1,...,Pi-1,Qi,Pi+1,..., Pn), z2>
(9) Wenn <P1, z1>  <P2, z2> dann <P is {P1}, z1>  <P2, z2>
Weiterhin wird für Par folgendes festgelegt:
<Par(P1,...,Pi-1,E,Pi+1,..., Pn), z> = <Par(P1,...,Pi-1,Pi+1,..., Pn), z>
<Par(P1,...,Pi-1,Par(Q,R),Pi+1,..., Pn), z> =
<Par(P1,...,Pi-1,Q,R,Pi+1,..., Pn), z>
<Par(E),z> = <E,z>
• Teilprogramme können unabhängig voranschreiten
(Interleaving-Semantik), aber nicht gleichzeitig
Formale Modelle der Softwareentwicklung
Stephan Kleuker
389
Mehrere Endzustände (1/2)
P1 is {
if(x>1){
x=3;
}
}
P2 is{
x=2;
}
P is {
start(P1);
start(P2);
}
Formale Modelle der Softwareentwicklung
Parallele Programme können
typischerweise miteinander
kommunizieren, d. h.
Informationen austauschen, z. B.
- über gemeinsame Variablen
- über Kommunikationskanäle
Interleaving-Semantik kann zu
verschiedenen Endergebnissen
führen
Stephan Kleuker
390
Mehrere Endzustände (2/2)
<Prog,z> mit z(x)=1
(7),(9)
<Par(start(Prog2); , Prog1), z>
(7)
<Par(Prog2,Prog1), z>
(1),(8),(9)
<Par(Prog1), z11> mit z11(x)=2
(4),(8),(9)
<Par(start(Prog2); ), z>
(4),(8),(9)
<Par(Prog2), z>
(3),(8),(9)
<Par(x=3;),z11>
(7)
(1),(8),(9)
<E, z21> mit z21(x)=2
(1),(8)
<E,z12> mit z12(x)=3
Formale Modelle der Softwareentwicklung
Stephan Kleuker
391
Mögliche Divergenz durch Parallelität
P1 is {
while(x>0){
y=y+1;
}
}
P2 is {
x=0;
}
P is {
start(P1);
start(P2);
}
• z(x)=2, Sem(P,z) = { zz | zz(x)=0, zz(y)N}  {}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
392
Interleaving genauer (1/2)
P1 is {
x=x*x;
}
P is {
start(P1);
start(P1);
start(P1);
}
Q1 is {
y=x*x;
x=y;
}
Q is {
start(Q1);
start(Q1);
start(Q1);
}
• P1 und Q1 verhalten sich bzgl. x gleich, berechnen x2
• Durch Interleaving verhalten sich P und Q bzgl. x
unterschiedlich, P berechnet x8, Q berechnet x2, x4, x6 oder x8
Formale Modelle der Softwareentwicklung
Stephan Kleuker
393
Interleaving genauer (2/2)
• Analysiert man aus Sicht des Compilers, was bei
x=x+1 passiert, so handelt es sich um mehrere
Schritte:
– Lade von der zu x gehörenden Speicheradresse
den Wert von x in einen Speicher der CPU
– Führe auf der CPU die Erhöhung um eins durch
– Schreibe das Ergebnis aus der CPU wieder in die
zu x gehörende Speicheradresse
• zwei parallele Teilprogramme, die x=x+1
durchführen, können zu x=2 oder x=3 kommen
• Wichtig ist, welche Aktionen ununterbrechbar sind
(in Semantik festgelegt), diese Aktionen heißen
atomar
Formale Modelle der Softwareentwicklung
Stephan Kleuker
394
Atomare Bereiche
• <Befehl> ::= atomic{ <Befehlssequenz> }
• Definition (Semantik der Ausführung atomarer
Bereiche): Die bisherige Semantik der
Programmausführung wird um folgende Regel
ergänzt:
(10) Wenn <P,z> * <E,zz>,
dann <atomic{ P }, z>  <E,zz>
• Die Regel formalisiert, dass Zustände innerhalb der
Ausführung des Programms P für die Semantik
unwichtig sind und nur das Ergebnis am Ende des
atomaren Bereichs interessiert
Formale Modelle der Softwareentwicklung
Stephan Kleuker
395
5.8 Beweissysteme für parallele Programme
• Beweisregel für atomare Bereiche
• Interferenzfreiheit
• Beweissystem für partielle Korrektheit
• Beweissystem für totale Korrektheit
Formale Modelle der Softwareentwicklung
Stephan Kleuker
396
Beispiel mit atomaren Bereichen und Beweisregel
P1 is {
atomic{
x=x+1;
x=x+1;
}
}
Formale Modelle der Softwareentwicklung
P2 is {
atomic{
x=x*2;
x=x*2;
}
}
P is {
start(P1);
start(P2);
}
Stephan Kleuker
397
Versuch Beweise zu komponieren (1/2)
• {x=1} x=x+1; {x=2} gilt
• {x=2} x=0; {x=0} gilt
• P1 is {x=x+1;}
P2 is {x=0;}
• {x=1  x=2} start(P1); start(P2); {x=2  x=0} ist
nicht gültig
• {x=1  x=2} start(P1); start(P2); {x=2  x=0} ist
gültig (hier, geht nicht generell)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
398
Versuch Beweise zu komponieren (2/2)
• {x=0} x=x+1; x=x+1; {x=2} gilt
• {x=0} x=2; {x=2} gilt
• P1 is {x=x+1; x=x+1}
P2 is {x=2;}
• {x=0  x=0} start(P1); start(P2); {x=2  x=2}
gilt nicht, wegen
• {x=0} x=x+1; x=2; x=x+1; {x=2} gilt nicht
Formale Modelle der Softwareentwicklung
Stephan Kleuker
399
Interferenzfreiheit (partiell)
Definition (Interferenzfreiheit, partielle Korrektheit): Sei {p1} P1
{p2} P2 ... {pn} Pn {pn+1} eine Beweisskizze für die partielle
Korrektheit eines Programms P. Sei Q ein Programmstück aus
einer anderen Beweisskizze eines anderen Teilprogramms mit
der Zusicherung pre(Q) als Vorbedingung. Dann interferiert Q
nicht mit der Beweisskizze von P, wenn für alle Zusicherungen
pi der Beweisskizze von P
{pi  pre(Q)} Q {pi}
gilt.
Seien {pi,1} Pi,1 {pi,2} Pi,2 ... {pi,n} Pi,ni {pi,ni+1} Beweisskizzen für
die partielle Korrektheit eines Programms Pi (mit 1im), dann
heißen diese Beweisskizzen interferenzfrei, falls keine
Zuweisung und kein atomarer Bereich Q eines der Programme
Pi mit der Beweisskizze {pj,1} Pj,1 {pj,2} Pj,2 ... {pj,n} Pj,n {pj,n+1}
eines anderen Programms Pj (ij) interferiert.
Formale Modelle der Softwareentwicklung
Stephan Kleuker
400
Beweisregel, parallel
Formale Modelle der Softwareentwicklung
Stephan Kleuker
401
Interferenzfreiheit (total)
Definition (Interferenzfreiheit, totale Korrektheit): Sei {p1} P1 {p2}
P2 ... {pn} Pn {pn+1} eine Beweisskizze für die totale Korrektheit
eines Programms P. Sei Q ein Programmstück aus einer
anderen Beweisskizze eines anderen Teilprogramms mit der
Zusicherung pre(Q), das nicht mit der Beweisskizze bezüglich
partieller Korrektheit interferiert als Vorbedingung. Sei t eine
Terminierungsfunktion einer Schleife aus P, z eine ganzzahlige
Variable, die sonst nicht vorkommt und gilt
{t=z  t0  pre(Q)} Q {t0  tz}
für alle Schleifen aus P, dann interferiert Q nicht mit der
Beweisskizze für P.
Seien {pi,1} Pi,1 {pi,2} Pi,2 ... {pi,n} Pi,ni {pi,ni+1} Beweisskizzen für
die totale Korrektheit eines Programms Pi (mit 1im), dann
heißen diese Beweisskizzen interferenzfrei, falls keine
Zuweisung und kein atomarer Bereich Q eines der Programme
Pi mit der Beweisskizze {pj,1} Pj,1 {pj,2} Pj,2 ... {pj,n} Pj,n {pj,n+1}
eines anderen Programms Pj (ij) interferiert.
• Beweisregel (letzte Folie) wird so übernommen
Formale Modelle der Softwareentwicklung
Stephan Kleuker
402
Disjunkte Programme
P1 is {
{a=x}
x=x+1;
{a=x-1}
x=x+2;
{a=x-3}
}
P2 is {
{b=y}
y=y*2;
{b=y/2}
y=y*3;
{b=y/6}
}
P is {
start(P1);
start(P2);
}
zu zeigen: {a=x  b=y} P {a=x-3  b=y/6}
gilt da:
{a=x  b=y} y=y*2; {a=x}
{a=x-1  b=y} y=y*2; {a=x-1}
{a=x-3  b=y} y=y*2; {a=x-3}
{a=x  b=y/2} y=y*3; {a=x}
{a=x-1  b=y/2} y=y*3; {a=x-1}
{a=x-3  b=y/2} y=y*3; {a=x-3}
{b=y  a=x} x=x+1; {b=y}
{b=y/2  a=x} x=x+1; {b=y/2}
{b=y/6  a=x} x=x+1; {b=y/6}
{b=y  a=x-1} x=x+2; {b=y}
{b=y/2  a=x-1} x=x+2; {b=y/2}
{b=y/6  a=x-1} x=x+2; {b=y/6}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
403
Beweisbarkeit herstellen
• Man kann zeigen, dass die Beweissysteme korrekt, aber nicht
vollständig sind
• Typisches Problem: man weiß bei Beweisen nicht, an welcher
Stelle sich Programme befinden
• Ansatz: Einführung von Hilfsvariablen (Variablen die nur
geschrieben werden, nie gelesen und den Programmablauf
nicht beeinflussen), Programmzähler nach Lamport
P is {
y=x+1;
z=y+2;
}
PmitHilfvariable is {
position=0;
atomic{
y=x+1;
position=1;
}
atomic{
z=y+2;
position=2;
}
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
404
Nicht interferenzfreie Beweisskizzen
P1 is {
{y=x}
x=x+1;
{y=x-1}
x=x+1;
{y=x-2}
}
P2 is {
{y=x}
x=x*2;
{y=x/2}
}
{y=x  y=x} x=x*2; {y=x} gilt nicht
P is {
start(P1);
start(P2);
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
405
Interferenzfreie Beweisskizzen (1/2)
P1 is {
{tmp1=0  (tmp2=0  y=x)  (tmp2=1  y=x/2)}
atomic{
x=x+1;
tmp1=1;
}
{ tmp1=1  (tmp2=0  y=x-1)
 (tmp2=1  (y=(x-1)/2)  y=x/2-1)}
atomic{
x=x+1;
tmp1=2;
}
{tmp1=2  (tmp2=0  y=x-2)
 (tmp2=1  (y=(x-2)/2)  y=(x-1)/2-1  y=(x/2)-2)}
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
406
Interferenzfreie Beweisskizzen (2/2)
P2 is {
{ tmp2=0  (tmp1=0  y=x)
 (tmp1=1  y=x-1)
 (tmp1=2  y=x-2)}
atomic{
x=x*2;
tmp2=1;
}
{tmp2=1  (tmp1=0  y=x/2)
 (tmp1=1  (y=(x-1)/2  y=x/2-1)
 (tmp1=2  (y=(x-2)/2)  y=(x-1)/2-1  y=(x/2)-2)}
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
407
Beispiel: totale Korrektheit (1/3)
• es ist nicht immer notwendig, in jeder Komponente
Programmzähler zu ergänzen
P2 is {
{tmp2=0}
atomic{
x=x-1;
tmp2=1;
}
{tmp2=1}
}
P1 is {
erg=0;
while(x>0){
x=x-1;
erg=erg+1;
}
}
P is {
start(P1);
start(P2);
}
zu zeigen:
{y=x  x>0} P { y=erg  y=erg+1}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
408
Beispiel: totale Korrektheit (2/3)
P1 is {
{x>0  (tmp2=0  y=x)  (tmp2=1  y=x+1)  (tmp2=0  tmp2=1) }
erg=0;
{x>0  (tmp2=0  y=erg+x)  (tmp2=1  y=erg+x+1)
 (tmp2=0  tmp2=1) }
while(x>0){
{ (tmp2=0  (y=erg+x  x0))  (tmp2=1  (y=erg+x+1  x-1))
 (tmp2=0  tmp2=1) }
x=x-1;
{ (tmp2=0  (y=erg+x+1 x0))  (tmp2=1  (y=erg+x+2  x-1))
 (tmp2=0  tmp2=1)}
erg=erg+1;
{ (tmp2=0  (y=erg+x x0))  (tmp2=1  (y=erg+x+1  x-1))
 (tmp2=0  tmp2=1) }
}
{ (tmp2=0  (y=erg)  (tmp2=1  (y=erg  y=erg+1)) }
}
Formale Modelle der Softwareentwicklung
Stephan Kleuker
409
Beispiel: totale Korrektheit (3/3)
Anmerkungen zum Beweis:
• Es fehlt die Terminierungsfunktion, allein für P1
klappt t=x+1, aber
{x+1=z  x+10  tmp2=0}
atomic{x=x-1; tmp2=1;}
{x+10  x+1z} scheitert
• Trick: binde Programmzähler in t ein t= x+1+tmp2
• {x+1+tmp20  x+1+tmp2z}[tmp2:=1][x:=x-1]
umgeformt ergibt {x+10  x+1z}
• Korrektheit folgt mit:
(x+1+tmp2=z  x+1+tmp20  tmp2=0)
 (x+10  x+1z)
Formale Modelle der Softwareentwicklung
Stephan Kleuker
410