• Keine Ergebnisse gefunden

Entwicklung einer funktionalen Schnittstelle

Um die Datentypsemantik von SDL-2000 zu formalisieren, müssen Antworten auf folgende Fragen gefunden werden:

1. Wie werden Werte von Ausdrücken repräsentiert?

2. Wie wird die Belegung von Variablen repräsentiert?

3. Wie erfolgt die Berechnung von Operatoren?

Die Beantwortung der ersten Frage ist Voraussetzung der Beantwortung der zweiten und dritten Frage: Solange man nicht weiß, was ein Wert ist, kann man auch nicht definieren, wie der Wert einer Variablen ermittelt wird. Genauso wenig kann man definieren, was ein Operatorruf ist, da dieser Werte als aktuelle Argumente haben wird.

8.1.1 Werte

Auf der Basis der Domänenkonstruktionsmöglichkeiten der formalen Semantikdefinition wurde die Domäne Value definiert als Vereinigung aller möglichen Werte, die in SDL auftreten können, also als Vereinigung

VALUE =def SDLINTEGER SDLBOOLEAN SDLREAL SDLCHARACTER SDLSTRING

PID OBJECT SDLLITERALS SDLSTRUCTURE SDLARRAY SDLPOWERSET

SDLBAG SDLTIME SDLDURATION

Jede der einzelnen Teildomänen wird in den folgenden Abschnitten definiert. Zunächst waren für die Domänen, die durch vordefinierte Domänen des ASM-Kalküls realisiert wurden (also INTEGER, BOOLEAN) in der Domäne VALUE tatsächlich die vordefinierten Domänen aufgeführt.

Es zeigte sich aber, dass mit dieser Repräsentation keine polymorphen Variablen modelliert werden können, da bei Spezialisierung eines vordefinierten Typs (etwa Boolean) in SDL die dy-namische Repräsentation keine Typzugehörigkeit mehr erfasst. Deshalb sind die einzelnen Teil-domänen in der Regel TupelTeil-domänen, bei denen die zweite Projektion den dynamischen Typ im SDL-Sinne enthält.

Da eine Reihe von Funktionen der Datentypschnittstelle Parameter vom Typ Value haben, muss auch diese Domäne Teil der Schnittstelle sein – allerdings nur ihr Name, nicht (wie hier angegeben) auch ihre Definition.

8.1.2 Zustände

Mit Festlegung der Domäne VALUE kann man nun das Konzept der Variablenbelegung defi-nieren. Dabei müssen folgende Aspekte beachtet werden:

• Variablen mit verschiedenem Bezeichnern können verschiedene Werte haben.

• Variablen mit gleichem Bezeichner können auch verschiedene Werte haben, wenn sie zu verschiedenen SDL-Agenten oder zu verschiedenen Prozeduraufrufen gehören.

• Innerhalb eines Prozessagenten können verschachtelte Agenten sowie gerufene Prozeduren auf die Variablen umliegender Sichtbarkeitsbereiche zugreifen23.

• Sofern der zugreifende Agent und die zugreifende Prozedur bekannt sind, hat eine

bestimmte Variable zu jedem Zeitpunkt nur einen Wert. Bei Zuweisung ändert sich dieser Wert.

Um begrifflich die Unterscheidung zwischen einer in der abstrakten Syntax deklarierten Vari-ablen und ihren potentiell mehreren zugeordneten Werten zu ermöglichen, sollen folgende Be-griffe eingeführt werden:

• Der Variablenbezeichner ist die Kennung einer Variablen in der abstrakten Syntax: Jeder Knoten Variable-definition der abstrakten Syntax 1 ist genau einem Variablenbezeichner zugeordnet.

• Die Variable ist eine konkrete Inkarnation eines Variablenbezeichners, in einem konkreten Kontext (also einem Agenten oder einem Prozedurruf).

• Der Variablenwert ist der Wert, den eine Variable in einem bestimmten Systemzustand hat.

Zwischen diesen Begriffen gelten die Relationen, wie sie in Abbildung 11 dargestellt sind:

• Für eine Variablendefinition kann es beliebig viele Variablen geben.

• Eine Variable kann während der Abarbeitung eines Systems beliebig viele Werte haben.

Um den Wert einer Variable zu ermitteln, benötigt man die Variablendefinition sowie den „Kon-text“, in dem der Variablenzugriff erfolgt. Es liegt nahe, als „Kontext“ den Agenten zu verwen-den, der auf die Variable zugreift. Mit dieser Definition lässt sich aber die SDL-Semantik nicht wiedergeben, da beispielsweise innerhalb einer rekursiven Prozedur innerhalb eines Agenten die gleiche Variablendefinition gleichzeitig mehreren Werten zugeordnet sein kann (in verschie-denen der verschachtelten Prozeduraufrufe).

Während der Interpretation eines Agenten werden offenbar dynamisch neue Sätze von Vari-ablen angelegt, beispielsweise jedes Mal, wenn eine Prozedur gerufen wird. Ein solcher Satz von Variablen wird nun in der Datentypsemantik durch die Domäne State beschrieben. Unter Ausnutzung der ASM-Konzepte könnte nun die Zuordnung von Variablen zu Werten relativ einfach durch eine Funktion vom Typ controlled erfolgen:

controlled variableValue: STATE × IDENTIFIERVALUE

Leider verletzt diese Definition die Forderung, dass die Datentypsemantik eine funktionale Schnittstelle besitzt: Die Änderung dieser Funktion variableValue ist Aufgabe der

Datentypse-23. Innerhalb eines Blocks können Prozeduren und Prozesse ebenfalls auf die Blockvariablen zugreifen.

Allerdings erfolgt dieser Zugriff nicht direkt, sondern durch Signalaustausch. Die Formalisierung des Signalaustauschs ist nicht Aufgabe der Datentypsemantik.

Abbildung 11: Relation zwischen Variablendefinition, Variablen und Werten Variablendefinition

Variable Wert 1

n

1 n

definiert

besitzt nacheinander

mantik. Jede Änderung von controlled-Funktionen ist aber ein Seiteneffekt, der ja für die Da-tentypsemantik nicht erlaubt sein soll.

Um überhaupt Zustandsänderungen modellieren zu können, muss man annehmen, dass jeder Agent bei einer Zuweisung einer Variablen eine Funktion der Datentypsemantik ruft, und das Ergebnis dieses Funktionsrufs an eine controlled-Funktion zuweist. Die Funktion

assign: Variable-identifier × VALUE× STATE STATE

könnte beispielsweise dazu benutzt werden, Zuweisungen zu realisieren: Als Argumente erhält sie die Variable, den Wert und den alten Zustand, als Ergebnis liefert sie den neuen Zustand. Die eigentliche Repräsentation des Zustands ist dann Aufgabe der Datentypsemantik. Da es sich si-cher um einen strukturierten Wert handelt, bei Erzeugung eines Agenten oder bei Aufruf einer Prozedur eine Initialisierungsfunktion, etwa initState, gerufen werden, die beispielsweise auch die Standardwerte für Variablen setzt.

Nun kann bei einer Zuweisung an eine Variable in einer Prozedur die Variable auch vom um-liegenden Agenten definiert sein.

Beispiel 40. In textueller Syntax wird hier innerhalb einer Prozedur eine Variable des Agenten geändert.

process Agent;

dcl i Integer;

procedure Funktion(k Integer);

dcl m Integer;

start;

task m := k; /* lokale Zuweisung */

task i := k; /* globale Zuweisung */

return;

endprocedure;

start;

call Funktion(5);

stop;

endprocess;

Um die beiden Zuweisungen des Beispiels zu realisieren, müsste die Agentensemantik für die beiden Zuweisungen verschiedene Zustandsobjekte übergeben, und dazu also ermitteln, welche Variablen in welchen Zuständen vorhanden sind. Die Interpretation der Zustände ist aber Auf-gabe der Datentypsemantik.

Also muss die Agentensemantik stets den gesamten Zustand des Agenten (also all seine Va-riablen) an die Datentypsemantik übergeben, welche dann einen neuen Gesamtzustand zurück-gibt.

Der Gesamtzustand ist hierbei der Zustand, auf den verschachtelte Definitionen „direkt“ (al-so ohne Kommunikation) zugreifen können. Wie in Abbildung 12 dargestellt, ist er hierarchisch aufgebaut:

• Innere Agenten können auf die Variablen äußerer Agenten zugreifen.

• Verschachtelte SDL-Zustände können auf die Variablen umliegender Zustände und auf die des Agenten zugreifen.

• Innere Prozeduren können auf die Variablen ihrer umliegenden Rufer zugreifen. Durch das State-Aggregation-Konstrukt können in einem Agenten mehrere Prozedurstacks bestehen.

Aus diesen Betrachtungen folgt, dass stets der äußerste Prozess-Agent den Zustand aller ver-schachtelten Agenten sowie der Prozeduren verwaltet. Ein Blockagent ist selbst sein äußerster

Agent. Die Verschachtelung betrifft dann lediglich Prozeduren, die in dem Block selbst gerufen werden.

Da innerhalb eines solchen Gesamt-Zustands jede Variable mehrfach gebunden sein kann, müssen zur Kennung der Variablen Teile des Zustands identifiziert werden. Um diese Identifi-kation zu ermöglichen, wurde der Typ STATEID definiert:

controlled domain STATEID

Werte dieses Typs werden von der Agentensemantik dynamisch erzeugt, wenn ein neuer Teil-zustand benötigt wird24. Der Zugriff auf eine Variable benötigt nun also den Variablenbezeich-ner, den Zustand, sowie die Zustandsidentifikation. Die Variablenzugriffsfunktion kann damit durch folgende Signatur deklariert werden:

eval: Variable-identifier × STATE× STATEID VALUE

Die Änderungsfunktion für Variablen ändert sich damit zu

assign: Variable-identifier × VALUE× STATE× STATEID STATE

Zusätzlich werden noch einige Initialisierungsfunktionen benötigt, mit denen der Zustand um initiale Variablenbindungen angereichert werden kann:

DECLARATION =DEFPROCEDURE-FORMAL-PARAMETER ∪ VARIABLE-DEFINITION initAgentState: [STATE] × STATEID × [STATEID] × DECLARATION-set→ STATE initProcedureState: STATE × STATEID × STATEID × DECLARATION-set ×

VALUEORIDENTIFIER* × VALUE* × VARIABLE-IDENTIFIER*→ STATE

Zur Initialisierung eines Agentenzustands wird optional der alte Agentenzustand, die neue Zu-standidentifikation, optional die Identifikation des umliegenden Zustands sowie die Liste der zu deklarierenden Variablen benötigt. Bei der Initialisierung des Zustands einer Prozedur ist die Angabe des umliegenden Zustands nicht optional, zusätzlich werden die Parameternamen und Werte benötigt.

Abbildung 12: Variablenbindungen sind in SDL verschachtelt.

24. Auch die Erzeugung eines neuen Werts in einer controlled-Domäne ist eine Operation mit Seiteneffekt, also nicht-funktional.

Agent

Agent

Agent

Prozedur Prozedur

Prozedur

8.1.3 Ausnahmen

Die Operationen der Datentypsemantik können neben einer erfolgreichen Berechnung eines Er-gebnisses auch Ausnahmen produzieren. Falls eine Operation eine Ausnahme liefert, ändert sich der Systemzustand nicht.

Zur Repräsentation von Ausnahmen in der Datentypschnittstelle wurde die Domäne Excep-tion definiert:

EXCEPTION =def Identifier

Auf die Repräsentation von Parametern der Ausnahme konnte verzichtet werden, da in der Da-tentypsemantik nur die vordefinierten Ausnahmen auftreten können, und diese sämtlich ohne Parameter auskommen.25 Dies bedeutet natürlich eine Einschränkung für mögliche alternative Datentypsemantiken (etwa von C++): Falls sie Operatoren realisieren wollen, die parameterbe-haftete Ausnahmen auslösen, muss die Schnittstelle der Datentypsemantik angepasst werden.

Berechnungen der Datentypsemantik geben nun entweder einen neuen Zustand oder eine Ausnahme zurück. Dieser Rückgabetyp wird durch die Domäne STATEOREXCEPTION definiert.

Analog kann die Domäne VALUEOREXCEPTION wahlweise Werte oder Ausnahmen repräsentie-ren:

STATEOREXCEPTION =def STATE EXCEPTION

VALUEOREXCEPTION =def VALUE EXCEPTION

Da auch Zuweisungen Ausnahmen auslösen können, ändert sich die Signatur der Funktion assign in die endgültige Form

assign: Variable-identifier × VALUE× STATE× STATEID STATEOREXCEPTION

8.1.4 Berechnung von Operatoren

Wie in Abschnitt 7.3.3 bereits dargestellt, werden nutzerdefinierte Operatoren in Prozeduren transformiert und in der abstrakten Syntax ein Verweis auf die Prozedur hinterlegt.

Vordefinierte Operatoren (also Operatoren aus dem Paket predefined) können nicht auf die gleiche Weise interpretiert werden, da für sie keine Definition mit SDL-Mitteln angegeben wer-den kann. Deshalb muss die Berechnung von vordefinierten Operatoren „direkt“ in der Daten-typsemantik erfolgen.

Zur Bewertung eines Operatorrufs muss die dynamische Semantik also folgende Fragen be-antworten:

• Gegeben sei ein Operatorruf: Ist das der Ruf einer vordefinierten (funktionalen) Operation, oder erfordert er die Abarbeitung einer Prozedur?

• Falls eine Prozedur interpretiert werden soll: Welche?

• Anderenfalls, gegeben die Operationsargumente, wie lautet das Operationsergebnis?

Aus diesen drei Fragen wurde die folgende Operationssignatur abgeleitet:

functional: PROCEDURE × VALUE* → BOOLEAN dispatch: PROCEDURE × VALUE* → IDENTIFIER.

compute: PROCEDURE × VALUE* → VALUEOREXCEPTION

PROCEDURE =DEFSTATIC-OPERATION-SIGNATURE ∪ DYNAMIC-OPERATION-SIGNATURE

∪ LITERAL-SIGNATURE

25. Nutzerdefinierte Operatoren können natürlich auch parameterbehaftete Ausnahmen auslösen. Wie in 7.3.3 dargestellt, werden diese jedoch in Prozeduren transformiert und von der Agentensemantik interpretiert.

Mit der Funktion functional wird ermittelt, ob eine gegebene Operation für eine gegebene Ar-gumentliste funktional ist (also eine vordefinierte Semantik hat), oder durch eine Prozedur de-finiert wird. Die Funktion dispatch ermittelt in letzterem Fall die zu interpretierende Prozedur und gibt deren Bezeichner zurück. Für vordefinierte Operatoren ermittelt die Funktion compute den Ergebniswert (der unter Umständen eine Ausnahme ist).

Beim Versuch, die Funktion compute zu definieren, zeigte sich, dass diese Schnittstelle zureichend für die SDL-Semantik ist: auch die Berechnung vordefinierter Operatoren kann un-ter Umständen Seiteneffekte haben, wie beispielsweise die verändernden Operatoren für Strukturtypen und Felder. Deshalb wurde eine Funktion computeSideEffects in die Schnittstelle aufgenommen, die den neuen Agentenzustand ermittelt:

computeSideEffects: PROCEDURE × VALUE* × STATE × STATEID → STATE

8.1.5 Semantische Werte

Mit den soweit definierten Funktionen kann die Agentensemantik die Datentypsemantik einbet-ten, also alle nötigen Berechnungen ausführen. Tatsächlich reicht das aber zur Definition der Agentensemantik nicht. Wenn beispielsweise das Decision-Konstrukt interpretiert werden soll, so muss nicht nur der Testausdruck ausgewertet und mit den möglichen Antworten verglichen werden. Es muss auch noch ermittelt werden, ob die Antwort wahr oder falsch ist.

Aus diesem Grund wurde eine Reihe von Funktionen definiert, die für einen Wert der Domä-ne VALUE ermittelt, was der zugrunde liegende Wert einer der vordefinierten ASM-Domänen ist:

semvalueBool: SDLBOOLEAN BOOLEAN semvalueInt: SDLInteger Nat

Dabei ermittelt die Funktion semvalueBool den zugrunde liegenden Wahrheitswert und die Funktion semvalueInt die zugrunde liegende Zahl.