Temporale Logik der Aktionen

Aus testwiki
Zur Navigation springen Zur Suche springen

Die Temporale Logik der Aktionen (TLA, Vorlage:EnS) wurde von Leslie Lamport entwickelt. Sie baut zum einen auf der Temporalen Logik (engl. Vorlage:Lang) und zum anderen auf der Logik der Aktionen (engl. Vorlage:Lang) auf, ist folglich im Ansatz eine Verknüpfung einer Erweiterung der Aussagenlogik durch die Temporale Logik mit der Sprache Logik der Aktionen, in der sich Prädikate, Zustandsfunktionen und Aktionen beschreiben lassen. Es handelt sich um eine Variante der von Amir Pnueli eingeführten temporalen Logik für Programme.

Die Temporale Logik der Aktionen wird in der Informatik zur Spezifikation, Argumentation und Verifikation von Systemen (z. B. Programmen) verwendet. Eine Spezifikation in TLA ist eine logische Formel, die jedes mögliche und korrekte Verhalten eines Systems beschreibt. Anhand dieser logischen Formel können Systeme auf unerwünschte und gewünschte Eigenschaften geprüft werden.

Logik der Aktionen

Die Logik der Aktionen in der theoretischen Informatik beschäftigt sich mit der Korrektheit von Ausführungen von Computerprogrammen und ermöglicht die Untersuchung der Korrektheit von Programmen.[1]

Notationsgrundlagen

  • Sei F ein syntaktisches Objekt, dann ist [[F]] seine semantische Bedeutung.
  • =^ ist eine andere Schreibweise für := und bedeutet „gleich per definitionem“.
  • s[[v]]/v bedeutet, dass v durch s[[v]] ersetzt wird.

Variablen, Werte und Zustände

Die Logik der Aktionen verwendet die folgenden drei Klassen:

Var – die Klasse aller Variablennamen
Val – die Klasse aller möglichen Werte für die Variablen (z. B. 10, „string“, True)
St – die Klasse aller möglichen Zustände

Ein Zustand ist eine Abbildung s:VarVal,xs(x), das heißt, der Variablen x wird der Zustand s(x) zugewiesen. Die Zustände beschreiben die Semantik. Man verwendet s[[x]] statt s(x). Mit [[x]] bezeichnet man somit die Abbildung [[x]]:StVal.

Somit ist die Schreibweise s[[x]] in polnischer Notation und bedeutet Anwendung von s.[2]

Zustandsfunktion

Eine Zustandsfunktion (engl. state function) ist ein nicht-boolescher Ausdruck aus Variablen und Konstanten, zum Beispiel f:=x2+y+4, dazu gehören auch Variablen x (da eine Variable als die Identitätsabbildung xx interpretiert werden kann). Der Ausdruck [[f]] ist dann die Abbildung [[f]]:StVal,ss[[f]], das heißt, [[f]] oder [[x2+y+4]] ist eine Abbildung, die dem Zustand s den Wert (s[[x]])2+s[[y]]+4 zuordnet. Die Notation s[[f]] bezeichnet den Wert, den [[f]] dem Zustand s zuordnet.

Die semantische Definition von s[[f]] lautet[3]

s[[f]] =^ f(v:s[[v]]/v).

Der Ausdruck f(v:s[[v]]/v) bedeutet somit den Wert von f, wenn man alle v durch s[[v]] ersetzt.

Zusammenfassend:

Zustand s VarVal,xs(x)=:s[[x]]
Zustandsfunktion f x2+y+4
Semantik [[f]] StVal,ss[[f]]=(s[[x]])2+s[[y]]+4

Zustandsprädikat

Ein boolescher Ausdruck P aus Variablen und Konstanten wird Zustandsprädikat (oder kurz Prädikat) genannt, ein Beispiel ist der Ausdruck x=3+y. Mit [[P]] bezeichnet man die Abbildung [[P]]:StBooleans und s[[P]] ordnet entweder True oder False dem Zustand s zu. Wenn s[[P]]=True gilt, dann sagt man s erfüllt das Prädikat P.[3]

Aktion und Schritte

Eine Aktion 𝒜 ist ein boolescher Ausdruck, der die Beziehung zwischen einem alten Zustand s und einem neuen Zustand t beschreibt. Die Aktion besteht aus „alten Variablen“ und „neuen Variablen“, wobei letztere mit einem markiert sind. Zum Beispiel ist x+2=y eine Aktion, die sagt, dass y im alten Zustand um 2 größer ist als x im neuen Zustand.

Der Ausdruck [[𝒜]] beschreibt die Beziehung zwischen zwei Zuständen, das heißt einen binären Operator, der den beiden Zuständen s,t einen booleschen Wert s[[𝒜]]t zuweist, dabei wird per definitionem links der alte Zustand und rechts der neue Zustand geschrieben. Die semantische Bedeutung s[[𝒜]]t von 𝒜 erhält man, indem man v durch s[[v]] und v durch t[[v]] ersetzt. Ist s[[𝒜]]t=True, dann nennt man s,t einen 𝒜-Schritt (engl. 𝒜-step).

Der Ausdruck s[[y=x+1]]t bedeutet somit das Gleiche wie der boolesche Ausdruck s[[y]]=t[[x]]+1.

Die semantische Definition von s[[𝒜]]t lautet

s[[𝒜]]t =^ 𝒜(v:s[[v]]/v, t[[v]]/v).

Variablen die unterschiedliche Werte in verschiedenen Zuständen besitzen können, werden flexible Variablen (engl. flexible variables) genannt. Variablen die konstant bleiben (aber auch unbekannt sein könne) werden rigide Variablen (engl. rigid variables) genannt. Beispielsweise sei x eine flexible Variable, dann besitzt die Aktion

m:mx=n+x

zwei rigide Variablen m,n, die nicht verändert werden.

Prädikat als Aktion

Ein Prädikat kann als Aktion ohne Variablen mit verstanden werden. Die Aktion s[[P]]t ist gleich dem booleschen Ausdruck s[[P]] für alle s,t. Für Zustandsfunktionen und Prädikate F definiert man F als den Ausdruck, den man erhält, wenn man alle Variablen durch deren neue Variable ersetzt, das heißt also

F =^ F(v:v/v).

Des Weiteren ist s[[P]]t der gleiche Ausdruck wie t[[P]], für alle Zustände s,t.

Beweisbarkeit und Gültigkeit

Eine Aktion 𝒜 ist gültig (engl. valid), geschrieben 𝒜 (siehe Tautologie), falls jeder Schritt ein 𝒜-Schritt ist, das heißt also, s[[𝒜]]t ist True für alle s,tSt. Die semantische Definition lautet

𝒜 =^ s,tSt: s[[𝒜]]t

und für ein Prädikat P

P =^ sSt: s[[P]].

Ein Beispiel für eine gültige Aussage ist

(x+y)(x+yx+y).

Beweisbare Formeln F werden wie in der mathematischen Logik mit F notiert (siehe Ableitung).

Enabled-Prädikate

Sei 𝒜 eine Aktion, dann ist Enabled 𝒜 ein Prädikat, das genau dann für einen Zustand wahr ist, falls es in dem Zustand möglich ist, einen 𝒜-Schritt auszuführen. Die semantische Definition lautet[4]

s[[Enabled 𝒜]] =^ tSt:s[[𝒜]]t

für jeden Zustand s.

Temporale Logik

Die temporale Logik ist ein System von Regeln und Symbolen, durch die man zeitliche Abläufe erfassen kann. Die Semantik der temporalen Logic baut auf „Verhalten“ (engl. behaviors) auf, wobei damit eine unendliche Folge von Zuständen gemeint ist.[5]

Temporale Formeln

Temporale Formeln bestehen aus elementaren Formeln sowie booleschen Operatoren und dem unären Operator , der „immer“ (engl. always) oder „global“ (engl. global) bedeutet. Mit σ[[F]] wird der boolesche Ausdruck bezeichnet, den das F dem Verhalten σ zuweist. Mit s0,s1, wird das Verhalten bezeichnet, das im Zustand s0 beginnt. Man sagt σ erfüllt F genau dann, wenn σ[[F]]=True.

Da alle booleschen Ausdrücke durch und ¬ beschrieben werden können, genügt es, die Ausdrücke [[¬F]],[[FG]] und [[F]] zu definieren. Die semantischen Definitionen sind somit[6]

σ[[FG]] =^ σ[[F]]σ[[G]]
σ[[¬F]] =^ ¬σ[[F]]
s0,s1,[[F]] =^ n:sn,sn+1,sn+2,[[F]],

wobei der erste Ausdruck bedeutet, dass ein Verhalten FG erfüllt, falls es beide Formeln F und G erfüllt. Der zweite Ausdruck bedeutet, dass das Verhalten ¬F erfüllt, wenn es F nicht erfüllt. Die linke Seite des dritten Ausdruckes s0,s1,[[F]] bedeutet, dass die Formel F ab Zustand s0 gültig ist. Das heißt, die letzte Definition sagt, dass F immer gültig ist (da es per Induktionsschritt definiert ist).[3]

Schlussendlich-Operator

Die Formel ¬¬F bedeutet, dass F nicht immer falsch ist und wird mit F abgekürzt und schlussendlich (engl. eventually) genannt:

F =^ ¬¬F

Die Formel F bedeutet, dass F schlussendlich immer wahr ist.

Gültigkeit

Eine temporale Formel F ist gültig, falls jedes Verhalten die Formel erfüllt:

F =^ σSt:σ[[F]]

Temporale Logik der Aktionen

Die temporale Logik der Aktionen erhält man, wenn temporale Formeln Aktionen sein können. Die Formeln der TLA bestehen somit aus den logischen Operatoren sowie dem temporalen Operator .

Ein einfaches Beispiel

Gegeben sei ein Algorithmus, der im Zustand x=0 und z=0 beginnt und dann nichtdeterministisch entweder x inkrementiert und z dekrementiert, oder umgekehrt. Als TLA würde das so aussehen:

Initϕ =^ (x=0)(z=0)
𝒜1 =^ (x=x+1)(z=z1)
𝒜2 =^ (x=x1)(z=z+1)
𝒜 =^ 𝒜1𝒜2
ϕ =^ Initϕ𝒜

Dabei bezeichnet ϕ eine Formel, Initϕ den Initialzustand und 𝒜 eine Aktion.

Stotternde Schritte

Als stotternde Schritte (engl. stuttering steps) werden Schritte bezeichnet, die das Programm pausieren. In dem Beispiel oben würde das bedeuten, dass x und z nicht verändert werden. Ein solcher Schritt lässt sich zum Beispiel so implementieren:[7]

Initϕ =^ (x=0)(z=0)
𝒜1 =^ (x=x+1)(z=z1)
𝒜2 =^ (x=x1)(z=z+1)
𝒮1 =^ (x=x)(z=z)
𝒜 =^ 𝒜1𝒜2
ϕ =^ Initϕ(𝒜𝒮1)

Um stotternde Schritte einfach zu beschreiben, führt man weitere Notationen ein. Mit der Notation x,z=x,z wird (x=x)(z=z) bezeichnet und statt x,z zu schreiben, notiert man einfach x,z. Für eine Zustandsfunktion f und eine Aktion 𝒜 definieren wir:

[𝒜]f =^ 𝒜(f=f)

Dann bedeutet []x,z somit:

[]x,z=(x,z=x,z)=((x=x)(z=z))=𝒮1

Somit lassen sich die beiden Zeilen

𝒮1 =^ (x=x)(z=z)
ϕ =^ Initϕ(𝒜𝒮1)

vereinfachen zu

ϕ =^ Initϕ[𝒜]x,z.

Syntax und Semantik

Für die TLA gelten die Symbole der booleschen Algebra sowie alle oben definierten Ausdrücke und zusätzlich

[𝒜]f =^ 𝒜(f=f)
𝒜f =^ 𝒜(ff),

wobei 𝒜 eine Aktion ist, f eine Zustandsfunktion ist und durch Anwendung logischer Gesetze (𝒜(ff))=¬(¬𝒜(f=f)) gilt.

Für die Formel-Syntax gilt:

Formel

=^

FormelFormel | FormelFormel | ¬Formel | Formel | Formel | Pra¨dikat | [Aktion]f | Aktionf

Das Symbol | ist als Trennungszeichen zu verstehen.

Verhaltenseigenschaften

Eine Sicherheitseigenschaft (engl. safety property) garantiert, dass unerwünschte Zustände nicht passieren. Zum Beispiel ist der durch Initϕ spezifizierte Start eine Sicherheitseigenschaft.

Eine Lebendigkeitseigenschaft (engl. liveness property) garantiert, dass erwünschte Zustände erreicht werden, was mit dem 𝒜 formuliert werden kann. Möchte man eine Fairness und dass zwei Eigenschaften unendlich Mal wiederholt werden, so verwendet man stattdessen 𝒜1𝒜2. Somit würde man im obigen Beispiel Folgendes erhalten:

ϕ =^ Initϕ[𝒜]x,z𝒜1𝒜2

Schwache und starke Fairness

In einem nebenläufigen System unterscheidet man zwischen schwacher und starker Fairness.

Schwache Fairness WF (engl. weak fairness, justice) bedeutet, dass eine Aktion unendlich oft ausgeführt werden muss, wenn ihre Ausführung ab einem bestimmten Zeitpunkt immer möglich ist.

Starke Fairness SF (engl. strong fairness, compassion) bedeutet, dass eine Aktion ausgeführt werden muss, wenn ihre Ausführung so oft möglich ist.

Ist ein Verhalten stark fair bezüglich einer Aktion, so ist es auch schwach fair für diese Aktion.

Siehe auch

Literatur

  • Leslie Lamport: The Temporal Logic of Actions. ACM Transactions on Programming Languages and Systems, Band 16, Mai 1994, S. 872–892 (PDF; 485 kB).
  • Leslie Lamport: Introduction to TLA. Digital System Research Center, Palo Alto 1997 (PDF; 121 kB).

Einzelnachweise