Übung 3: ggT–Berechnung verteilt

Werbung
Übung 3: ggT–Berechnung verteilt
Übungsgegenstand ist eine verteilte Fassung des Euklidischen Algorithmus zur Berechnung
des größten gemeinsamen Teilers (ggT) einer Zahlenmenge.
Euklidischer Algorithmus zur ggT-Berechnung zweier Zahlen
Der Euklidische Algorithmus basiert auf einem Satz von Euklid:
(E0) x,y ganze Zahlen ∧ x > y > 0 ⇒ ggT(x,y) = ggT(y, mod(x, y)).
Der darauf basierende euklidische Algorithmus berechnet den ggT zweier Zahlen durch
wiederholte entsprechende Ersetzung ((x, y) ←(y, mod(x, y)), Abbruchbedingung y = 0).
ggT über Zahlenmenge
Satz (E0) lässt sich auf eine Zahlenmenge übertragen. Man kann in einer Zahlenmenge ein
Element durch seinen Modulus mit einer anderen, kleineren Zahl der Menge ersetzen, ohne
dass sich der ggT verändert:
(S0) x1.., xj, .., xk, .., xn ganze Zahlen ∧ ∀ i∈ 1..n : xi > 0 ∧ xj < xk ⇒
ggT(x1.., xj, .., xk, .., xn) = ggT(x1 .., xj, .., mod(xk, xj) .., xn).
Verteilte Berechnung des ggT einer Zahlenmenge
Die Funktion md(x,y) entspreche der Funktion mod(x,y) mit der Ausnahme, dass sie bei
restloser Teilbarkeit den Teiler y statt der 0 liefere:
md(x,y)::=if mod(x, y)=0 then y else mod(x, y)
(entspricht auch: md(x, y) ::= mod(x-1, y)+1)
Eine verteilte und auf eine Zahlenmenge der Kardinalität n erweiterte Fassung des
Euklidischen Algorithmus ergibt sich dadurch, dass die Ersetzung
((x1, x2, ..,xj, ..,xk, .., xn) ← (x1, x2, .., md(xj, xk), ..,xk, .., xn))
fortwährend für verschiedene Paare xi und xj angewendet wird. Der Zahlenvektor konvergiert,
weil die Funktion md verwendet wird, dabei zum Wert (g, g, g, …, g) mit g = ggT(x1 .., xn).
Der Algorithmus kann damit folgendermaßen skizziert werden:
•
Es gibt n Stationen, jede Station i verwaltet einen variablen Zahlenwert Mi und kennt
eine eigene Konstante ci. Berechnet werden soll ggT(c1, c2, .., cn).
•
Initial gilt Mi = ci.
•
Stationen senden ihren aktuellen Wert Mi an Nachbarstationen.
•
Eine Station j, die einen Wert Mk empfängt, der kleiner als der eigene Wert Mj ist,
berechnet Mj neu (Mj’=md(Mj, Mk)) und sendet den neuen Wert Mj’ an Nachbarn
weiter.
Übungen zur Vorlesung „Verteilte Algorithmen II“, Heiko Krumm, Universität Dortmund, FB Informatik
21.05.2012 10:04
-2-
Ueb3.doc
Spezifikation von NTS-Prozess und Stationsprozessen
Zur kompositionalen Spezifikation des Algorithmus geben wir zunächst zwei Prozesstypen
an, und setzen im Prozesstyp Algo dann das Algorithmus-entsprechende Gesamtsystem aus
Instanzen dieser Typen zusammen.
const
n;
c1, .., cn
Nachb1,.., Nachbn
// Anzahl der Stationen, Adressen 1..n
// Die Zahlenmenge
// Die Netztopologie (Nachbarstationsmengen)
process NTS ;
// Nachrichtentransportsystem
var b : bag of <dst, z> ;
// Der Puffer der im Transfer befindlichen Nachrichten
Init ::= b = {} ;
actions
send ( m : <dst, z>) ::= b’ = b ∪ {m} ;
recv ( i : 1..n ; m : <dst, z>) ::= i = dst ∧ m ∈ b ∧ b’ = b \ {m} ;
end ;
process Station (c : card ; i : 1..n; Nachb : set of 1..n );
// Stationsprozess
var
M : card ;
// Zahlenmerker
ts : set of 1..n ;
// Weitergabeziel-Merker
Init ::= M = c ∧ ts = Nachb ;
actions
recvgre ( m : <dst, z>) ::= // Empfange nicht-aktualisierende Zahl
z ≥ M ∧ M’ = M ∧ ts’ = ts ;
recvlth ( m : <dst, z>) ::=
// Empfange aktualisierende Zahl
z < M ∧ M’ = mod(M-1, z)+1 ∧ ts’=Nachb ;
send (m : <dst,z> ) ::=
// Sende M an Nachbarn
z = M ∧ dst ∈ ts ∧ M’ = M ∧ ts’ = ts \ {dst} ;
end ;
process Algo ( n : card ; c : array [1..n] of card ; Nachb : array [1..n] of set of 1..n ) ;
processes
T : NTS ;
// Das Transportsystem
S : array [i: 1..n] of Station(ci, i, Nachbi) ; // Die Stationsprozesse S1, .. Sn.
actions
recvgre ( i : 1..n ; m : <dst, z>) ::= // Si empfängt nicht-aktualisierende Zahl
Si.recvgre(m) ∧ T.recv(i,m) ∧ ∀ j ∈ 1..n, j ≠ i: Sj.Stutter ;
recvlth ( i : 1..n ; m : <dst, z>) ::= // Si empfängt aktualisierende Zahl
Si.recvlth(m) ∧ T.recv(i,m) ∧ ∀ j ∈ 1..n, j ≠ i: Sj.Stutter ;
send ( i : 1..n ; m : <dst,z> ) ::=
// Si sendet sein M an Nachbarn
Si.send(m) ∧ T.send(m) ∧ ∀ j ∈ 1..n, j ≠ i: Sj.Stutter ;
end ;
Übungen zur Vorlesung „Verteilte Algorithmen II“, Heiko Krumm, Universität Dortmund, FB Informatik
21.05.2012 10:04
-3-
Ueb3.doc
Spezifikation des Gesamtsystems als einfacher Prozess
Zur Verifikation verwenden wir die expandierte und syntaktisch leicht vereinfachte Version
Algof des Prozesstyps Algo. Bitte zunächst das blau Geschriebene ignorieren. Es handelt sich
um Hilfsvariablen-Historieninformation, welche Informationen aus dem vergangenen Ablauf
speichert und später den Safety-Beweis unterstützt (Wir bemerken, dass die blauen Teile der
Spezifikation keinen Einfluss auf die schwarzen Teile haben. Sie kommen weder in einem
Guard einer Aktion noch in einem Effekt auf schwarze Zustandskomponenten vor).
process Algof ( n : card ; c : array [1..n] of card ; Nachb : array [1..n] of set of 1..n ) ;
var
b : bag of <D, dst, z> ;
// Der Puffer der im Transfer befindlichen Nachrichten
// mit D: set of 1…n; Stationsnummernmenge
// dst: 1..n ; Zielstationsnummer
// z: card ; Nachrichteninhalt, Zahl
M : array [1..n] of card ;
// Die Zahlenmerker der Stationen
ts : array [1..n] of set of 1..n ; // Die Weitergabeziel-Merker der Stationen
Init ::= b = {} ∧ ∀ i ∈ 1..n: ( Mi=ci ∧ tsi = Nachbi) ;
actions
recvgre ( i : 1..n ; m : <D, dst, z>) ::= // Si empfängt nicht-aktualisierende Zahl
z ≥ Mi ∧ i = dst ∧ m ∈ b ∧ M’ = M ∧ ts’ = ts ∧ b’ = b \ {m} ;
recvlth ( i : 1..n ; m : <D, dst, z>) ::= // Si empfängt aktualisierende Zahl
z < Mi ∧ i = dst ∧ m ∈ b ∧
M’ = M außer Mi’ = mod(Mi-1, z)+1 ∧ ts’= ts außer tsi’=Nachbi ∧
b’ = b \{m}\{<E,j,v>: <E,j,v>∈b ∧ i∈E}∪{<E∪D,j,v>: <E,j,v> ∈b ∧ i∈E} ;
send ( i : 1..n ; m : <D, dst, z> ) ::= // Si sendet sein M an einen Nachbarn
z = Mi ∧ dst ∈ tsi ∧ M’ = M ∧ D={i} ∧
ts’ = ts außer tsi’ = tsi \ {dst} ∧ b’ = b ∪ {m} ;
end ;
Interessierende Safety-Eigenschaften
Die korrektheitsrelevante Safety-Eigenschaft ist, dass der Vektor M bei Terminierung den
Wert <g, g, .., g> mit g = ggT(c1, c2, .., cn) besitzt. Eine Eigenschaft, die nicht besagt, dass die
Terminierung tatsächlich immer eintreten muss (dies wäre nämlich keine Safety- sondern eine
Liveness-Eigenschaft).
Vorbereitend beweisen wir eine Formel als Invariante, die auch über die Zwischenzustände,
und nicht nur über Terminierungszustände, etwas aussagt:
□ ( ggT(M1, M2, .., Mn) = ggT(c1, c2, .., cn)).
Anmerkung
Der Beweis wurde in Zusammenarbeit mit Martin Schuster erarbeitet, der auch entdeckte,
dass die vorherige Fassung fehlerhaft war.
Übungen zur Vorlesung „Verteilte Algorithmen II“, Heiko Krumm, Universität Dortmund, FB Informatik
21.05.2012 10:04
-4-
Ueb3.doc
Der Beweis ist ‒ entgegen der ersten Vermutung ‒ nicht einfach. Denn der Algorithmus lässt
es zu, dass ein in einer Nachricht enthaltener z-Wert schon veraltet ist, weil die sendende
Station zwischenzeitlich eine Nachricht empfing und ihren Wert Mk auf Mk‘=md(Mk,ze)
änderte. Wenn nun die Nachricht mit dem veralteten z-Wert empfangen wird und beim
Empfänger dst die Aktualisierung hervorruft, wird dort Mdst‘=md(Mdst,z) gesetzt, ohne dass
die Zahl z noch in der Menge M enthalten sein muss. Nun kann mod(x,y) aber gegenüber x
neue Primfaktoren enthalten. Der Satz „ggT(x,y) = ggT(y, mod(x, y))“ gilt nur deshalb, weil
die unter Umständen in mod(x,y) gegenüber x neu hinzukommenden Primfaktoren garantiert
keine Primfaktoren von y sind, y sie also sozusagen wegschneidet. Wenn y aber plötzlich
fehlt, können neue Faktoren eingeführt und ein zu großer ggT-Wert berechnet werden.
Beweis per Induktion über möglichen Ablauf, 1. Versuch
Induktionsstart
Es gilt Init ⇒ ggT(M1, M2, .., Mn) = ggT(c1, c2, .., cn) da Mi = ci.
Induktionsschritte
Kritisch ist nur die Aktion recvlth, da sich nur hier ein Mi ändert.
Es ist zu beweisen:
ggt(M1, M2, .., Mn) = ggt(c1, c2, .., cn) ∧
// Induktionsvoraussetzung (IV)
z < Mi ∧ i = dst ∧ m ∈ b ∧
// Aktion recvlth
M’ = M außer Mi’ = mod(Mi-1, z)+1 ∧ ts’= ts außer tsi’=Nachbi ∧ b’ = b \ {m}
⇒
ggt(M1’, M2’, .., Mn’) = ggt(c1, c2, .., cn)
// Induktionsbehauptung (IB)
Dies lässt sich allerdings so nicht beweisen, weil wir nichts über den Wert z wissen. Es
müsste sichergestellt sein, dass z der Wert eines Mk mit k≠i ist, oder falls es ein veralteter
Wert ist, dass dann wenigstens die aktuellen M-s ohne Mi im Schnitt nicht mehr Primfaktoren
als z haben.
Die zu beweisende Invariante „ggT(M1, M2, .., Mn) = ggT(c1, c2, .., cn)“ ist also nicht induktiv.
Sie muss verschärft werden. Eine geeignete Verschärfung zu finden, ist hier allerdings wegen
der o.g. Komplikationen sehr schwierig.
Vorabüberlegung und Einführung von Historieninformation
Wie oben gesagt, kann an einer Station i ein z-Wert eintreffen, der nicht mehr direkt einem Mj
entspricht, weil dieses schon aktualisiert wurde. Wir dürfen nur dann Mi gemäß
Mi‘=mod(Mi,z) verändern, ohne dass dabei möglicherweise der ggT der Menge M‘ ein
anderer als der von M ist, wenn sichergestellt ist, dass die u.U. in Mi‘ gegenüber Mi
dazukommenden Primfaktoren durch die anderen M-Werte ausgeschlossen werden. Es dort
also je neuem Primfaktor mindestens ein Mj mit j≠i gibt, das diesen Primfaktor nicht enthält.
Der Algorithmus stellt, wenn er korrekt ist – und davon gehen wir aus ‒, dies implizit sicher,
und die Idee ist nun, je Nachricht eine Hilfsvariablen-Historieninformation einzuführen,
welche mitaufzeichnet, welche M-Werte jeweils gerade notwendig sind, um sicherzustellen,
dass man Mi‘=mod(Mi,z) durchführen kann, ohne dadurch den ggT von M‘ gegenüber M zu
verändern.
Übungen zur Vorlesung „Verteilte Algorithmen II“, Heiko Krumm, Universität Dortmund, FB Informatik
21.05.2012 10:04
-5-
Ueb3.doc
Dies ist der blau gefärbte Teil der Spezifikation. Eine Nachricht für Wert z= Mi wird beim
Senden mit der einelementigen Menge {i}, d.h. der Absenderadresse, versehen. Dies besagt,
dass gegenwärtig schon der Wert Mi ausreicht um sicherzustellen, dass für ein k≠i durch eine
Modulo-Bildung mit z gemäß Mk‘=mod(Mk,z) sich keine ggT-verändernden neuen Faktoren
von Mk durchsetzen können, denn es gilt Mi=z.
Wenn nun irgendwann später eine Station k eine Nachricht <D,k,z> empfängt und ihren Wert
verändert zu Mk‘=mod(Mk,z), dann muss man bedenken, dass z und damit die Wertemenge
{Mj: j∈D} nötig ist, um sicherzustellen, dass mit Mk‘=mod(Mk,z) der ggT von M’ gegenüber
M nicht verändert wird.
Für jede Nachricht <E,j,v>∈b mit k∈E gilt aber, dass Mk benötigt wird, um bei einer ModuloBildung mit v zusätzliche Faktoren zu verhindern. Deshalb wird in jeder solchen Nachricht
das E um D erweitert, die Nachricht lautet dann <E∪D,j,v>.
Anmerkung 1: Es sei PF(x) die Primfaktorzerlegung einer natürlichen Zahl x (eine
Vielfachmenge). Es sei PF(M), die Primfaktorzerlegung einer nichtleeren Zahlenmenge M⊂ℕ
definiert als: ∩(PF(x): x ∈M). „ggT(M)=ggT(M,x)“ ist dann gleichbedeutend mit: „PF(M) ⊂
PF(x)“ für eine nichtleere Menge M⊂ℕ.
Anmerkung 2: Es seien M und N nichtleere Zahlenmengen mit M, N ⊂ℕ. Dann ist
„ggT(M)=ggT(N)“ gleichbedeutend zu „PF(M)=PF(N)“.
Verschärfung der Invarianten
Nach den Vorüberlegungen wird die Invariante folgendermaßen verschärft:
(1)
(2)
(3)
ggT(M1, ..., Mn) = ggT(c1, ..., cn) ∧
( <D,j,u> ∈ b ⇒
ggT({Mi: i ∈ D}) = ggT({Mi: i ∈ D}∪{u}) ∧
(i ∈ D ⇒ u ≥ Mi) )
Die verschärfte Invariante wird per Induktion über dem Algorithmus-Ablauf bewiesen:
Induktionsstart: Init impliziert, dass b leer ist, weshalb die Verschärfungen (2) und (3)
trivialerweise gelten.
Induktionsschritt recvgre: M wird nicht verändert. Die Menge {x: <*, x> ∈ b} wird
allenfalls kleiner. Deshalb kann IB aus IV gefolgert werden.
Induktionsschritt recvlth:
Station i empfängt eine Nachricht <D,i,z>, deren Wert z gemäß Guard der Aktion kleiner als
Mi ist: z< Mi (*). Also ist i nach IV(3) nicht in D enthalten, alle gemeinsamen Primfaktoren
der M-s aus D sind deshalb nach IV(2) und Anmerkung 1 auch Primfaktoren von z, weshalb
Mi‘=mod(Mi,z) höchstens solche neuen Primfaktoren einführt, welche von den anderen M-s
weggeschnitten werden. Es gilt deshalb
PF({Mk: k ∈ D }, Mi)= PF({Mk: k ∈ D }, Mi‘) (**)
Übungen zur Vorlesung „Verteilte Algorithmen II“, Heiko Krumm, Universität Dortmund, FB Informatik
21.05.2012 10:04
-6-
Ueb3.doc
und mit Anmerkung 2 gilt ggT({Mk: k ∈ D }, Mi)=ggT({Mk: k ∈ D }, Mi‘). Ergänzen beider
Mengen um die fehlenden M-s führt zusammen mit IV(1) zu IB(1).
Die Aktion verändert den Historienteil der Nachrichten in b. Bei jeder Nachricht <E,j,v>,
deren Historienteil E die Stationsnummer i enthält, ist zu beachten, dass diese das alte Mi
benötigte, dieses sich aber zu Mi‘ verändert, welches wiederum die Mk-s der Stationen k aus
D benötigt. Da aber jede solche Nachricht <E,j,v> aus b in b‘ zu <E∪D,j,v> aktualisiert wird,
gilt IB(2) im Folgezustand der Aktion.
Genauer folgt IB(2), was nach Anmerkung 1 gleichbedeutend zu „PF(E') ⊂ PF(v)“ ist,
zusammen mit der aus IV(2) bekannten Tatsache „PF(E) ⊂ PF(v)“ aus:
PF(E') = PF({Mk ': k ∈D}) ∩ PF({Mk ' : k∈E}) =
PF({Mk ': k ∈D}) ∩ PF({Mk ': k∈E}\{Mi'}) ∩ PF(Mi') =
PF({Mk ': k ∈D}, Mi') ∩ PF({Mk ': k ∈E}\{Mi'}) = (nach (**))
PF({Mk ': k ∈D}, Mi) ∩ PF({Mk ': k ∈E}\{Mi'})=
PF({Mk ': k ∈D}) ∩ PF({Mk ': k ∈E}\{Mi'}, Mi) =
PF({Mk ': k ∈D}) ∩ PF(E)
⊂ PF(v).
IB(3) gilt wegen der Transitivität von „≥“. Der Wert z der empfangenen Nachricht <D,i,z> ist
laut IV(3) größer gleich jedem M-Wert der Stationen aus D, kurz z≥ Mk (k ∈ D). Der Wert v
ist laut IV(3) größer gleich jedem M-Wert der Stationen aus E, kurz v≥ Mh (h ∈ E). Da sich
auch i in E befindet, gilt v≥ Mi. Wegen (*) gilt v≥ Mi>z≥ Mk (k ∈ D), so dass v auch größer
gleich jedem M-Wert der Stationen aus D sein muss. Der Wechsel von Mi zu Mi‘ stört nicht,
da Mi‘ kleiner als Mi sein muss.
Induktionsschritt send:
M wird nicht verändert. b wird um ein neues Element größer, dessen z-Wert direkt dem Mi
entspricht.
Partielle Korrektheit
Die Safety-Eigenschaft der partiellen Korrektheit (wenn Algorithmus terminierte, gilt dass
das gewünschte Ergebnis berechnet wurde) lautet formal:
P ::= (∀ k, l : Mk = Ml) ⇒ ∀ m : Mm = ggT(c1, .., cn)
Wenn alle Merker M den gleichen Wert enthalten, ist es der gesuchte ggT.
Die oben bewiesene Invariante gilt für alle erreichbaren Zustände, also auch, wenn ein
Zustand mit ∀ k, l : Mk = Ml vorliegt.
Es gilt dann also <M1, .., Mk> = <g, .., g> und ggT(<g, .., g>)=ggT(<c1, .., cn>).
Der größte gemeinsame Teiler einer einelementigen Zahlenmenge {g} ist ferner natürlich g
selber.
Im Fazit lässt sich daraus P ableiten, also die partielle Korrektheit beweisen.
Übungen zur Vorlesung „Verteilte Algorithmen II“, Heiko Krumm, Universität Dortmund, FB Informatik
21.05.2012 10:04
-7-
Ueb3.doc
Terminierung
Als letztes soll die Liveness-Eigenschaft der Terminierung bewiesen werden. Die
entsprechende Leads-To-Formel ist:
Init ~> (∀ k, l : Mk’ = Ml’).
Lattice
Wir definieren die Funktion L als Abbildung der Zustände auf Vektoren:
L ::= <M1-ggT(c1,..,cn), M2-ggT(c1,..,cn).., .., Mn-ggT(c1,..,cn)>
L gibt wieder, wie weit der aktuelle Zustand der Mi vom Ziel <g,g, .., g> entfernt ist.
Der Bildbereich von L ist ein wohlfundierter Lattice mit der Halbordnung „<“
Vektorvergleich und dem Minimum <0,0,..,0>. Da wir in ganzen Zahlen rechnen, gibt es für
jeden möglich L-Wert nur endlich viele Schritte, in welchen der Wert vermindert werden
kann. Dann muss das Minimum erreicht sein.
Lebendige Lattice-Schritte
Gelingt es uns jetzt nachzuweisen, dass die Schritte im Lattice lebendig sind, sind wir fertig:
L = X ≠ <0,0,..,0> ~> L < X
Beweis-Skizze:
X ≠ <0,0,..,0> ⇒ ∃ i,j: Mi ≠ Mj Dies können wir aus unseren Safety-Betrachtungen schließen.
∃ i,j: Mi ≠ Mj ⇒ ∃ k,l: Mk < Ml ∧ k ist Nachbar von l
Dies gilt, da das Netz zusammenhängend ist.
Hilfreich ist außerdem noch folgende vermutete Invariante:
F::= ∀ k,l: Mk < Ml ∧ k ist Nachbar von l ⇒ <l,Mk>∈b ∨ l ∈tsk
F lässt sich als Invariante beweisen:
Init ⇒ F F folgt direkt aus der Initialisierung
F ∧ recvgre ⇒ F’ Es wird zwar eine Nachricht gelöscht.
Es ist jedoch keine Nachricht, welche von einer Station mit kleinerem M
an eine Station mit größerem M gerichtet ist.
F ∧ recvlth ⇒ F’
Wenn <l,Mk> empfangen wird, wird Ml aktualisiert, und es gilt Mk’ ≥ Ml’, so dass
die linke Seite von F’ nicht mehr auf k und l zutrifft.
Für die anderen Stationen o, p mit „o,p sind Nachbarn und Mo<Mp“ hat sich nichts
geändert, deshalb gilt für sie F’ wegen der Induktionsvoraussetzung F.
Dadurch dass Mk’ kleiner geworden ist, kann es aber sein, dass es neue direkte
Nachbarnpaare o,p mit „o,p sind Nachbarn und Mo<Mp“ gibt, nämlich solche mit o=k.
Die Aktion aktualisierte aber tsk: tsk’=Nachbarn(k). Damit gilt hier die rechte Seite
von F’.
F ∧ send ⇒ F’ Wenn l aus tsk entfernt wird, sendet k an l und es gibt <l,Mk’>∈b’
Mit der nun bewiesenen Invariante F lässt sich aus „∃ k,l: Mk < Ml ∧ k ist Nachbar von l“
folgern, dass auch gilt ∃ k,l: Mk < Ml ∧ k ist Nachbar von l ∧ ( <l,Mk>∈b ∨ l ∈tsk )
Übungen zur Vorlesung „Verteilte Algorithmen II“, Heiko Krumm, Universität Dortmund, FB Informatik
21.05.2012 10:04
-8-
Ueb3.doc
Damit ist nachgewiesen:
L = X ≠ <0,0,..,0> ⇒ ∃ k,l: Mk < Ml ∧ k ist Nachbar von l ∧ ( <l,Mk>∈b ∨ l ∈tsk )
Jetzt werden zwei Leads-To Schritte transitiv verbunden:
Schritt 1: „Schon da oder Send schaltet“
∃ k,l: Mk < Ml ∧ k ist Nachbar von l ∧ ( <l,Mk>∈b ∨ l ∈tsk )
~>
∃ k,l: Mk < Ml ∧ k ist Nachbar von l ∧ <l,Mk>∈b
Schritt 2: „Recvlth schaltet“
∃ k,l: Mk < Ml ∧ k ist Nachbar von l ∧ <l,Mk>∈b ∧ L = X
~>
L’<X
Die Schritte lassen sich wie folgt beweisen.
Schritt 1:
Fall a: Es gelte <l,Mk>∈b, damit greift die „Schon da“ Regel (P⇒Q / P~> Q)
Fall b: Es gelte ⌐<l,Mk>∈b, damit muss gelten l ∈tsk,
damit greift die Ein-Weak-Fairer-Schritt-Regel mit der Aktion send.
Schritt 2:
Es greift die Ein-Weak-Fairer-Schritt-Regel mit der Aktion recvlth.
Die einzige Regel-Prämisse die nicht offensichtlich gilt, ist die Stabilität von
Enabled(<recvlth>), bis recvlth feuert. Sie ist gegeben, da alle anderen Aktionen
kein l∈tsi entfernen.
Die transitive Verbindung der Schritte (P~>R, R~>Q / P~>Q) sowie zu Beginn die „Schon
da“-Regel (P=>Q / P~>Q) führen zum gewünschten Ziel.
Der Liveness-Beweis gelingt natürlich nur, wenn die beiden Aktionen recvlth und send weak
fair ausgeführt werden. Die Spezifikation muss um diese beiden Fairness-Annahmen ergänzt
werden.
===
Übungen zur Vorlesung „Verteilte Algorithmen II“, Heiko Krumm, Universität Dortmund, FB Informatik
Herunterladen