So, einen schönen guten Tag. Am letzten Termin haben
wir uns damit beschäftigt, wie man bei endlichen Zustandsräumen CTL-Modelchecking
tatsächlich direkt auf dem Graphen der Kripke-Struktur machen kann.
Wir haben da ein Verfahren entwickelt,
das rekursiv das Ganze aufruft,
nehmen wir über den Formelaufbau
verschiedene Unterprozeduren aufrufen
Und dabei gab es relativ einfache Fälle, nämlich die ersten
vier Fälle konnte man sofort an Ort und Stelle erledigen.
Nämlich der Fall, dass wir als Teilformen eine atomare Formel haben,
der erste Fall. Für diesen Fall haben wir einfach nur
überprüfen müssen, wie sieht das aus mit der Etikette?
Wenn die Formel, diese atomare Formel in der Etikette vorkommt,
dann ist sie da offensichtlich gültig, also packen wir sie zur Labelmenge hinzu.
Und das nächste ist, wenn wir eine negierte Formel haben,
F hat also die Form Negation von F1,
da rechnen wir erstmal rekrusiv aus, in welchen Zuständen F1 gilt.
Und wenn wir das wissen, überprüfen wir nur noch,
gilt jetzt F1 in diesem Zustand S gerade nicht,
also es ist nicht in der Label-Menge.
Wenn das zutrifft, dann packen wir das F,
also genau das andere, die Negation der Negation hinzu zur
Label-Menge von S und das machen wir wieder für alle Zuständen.
Also genau die Semantik der Negation, das Gegenteil tun.
Bei der Disjumption F ist F1 oder F2 gehen wir weiter und machen
Erst mal ein Aufruf für F1 und F2 und für alle Knoten überprüfen wir dann,
ob eine der beiden Teilformen in entweder F1 oder F2
oder beide in der Beschriftung des Zustandes es vorkommt,
sollte das der Fall sein, packen wir es zur Labelmenge hinzu.
Und das wieder für alle Zustände. Und jetzt die drei
temporalen Operatoren, wir mussten ja drei Stück reichen,
um alle anderen fünf Kombinationen auch auszudrücken.
Also beschränken wir uns auf diese drei. EXF1 ist noch
relativ einfach. Das sagt er, es gibt einen Pfad,
auf dem im nächsten Zustand F1 gilt.
Wir müssen also nur in die Zukunft schauen. Also erst
einmal markieren wir wieder rekursiv alle Zustände, in denen F1 gilt.
Und jetzt gucken wir für jeden Zustand erst nach,
ob es einen Zustand T gibt,
sodass Tee ein direkter Nachfolger von Es ist.
Also S und Tee stehen in Relation Groß R. Und
ich schaue nach Guilt F1 in diesem Zustand Tee.
Also es gibt einen direkten Nachfolger Tee, der die Eigenschaft hat,
F1 wahrzumachen. Dann ist auch die Formel EXF1 war,
deswegen packe ich dann den Zustand
Der der Vorgänger von Tee ist, hin,
zu dem packe ich dann die Formel F hinzu.
Ja, und dann bleiben die beiden komplizierten Fälle übrig,
nämlich EF1 an Till F2 und EGF1.
Also es gibt einen Pfad auf dem F1,
so lange gilt, bis irgendwann F2 gilt.
Dafür haben wir eine Subprozedur entwickelt. Oder die zweite Sache,
es gibt einen Pfad auf dem Immer F1-Skill.
Und die Unterprozeduren, die sahen ungefähr so aus,
da steckt dir die Idee drin, wenn ich,
es gibt einen Pfad auf dem F1,
Antil F2 gilt,
überprüfen will
Denn betrachte ich erst mal die Zustandsmenge Großthemen mit allen Zuständen,
in denen bereits F2 gilt. Und in all diesen sage ich,
da gilt die Gesamtformel. Denn wenn F2 bereits gültig ist,
dann gilt die Formel, ja, nach null Schritten.
Und jetzt ist die Grundidee, ich suche jetzt Zustände,
die die Eigenschaft haben, dass ich durch lauter Knoten gehen kann,
Zustände, in denen F1 gilt und ich lande,
schlussendlich in einem Zustand im F2 gilt.
Operationalisiert wird das jetzt folgendermaßen, wir nehmen uns die ganze Menge,
von denen wir schon wissen,
dass dort die Formel gültig ist
Am Anfang sind das alle Knoten in den F2 gilt.
Also das ist die Menge Groß-Tee. Und jetzt,
das ist die Waldschleife, solange es noch Knoten gibt,
laufe ich rückwärts die Kanten entlang und überlaufe dabei nur solche Knoten, in denen auch F1 geht.
Also rückwärts die Kanten ablaufen und nur über F1 erfüllende Zustände gehen. Da sieht man,
der Wildschleife, ich nehme mir also einen Zustand, kleinen S,
entferne ihn aus der Menge Groß-Tee und betrachte jetzt alle Vorgängerzustände, Kleintee,
Also es ist ein Vorgängerzustand, weil T und S und Relation stehen.
Es gibt also eine Kante von T nach S. Und jetzt gucke ich nach,
wenn ich diesen Knoten noch gar nicht betrachtet habe,
also er ist noch nicht mit der Formel F selbst gekennzeichnet und er hat die Eigenschaft,
ich darf ihn besuchen, also F1 ist hier gültig,
dann habe ich offensichtlich geschafft,
einen weiter rückwärts zu laufen, korrekter Natur,
dann packe ich auch die Formel F hinzu zur Labeling-Menge
von dem Knotentee,
dem direkten Vorgänger
Und da das jetzt offensichtlich ein neuer Knoten ist,
von dem ich die Prozedur wieder starten kann,
von dem ich weiter rückwärts suchen will,
packe ich diesen Knoten einen kleinen Tee in die Suchmenge Großtee hinzu.
Und jetzt habe ich wieder eine Menge von Knoten,
die ich noch untersuchen muss. Und das mache ich so
lange, bis ihr keinen Knoten noch zu bearbeiten ist.
Denn irgendwann habe ich jeden Knoten mal angefasst und bin mit
meiner Rückwärtssuche zu enden. Das war so das eine.
Ich fange mit F2 an und arbeite mich rückwärts über F1-Knoten vor.
Und der zweite Algorithmus war, E-G-F1. Also es gibt einen Pfad,
auf dem immer F1 gilt. Da war die Grundidee,
dass wir starke Zusammenhangskomponenten bilden, von solchen Zuständen,
in denen F1 gilt. Alle diesen Zustände,
da kann ich starten in so einer Zustandskomponenskomponente, egal wo ich starte,
ich kann da ja beliebig im Kreis laufen,
weil in einer Zusammenhangskomponente kann jeder Knoten, jeden anderen Knoten erreichen.
Also habe ich es dort sehr leicht,
ich kann von jedem Knoten aus einen unendlichen Pfad starten und
in jedem Knoten gilt dort bereits die Eigenschaft
So, das sind die ersten Schritte, die diese Algorithmen uns macht.
Er berechnet erstmal die Menge aller Knoten. Er ist Strich,
die die Eigenschaft haben, dass F1 in ihnen gilt.
Danach werden alle strengen Zusammenhangskomponenten gebildet, die nicht trivial sind.
Also SCC ist die Menge der Nicht-Trivialen.
Strengen Zusammenhangskomponenten bezüglich S-Strich. Also ich betrachte nur noch Zustände,
in denen F1 gilt, das war die Restriktion des Grafen,
Knoten, in denen F1 nicht gilt,
werden einfach jetzt vergessen
Und jetzt packe ich alle Knoten in die Menge, Tee hinein,
die sich in solchen nicht trivialen, strengen Zusammenhangskomponenten befinden.
Ja, jetzt habe ich also Situationen, Tee enthält schon mal alles,
was korrekterweise eine unendliche Fahrt, auf dem immer F1 gilt, erlaubt.
Und das drückt sich in der nächsten Zeile aus, dass wir sagen,
alle Zustände kleinen SNT fügen wir jetzt die Formel EGF1 zum Label-Set hinzu.
So, das sind jetzt aber nicht alle Zustände,
auf denen das gilt, sondern ich nehme jetzt alle Zustände hinzu,
die die Eigenschaft haben,
es führt ein Pfad in die Menge der strengen Zusammenhangskomponenten.
So, also ein Pfad dahin heißt, wie kriege ich den?
Ich nehme jetzt diese Menge als Ausgangspunkt und laufe jetzt wieder rückwärts über F1 erfüllende Knoten.
So ähnlich, wie ich das eben gemacht habe.
Der Codeblock sieht genauso aus wie bei dem Antil von eben.
Ich sage also, solange ich noch was zu tun habe,
weil Tee ungleich MT Set, du,
nimm dir einen Zustand, ess aus Tee raus,
entferne ihn und schaue jetzt für alle Vorgängerknoten Tee,
allerdings aus der Einschränkung,
ess Strich
Und guckt nach, hast du ihn schon behandelt?
Also gibt es EGF 1 noch nicht da im Labeling?
Und wenn das der Fall ist,
da ich nur Knoten betrachte, die EF1 erfüllen,
weiß ich, aha, ich habe jetzt einen Knoten,
der rückwärts betrachtet irgendwie einen unendlichen Pfad erzeugen kann.
Wenn ich jetzt F1 habe, kann ich das vorne ranpacken.
Deswegen ist es sinnvoll an diesem Knoten Tee,
auch zu sagen, dass dieser Knoten Tee einen unendlichen Pfad erlaubt,
an dem immer nur F1 gilt.
Und deswegen packe ich in der nächsten Zeile zu dem Label-Set
von Tee, die Formel EGF1 auch hinzu
So, und offensichtlich kann ich das Spiel bei dem Knoten
kleinen Tee weitermachen. Das packe ich. Deswegen packe ich
das in die Menge Großthemen zu. So,
diese drei Algorithmen hatten wir uns beim letzten Mal angeschaut.
Wir hatten das auch mit ein, zwei Lämmertage rechtfertigt,
dass das eine korrekte Konstruktion ist, die so funktioniert.
Und wir hatten uns auch angesehen, wie groß die Komplexität
ist bei der Antillt-Prozedur, ist die Komplexität relativ klar.
Ich gucke mir jeden Zustand an, ob F2 gilt.
Die markiere ich. Also wenn ich es sehr naiv mache,
laufe ich einmal über den kompletten Grafen und sagt dann,
F2 gilt ja oder nein.
Habe ich also diese Menge gebildet. Und dann fange ich an,
von diesen Knoten rückwärts zu suchen,
in welchen Knoten kann ich jetzt rückwärts laufend F1-Knoten erreichen?
Die packe ich alle hinzu. Dabei packe ich im Wesentlichen
jeden Knoten nochmal an. Das heißt, die Laufzeit für
die Antil-Prozedur ist im Wesentlichen proportional zur Größe der Zustands- und Kantenmenge.
Also proportional zur Größe der Kripke-Struktur.
Jeden Knoten fasse ich zweimal an ungefähr
Bei dieser Prozedur mache ich was Ähnliches, da fasse ich
auch im Wesentlichen jeden Knoten so ein-, zweimal an.
Das einzige, was jetzt entscheidend ist, wie aufwendig ist es,
die strengen Zusammenhangskomponenten zu berechnen. Und da steckt die Hauptkomplexität drin,
aber glücklicherweise gibt es da einen sehr cleveren Algorithmus,
der das Ganze auch in einer Zeit proportional zur Größe des Grafen schafft.
Das heißt, der Schritt zwei, das Berechnen aller strengen Zusammenhangskomponenten,
SCC, der geht auch proportional zur Größe der Kryptostruktur.
Das heißt, die Unterprozedur braucht auch nur so viel Zeit,
wie die Kriprestruktur groß ist, mal Konstante.
In der U-Notation können wir die Konstanten jetzt verstecken.
Und wenn wir diese Ideen zusammenpacken, dann kriegen wir folgende Komplexitätsabschätzung. Der Satz sagt jetzt,
es gibt einen Algorithmus, nämlich den,
den wir eben angeguckt haben, der Vereine Kriprestruktur M entscheidet,
ob eine CTL-Formel F gilt, und er macht das in einer Zeit,
die in Opern, Größe der Formel F,
mal Größe der Kriprestruktur,
also Anzahl der Zustände plus Anzahl der Kanten liegt
Also proportional zur Größe der Formel und proportional zur Größe der Kripke-Struktur ist.
Das sind die beiden Eingangsgrößen. Das ist jetzt besser als das,
was wir bei LTL gesehen haben,
da sah das fast genauso aus,
nur dass nicht die Größe der Formel direkt eingeht,
als linearer Therm, sondern es gilt ein als zwei Hoch-O von F.
Die Größe der Formel geht deutlich stärker ein. So,
woran liegt das jetzt, dass ich diese Komplexitätsabschätzung machen kann?
Das liegt im Wesentlichen daran, dass ich ein rekrusives Verfahren habe,
das portional zur Anzahl der Teilformeln in die Subalgorithmen aufruft.
Für jede Teilformel-Setting, also für jeden Hauptoperator, kriege ich
einen neuen Aufruf. Wenn ich ein Oder habe,
zwei Teilaufrufe. Wenn ich ein E an Till habe,
teilaufrufe, wenn ich E-G-F1 habe, teilaufrufe. So,
wenn ich also den Algorithmus jetzt auf eine Kryptenstruktur anwende,
weiß ich für jede Teilformel von App mit so einer Subprozedur gestartet.
Und die Anzahl der Teilformeln ist durch O von F beschränkt.
Also es gibt höchstens so viele Teilformeln in F,
wie F lang ist
So, und wie groß ist der maximale Aufwand in jeder Subprozedur für jede Teilformel?
Ja, für die elementaren Fälle, also atomare Formel,
Negation, Desjunktionen oder EX-F1, haben wir sofort gesehen,
na da müssen wir nur lokal um die Zustände rumgucken.
Das heißt, die Prozeduren gucken sich jeden Zustand erst an
und machen da konstant viele Schritte.
Das geht also in Linearzeit. Wir haben uns eben angeguckt,
wie groß ist der Aufwand für den Operator E an Till
Ja, da haben wir auch gesehen, proportional zur Größe der Kripke-Struktur.
Und das Gleiche gilt für EG, den Operator. Da kann ich,
weil ich die SCCs in den Jahrzeit berechnen kann,
kann ich auch die Gesamtunterprozedur in dem Jahrzeit berechnen.
Das heißt, jeder Teilaufruf braucht maximal Ohr von Anzahl
der Zustände plus Anzahl erkannten viele Zeitschritte. So,
wenn ich das zusammennehme, ich habe maximal O von F
Aufrufe und jeder dauert maximal O von S plus R,
dann habe ich insgesamt also O von F mal S plus
Viele Zeitschritte, die ich brauche, um den ganzen Algorithmus
durchlaufen zu lassen. So kommt man zu dieser Komplexitätsabschätzung.
Jetzt gucken wir noch mal an, wie funktioniert dieser Algorithmus?
Wir hatten ja die Operation noch nicht so richtig in live gesehen.
Nehmen wir mal wieder das Beispiel des Mikrowellenofens,
so schön klein, seinen sieben Zuständen.
Was wollen wir da jetzt machen? Wir wollen eine einfache
Formel spezifizieren, die Formel F, AG,
also auf allen Faden
gilt immer
Dass wenn das Ganze gestartet wird, dass dann auf allen Fahren irgendwann
in der Zukunft mal gilt, dass das Ding auch aufheizt.
Also es gilt immer mal lax gesprochen,
wenn ich den Startknopf drücke, heizt das auch irgendwann mal.
So, also nach einem Zustand der Start erfüllt wird
später einmal ein Zustand eingenommen, der Heat erfüllt.
So, was mache ich jetzt? Mit dieser Formel kann ich erstmal
noch nichts anfangen oder der Algorithmus kann damit nichts anfangen,
denn es kommt da der Operator AG vor und der Operator AF
Dafür habe ich keine Subprozeduren für diese Formel ist der Algorithmus nicht ausgelegt. Da,
wenn ich jetzt die Äquivalenzen drauf an,
ich berechne also eine Normalform und ich kann das jetzt umformen,
durch eine Negation, AG wird zur, also erstmal,
wo kriege ich eine Negation her, durch Staat impliziert,
AF-Feed, eine Implikation,
B-A impliziert B ist immer nicht A oder B.
Das kann ich als Dissunktion jetzt aufschreiben. So,
wenn ich das jetzt raustreibe, die Negation, Wieso steht eigentlich und?
Na gut. Wenn ich die Negation jetzt raustreibe,
dann wird aus dem GNF und aus dem ANE und die Negation steht ganz vorne.
Und was brauche ich dennoch, das ARF-Feed stört mich auch,
da brauche ich auch eine Negation.
Also deswegen den Morgen. ARF, wenn ich da die
Negation gerne hätte, dann muss ich das auch reintreiben.
Das heißt, dann wird aus ARF-EG nicht heat.
Gut, damit kann ich jetzt operieren, da habe ich
fast die Operatoren, die ich brauche.
Ich habe mich eG, das ist ein Operator,
den ich habe
Und ich habe EF, einen Operator, den ich fast habe.
Denn EF, das kann ich ja leicht durch Antil ausdrücken.
Das ist ja nichts weiter als, es gibt einen Pfad,
auf dem True gilt an Till.
Und jetzt der geklammerte Ausdruck. Das heißt, EF ist
unmittelbar durch einen True, durch den Antil-Operator auszudrücken.
So, hier kann man das nochmal nachgucken, ob das
auch alles stimmt, was ich mir so eben gedacht habe.
Wenn ich die Formel F umschreiben will, an EF1,
AG F1 ist nicht EF,
Okay, da haben wir schon nicht EF und nicht F1,
ist, wenn ich die Implikation auflöse, Nichtstaat oder AFF,
noch eine Negation rein, dann hebt sich das bei Staat auf.
Deswegen ist auch das unter. Und die andere Negation durch
den Morgen vor AF kann ich denn umwandeln in,
nicht für alle Fahrer, das heißt, es gibt einen Pfad,
auf dem nicht in der Zukunft gilt, also immer gilt nicht, geht.
So, wenn ich möchte,
kann ich jetzt EF noch durch Antil ausdrücken,
also ich Ich kann das EF tatsächlich so in diese Form bringen,
dass ich den Antill-Operator habe.
Ich lasse das jetzt einfach mal als EF-Start und EG nicht hielt,
dann ist die Form in Teg kleiner zu schreiben.
Ja, aber wir wissen, wir müssen dafür gleich
den Antill-Operator und die Sub-Prozydur dafür verwenden.
Gut, also diese Formel wollen wir jetzt verwenden,
um in dieser Mikrowelle zu gucken, was da ist.
Naja, da gehen wir im Wesentlichen bei den
mehr oder weniger atomaren Formeln mal los,
also Heat und nicht Heat
Wo gilt das? Nicht Heat gilt in diesem Rot
eingefärbten Zuständen. Also in den Zuständen 1, 2,
3, 5 und 6. Und das nächste ist jetzt,
ich will EG nicht Heat ausrechnen, der EG-Operator,
der sagt jetzt, okay, ich suche einen Pfad,
auf dem immer irgendwas gilt.
Was mache ich da? Strenge Zusammenhangskomponenten berechnen macht diese Operator
. Der Algorithmus berechnet die strengen Zusammenhangskomponenten
Also, wenn ich die strengen Zusammenhangskomponenten jetzt in dem
rot gefärbten Bereich suche, dann stelle ich fest,
von eins komme ich nach zwei, komme ich nach fünf,
komme ich nach drei, komme ich nach eins.
Das ist also ein Zyklus. Ich komme zwar auch nach sechs,
aber von sechs komme ich nicht wieder zurück in diese Zustandsmenge,
sondern nur raus. Das führt also jetzt dazu,
dass das hier eine große strenge Zusammenhangskomponente ist,
in der nicht Heat gilt.
Und der sechste Knoten ist eben außerhalb und bildet einen trivialen,
eine triviale Komponente.
Das ist nämlich
ein Knoten
Ja, und in dem komme ich aber nicht wieder raus im reduzierten Grafen.
Denn der reduzierte Graf ist das, was ich erhalte,
wenn ich mich nur im roten Teil bewege.
So, was heißt das? Das heißt, dass die Knoten,
die ich jetzt umkringelt habe, 1, 2, 3,
5, genau in denen gilt jetzt also EG nicht Heat.
Das ist der Bereich. So, also weiß ich,
für diese Teilformel habe ich das Labeling schon komplett bestimmt.
Der nächste Operator ist jetzt Start
Das müsste jetzt eigentlich alles negieren und mit oder versehen,
damit ich das wieder auf den Ode-Operator zurückführen kann.
Wir ersparen uns das mal und tun jetzt mal so,
es kostet auch nicht viel zu sagen, bei uns,
bei einer Unformel nehme ich halt nur das hinzu,
wenn in sowohl die eine als auch die andere Teilform im Labeling vorkommt.
Oder sagt eins von beiden. Gut, was muss ich jetzt
also gucken? Ich nehme jetzt Start hinzu und frage mich,
in welchen Knoten gilt Start? Das sind die Grünen hier,
2,5, 6,7. Und wenn ich das jetzt mit einem Unverbinde,
Konjunktiv verbinde, dann sieht man, naja,
das sind die Knoten 2 und5,
die beides erfüllen
Also ich bilde hier den Durchschnitt. Das ist sinnvoll für
eine Konjunktion. Dann weiß ich also in diesen beiden Zuständen,
2 und 5 gilt Start und EGN nicht heat.
Habe ich schon mal diese Teilformel abgearbeitet. So,
und jetzt soll ich weitergehen. Das ist noch nicht die
gesamte Formel. Ich soll jetzt davon weiterrechnen. Ich will
ja als nächste Teilformel EFG, also E-E-True Antil G,
ausrechnen,
wobei G
diese Teilformel ist
Staat und EG Northeat. Das Und muss vor das EG
. Ja, das Antil macht folgendes,
es prüft erstmal, wo gilt die zweite Formel.
Also wo gilt G? Ja, das wissen wir schon,
dass es dieser gelb umrandete Bereich. Damit fange ich an.
Und jetzt firsche ich mich rückwärts über alle Kanten zu Zuständen,
die eins erfüllen, also das True in diesem Fall.
Wenn ich da rückwärts laufe, stelle ich fest,
aha, ich komme überall hin, wenn ich rückwärts laufe.
Denn in allen Knoten gilt ja True und ich kann alle Knoten erreichen.
Also von 2,5 kann ich rückwärts alles erreichen. Also stelle ich fest,
die Knotenmenge für die Formel, EF,
Start und EG-Natid ist die Gesamtknotenmenge 1 bis 7. Was im Umkehrschluss heißt,
die Knotenmenge für die Formel, die uns eigentlich interessiert,
dass die Negation der Formel nicht EF,
Start und EG-Natid,
das ist die leere Menge
Für eine Negation nehme ich genau das Kompliment der alten Menge.
Das heißt, ich habe bewiesen, dass kein Zustand die Formel erfüllt.
Also was wurde bewiesen, andersrum? Diese Formel F,
die ich umformen kann, zu Nicht-EF-Staat und E-Genatit.
Die hat die leere Menge als Zustandsmenge, also die Menge
aller Zustände, diese Formel erfüllt, ist leer.
Oder platter gesagt, die Formel gilt nirgends,
also gilt überhaupt nicht
Und das kann man hier insbesondere daran sehen,
dass man weiß, wo ist denn das Gegenbeispiel,
das Gegenbeispiel, versteckt sich in dieser strengen Zusammenhangskomponente.
Wenn ich nämlich die Zustände 1, 3,
1 und dann immer zwischen 1, 3, 1,
dann zu 2 und 5 und dann bei 2,
5 stecken bleibe, dann bin ich in so einer Sackgasse,
dann öffne und schließe ich die Tür immer nur noch.
Das ist zwar möglich, aber ist für die Mikrowelle relativ schwer,
wenn ich dauernd auf und zu mache,
dass die irgendwann aufheizt und das ist der anschauliche Grund,
wenn da ständig einer rumrüttelt, dass die Mikrowelle nicht aufheizt.
So, eigentlich ist ja gedacht, dass das aber ein
ziemlich beknacktes Verhalten ist, das praktisch wohl nicht auftreten wird.
Man stellt sich sofort, das passiert eigentlich nur endlich oft und nicht unendlich lange.
Irgendwann hat der Benutzer keine Lust mehr, einfach an der
Tür zu rütteln und festzustellen, die Fehlerlampe leuchtet weiter.
Und dann nervt, nimmt man an,
nach endlicher Zeit drückt man einen Reset-Knopf.
Wie im richtigen Leben beim Computer.
Dann drückt man auch irgendwann Reset
Das heißt, man hat so eine gewisse Vorstellung, dass gewisse Abläufe unwahrscheinlich sind.
Also unwahrscheinlich in dem Sinne, dass die eigentlich nicht auftreten werden.
Denn wenn die doch auftreten, dann sagen wir, naja,
da können wir auch nicht helfen. In diesem Fall möchte ich also sagen,
dass ein Szenario, das rein hypothetisch auftreten kann,
in denen ein Fehlerfall da ein Typ vorsteht und nur noch
die Tür schließt und öffnen schließt und öffnet unendlich lange,
dass das eigentlich eins ist,
dass zwar vielleicht irgendwie ein Problem darstellt,
aber praktisch nicht.
So ein Typ wird auch nie
die Hopline anrufen
Erstens wird er nie fertig und zweitens. Ich glaube,
das wäre einem dann doch peinlich. So gut,
wie kann man das jetzt in den Griff kriegen,
dass man sagt, das ist zwar hypothetisch ein möglicher Ablauf,
aber einer, der nicht vorkommen will,
den ich also von meiner Betrachtung ausschließen will.
Dafür hatten wir schon ein Konzept. Wir hatten das mal
im weitesten Sinne Fairness genannt. Wir haben gesagt,
naja, das ist irgendwie unfair in dem Sinne,
dass das System ja immer noch was Vernünftiges machen könnte.
Ja, ich könnte ja irgendwann mal über den Reset Knopf,
also die Reset-Kante nehmen, Reset-Knopf drücken und dann wird auch aufgeheizt.
So, gewissermaßen, eigentlich wäre es ja immer möglich,
aber irgendwie hat sich da jemand ganz unfairerweise genau den eigentlich blödsinnigsten Weg ausgesucht,
den ich gar nicht behandeln will, weil ich nicht glaube,
dass er passiert.
Also es steckt so ein bisschen Wunsch darüber,
was ich als nicht wirklich relevantes Verhalten betrachte. So,
und jetzt ist der Punkt, wir haben gesehen,
in LTL kann ich Fairness-Eigenschaften verschiedenster Bauart direkt ausdrücken als Formel.
Im CTL Geht das nicht so einfach,
weil ich da Paarungsoperatoren brauche, also so direkt GF hintereinander.
Das kann ich in CTL nicht äquivalent ausdrücken.
Also habe ich ein Problem, dann gehe ich entweder zur
stärkeren Logik CTL-Sternchen über, wie kann das alles?
Oder ich überlege, naja, gut,
mir gefallen aber die Komplexitätsresultate bei CTL so sehr,
dass sie eigentlich nicht davon weg möchte.
Fußnote, CTL-Sternmodel-Checking ist unheimlich aufwendig.
CTL Model-Checking ist dagegen
paradiesisch einfach
Und aus diesem Paradies wollen wir nicht vertrieben werden.
Und wir sagen, gut, drehen wir an der Definition.
Wir nehmen jetzt eine faire Kripke-Struktur. Dieses Konzept hatten wir schon mal.
Wir hatten ja gesagt, was ist jetzt die Semantik,
die faire Semantik vom CTL-Formel? Und die ganze Grundidee weiß,
man führt jetzt so wie beim Büchi-Automaten so Endzustandsmengen,
E1 bis EK, so Finalmengen ein,
haben damals gesagt, und wir haben eine Büchi-Akzeptanzbedingung,
wir sagen, wir betrachten Abläufe, nur dann,
wenn sie die Eigenschaft haben,
durch diese Endzustandsmengen tatsächlich auch unendlich oft irgendwie durchzurauschen.
Also illustriert hatten wir das beim letzten Mal,
dass wir gesagt haben, okay,
wenn wir hier so eine Endzustandsmenge haben von Knoten,
dann müssen wir da ja unendlich oft rein.
Ja, und da haben wir dann verschiedene Möglichkeiten,
wie wir da durchgehen können. Wir können zum Beispiel den
Knoten rechts unten, den könnten wir ausschließen. Ja,
aber wenn ich zum Beispiel eine andere Endzustandsmenge nur mit den
drei Knoten rechts unten machen würde, dann würde ich erzwingen,
dass ich in diesem Dreieck rechts unten unendlich oft durchlaufen.
Das Ganze müsste. So, in diesem Sinne,
Kann ich also über diese Endzustandsmengen des Verallgemeinerten Büchi-Automaten kontrollieren,
welche Abläufe ich als vernünftig ansehe und welche nicht?
Und dann hat man gesagt, die Unvernünftigen betrachte ich einfach nicht mehr.
In der Semantik hat man jetzt festgelegt, EEG,
also es gibt einen Pfad, auf dem immer gilt,
da will ich nur noch faire Pfade betrachten, die unfair ignoriere ich.
Und genauso für alles. Also wann immer ich jetzt einen
Pfad betrachte, muss er auch fair sein. So,
und wenn wir jetzt algorithmisch faires Model-Checking machen wollen,
also nur die fairen Pfade betrachten wollen,
dann müssen wir bei den Operatoren EG und E an Till ein bisschen dran drehen.
Aber wir müssen gar nicht viel machen. Wir müssen nur an
einer wichtigen Stelle drehen, nämlich bei den strengen Zusammenhangskomponenten.
Bei den strengen Zusammenhangskomponenten, sage ich jetzt,
eine starke oder starke Zusammenhangskomponente C, die ist auch noch fair,
wenn sie die Eigenschaft hat, dass meine Zusammenhangskomponente,
wenn die geschnitten mit jeder Endzustandsmenge EI nicht leer ist.
Das heißt,
in meiner Zusammenhangskomponente kommt auch immer ein Endzustand vor
Was also nicht passieren kann, ist, dass ich eine Zusammenhangskomponente habe,
eine Stärke, die keinen Knoten hat aus den Endzustand zu melden.
Das heißt, es gibt keine,
oder die ist unfair, wenn sie die Eigenschaft hat,
ich kann da zwar unendlich lange drinbleiben,
aber würde ich das tun, würde ich keinen End.
Würde ich nicht mehr nach Büchi akzeptieren. Dann würde ich
diese Fairness-Bedingungen verletzen, da hätte ich die Möglichkeit,
in C zu bleiben und endlich lange zu laufen.
Und das Wort, was ich dann generieren würde,
ist ein omega Wort,
was nach Büchi-Akzeptanzbedingungen
nicht mehr akzeptiert wird
So, also genau die Dinge, die unfairen Sachen werden somit ausgeschlossen.
Unfaire Abläufe. So, dann kann ich Folgendes machen.
Ich kann jetzt die Kryptostruktur M nehmen und ich kann sie einschränken auf M
Strich wieder, an dem ich Folgendes mache.
Wie gehabt, ich nehme alle Zustände S hinein,
die die Eigenschaft haben, dass sie F1 erfüllen.
Das habe ich bei EG auch schon gemacht, die Einschränkung auf F1.
Allerdings jetzt, F1 muss nicht irgendwie erfüllt werden,
sondern unter der fairen Semantik.
Das ist wichtig
Also ich will nur Pferdefahle, faire Pfade betrachten.
So, und wenn ich das gemacht habe,
dann betrachte ich nur noch die damit verbundenen Kanten.
Ich schränke das Labeling von ES ein,
auf nur noch die übrigbleibenden Knoten in das Strich.
Und die Endzustandsmengen, die ich dann habe,
F1 bis FK, ja,
dann nehme ich die alten Endzustandsmengen E-O-I
und schneide sie mit der strengen Zusammenhangskomponente
Wenn ich das so mache,
dann kann ich das alte Lämmer, was ich mal hatte,
dass mir eine Eigenschaft, ein Kriterium gibt für EGF1.
Das kann ich jetzt reformulieren für die faire Semantik.
Also für die normale Semantik galt ja EGF1 genau dann,
wenn ich von einem Zustand einen Pfad zu einer starken Zusammenhangskomponente im eingeschränkten Grafen habe.
Und jetzt kommt hier hinzu,
ich sage EGF1 gilt unter der fairen Semantik,
wenn es vom Zustand es ein Pfad in eine Fähre Nicht triviale Zusammenhangskomponente gibt.
Also die faire Semantik, die es erfüllt genau dann,
und da muss ich nur ergänzen, eine faire Zusammenhangskomponente.
Das heißt, sinngemäß gilt alles genauso, wie es vorher gilt.
Das heißt, das Modelchecking von EG führe ich jetzt auch
wieder zurück auf das Berechnung von fairen, starken Zusammenhangsgruppen.
Gehen wir noch mal zu unserem Beispiel von eben zurück,
dass er genau pathologisch war. Also das war ja der Mikrowellenofen,
wo ich sagte, die Formel nicht EF-Start E-Genortit,
also wo immer ich bin und starte, es wird aufgeheizt.
Da hatten wir festgestellt, dass diese Formel nirgends gültig ist,
weil ich die Möglichkeit habe,
mich in dieser Schleife zwischen zwei und fünf durch öffnenden Schließen der Tür zu verheddern.
So, das will ich jetzt aber gar nicht haben,
weil ich sage, das ist unfair.
Da muss ich jetzt also was tun an dieser Stelle.
Möchte ich also jetzt dran, dass das gar nicht mehr gilt?
Wie mache ich das? Das mache ich. Indem
ich mir jetzt überlege, was sind die Fähren und
was sind die unfairen Abläufe
So, ich möchte jetzt also die Formel App wieder betrachten,
setze aber voraus, dass der Benutzer da vom Mikrowellenofen,
die auch sinnvoll korrekt bedient, ja,
und korrekt bedienen heißt, das Ganze,
das unendlich oft gilt, Staat und Klos und nicht Error.
Das heißt, der Benutzer verhält sich so, dass unendlich oft gestartet,
geschlossen und das Ganze auch zu einem Nicht-Fehlerfall führt.
Wenn man mal guckt, wo ist das der Fall,
diese Mikrowellenofen, Also korrekt bedienen heißt unendlich,
oft gilt Start und Close und nicht Error.
Dann stellt man fest, die Zustände,
die das erfüllen, Start und Close und Not Error,
sind die Zustände sechs und sieben hier unten.
In denen gilt genau Start und Close und Not Error.
Die unterscheiden sich halt nur in der noch übrigbleibenden Variable Heat.
Sechs hat Not Heat als Eigenschaft, sie mathied als Eigenschaft.
Diese beiden Knoten sechs und sieben setzen wir jetzt also
als Eigenschaft, das wollen wir unendlich oft haben.
Da wollen wir unendlich oft durch
Wenn wir da unendlich auf durchwollen und dass unsere einzige Bedingung ist,
dann setzen wir jetzt also die Endzustandsmenge E1 auf
genau diese Menge von Knoten, sechs und sieben.
Also unendlich oft möchte ich da jetzt sein.
Damit ich sage, da sitzt ein vernünftiger Bediener vor.
Was passiert da jetzt? Wir starten das ganze Model-Checking-Prozedere nochmal
. Was passiert da jetzt? Naja, also gewisse Grunddinge
für Staat ist klar. Wo die gelten,
wo gilt das Nächste, was uns jetzt interessiert,
ist,
wo gilt
Not heat. Das ist wieder der rote Bereich. Und jetzt,
als nächstes, Start, ja, das sind die Grünen,
wissen wir auch, dieser Bereich 2, 5,
6, 7 da unten.
Und jetzt müssen wir wieder gucken, EG-Notit. Aber jetzt
unter der fairen Semantik. Was passiert da? EG-Notit,
also in dem Bereich, das ist wieder eine strenge Zusammenhangskomponente.
Bis hierhin ist alles genauso wie vorher.
Und jetzt ist die Frage,
ist sie fair
Wenn wir uns das angucken, die Frage nach der Fairness,
dann stellen wir fest, dieser Cluster, 1,
2, 3, 5, was wir eben hatten,
der ist nicht fair, wenn wir angucken,
machen wir noch ein bisschen was dazu.
Die beiden Sachen. Und dann stellen wir eben fest,
die Menge EO1, das ist ja die Zustandsmenge 6,
7, der gelbe Kasten.
Das ist mein Fairness-Bereich. Da muss ich unendlich auf durch
Während die starke Zusammenhangskomponente ist, da violett umrandete Bereich,
1, 2, 5, 3.
Und die sind es jungt. Also kommt da raus,
wenn die das jungt sind, ist das eine unfaire,
also eine nicht faire, strenge Zusammenhangskomponente.
So, dann muss sie aber nichts erfüllen.
Wenn die Schnittmenge leer ist, dann ist sie nicht fair.
Ich muss aber nur was für die fairen, strengen Zusammenhangskomponenten erfüllen.
So, da ist dann keine Fähre mehr gibt,
bleibt ja nichts mehr übrig, weiß ich sofort,
dass die Zustandsmenge,
die EG-Notit erfüllt,
dass die leer ist
Und das ist jetzt neu. Vorher war es eben so,
dass die Menge die EG Notit erfüllt, war eben genau die starke Zusammenhängskomponente.
So, und wenn ich weiß, EG Notit ist leer,
und ich verbinde das konjunktiv mit Staat, naja,
konjunktiv etwas verbinden als Mengenschnitt.
Wenn ich aber was mit der leeren Menge schneide, bleibt es die leere Menge.
Und wenn ich dann noch ein EF davor packe,
also irgendwie in die Zukunft gucke, naja,
wenn ich keine Zustände habe, die ich erreichen kann,
in denen das gilt,
dann gibt es auch keinen Fahrt,
wo das gilt
Also es ist auch EF-Start und E-Genotit, die leere Menge.
Und das führt im Umkehrschluss jetzt dazu, dass die Formel,
die uns interessiert, war ja die Negation,
nicht EF-Start und E-Genotit, dass die in allen Zuständen jetzt gilt.
Also genau umgekehrte Situationen unter der fairen Semantik durchs faire Model-Checking
stellen wir fest, dass die Formel F allgemeingültig ist.
Sie gilt in jedem Zustand, das Mikrobellenofen, egal wo der startet.
Und das liegt eben genau an dem Punkt, dass das,
was vorher problematisch war, die strenge Zusammenhangskomponente,
und die ich geschnitten habe nachher mit Staat,
da kam ja genau als Schnittmenge, wenn ich das mit Staat schneide, die Menge 2,5 raus.
Das waren die gemeinsamen Knoten. Hier kommt jetzt die leere
Menge raus. Das führt eben dazu, dass da eine
ganz andere Semantik hinter steckt, wenn ich Fairness annehme.
Das Nette ist, algorithmisch passiert da gar nicht so viel.
Also der Aufwand ist nicht viel größer.
Das habe ich also jetzt bewiesen unter der Annahme,
dass der Benutzer das Ganze immer korrekt bedient,
wobei korrekt bedienen durch eine Fairness-Eigenschaft
Formuliert wurde. Wir haben nicht gesagt,
korrekt bedienen heißt unendlich oft gestart und close und not error.
Ja, und das macht er immer,
also unendlich oft, so übersetzen wir das.
Dann stellen wir fest, diese Formel gilt. Sie ist
allgemeingültig und es gibt kein Gegenbeispiel. So. Also das,
was man eigentlich erwarten würde,
irgendwann komme ich unter vernünftigen Abläufen bei vernünftigen Bedienern mal auf
die rechte Seite des Zustandsdiagramms und auf der rechten Seite des Zustandsdiagramms
sieht man da,
heizt die Maschine auch auf
Ja, denn es gibt, so könnte man argumentieren,
inhaltlich keinen vernünftigen Grund, warum das Ganze nicht mal heizen sollte.
Also nicht mal einen Zustand einnehmen sollte, den es
immer erreichen kann. Denn wenn ich noch mal hingucke,
jetzt diese Zustandskombination 2,5, wenn ich die unendlich oft durchlaufe,
komme ich ja auch unendlich oft an Zustand 5 vorbei.
Und dieser Zustand 5, der hat immer zwei Kanten zur Auswahl.
Er sagt, okay, wenn ich im Zustand 5 bin,
gibt es zwei Möglichkeiten.
Entweder einen Zustand 2 wieder zurück oder den Zustand
Ja, und unfaires Verhalten drückt sich jetzt dadurch aus,
dass diese Möglichkeit in den Zustand 3 zu gelangen,
unendlich oft habe ich die Möglichkeit und nie wird sie eingenommen.
Und deswegen der Begriff unfair. Die Möglichkeit nach Zustand 3
zu gelangen, wird unfairerweise unendlich oft abgelehnt.
Ab einem gewissen Zeitpunkt nämlich nie mehr realisiert.
So, das waren jetzt gewissermaßen die bunten animierten Bildchen.
Wie sieht so etwas real aus, wenn ich das wirklich benutze?
Ja, da gucken wir uns mal ein Tool an
Der Molchecker SMV, also das älteste Tool dazu.
SMV steht für Symbolic Model Checker. Symbolic hat damit zu
tun, dass beim Symbolischen Model Checking etwas gemacht wird.
Meine spezielle Grafen-Datenstrukturen, die uns erlauben, diesen riesigen Grafen,
der den Zustandsraum beschreibt, viel, viel kleiner zu repräsentieren.
Er wird also nicht mehr eins zu eins dargestellt,
sondern er hat eine symbolische Repräsentation davon,
aber die ist ausreichend, um darauf zu rechnen.
Wenn ich das benutze, muss mich das nicht interessieren,
dann ist das nur eine clevere Datenstruktur.
Und wenn ich das benutze, dann benutze ich das wie
ein normaler Programmierer. Ich tippe da so Quellcode ein.
Also ich tippe so eine Datei,
drei Mutext 2,
also ein Mutial Exclusion für
In die Datei SMV und sagt, okay, das ist ein Modul.
Und jetzt wird da runter programmiert. Die Hauptroutine hat Variablen.
Ich habe die Zustandsmenge S.0. Nicht kritisch, trying critical.
Und er ist eins das Gleiche. Ich habe noch eine
globale Variable Turn. Und ich habe zwei Prozesse. Prozess,
Nullenprozess eins. Und die sollen im Wesentlichen so etwas,
was wir schon kennen, darstellen. Das heißt,
vom nicht-kritischen Abschnitt will ich gerne in den kritischen Abschnitt und
unter gewissen Bedingungen, die ja in den Kanten dranstehen,
wechselt der Prozess in den kritischen Abschnitt,
in Miroten
Bleibt dort eine Weile drin und verlässt ihn dann wieder und geht ihn
hoffentlich dann in den grünen Bereich wieder in den Richtkritischen Abschnitt.
So, und da gibt es dann eben die Turn-Variable,
die am Anfang auf null initialisiert wird.
Und die beiden Prozesse, das haben wir uns mal klargemacht,
das ist eine Möglichkeit, wechselseitigen Ausschluss herzustellen. Ja,
sobald ich, nehmen wir mal den linken Prozess,
im nichtkritischen Abschnitt bin, will ich irgendwann, es gibt zwei Möglichkeiten,
der andere will gar nicht in den nicht kritischen Abschnitt,
non-critical is true.
Ja, freie Fahrt für freie Bürger
Der andere Prozess versucht auch gerade reinzukommen.
Ja, aber die Turn-Variable sagt, ich sei dran.
Dann darf ich auch in den kritischen Abschnitt. So,
und das ist die Sicht vom einen, die Sicht vom anderen läuft komplementär,
dann bleibt er eine gewisse Zeit im Abschnitt. Ja,
da müsste man jetzt irgendwie auch mit Fairness wieder dafür sorgen,
dass ich den roten Zustand Critical Zero nicht unendlich lange durchlaufe,
sondern irgendwann mal feststelle, aha, ich kann das auch wieder verlassen.
Und da gibt es dann noch eine Anweisung,
wenn die Turn-Variable gerade null ist,
dann setze ich sie jetzt auf eins,
um zu sagen,
der andere ist dran
So, wie wird das jetzt ausgedrückt? Bislang haben wir
nur eine Initialisierung. Das nächste, was wir jetzt machen,
ist, wir definieren für die beiden Prozesse,
also pri null, das ist ein Prozess,
mit S0 ist 1 Turn und dem Parameter Zero.
Und jetzt muss ich definieren, wie die Nachfolgezustände sich ergeben,
also die kannten. In dieser Programmiersprache sagt man dann,
okay, für jeden Prozess gibt es jetzt ein Modul und ich sage,
am Anfang ist der Zustand des Prozess null,
also State Zero
ist non-critical
Also ich starte in dem oberen grünen Zustatt.
Und jetzt mache ich einfach eine große Tabelle,
die mir sagt, okay, was ist der nächste Zustand?
Next von State Zero ist. Und dann kommt eine Fallunterscheidung
. Also tabellarisch mache ich jetzt eine Überprüfung,
wenn ich sage, naja, da gibt es mehrere Möglichkeiten.
Wenn der aktuelle Zustand nicht kritisch ist,
dann bleibe ich da entweder drin, das ist die Schleife.
Oder ich gehe in den Zustand trying
Mach also die Kante nach unten mit. Wenn mein Zustand Trying ist,
dass die nächste Zeile und der Zustand des anderen,
also State One ist non-critical,
dann darf ich in den Zustand Critical übergehen.
Das ist also die linke Kante. Da steht ja
non-critical One ist gleich True. Das ist genau die zweite
Bedingung. Also das, was in der Kante steht,
packe ich hier auch noch als Bedingung hinter.
Die dritte Fallunterscheidung sagt, okay, wenn ich versuche gerade reinzukommen,
also State Zero ist Trying, Der andere Prozess versucht auch,
State One is drying, and turn equits, turn zero.
Also der Ausdruck, der an der rechten Kante steht,
wenn das der Fall ist, gehe ich auch in den Zustand Critical über.
Und die vierte Zeile sagt, wenn ich im Zustand Critical bin,
dann bleibe ich da drin oder gehe wieder zurück in den Zustand non-critical.
Und naja, ansonsten, wenn etwas anderes gilt,
dann bin ich im Zustand null.
Gut, kommt nicht vor, aber so ein Catch All
an dieser Stelle
wird eingefügt
Und dabei sind eben zwei Sachen wichtig. State Zero ist der eine Prozess,
Date Mann, der andere. Was jetzt noch fehlt,
ist, bislang habe ich die Variable State Zero verwaltet,
was jetzt noch verwalten muss, ist die Variable Turn.
Es gibt auch ein Next, den Zustandsübergang für Turn.
Und da ist die Definition Next von Turn ist, naja,
wenn Turn jetzt Turn Zero ist, also Prozess Null ist dran,
und der Prozess Null ist im Zustand kritisch,
also State Zero ist Critical, dann wird die Variable Turn komplementiert,
also die Negation von Turn mitgewählt.
Und ansonsten ist der Nachfolgewert von Turn der alte Wert.
Turn. Das sind also die Dinge, die er machen kann. So,
und dann gibt es noch eine globale Fairness-Eigenschaft, Running,
was so viel heißt,
dass sie nicht unendlich oft einen möglichen Weg vernachlässigt,
also insbesondere im kritischen Abschnitt Critical Zero,
habe ich unendlich oft die Auswahl.
Ja, und dann heißt das, ich komme da
auch unendlich oft raus. Es ist nicht so,
dass dieser Prozess unendlich lange Im Zustand Critical bleiben könnte.
Das schließe ich aus. Sowas kann ich jetzt machen.
Weitere Fairness-Eigenschaften. Was mich jetzt interessiert, sind Spezifikationsmöglichkeiten,
also Formeln, die ich gerne nachweisen möchte.
Bislang habe ich programmiert, jetzt schreibe ich einen gleichen Werkzeug,
die Spezifikationen rein. Eines Speck. Und da steht AG,
ja, das kennen wir auf allen Faden,
gilt immer, dass es nicht der Fall ist,
dass der erste Prozess kritisch ist und der zweite auch,
also er ist Zero Critical and as one Critical
Weil das wäre schon mal gut, dass wir gewissermaßen die
Safety-Eigenschaft des Prozesses, also die Muty Exclusion wird erfüllt.
Nie sind beide gleichzeitig in ihrem kritischen Abschnitt. Das hätte
ich gerne. So, was hätte ich noch gerne?
Ich hätte vielleicht gerne so eine Eigenschaft, wie immer gilt,
AG. Wenn der Prozess null versucht, dann gilt auch
immer in der Zukunft, dass er irgendwann mal drankommt.
Also vom Zustand treiben komme ich tatsächlich auch in den Zustand Critical.
Wenn ich möchte, darf ich irgendwann. Das ist die Liveness-Eigenschaft
für den ersten Prozess mit der Index Nummer 0 und symmetrischerweise
gibt es das Ganze dann auch für den zweiten Prozess,
wenn der Prozess im State One das Ganze versucht,
dann darf er irgendwann auch mal in den kritischen Abschnitt.
Das sind also wünschenswerte Eigenschaften, die man nachweisen möchte.
Und vielleicht noch ein paar mehr. So und irgendwie sinngemäß
drückt man jetzt auf den Go-Button und dann hat man so eine Sitzung,
das Ganze ist dann mehr oder weniger Shell orientiert,
sei denn man hat noch irgendwie was drum rumgekapselt und dann antwortet die Maschine,
nachdem es das eingelesen hat und ein bisschen gerechnet hat,
Specification, AG, also immer gilt.
Es ist nicht der Fall, dass beide im kritischen Abschnitt sind,
ist true. Diese Eigenschaft erfüllt mein System. Er hat
also den Zustandsraum aufgebaut und diese Formel überprüft und stellt fest,
ja, sie gilt. Das ist schon mal nett.
Also da können wir schon mal ganz beruhigt sein. Das nächste,
was er uns denn sagt, ist, die Spezifikation,
dass immer gilt, wenn der erste Prozess möchte,
dass er dann irgendwann auch mal in den kritischen Abschnitt eintritt, ist auch wahr.
So, sinngemäß dann auch das andere, ist klar,
weil die absolut symmetrisch sind, die beiden Prozesse,
wird auch das andere gelten. Und jetzt sagt er,
mal eine komplexere Formel AG,
wenn ich einen kritischen Abschnitt bin, dann gilt immer,
dass kritisch gilt, solange es nicht der Fall ist,
dass ich kritisch bin und es gilt immer,
dass es null nicht kritisch ist, solange es eins kritisch ist.
Das ist eine Eigenschaft, die falsch ist. Gut,
warum sich das auch jemand hingeschrieben hat, immer,
keine Ahnung, auf jeden Fall wird er
vom System belehrt
Ja, das ist ein Gegenbeispiel. Also hier ist ein Trace,
das ist ein CTL-Counter-Example. Und da geht er vom Zustand 1-1,
Mutter 0 ist, beide sind im Zustand, non-critical. Ja,
dann wird der erste Prozess mit der Index Nummer 0 selektiert,
der geht in den Zustand trying, also links rum,
dann wird er wiedergewählt, geht in den Abschnitt kritisch,
dann wird er wiedergewählt, turn, aha,
dann geht er in den Zustand non-critical,
dann wird er wiedergewählt und so weiter.
Man sieht, also er bleibt immer beim einen Prozess verharrt
Also so kann man mit einem System arbeiten,
das kann man jetzt vielleicht noch ein bisschen aufpeppen in der Benutzbarkeit,
aber prinzipiell ist das so ziemlich das,
was man von einem solchen System erwartet.
Eine Programmiersprache, es hat den großen Vorteil,
die Programmiersprache, damit kann das Tool dann effizient umgehen.
Wenn ich sagen würde, ich nehme ein beliebiges Java-Programm,
dann müsste ich das erst mal in eine Krypto-Struktur umwandeln.
Da müsste ich also über die externe Semantik von Java gehen.
Wenn das Tool selbst die Programmiersprache vorgibt,
dann kann es intern auch gleich festlegen, wie das System,
die Krypto-Struktur dahinter aussieht und kann die effizient kodieren und so weiter und so fort.
Und zweitens, es ist typischerweise so,
dass diese Systeme nicht irgendeine Programmiersprache unterstützen,
sondern da ist meistens irgendein Anwendungsszenario im Hinterkopf.
Und wenn man sich diese Spezifikationsprogrammiersprache anschaut, dann ist die
ganz stark angelehnt an Hardware-Beschreibungssprachen. Also wenn man heutzutage einen Chip entwirft,
dann schwingt man ja keinen Lötkolben oder belichtet da irgendwas,
sondern das programmiert man genauso runter in der Programmiersprache,
die irgendwie so eine Mischung aus C-A da und noch so paar Sachen sind.
Also da wird das
einfach runterprogrammiert
Nur, dass die Variablen dann oftmals die Eigenschaft haben,
nur ein Bit zu sein oder ein festgelegtes Bit oder Flip-Flops
beschrieben werden, all so etwas.
Also eine digitale Hardware-Beschreibungssprache. Und da steckt dann ein
ziemlich mächtiger und deswegen auch ziemlich teurer Compiler dahinter,
deutlich mehrstelligen Bereich, mit dem dann irgendwas produziert wird,
was man dann in Hardware-Firmen geben kann.
Also die Fabrik kriegt dann eine riesen Datei und macht mir
daraus einen Chip. Das wird dabei kompiliert. Und diese
Programmiersprache ist ungefähr so ähnlich an das angelehnt,
also das Ganze hat hier den Sinn und Zweck,
Hardware zu verifizieren
Da, wo Morning Checking auch sehr erfolgreich ist,
weil bei Hardware ganz klar ist, dass ich einen endlichen Zustandsraum habe.
Endlich viele Bits ergeben endlich viele Zustände. Und meistens noch relativ überschaubar,
wobei relativ natürlich beim ausgewachsenen Pentium-Prozess,
da sind da schon viele Zustände, die ich haben kann,
aber man kann da tatsächlich sehr weit gehen,
also 10.50 Uhr, 10.60 Uhr Zustände,
das wird praktisch gerade gemacht.
Gut, das jetzt erstmal zum Model-Checking auf diesen Krypto-Strukturen,
was wir jetzt machen wollen, Petri Netze.
Neues Kapitel. Und Petri Netze sind jetzt irgendwie
der nächste konsequente Schritt. Denn wir haben schon festgestellt,
wir benutzen gerade ein System interagierender Prozesse.
Bei unserem wechselseitigen Ausschluss hatten wir
zwei Prozesse
Die auf gemeinsamen Variablen operieren. Aber es ist jetzt nicht mehr so,
dass ich sagen würde, das ist ein System,
das Sequenziel operiert, sondern es ist eine Überlappung, Zweier kommunizierender Systeme.
Nun beschreibe ich das aber mit einer Kripke-Struktur, also sowas ähnlich
wie im endlichen Automaten. Und da kann man natürlich sagen,
das ist vielleicht ein bisschen merkwürdig, dass sich ein Beschreibungsmittel nehme,
ein Automatenmodell eigentlich, das für sequenziell operierende Prozesse gedacht ist.
Und das benutze ich jetzt, um damit interagierende Prozesse zu beschreiben.
Also ein verteiltes System, Parallelsystem irgend sowas in der Art.
Da kann man natürlich sagen, naja, irgendwie klappt das schon,
indem ich sage mal der eine, mal der andere,
immer so abwechseln. Aber das ist irgendwie nicht das Modell,
bei dem man sagen würde, das ist das erste,
was man so richtig gerne hätte, wenn man ein interagierendes System beschreibt.
Und deswegen kommt man dann bei verschiedenen anderen Formalismen an. Wir gucken uns zwei Formalismen an,
die sich so ein bisschen primär das Ziel gesetzt haben,
zu sagen, wir wollen weg von dem Sequenziellen,
sondern wir wollen ein Modell haben,
das ich tatsächlich schon mal ganz am Anfang Gedanken darüber mache,
dass es Interaktion gibt zwischen verschiedenen Systemkomponenten
Also so wie es immer ist,
ob ich nun ein Rechner-Netzwerk betreibe oder ein Computership oder ein Parallelrechner,
immer interagierender verschiedene Prozesse miteinander.
Ja, ein Petri-Netz. Was sind jetzt zu allgemeine Eigenschaften
von Petri-Netzen? Während der E-Vorlesung war,
hat er schon mal irgendwie bei mir was über Petrinnetze gehört.
Zumindest weiß er schon, dass es die Dinge gibt und
dass es da rund und eckige Sachen gibt,
so wie da links unten dargestellt.
Naja, und was das nett an Petra-Netzen ist,
man kann sie hinmalen,
also es gibt eine grafische Darstellung
Das ist ja schon mal ein guter Ansatzpunkt,
so wie bei Transitionssystemen auch. Die konnte ich auch hinmalen
. Man kann es auch mathematisch darstellen. Klar,
irgendwie will ich damit ja arbeiten. Das Nette ist,
es gibt formal abgesicherte Algorithmen, um Patrinnetze zu analysieren.
Das heißt, man kann da auch,
wenn man Patrinnetz hat, tatsächlich was mit tun.
Es gibt also Werkzeuge, die damit mir irgendwelche Fragen beantworten können.
Also insbesondere Model-Checking-Werkzeuge. Es gibt Techniken zur Abstraktion für
hierarchische Strukturen, also verschachtelte Systeme,
prozedurale Aspekte,
das gibt es
Es ist das Standardwerkzeug der Theorie, um Nebenläufigkeit zu beschreiben.
Also im Englischen Cancurrency,
der Formalismus, mit dem ich wirklich direkt beschreiben kann,
dass Aktionen keinerlei kausale Beziehung haben, ohne irgendwelche Krücken,
sondern die Mathematik ist da wirklich gnadenlos direkt.
Aber man kann erwarten, dass es vielleicht ein bisschen Aufwand ist.
Also die Mathematik, die man braucht für Nebenläufigkeit,
um so einen etwas auszudrücken,
werden wir feststellen,
ist ein Tick erstmal
eine Erweiterung
Konstrukt heißt normalerweise, man muss da irgendwas reinstecken.
Irgendwie ist das anders als im Sequenziellen. Und was ist da
anders? Naja, im Sequenziellen ist die Welt heile.
Da weiß sie eigentlich immer, aktueller Zustand, Folgezustand.
Wegen dieser Randbedingung, die gilt bei nebenläufigen Systemen nicht mehr
da, sage ich aktueller Zustand.
Und den Folgezustand gibt es da gar nicht.
Aber dieses Konstrukt des eindeutig bestimmten Folgezustands nicht gibt,
dann kann man sich schon denken,
wo ich mich darauf nicht mehr verlassen kann,
muss die Theorie da irgendwie
ein bisschen feinfühliger mit umgehen
Das Nächste ist, es gibt Werkzeuge,
also man kann das nicht nur irgendwie,
was weiß ich, mit Call Door hinpinseln irgendwie,
sondern es gibt tatsächlich auf Petrinetz spezialisierte Tools,
mit denen man das malen kann.
Also die Tools, die wissen auch, was ein Petrinetz ist.
Und noch besser, man kann sie benutzen, um damit
einen Netzablauf zu simulieren. Das heißt, ich gebe ein Netz,
schmeiße da ein paar Marken drauf und lasse da mal laufen.
Sieht ganz hübsch aus, vielleicht ist es auch tatsächlich ein Prototyp eines Softwaresystems.
Zum Beispiel ein Tool ist das aus dem Hause C,
also aus meinem Stall. Das heißt, bei uns werdet ihr
nochmal vielleicht eine Übungsaufgabe machen, wo ihr unser Tour-Renew benutzt.
Frei verfügbar auf Java-basiert, dann werdet ihr mal genötigt,
dass unter dieser Web-Adresse auch runterzuladen.
Und das Nette ist, dass es so generell universal ist,
dass es eigentlich die eierlegende Wollmichsau ist.
Naja, und wo man so universal ist,
gibt es dann auch immer Erweiterungen, die das ein bisschen in Spezialecken treiben.
Es gibt dann Petrinetze, die nicht mehr betrachten wollen,
so ein Detail, das sind Zeitnetze,
da geht man davon aus, dass das Schalten zu gewissen Zeitpunkten stattfindet.
Man kann angehen, Schalten dauert mindestens fünf Sekunden, Schalten
findet frühestens nach drei Sekunden statt, spätestens nach zehn Sekunden.
Oder Stochhastische Petrinetze, da sagt man nicht mehr,
findet dann und dann statt, sondern man sagt,
die Verteilung der Schaltzeiten ist vielleicht eine Exponentialverteilung.
Also meistens zwei Sekunden kann aber auch schneller gehen.
Manchmal dauert es auch deutlich länger. Und dann interessiert man
sich über die Verteilung des gesamten Verhaltens
Ja, wer schon viel storastig gemacht hat und Warteschlanktheorie inhaliert hat,
was bei euch, glaube ich,
noch nicht der Fall war, kommt noch in Stochastik.
Dann habt ihr ja die Möglichkeit, solche Markhoff-Ketten zu studieren,
die die Grundlage sind. High-Level gibt es, High-Level heißt,
dass man nicht nur diese schwarzen Kuller da durchscheucht,
sondern auch Datentypen wie Strings, Intature und sowas.
Und objektorientiert heißt, dass man Klassenkonzept drauf macht und,
und, und, und, und. So,
das ist die Theorie, der Petrin jetzt historisch,
was es da alles gibt,
wo kommt der Begriff Petrin
jetzt eigentlich her
Hat jetzt nichts damit zu tun, dass Petri irgendwie ein
Fischer gewesen wäre und der mit seinem Netz gefischt hat,
sondern Karl Adam Petri mittlerweile verstorben.
Ehrenprofessor, der hat sich diesen Formalismus mal ausgedacht.
Hier sieht man ihn in seiner typischen Pose.
Er hat was mit Helmut Schmidt gemeinsam, er rauchte ständig,
aber nicht Zigarette, sondern der Quarze Zigarillo,
dass man ihn kaum sehen konnte.
Also wäre ich Petri, würde ich mich nicht sehen im Moment.
Er rauchte auch im Konrad Zuse-Hörseil. Also das ist das
, glaube ich, wo man ihn gerade sieht.
Also in dem Hörseil, in dem Rauchen verboten ist
Und keiner hat was gesagt. Und wenn man ein bisschen
so guckt und auf Skolapedia findet man zum Beispiel einen Artikel und im Hintergrund
sieht man übrigens noch zu schön in Schreibmaschine aus den 60er Jahren die Dissertation.
Da oben steht der Titel Kommunikation mit Automaten.
Das ist die Dissertation Petrinetzen. Und Petri selbst hat die Darstellung
der Petrinetze als 13-jähriger Schüler mal erfunden für sich selbst.
So geht die Anekdote um chemische Prozesse zu beschreiben.
Das sieht man hier. Auf der linken Seite kommt ein
bisschen Kohlenstoff rein, zweimal Sauerstoff,
es macht einmal Peng und ich habe
Denn noch ein bisschen was anderes, ja, und dann kriege ich verschiedene Produkte.
Und da gilten so gewisse Haltungen. Bei chemischen Prozessen ist
das ja so schön, da geht nichts verloren.
Da wird nur umgewandelt. Das heißt,
man kann wunderbar solche Syntheseketten durch Petrinne zu beschreiben,
was mittlerweile auch in den 90er Jahren, also,
naja, so, sagen wir mal so, 50,
60 Jahre später, wieder aufgegriffen wird.
Also Biological Passways sind These, Vorgänge in Zellen,
das modelliert man jetzt mittlerweile mit Petrinnetzen deswegen, ist naheliegend.
Und wenn ihr in seine Dissertation guckt,
da war ja schon ein bisschen älter als 13,
Wir versuchen nach solchen Grafiken, wer die,
der keine einzige finden.
Das hat zwei Gründe. Zum einen macht mal solche
runden Sachen mit einer Schreibmaschine. Das ist das eine.
Gut, das hätte man früher handschriftlich eingemalt.
Und zwar in jedes Exemplar. Das zweite Problem ist,
Informatik gab es damals noch nicht, Karl-Heinz Petrett in der Mathematik.
Man sieht an der Fakultät für Mathematik und Physik promoviert.
Und er hatte schlichtweg Angst, dass wenn das grafisch malt,
dass das irgendwie nicht ernsthaft genug rüberkommt.
In der ganzen Arbeit gibt es keine Grafik.
Das funktioniert komplett formal allgebrage
Geht auch. Wir machen es jetzt doch ein bisschen mit Grafik.
Das ist erleichtert, die Kommunikation. Kann man sich fragen
, wo kommt Petrinetze her? Dann kann man sagen,
sie sind eigentlich folgerichtig, weiter gedacht, wenn man irgendwie drei Ideen hat.
Eine von den drei Folgen, in denen könnte es gewesen sein.
Entweder sagt man, wir wollen Programmcode entwickeln,
also so Ideen aus der Ecke vom Compilerbau, fragen uns,
welche Statements sind nebenläufig, wie kann ich die umarrangieren,
wie kann ich die Pipelines in meiner in meinem Prozessor die verschiedenen Prozesserkerne,
wie kann ich das optimal befüllen?
Aus solchen Nebenläufigkeitserwägungen muss ich jetzt eine Analyse machen,
wo ist dann die Nebenläufigkeit? Das muss man irgendwie darstellen.
Gucken wir uns gleich mal an. Oder man stellt sich vor,
ich habe nicht nur einen endlichen Automaten, also ein System,
sondern ich habe ganz viele davon und die kommunizieren miteinander,
beispielsweise nehme ich sage,
der eine und der andere machen jetzt gemeinsam synchrone Aktionen.
Also Brandivou-Synchronisation, Handshaking,
gemeinsam kommunizieren die
Also gewissermaßen endliche Automaten in der Formate gibt es schon ewig gefühlt.
Also bestimmt schon 30 Jahre für die Informatik, also ewig.
Und jetzt kann man irgendwie auf den Gedanken gekommen,
ich nehme zwei davon und sage, die müssen im Prinzip so laufen,
aber sie machen gewisse Dinge gemeinsam und synchronisieren sich.
Ja, oder es gibt abstrakt,
so wie man das überlegen kann, sich von diesen chemischen Reaktionsprozessen,
kann man zu Petrinetzen kommen, von einfachen zu höheren Netzen.
So, das wären drei Ansätze,
wie wir das einführen könnten hier,
wieder dieser drei Ansätze,
wäre so
ein didaktischer Staat
Ja, wir machen, wir können uns nicht entscheiden, wir machen alle drei.
Gut, in der Reihenfolge. Wenn ich das Ausgangspunkt habe,
ein Programm, also einen gewissen Programmcode,
also nichts wirklich Tiefsinniges, ich sage, XS 3,
YS 4 und Z ist X plus Y. Ganz einfach.
Also drei Anweisungen, davor Start und Stopp. Ja,
was mache ich als erstes? Male ich mir das mal
so hin? Dann sagt drei Anweisungen in der Reihenfolge,
Start und Stopp, so extra markiert.
Also ein runder Bubble zum Starten und zum Ende und dazwischen
so die drei Anweisungen in grün
Das ist ja schon fast ein Petri-Nelz, so wie wir es kennen.
Ich mache einfach nochmal zwei Cola dazwischen. Ja,
dann ist es syntaktisch, auch in der Repräsentation etwas,
wo was Rundes und was Eckiges sich abwechselt.
Und das ist jetzt nicht nur eine grafische Spielerei,
sondern jetzt kann man sich überlegen, was bedeutet denn dieser Programmablauf?
Dieser Programmablauf, sequenzielle Programmierung bedeutet, ich starte.
Ich bearbeite die erste Zeile, die zweite,
die dritte,
ich stoppe
Ja, und unser intuitives Verständnis von Petri-Netzen sagt uns,
ich starte, mache die erste Anweisung, mache die zweite Anweisung,
die dritte Anweisung und bin dann fertig.
Ja, das heißt,
wenn ich so die Idee habe mit den Spielmarken,
das durchzulaufen, dann ist das Ablaufverhalten schon mal gewährleistet.
Da habe ich eine 1-zu-1-Korrespondenz, also die Darstellung ist ähnlich,
das Ablaufverhalten passt. Na gut, wäre noch nicht
so viel gewonnen. Was mache ich jetzt?
Mir jetzt
Gehe ich davon aus, ich habe wieder diese Darstellung,
aber das ist ja nicht die einzig mögliche Darstellung.
Das ist die Darstellung, die ich habe,
wenn ich gewissermaßen den Quelltext abschreibe in einem Petrinetz,
einfach nur abschreiben. Wenn man sich jetzt anguckt,
ob ich erst die Zeile mit der Linie Nummer 10
und dann die Zeile 20 ausführe oder umgekehrt,
das macht gar keinen Unterschied.
Denn ob ich X-Sinn werde, drei zuweise und ich werde
vier oder andersrum, da ist keine logische Beziehung zwischen den
beiden.
Also hier könnten Compiler ansetzen
Und damit der Compiler das weiß, müsste er eigentlich so eine Darstellung finden.
So eine Darstellung wie auf der linken Seite sagt uns,
aha, ich habe eigentlich zwei unabhängige Startpunkte,
kann unabhängig davon die Zuweisung 10 und 20,
die X und Y was zuweisen, ausführen.
Und dann erst in Z die Summe der beiden Berechnung.
Wenn ich das so mache,
dann gebe ich gewissermaßen in Vorformen des Compilings,
lege ich mich noch nicht fest.
Dann sage ich,
irgendwas ist es nicht wichtig
Ja. Liebe nachfolgenden Compiler-Schritte, sucht euch noch was aus,
was effizient ist. Und dann kann es eben sein,
dass die eine Reihenfolge effizient ist oder die andere.
Und das passt hier genau, also als Peter-Netz betrachtet,
sind beide Transitionen aktiviert,
sowohl die Transition mit X und als auch die Transition mit Y.
Ich kann mir jetzt also eine der beiden Transitionen aussuchen und eine schalten,
zum Beispiel die Linke.
Ja, und dann kann nur eine Sache passieren,
denn die Transition 10 kann nicht mehr schalten,
die Transition 30
noch nicht
Transition 20, aber weiterhin, also lassen wir die doch
mal schalten. Und jetzt sind da beide Berechnungsergebnisse da,
sowohl X und Y haben ihre richtigen Werte gerade bekommen,
sodass sich die Transition 30 jetzt schalten kann.
Ja, ist erstmal vom Ablaufverhalten, ist mal das das Beispiel,
das nach außen hin genau gleich aussieht,
nämlich erst X-Zuweisung, dann die Y-Zuweisung und dann Z.
Das ist auch in diesem sequenziellen Strang auf der rechten Seite
so gewesen. Setup auch andersrum sein können.
Wenn ich die Wahl habe, welche Darstellung Ich nehme,
dann möchte ich aber immer die linke Netzdarstellung haben.
Denn in der linken Netzdarstellung behaupte ich, keine Abhängigkeiten,
die gar nicht da sind. Die rechte Netzdarstellung sagt,
ich muss erst X den Wert 3 zu weisen,
bevor es sinnvoll ist, Y den Wert zu 4 zuzuweisen.
Das stimmt aber gar nicht. Das heißt, das rechte
Netz behauptet irgendwie eine Abhängigkeit, die gar nicht da ist.
Und das linke Netz ist da ein bisschen ehrlicher,
das sagt zwischen dem Zuweisen auf X und dem Zuweisen auf Y
gibt es
keinerlei Beziehung
In dem Sinne muss ich mich da auch nicht drum kümmern,
sondern lass es erst mal unterspezifiziert, in welcher Reihenfolge es stattfindet.
Dieses Unterspezifizieren ist also genau das, was wir haben wollen.
Wir wollen mich nicht mehr sagen, als wirklich da ist.
Und so gesehen, wenn ich nur sequenzielle Abläufe beschreiben kann,
bin ich manchmal gezwungen, mehr zu spezifizieren, als da ist.
Der rechte Ablauf behauptet mich mehr als in Wirklichkeit da ist.
Gut, so an dieser Stelle könnten wir sagen,
so jetzt bitte die formalen Definitionen.
Aber ich hatte ja gesagt,
wir nehmen die anderen beiden Motivationen auch noch hinzu
Also nehmen wir uns mal endliche Automaten wieder vor.
So ein endlicher Automat ist ja irgendwie ein Zustandsverändernde Maschine.
Also so ein endlicher Automat ist vielleicht etwas ganz einfach.
Läuft hier so im Kreis herum. Ganz einfache Automat.
Jetzt stelle ich mir vor, ich habe den zweiten Automaten,
der sieht jetzt uns nicht zu kompliziert zu machen,
genauso wieder aus.
Also zwei Automaten, die würden jetzt erstmal völlig unabhängig laufen.
Da sage ich, okay, unabhängig laufende Automaten,
das ist völlig langweilig.
Wenn die keine Verbindung haben,
was soll das
Also richtig spannend wird das erst, wenn die beiden miteinander kommunizieren.
Also zum Beispiel die beiden Aktionen finden jetzt gemeinsam statt.
Da einigen sich darauf, die machen das jetzt zum gleichen Zeitpunkt.
Gemeinsam. Und was kann man jetzt machen? Und
da nicht irgendwie so einen roten Pfeil dazwischen zu malen,
schieben wir das einfach grafisch zusammen, kriegen so eine Doppelbox.
Naja, jetzt kriegen wir einen kommunizierenden Automaten und diese Doppelbox,
die stellen wir uns jetzt vor, einfach wie eine Transition.
Und wenn ich da gucke, was die so tut,
Kann ich das wie im Netz schalten lassen?
Ja, er ist der eine. Dann passiert aber noch nichts.
Das liegt daran, dass für diese gemeinsame Aktion bräuchte ich
rechts unten noch eine Marke, die ist aber noch nicht da.
Also muss ich erst mal dafür sorgen,
dass diese Marke dahin kommt, wo ich sie gerne hätte.
Und dann kann diese Transition schalten. Und wenn ich
das gemacht habe, dann ist es ziemlich klar,
dass ich aus endlichen Automaten mir ein Petrinetz zusammenbasteln kann
Ja, und wenn ich schon so weit gekommen bin,
dann komme ich vielleicht auf die Idee,
nicht einfach nur endliche Automaten zusammenzupacken, sondern da einfach wild weiterzumalen.
Also zum Beispiel zu sagen, ja, das ist jetzt
so ein großer Block. Und jetzt breche ich diese Vorstellung auf,
dass einfach diese Marken da immer noch klar unterscheidbar sind,
dass ich sagen kann,
also die Marke von dem rechten Automaten geht auch wieder rechts rum und die vom linken Links rum.
Denn wenn ich jetzt schalte, was passiert, ja klar,
irgendwie die eine Marke links oben geht nach links unten.
Und die Marke rechts unten geht nach rechts oben
Aber jetzt kommt noch eine neue Marke hinzu.
So und das passt nicht mehr zu dieser Vorstellung.
Also mache ich da tatsächlich eine Erweiterung, eine sehr naheliegende Erweiterung.
Plötzlich ist da eine neue Marke da. Ich stelle mir also nicht nur vor,
dass ich Marken nehme und in der Gegend umherschiebe und vielleicht auch das mal synchronisiert tue,
sondern ich stelle mir auch vor,
dass bei diesen Aktionen neue Ressourcen generiert werden können oder neue oder welche auch konsumiert werden können.
Und es stellt sich jetzt die Frage,
ob es wirklich sinnvoll ist, davon auszugehen,
dass diese neue Marke auf dem linken Automaten noch identisch ist mit der Marke,
die vorher links oben war.
Naja, das kann man so hineininterpretieren. Ja,
oder man die andere Marke, ob das die Alte ist,
was ist denn die neue Marke?
Oder ist das vielleicht irgendwie eine von den beiden? So,
und von daher, wenn das hier so weiter schaltet,
ist das irgendwie unabhängig. Von daher wird da eher die Sichtweise bevorzugt,
dass man sagt, nee, die alten Marken werden konsumiert,
sind dann weg.
Und es werden komplett neue generiert. Und wenn man möchte,
denn es ist manchmal sinnvoll,
die Alten und die Neuen
irgendwie gedanklich zu verbinden
Das klappt aber eigentlich immer nur dann ganz gut,
wenn genauso viele Marken reingehen, wie Marken wieder rausgehen.
Wenn das nicht der Fall ist, also ein Ungleichgewicht,
dann muss ich mir das irgendwie anders vorstellen. So,
es gibt jetzt elementare Grundprinzipien, die bei Petra Netzen wichtig sind und
die man gut benutzen kann, um Dinge zu studieren.
Und das wichtigste Konzept ist eigentlich Lokalität und damit direkt verbunden das Konzept der Nebenläufigkeit.
Bei Petra Netzen gibt es nämlich verschiedene Orte der Aktivität,
verschiedene unabhängige Stellen, an denen etwas geschehen kann.
Und wenn es verschiedene, unabhängige Ecken des Netzes gibt,
dann passiert da offensichtlich was nebenläufig. So, das ist
das große Inhaltliche, was mit Petrinetzen zum ersten Mal ausdrückbar wird.
Bislang haben wir da keine vernünftige Darstellungstechnik.
Das geht mit Automaten nicht. Punkt 3 ist ganz nett,
ich kann es auch grafisch darstellen, formal, ja,
ist auch wichtig und damit Dinge zu tun,
also insbesondere Theorie mit zu beweisen,
aber dass es grafisch ist,
ist auch ganz nett,
um es zu benutzen
Und dass es nicht nur Petra-Netze gibt,
sondern dass die Grundideen sich von den ganz Einfachen bis zu den komplexesten Peter-Nets-Formalismen,
die man sich so ausdenken kann,
dass da die Grundprinzipien immer weitergereicht werden,
das macht diesen Formalismus eben auch so interessant.
Und wir versuchen uns jetzt diese Grundprinzipien erstmal an einem einfachen Beispiel klarzumachen,
also eins, das auch im Skript durchgängig verwendet,
wird das sogenannte Rennwagenbeispiel.
Und so ein Rennen soll jetzt vereinfacht mal ein paar Bedingungen haben,
also ein paar Zustände, die in einem solchen Rennen
gelten können.
Und es finden
ein paar Aktionen statt
Also die Bedingungen sind jetzt, ich habe einen Wagen A und einen Wagen
B gibt es auch noch. Und der Wagen A macht
sich startklar. Und vielleicht hat er auch einen Zustand,
er ist Statler und wartet jetzt für die Startfreigaben.
Oder das Auto A läuft, kriegt einen Freigabesignal, ein Startsignal.
Es gibt auch noch einen Starter, der auch noch
irgendwelche Dinge macht. Also dieser ganze Startprozess wird modelliert,
aus der Sicht des Wagen A. Und ab P8, P9, P10
Bis P12 ist das Ganze nochmal aus der Sicht des Wagen-B formuliert.
Also zwei Rennwagen und einer mit so einer Flagge,
der da irgendwie das Staatssignal geben darf. Und die Aktionen,
die hier möglich sein sollen, sind, dass das Auto A,
das Fertigsignal bekommt und dass jetzt geht's los,
also das Rennen wird gestartet.
Der Staat, da gibt Biden ein Signal und das Gleiche nochmal,
Ready Sign, Start Race Aktion für AutoB. So,
wie kann ich jetzt das darstellen?
Ich kann es darstellen, indem ich sage, okay,
ich male mal,
das kenne ich schon,
ein Transitionssystem
Ein Transitionssystem, da kann ich Transitionsübergänge malen. Also zum Beispiel kann ich sagen,
wenn ich so einen komplexen Zustand habe, ich habe ja die Zustände,
P-1 bis P12 und die können wahr oder falsch sein.
Und jetzt habe ich die Aktion 1 und die soll dann gelten,
wenn der Wagen A sich für den Staat vorbereitet.
Der Starter für das Signal war, auf das Signal wartet
und der Wagen B auch sich vorbereitet auf den Staat.
Wenn diese drei Dinge erfüllt sind,
also beide Autos vorbereitet und der Staat,
da wartet gerade auf die Freigabe,
dann kann eine Aktion T1 stattfinden, die jetzt irgendwie Dinge verändert.
Nämlich hinterher ist das Auto A nicht mehr in dem Zustand,
ist pripat sich, also am Vorbereiten, sondern es wartet auf den Staat.
Nächster Zustand, Auto B genauso. Ja,
und hinterher ist dann die Frage,
wird gut noch ready sein für KA,
das wäre auch noch schön und der Starter bleibt weiter in
dem Zustand.
Das heißt,
wo passiert da was
Ich gucke mir Dinge an und sage,
wo verändert sich da was durch Aktionen?
Das ist jetzt aber lokal. Es gibt also Aktionen,
die völlig irrelevant sind im Zustand, die damit gar nichts zu tun haben.
Das heißt, hier wird zwar ein Zustandsübergang T1,
wie eben dargestellt, global modelliert.
Dieser Zustand wird zu jedem, aber was war ursächlich dafür?
Sieht man damit gar nicht. Da müsste man das so modellieren,
dass man sagt, okay,
wenn sich das Auto A vorbereitet auf den Staat,
dann kann die Aktion T1 stattfinden und die verändert das
nur an einer Stelle
Nämlich lokal für das Auto A, wird jetzt gesagt,
du kannst jetzt den neuen Zustand P2 einnehmen und P4.
Diese beiden Dinge gelten. Das heißt,
eigentlich ist es nicht entscheidend, wie sich der Gesamtzustand ändert,
sondern welche lokalen Veränderungen, welches lokale Delta stattfindet.
So, und diese Lokalität ist bei Petrinnetzen ziemlich einfach darzustellen.
Denn wenn etwas ein lokaler Übergang ist,
diese lokale Information im Transitionssystem, kann ich sie nicht so einfach rausrechnen,
im Petrinnetz dagegen, kann ich das ziemlich gut.
Wenn ich jetzt nämlich den Zustand, ob eine Bedingung P1 war,
ist, durch einen Platz mit einer Marke modelliere,
also P1 vielleicht True, wird durch einen Platz P1 modelliert,
auf dem eine Marke liegt.
Und wenn ich dann schalte T1,
dann lege ich Marken hinterher auf P2 und P4.
Also das ist sowohl vorher als auch hinterher dargestellt.
Diese beiden Zustände sind halt gemahlt.
Das passierte also
Ich sehe also insbesondere die Lokalität. Und das ist jetzt ganz nett,
ich kann die gleiche Aktion sinngemäß auch unten für das zweite Auto betrachten.
Wenn sich das Auto B da unten vorbereitet auf PC,
darf ich. Und jetzt findet die analoge Aktion T4 statt,
dann wird P8 und P11 auf Wahl gesetzt.
Und man sieht, naja, das sind jetzt zwei Aktionen,
die erstmal nichts miteinander zu tun haben,
die sind völlig von der Lokalität unabhängig.
Wenn ich mir die Transitionen angucke,
die haben nichts miteinander zu tun
Völlig disjum. Ganz weit weg voneinander. So, das heißt,
die Unabhängigkeit der Zustandsübergänge oder auch die Nebenläufigkeit sehe ich hier
schon grafisch daran, dass an verschiedenen Stellen was getan wird.
So. Malen wir auch noch gleich das Netz,
aber jetzt erstmal, wir fangen mit den Grundprinzipien an.
Und das Grundprinzip ist, dass wir nicht irgendeinen Grafen haben,
sondern einen dualen Graf.
Ein Grafen mit zwei Elementen. Und das erste Element sind Pelemente,
die nennen wir auch State-Elements,
Plätze oder Stellen im Deutschen
Und die Tee-Elemente, die eckigen, das sind die Transitionselemente,
Transition. Und die beiden Welten sind es jung,
also kein Platz ist eine Transition und umgekehrt. So,
und was das heißt, was aber eine relativ robuste Annahme ist,
ist, dass wir die Welt komplett zerlegen in zwei Dinge.
Wir sagen, die Welt besteht aus Eigenheiten,
aus Entitäten, die entweder passiv sind oder aktiv.
So passive Elemente, das sind die Plätze, die malen wir rund.
Das sind Bedingungen logischer Natur, Betriebsmittel, Wartepools, Kommunikationskanäle so etwas.
Das sind Dinge, die liegen da rum, die machen aber selbst nichts.
Und dann gibt es die aktiven Elemente, die durch Transitionen repräsentiert werden.
Das sind Ereignisse, Aktionen, das Ausführen von Anweisungen,
das Übermitteln von Nachrichten und so weiter und so fort.
Ja, diese Zweiteilung der Welt nehmen wir jetzt vor.
Also es gibt nichts, was sowohl passiv als aktiv wird,
diese Dichotomie haben wir. Und das Zweite,
das haben wir auch schon gesehen, wir sagen,
der große Vorteil der Petinetz ist,
dass wir das Prinzip der Lokalität haben und Lokalität sagt uns,
dass das Verhalten einer Aktion nicht glücklich global beobachtet wird,
sondern ausschließlich durch ihre Lokalität bestimmt ist.
Und die Lokalität bestimmt sich für eine Transition aus der Gesamtheit der Ein- und Ausgangselemente.
Analog auch für einen Platz, aber das betrachten wir meist nicht.
Also auf einem Platz kann ich die Eingangs- und Ausgangstransition bestimmen,
dann weiß ich genau, wer da was machen darf.
Und Hand in Hand mit dem Prinzip der Lokalität
haben wir jetzt das Prinzip der Nebenläufigkeit bei Petrinetzen.
Wir haben jetzt erstmalig die Möglichkeit zu sagen,
was Nebenläufigkeit wirklich ist, Wir sagen nämlich, das sieht man sofort.
Denn Transitionen mit des Jung der Lokalität sind unabhängig.
Sie schalten nebenläufig im Englischen Can Countly. Das ist so
das Grundelement. Deswegen lohnt sich dieser ganze Ansatz,
dass wir zum ersten Mal überhaupt sagen können,
was ist eigentlich nebenläufiges Handeln?
Und das über diesen Weg der Lokalität bei Aktionen.
Lokalität bei Aktionen hatten wir bislang nicht.
Das ist das Neue bei Peter Netz.
Und da machen wir
nächste Woche weiter