Computergestützte Verifikation 23.4.2002 1 Inhalt Kapitel 1: Systeme Kapitel 2: Temporale Logik Simulation Fehlerbeseitigung System Abstraktion Gegenbeispiel Verfeinerung Modell Präzisierung Spezifikation Formalisierung log. Formel Model Checker Überlauf 2 + Temporale Logik Eigenschaften von Zuständen und deren Änderung in Systemabläufen Erweiterung der Aussagenlogik 3 Zustandseigenschaften “bin bei Anweisung k” “Mailbox ist leer” “nil dereferenziert” “x[17] > 35” q q,n k,q,n x,k Annahme: s(p) mit vernachlässigbarem Aufwand berechenbar aus Repräsentation von s im Rechner 4 CTL* CTL* CTL LTL Nur Zust.formeln nur Pfadformeln X, F, G, U X, F, G, U, A, E EX, AX, EF, AF, EG, AG, E( . U . ) A( . U . ) 5 Progress und Fairness e d a b p a p p d f c b p e F p gilt nicht !!?!?!?! 6 Lösung: Fairnessannahmen Eine Fairnessannahme ist eine Pfadeigenschaft und Bestandteil der Systembeschreibung. Gültigkeit unter Fairness: A = für jeden Pfad, der alle Fairnessannahmen erfüllt, gilt.... E = es gibt einen Pfad, der alle Fairnessannahmen erfüllt und ... Fairness aktionsbasiert zustandsbasiert 7 Progress (= schwache Fairness) informal: Komponenten bleiben nicht einfach so stehen aktionsbasiert: Ein Pfad p behandelt eine Aktion a schwach fair, wenn: Wenn a in p von einem Zustand s an unendlich lange aktiviert ist, wird a bei einem Nachfolger von s ausgeführt zustandsbasiert: Eigenschaften der Form G F f (f ist Zustandseigenschaft) werden Progress-Annahmen genannt (oder schwache Fairnessannahmen). Beispiele: G F pc k GF input = 0 GF input = 1 8 Starke Fairness informal: Wenn sich mehrere Prozesse wiederholt um geteilte Ressourcen bewerben, kommt jeder mal dran aktionsbasiert: Ein Pfad p behandelt eine Aktion a stark fair, wenn: Wenn a in p unendlich oft enabled ist, wird a auch unendlich oft ausgeführt zustandsbasiert: Eigenschaften der Form (G F f ) (G F y) werden starke Fairnessannahmen genannt. Beispiel: ( G F ressource beantragt ) ( G F ressource erhalten) 9 Fairness - Zusammenfassung System = Transitionssystem + Fairnessannahmen Spezifikation = Sicherheitseigenschaft + Lebendigkeitseigenschaft Fairnessannahmen sind Lebendigkeitseigenschaften Vorsicht! G F pck k: receive(m,Mailbox) G F (pckMailbox=) 10 Beispiele Wechselseitiger Ausschluss S: G (pc1 “critical” pc2 “critical” ) L: G (pc = “request” F pc = “critical”) TS: Pr i (pc: lokale Variable, sem: globale Variable) init(pc) = “idle” init(sem) = 1 g0: pc = “idle” pc = “idle” /* do something else */ g1: pc = “idle” pc = “request” g2: pc = “request” sem = 1 sem = 0, pc = “critical” g3: pc = “critical” pc = “idle”, sem = 1 F: schwach: g3 stark: g2 F’: G F pc “critical” , (G F (pc = “request” sem = 1))11 (G F pc = “critical”) Beispiele F: schwach: g3 stark: g2 F’: G F pc “critical” , (G F (pc = “request” sem = 1)) (G F pc = “critical”) g0,g0’ (i,i,1) g1’ g1 g3 g0’ g0’ (r,i,1) g1’ g2 (c,i,0) g1 (r,r,1) g3 g1’ g2 (c,r,0) g0 (i,r,1) g3’ g2’ g3’ g2’ (r,c,0) g0 (i,c,0) g1 12 Beispiele F: schwach: g3 stark: g2 F’: G F pc “critical” , (G F (pc = “request” sem = 1)) (G F pc = “critical”) schwach unfair bzgl. g2 g3 g0’ g0,g0’ (i,i,1) g1’ g1 g0’ (r,i,1) g1’ g2 (c,i,0) g1 (r,r,1) g3 g1’ g2 (c,r,0) g0 (i,r,1) g3’ g2’ g3’ g2’ (r,c,0) g0 (i,c,0) g1 13 Beispiele F: schwach: g3 stark: g2 F’: G F pc “critical” , (G F (pc = “request” sem = 1)) (G F pc = “critical”) schwach fair, aber stark unfair bzgl. g2 g0,g0’ (i,i,1) g1’ g1 g3 g0’ g0’ (r,i,1) g1’ g2 (c,i,0) g1 (r,r,1) g3 g1’ g2 (c,r,0) g0 (i,r,1) g3’ g2’ g3’ g2’ (r,c,0) g0 (i,c,0) g1 14 Beispiele F: schwach: g3 stark: g2 F’: G F pc “critical” , (G F (pc = “request” sem = 1)) (G F pc = “critical”) fair, gewollter Ablauf wäre schwach unfair bzgl. g1 g3 g0’ g0,g0’ (i,i,1) g1’ g1 g0’ (r,i,1) g1’ g2 (c,i,0) g1 (r,r,1) g3 g1’ g2 (c,r,0) g0 (i,r,1) g3’ g2’ g3’ g2’ (r,c,0) g0 (i,c,0) g1 15 Beispiele “Echo”: propagation of information with feedback Prozess initiator (1) Prozesse other (n) Kommunikationsrelation N (bidirektional, zusammenh.) Nachricht: [Empfänger, Absender, Inhalt] initiator: g1: pc = idle c = choose, pc = active g2: pc = active send(N(myself) x {myself} x {c}),pc = waiting g3: pc = waiting received({myself} x N(myself} x {c}) pc = ready other: g4: pc = idle received([myself,f,c]) send(N(myself) \ {f} x {myself} x {c}), pc = pending g5: pc = pending received(N(myself) \ {f} x {myself} x {c}) send([f,myself,c]), pc = terminated F: schwach: g2-g5 L: G (initiator.pc = active F initiator.pc = ready) S: G (initiator.pc = ready o.c = initiator.c) o in other 16 Wie geht es weiter? Simulation Fehlerbeseitigung System Abstraktion Gegenbeispiel Verfeinerung Modell - Präzisierung Spezifikation Formalisierung A) Finite state systems log. Formel Model Checker Überlauf B) Infinite state systems 17 + Model Checking für finite state systems explizit: explizite Konstruktion eines Transitionssystems, das sich in bezug auf die untersuchte Eigenschaft äquivalent zum gegebenen verhält, aber in der Regel wesentlich kleiner ist. Eigenschaft wird durch Graphsuche nach Zeugen/ Gegenbeispielen verifiziert symbolisch: Datenstruktur, die Mengen von Zuständen bzw. Pfaden beschreibt, Operationen, die simultan die Nachfolger aller Zustände berechnet Eigenschaft wird durch Fixpunktoperationen auf der symbolischen Datenstruktur berechnet 18 Model Checking für finite state systems explizit: Kapitel 3 3.1: Tiefensuche 3.2: LTL-Model Checking 3.3: CTL-Model Checking 3.4: Fairness 3.5: Reduktion durch Symmetrie 3.6: Partial Order Reduction 3.7: Tools symbolisch: Kapitel 4 4.1: BDD-basiertes CTL-Model Checking 4.2: SAT-basiertes Model Checking 4.3: Tools 19 Kapitel 3 Explizites Model Checking 3.1. Tiefensuche 20 Setting Geg.: Gerichteter Graph [V,E] Ges.: stark zusammenhängende Komponenten v ~ v’ gdw. Es gibt einen Weg von v nach v’ und einen Weg von v’ nach v in G ~ ist Äquivalenzrelation; Klassen heißen SZK. SZK können durch Tiefensuche ermittelt werden (Tarjan21’72) Einfache Tiefensuche Annahme: Graph [V,E] zusammenhängend von v0 VAR schwarz, grau, weiss: Knotenmengen, dfs: Nat schwarz := grau := , weiss := V, maxdfs := 0 dfs(v0); dfs(v) v.dfs = maxdfs; maxdfs += 1; weiss := weiss \ {v}, grau := grau {v}; FOR ALL v’ ([v,v’] E) DO IF v’ weiss THEN dfs(v’) END END grau := grau \ {v}; schwarz := schwarz {v}; Invariant: weissgrau schwarz = V, schwarz reach(grau) = V Ende: grau = 22 Tiefensuchbaum Tiefensuche definiert Numerierung der Knoten (dfs) und Tiefensuchbaum [V,T]: [v,v’] T gdw. dfs(v’) wird von dfs(v) aus aufgerufen Beispiel: 6 2 2 5 1 4 3 v0 5 3 1 0 6 4 0 23 SZK und Tiefensuchbaum 6 2 5 4 3 Jede SZK bildet einen zusammenängenden Bereich im Tiefensuchbaum 1 0 Wurzel des Teilbaums ist Knoten mit kleinster dfs. 2 5 1 [v,v’] in T v.dfs < v’.dfs 3 6 4 0 In jedem Teilbaum ist die Menge der Tiefensuchnummern lückenlos 24 Klassifikation von E 6 2 [v,v’] ist Baumkante, falls [v,v’] in T 5 4 3 [v,v’] ist Vorwärtskante, falls [v,v’] in T*\T 1 [v,v’] ist Rückwärtskante, falls [v’,v] in T* [v,v’] ist Querkante, sonst 0 2 5 1 [v,v’] in Vorwärts v.dfs v’.dfs 3 6 4 0 [v,v’] in Quer v.dfs > v’.dfs [v,v’] in Rückwärts v.dfs > v’.dfs [v,v’] in Rückwärts v ~ v’ 25 Kriterium für Startknoten von SZK 4 4 5 21 6 44 3 3 11 v.lowlink = MIN(v’.dfs | v’ von v erreichbar über beliebig viele Baumkanten, gefolgt von max. einer anderen Kante [v,v’] mit v ~ v’) 00 4 5 21 1 1 3 Satz: v ist genau dann Startknoten einer SZK wenn v.lowlink = v.dfs 1 6 6 4 4 00 26 Tarjans Algorithmus VAR Tarj: Stack von Knoten, maxdfs: Nat, weiss: Knotenmenge weiss := V, maxdfs = 0; Tarj := empty stack dfs(v0); dfs(v): v.dfs = v.lowlink = maxdfs; maxdfs += 1; push(v,Tarj);weiss := weiss \ {v} FOR ALL v’ ([v,v’] in E) DO IF v’ in weiss THEN dfs(v’) Baumkante v.lowlink = MIN(v.lowlink,v’.lowlink) ELSE IF v’ on Tarj THEN v.lowlink = MIN(v.lowlink,v’.dfs) andere Kante END END END IF v.lowlink = v.dfs THEN REPEAT eine SZK v* = pop(Tarj) 27 UNTIL v = v* END lowlink wird korrekt berechnet ... gefolgt von einer anderen Kante [v,v’] mit v ~ v’ .... ELSE IF v’ on Tarj THEN v.lowlink = MIN(v.lowlink,v’.dfs) END END .... Fall 1: [v,v’] Vorwärtskante: also v.dfs < v’.dfs, also trägt v’ nicht zum Minimum bei Fall 2: [v,v’] Rückwärtskante: also v ~ v’, v’ vor v im Stack, also v’ noch auf Tarjanstack Fall 3: [v,v’] Querkante: ok, siehe Tafelskizze 28 Fazit Kapitel 3.1 Wir haben einen Algorithmus, der in O(|V| + |E|) die SZK eines gerichteten Graphen [V,E] bestimmt. Dieser Algorithmus kann mit der Konstruktion des Transitionssystems verbunden werden: FOR ALL [v,v’] in E DO .... FOR ALL commands g : g enabled in s DO s’ := execute g in s .... weiss noch nicht gesehen 29 Übung 1 Die Speisenden Philosophen. 5 Philosophen sitzen im Kreis am Tisch. Zwischen je zwei Philosophen liegt eine Gabel. Philosophen denken oder essen. Um essen zu können, benötigen sie die beiden Gabeln unmittelbar links und rechts von ihnen. Nach dem Essen legen sie die Gabeln wieder ab (zwei benachbarte Philosphen können also nie gleichzeitig essen, weil sie eine Gabel teilen). 1. Gib ein Transitionssystem an, das dieser Beschreibung entspricht und formuliere angemessene Fairnessannahmen! 2. Spezifiziere wünschenswerte Sicherheits- und Lebendigkeitseigenschaften! 30 Übung 2 Für ein von Dir gewähltes Tiefensuchszenario, 1. Ordne den Knoten die passenden dfs-Nummern zu 2. Klassifiziere die Kanten 3. Bestimme die lowlinkWerte 4. Kennzeichne die SZK 31 Übung 3 Gib einen möglichst kleinen gerichteten Graphen an, der bei geeigneter Tiefensuchreihenfolge alle Kantentypen enthält (und bei Vorwärts- und Querkanten jeweils sowohl eine innerhalb einer SZK als auch eine zwischen verschiedenen SZK). 32